[Scummvm-git-logs] scummvm master -> 8591ae2260ec6c6a202a6d6893a1ebde0164c011
sev-
noreply at scummvm.org
Mon Jan 16 16:37:11 UTC 2023
This automated email contains information about 47 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
851c74df30 TETRAEDGE: New WIP engine for Syberia macOS and others
d07187a1a4 TETRAEDGE: More progress on WIP engine.
681b4f8c55 TETRAEDGE: More WIP. First scene now loads, yay.
1d62d47edb TETRAEDGE: More WIP. Can now see Kate in first scene.
2c87391803 TETRAEDGE: WIP, fixed loads of TODOs.
710a1b9f1b TETRAEDGE: More WIP. Idle animations work, character rotation and position now right.
a5811c653a TETRAEDGE: More WIP. Started work on pathfinding.
d28e9a2212 TETRAEDGE: WIP, can almost walk around now.
036ad4bc04 TETRAEDGE: WIP, fix suitcase and faces on the floor.
85ed7742de TETRAEDGE: More WIP. Can now walk between screens.
194b1a8081 TETRAEDGE: Work in progress, some inventory stuff done.
64c7267283 TETRAEDGE: Many small improvements.
c27dca6b82 TETRAEDGE: More WIP. Lots of progress
501b00ebe7 TETRAEDGE: WIP. Fixed some callbacks, more bits of the game working.
791575b0c2 TETRAEDGE: WIP: Fix more interactions
531b53f66a TETRAEDGE: Switch button priority to z-order
a3eb8b9c1c TETRAEDGE: Fix inventory and other interactions
61e3520067 TETRAEDGE: More WIP. Fixed various object problems.
e3aff09674 TETRAEDGE: Lua bind functions now complete.
4a8f9984d4 TETRAEDGE: Fixed more bugs, started save/load support.
769d8d9b42 TETRAEDGE: Fix a lot of small rendering bugs.
8b3c8844fe TETRAEDGE: Fix a lot of memory cleanup
4479e6e346 TETRAEDGE: Implement FreeMoveZone building
066dd8e155 TETRAEDGE: More improvements
eba2fb9b5f MATH: Add ray triangle intersection and tests
7424452fff TETRAEDGE: More fixes, can now complete first act.
0ba854df9a TETRAEDGE: More fixes, can now complete game.
f84785ff3a TETRAEDGE: Cleanups, started working on credits etc
9dab12cf3c TETRAEDGE: Misc code cleanups. Less public members.
0d981983fc TETRAEDGE: add ability to save/load any time
87bbf9660e TETRAEDGE: Reduce dependency on OpenGL headers
48015aa751 TETRAEDGE: Small fixes.
d0d67e91f8 TETRAEDGE: Reduce movement janks and accidental moves
9cdfb0deee TETRAEDGE: Clean up includes
c4869ff02f TETRAEDGE: Fix whitespace and use uint consistently
b75e9faae3 TETRAEDGE: Remove unused Console class
68790973ba TETRAEDGE: Comment for detection entry
1a793bae5b TETRAEDGE: Remove static objects and improve cleanup
16c607cd94 TETRAEDGE: Split OpenGL-specific code out to allow TinyGL support
fd496bdd55 TETRAEDGE: Remove unused variable
47739e4585 TETRAEDGE: Only compile openGL files when OGL is enabled
e6c8059523 TETRAEDGE: Add TinyGL implementation for TeLight.
8dfe5e4b88 TETRAEDGE: Clean up OGL/TGL classes slightly
91f1e17ed3 TETRAEDGE: Fixes to get to main menu of Syberia 2
b310f5dea3 TETRAEDGE: Fix compiler guards for GL (no shaders)
dbe6da9980 TETRAEDGE: Remove compile warnings
8591ae2260 TETRAEDGE: Fix updating of global light value
Commit: 851c74df306e73b0a36eca93839ce55eac569ed9
https://github.com/scummvm/scummvm/commit/851c74df306e73b0a36eca93839ce55eac569ed9
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2023-01-16T17:36:43+01:00
Commit Message:
TETRAEDGE: New WIP engine for Syberia macOS and others
Changed paths:
A engines/tetraedge/configure.engine
A engines/tetraedge/console.cpp
A engines/tetraedge/console.h
A engines/tetraedge/credits.pl
A engines/tetraedge/detection.cpp
A engines/tetraedge/detection.h
A engines/tetraedge/detection_tables.h
A engines/tetraedge/game/application.cpp
A engines/tetraedge/game/application.h
A engines/tetraedge/game/billboard.cpp
A engines/tetraedge/game/billboard.h
A engines/tetraedge/game/bonus_menu.cpp
A engines/tetraedge/game/bonus_menu.h
A engines/tetraedge/game/cellphone.cpp
A engines/tetraedge/game/cellphone.h
A engines/tetraedge/game/character.cpp
A engines/tetraedge/game/character.h
A engines/tetraedge/game/character_settings_xml_parser.cpp
A engines/tetraedge/game/character_settings_xml_parser.h
A engines/tetraedge/game/characters_shadow.cpp
A engines/tetraedge/game/characters_shadow.h
A engines/tetraedge/game/confirm.cpp
A engines/tetraedge/game/confirm.h
A engines/tetraedge/game/credits.cpp
A engines/tetraedge/game/credits.h
A engines/tetraedge/game/dialog2.cpp
A engines/tetraedge/game/dialog2.h
A engines/tetraedge/game/document.cpp
A engines/tetraedge/game/document.h
A engines/tetraedge/game/documents_browser.cpp
A engines/tetraedge/game/documents_browser.h
A engines/tetraedge/game/gallery_menu.cpp
A engines/tetraedge/game/gallery_menu.h
A engines/tetraedge/game/game.cpp
A engines/tetraedge/game/game.h
A engines/tetraedge/game/game_achievements.cpp
A engines/tetraedge/game/game_achievements.h
A engines/tetraedge/game/game_sound.cpp
A engines/tetraedge/game/game_sound.h
A engines/tetraedge/game/global_bonus_menu.cpp
A engines/tetraedge/game/global_bonus_menu.h
A engines/tetraedge/game/help_option_menu.cpp
A engines/tetraedge/game/help_option_menu.h
A engines/tetraedge/game/how_to.cpp
A engines/tetraedge/game/how_to.h
A engines/tetraedge/game/in_game_scene.cpp
A engines/tetraedge/game/in_game_scene.h
A engines/tetraedge/game/inventory.cpp
A engines/tetraedge/game/inventory.h
A engines/tetraedge/game/inventory_menu.cpp
A engines/tetraedge/game/inventory_menu.h
A engines/tetraedge/game/inventory_object.cpp
A engines/tetraedge/game/inventory_object.h
A engines/tetraedge/game/inventory_objects_xml_parser.cpp
A engines/tetraedge/game/inventory_objects_xml_parser.h
A engines/tetraedge/game/loading_menu.cpp
A engines/tetraedge/game/loading_menu.h
A engines/tetraedge/game/loc_file.cpp
A engines/tetraedge/game/loc_file.h
A engines/tetraedge/game/lua_binds.cpp
A engines/tetraedge/game/lua_binds.h
A engines/tetraedge/game/main_menu.cpp
A engines/tetraedge/game/main_menu.h
A engines/tetraedge/game/notifier.cpp
A engines/tetraedge/game/notifier.h
A engines/tetraedge/game/object3d.cpp
A engines/tetraedge/game/object3d.h
A engines/tetraedge/game/object_settings_xml_parser.cpp
A engines/tetraedge/game/object_settings_xml_parser.h
A engines/tetraedge/game/objectif.cpp
A engines/tetraedge/game/objectif.h
A engines/tetraedge/game/options_menu.cpp
A engines/tetraedge/game/options_menu.h
A engines/tetraedge/game/owner_error_menu.cpp
A engines/tetraedge/game/owner_error_menu.h
A engines/tetraedge/game/question2.cpp
A engines/tetraedge/game/question2.h
A engines/tetraedge/game/splash_screens.cpp
A engines/tetraedge/game/splash_screens.h
A engines/tetraedge/metaengine.cpp
A engines/tetraedge/metaengine.h
A engines/tetraedge/module.mk
A engines/tetraedge/te/micropather.cpp
A engines/tetraedge/te/micropather.h
A engines/tetraedge/te/te_3d_object2.cpp
A engines/tetraedge/te/te_3d_object2.h
A engines/tetraedge/te/te_3d_texture.cpp
A engines/tetraedge/te/te_3d_texture.h
A engines/tetraedge/te/te_animation.cpp
A engines/tetraedge/te/te_animation.h
A engines/tetraedge/te/te_bezier_curve.cpp
A engines/tetraedge/te/te_bezier_curve.h
A engines/tetraedge/te/te_button_layout.cpp
A engines/tetraedge/te/te_button_layout.h
A engines/tetraedge/te/te_callback.h
A engines/tetraedge/te/te_camera.cpp
A engines/tetraedge/te/te_camera.h
A engines/tetraedge/te/te_checkbox_layout.cpp
A engines/tetraedge/te/te_checkbox_layout.h
A engines/tetraedge/te/te_clip_layout.cpp
A engines/tetraedge/te/te_clip_layout.h
A engines/tetraedge/te/te_color.cpp
A engines/tetraedge/te/te_color.h
A engines/tetraedge/te/te_core.cpp
A engines/tetraedge/te/te_core.h
A engines/tetraedge/te/te_curve_anim2.h
A engines/tetraedge/te/te_extended_text_layout.cpp
A engines/tetraedge/te/te_extended_text_layout.h
A engines/tetraedge/te/te_fee_move_zone.cpp
A engines/tetraedge/te/te_fee_move_zone.h
A engines/tetraedge/te/te_font3.cpp
A engines/tetraedge/te/te_font3.h
A engines/tetraedge/te/te_frame_anim.cpp
A engines/tetraedge/te/te_frame_anim.h
A engines/tetraedge/te/te_free_move_zone.cpp
A engines/tetraedge/te/te_free_move_zone.h
A engines/tetraedge/te/te_i_3d_object2.cpp
A engines/tetraedge/te/te_i_3d_object2.h
A engines/tetraedge/te/te_i_codec.h
A engines/tetraedge/te/te_i_layout.cpp
A engines/tetraedge/te/te_i_layout.h
A engines/tetraedge/te/te_i_loc.cpp
A engines/tetraedge/te/te_i_loc.h
A engines/tetraedge/te/te_image.cpp
A engines/tetraedge/te/te_image.h
A engines/tetraedge/te/te_input_mgr.cpp
A engines/tetraedge/te/te_input_mgr.h
A engines/tetraedge/te/te_interpolation.cpp
A engines/tetraedge/te/te_interpolation.h
A engines/tetraedge/te/te_intrusive_ptr.h
A engines/tetraedge/te/te_jpeg.cpp
A engines/tetraedge/te/te_jpeg.h
A engines/tetraedge/te/te_layout.cpp
A engines/tetraedge/te/te_layout.h
A engines/tetraedge/te/te_light.cpp
A engines/tetraedge/te/te_light.h
A engines/tetraedge/te/te_list_layout.cpp
A engines/tetraedge/te/te_list_layout.h
A engines/tetraedge/te/te_lua_context.cpp
A engines/tetraedge/te/te_lua_context.h
A engines/tetraedge/te/te_lua_gui.cpp
A engines/tetraedge/te/te_lua_gui.h
A engines/tetraedge/te/te_lua_gui_lua_callbacks.cpp
A engines/tetraedge/te/te_lua_gui_lua_callbacks.h
A engines/tetraedge/te/te_lua_script.cpp
A engines/tetraedge/te/te_lua_script.h
A engines/tetraedge/te/te_lua_thread.cpp
A engines/tetraedge/te/te_lua_thread.h
A engines/tetraedge/te/te_material.cpp
A engines/tetraedge/te/te_material.h
A engines/tetraedge/te/te_matricies_stack.cpp
A engines/tetraedge/te/te_matricies_stack.h
A engines/tetraedge/te/te_matrix4x4.cpp
A engines/tetraedge/te/te_matrix4x4.h
A engines/tetraedge/te/te_mesh.cpp
A engines/tetraedge/te/te_mesh.h
A engines/tetraedge/te/te_model.cpp
A engines/tetraedge/te/te_model.h
A engines/tetraedge/te/te_model_animation.cpp
A engines/tetraedge/te/te_model_animation.h
A engines/tetraedge/te/te_model_vertex_animation.cpp
A engines/tetraedge/te/te_model_vertex_animation.h
A engines/tetraedge/te/te_music.cpp
A engines/tetraedge/te/te_music.h
A engines/tetraedge/te/te_name_val_xml_parser.cpp
A engines/tetraedge/te/te_name_val_xml_parser.h
A engines/tetraedge/te/te_object.cpp
A engines/tetraedge/te/te_object.h
A engines/tetraedge/te/te_obp.cpp
A engines/tetraedge/te/te_obp.h
A engines/tetraedge/te/te_palette.cpp
A engines/tetraedge/te/te_palette.h
A engines/tetraedge/te/te_pick_mesh2.cpp
A engines/tetraedge/te/te_pick_mesh2.h
A engines/tetraedge/te/te_png.cpp
A engines/tetraedge/te/te_png.h
A engines/tetraedge/te/te_quaternion.cpp
A engines/tetraedge/te/te_quaternion.h
A engines/tetraedge/te/te_real_timer.cpp
A engines/tetraedge/te/te_real_timer.h
A engines/tetraedge/te/te_references_counter.h
A engines/tetraedge/te/te_renderer.cpp
A engines/tetraedge/te/te_renderer.h
A engines/tetraedge/te/te_resource.cpp
A engines/tetraedge/te/te_resource.h
A engines/tetraedge/te/te_resource_manager.cpp
A engines/tetraedge/te/te_resource_manager.h
A engines/tetraedge/te/te_scene.cpp
A engines/tetraedge/te/te_scene.h
A engines/tetraedge/te/te_screen.cpp
A engines/tetraedge/te/te_screen.h
A engines/tetraedge/te/te_scrolling_layout.cpp
A engines/tetraedge/te/te_scrolling_layout.h
A engines/tetraedge/te/te_scummvm_codec.cpp
A engines/tetraedge/te/te_scummvm_codec.h
A engines/tetraedge/te/te_sfx.cpp
A engines/tetraedge/te/te_sfx.h
A engines/tetraedge/te/te_signal.h
A engines/tetraedge/te/te_sound_manager.cpp
A engines/tetraedge/te/te_sound_manager.h
A engines/tetraedge/te/te_sprite_layout.cpp
A engines/tetraedge/te/te_sprite_layout.h
A engines/tetraedge/te/te_text_base2.cpp
A engines/tetraedge/te/te_text_base2.h
A engines/tetraedge/te/te_text_layout.cpp
A engines/tetraedge/te/te_text_layout.h
A engines/tetraedge/te/te_text_layout_xml_parser.cpp
A engines/tetraedge/te/te_text_layout_xml_parser.h
A engines/tetraedge/te/te_tga.cpp
A engines/tetraedge/te/te_tga.h
A engines/tetraedge/te/te_theora.cpp
A engines/tetraedge/te/te_theora.h
A engines/tetraedge/te/te_tiled_surface.cpp
A engines/tetraedge/te/te_tiled_surface.h
A engines/tetraedge/te/te_tiled_texture.cpp
A engines/tetraedge/te/te_tiled_texture.h
A engines/tetraedge/te/te_timer.cpp
A engines/tetraedge/te/te_timer.h
A engines/tetraedge/te/te_trs.cpp
A engines/tetraedge/te/te_trs.h
A engines/tetraedge/te/te_variant.cpp
A engines/tetraedge/te/te_variant.h
A engines/tetraedge/te/te_vector2f32.cpp
A engines/tetraedge/te/te_vector2f32.h
A engines/tetraedge/te/te_vector2s32.cpp
A engines/tetraedge/te/te_vector2s32.h
A engines/tetraedge/te/te_vector3f32.cpp
A engines/tetraedge/te/te_vector3f32.h
A engines/tetraedge/te/te_visual_fade.cpp
A engines/tetraedge/te/te_visual_fade.h
A engines/tetraedge/te/te_xml_gui.cpp
A engines/tetraedge/te/te_xml_gui.h
A engines/tetraedge/tetraedge.cpp
A engines/tetraedge/tetraedge.h
A engines/tetraedge/to_lua.cpp
A engines/tetraedge/to_lua.h
diff --git a/engines/tetraedge/configure.engine b/engines/tetraedge/configure.engine
new file mode 100644
index 00000000000..5712178cc81
--- /dev/null
+++ b/engines/tetraedge/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]
+add_engine tetraedge "Tetraedge" no "" "" "highres freetype2 vorbis png jpeg lua theoradec"
diff --git a/engines/tetraedge/console.cpp b/engines/tetraedge/console.cpp
new file mode 100644
index 00000000000..c455866a69a
--- /dev/null
+++ b/engines/tetraedge/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 "tetraedge/console.h"
+
+namespace Tetraedge {
+
+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;
+}
+
+} // namespace Tetraedge
diff --git a/engines/tetraedge/console.h b/engines/tetraedge/console.h
new file mode 100644
index 00000000000..210f467ab37
--- /dev/null
+++ b/engines/tetraedge/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 TETRAEDGE_CONSOLE_H
+#define TETRAEDGE_CONSOLE_H
+
+#include "gui/debugger.h"
+
+namespace Tetraedge {
+
+class Console : public GUI::Debugger {
+private:
+ bool Cmd_test(int argc, const char **argv);
+public:
+ Console();
+ ~Console() override;
+};
+
+} // End of namespace Tetraedge
+
+#endif
diff --git a/engines/tetraedge/credits.pl b/engines/tetraedge/credits.pl
new file mode 100644
index 00000000000..a14c198dbb6
--- /dev/null
+++ b/engines/tetraedge/credits.pl
@@ -0,0 +1,3 @@
+begin_section("Tetraedge");
+ add_person("Matthew Duggan", "Handle 1", "");
+end_section();
diff --git a/engines/tetraedge/detection.cpp b/engines/tetraedge/detection.cpp
new file mode 100644
index 00000000000..938be16631e
--- /dev/null
+++ b/engines/tetraedge/detection.cpp
@@ -0,0 +1,47 @@
+/* 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 "tetraedge/detection.h"
+#include "tetraedge/detection_tables.h"
+
+const DebugChannelDef TetraedgeMetaEngineDetection::debugFlagList[] = {
+ { Tetraedge::kDebugGraphics, "Graphics", "Graphics debug level" },
+ { Tetraedge::kDebugPath, "Path", "Pathfinding debug level" },
+ { Tetraedge::kDebugFilePath, "FilePath", "File path debug level" },
+ { Tetraedge::kDebugScan, "Scan", "Scan for unrecognised games" },
+ { Tetraedge::kDebugScript, "Script", "Enable debug script dump" },
+ DEBUG_CHANNEL_END
+};
+
+TetraedgeMetaEngineDetection::TetraedgeMetaEngineDetection() : AdvancedMetaEngineDetection(Tetraedge::GAME_DESCRIPTIONS,
+ sizeof(ADGameDescription), Tetraedge::GAME_NAMES) {
+ _flags = kADFlagMatchFullPaths;
+ _maxScanDepth = 3;
+}
+
+REGISTER_PLUGIN_STATIC(TETRAEDGE_DETECTION, PLUGIN_TYPE_ENGINE_DETECTION, TetraedgeMetaEngineDetection);
diff --git a/engines/tetraedge/detection.h b/engines/tetraedge/detection.h
new file mode 100644
index 00000000000..e6efa6712cd
--- /dev/null
+++ b/engines/tetraedge/detection.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 TETRAEDGE_DETECTION_H
+#define TETRAEDGE_DETECTION_H
+
+#include "engines/advancedDetector.h"
+
+namespace Tetraedge {
+
+enum TetraedgeDebugChannels {
+ kDebugGraphics = 1 << 0,
+ kDebugPath = 1 << 1,
+ kDebugScan = 1 << 2,
+ kDebugFilePath = 1 << 3,
+ kDebugScript = 1 << 4
+};
+
+extern const PlainGameDescriptor GAME_NAMES[];
+
+extern const ADGameDescription GAME_DESCRIPTIONS[];
+
+} // namespace Tetraedge
+
+class TetraedgeMetaEngineDetection : public AdvancedMetaEngineDetection {
+ static const DebugChannelDef debugFlagList[];
+
+public:
+ TetraedgeMetaEngineDetection();
+ ~TetraedgeMetaEngineDetection() override {}
+
+ const char *getEngineName() const override {
+ return "Tetraedge Engine";
+ }
+
+ const char *getName() const override {
+ return "tetraedge";
+ }
+
+ const char *getOriginalCopyright() const override {
+ return "(C) Microids";
+ }
+
+ const DebugChannelDef *getDebugChannels() const override {
+ return debugFlagList;
+ }
+};
+
+#endif
diff --git a/engines/tetraedge/detection_tables.h b/engines/tetraedge/detection_tables.h
new file mode 100644
index 00000000000..a6db2b5a904
--- /dev/null
+++ b/engines/tetraedge/detection_tables.h
@@ -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/>.
+ *
+ */
+
+namespace Tetraedge {
+
+const PlainGameDescriptor GAME_NAMES[] = {
+ { "syberia", "Syberia" },
+ { "amerzone", "Amerzone" },
+ { "syberia2", "Syberia II" },
+ { 0, 0 }
+};
+
+const ADGameDescription GAME_DESCRIPTIONS[] = {
+ {
+ "syberia",
+ nullptr,
+ AD_ENTRY1s("MacOS/Syberia", "6951fb8f71fe06f34684564625f73cd8", 10640592),
+ Common::EN_ANY,
+ Common::kPlatformMacintosh,
+ ADGF_UNSTABLE,
+ GUIO1(GUIO_NONE)
+ },
+
+ AD_TABLE_END_MARKER
+};
+
+} // namespace Tetraedge
diff --git a/engines/tetraedge/game/application.cpp b/engines/tetraedge/game/application.cpp
new file mode 100644
index 00000000000..fbb337d8b1d
--- /dev/null
+++ b/engines/tetraedge/game/application.cpp
@@ -0,0 +1,498 @@
+/* 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/textconsole.h"
+#include "common/file.h"
+#include "common/util.h"
+#include "common/events.h"
+
+#include "graphics/opengl/system_headers.h"
+
+#include "tetraedge/tetraedge.h"
+#include "tetraedge/game/game.h"
+#include "tetraedge/game/application.h"
+#include "tetraedge/te/te_core.h"
+#include "tetraedge/te/te_resource_manager.h"
+#include "tetraedge/te/te_renderer.h"
+#include "tetraedge/te/te_font3.h"
+#include "tetraedge/te/te_input_mgr.h"
+//#include "tetraedge/te/te_textbase2.h"
+
+namespace Tetraedge {
+
+bool Application::_dontUpdateWhenApplicationPaused = false;
+
+Application::Application() : _finishedGame(false), _finishedFremium(false),
+_captureFade(false), _difficulty(1), _created(false), _tutoActivated(false) {
+ TeCore *core = g_engine->getCore();
+ core->_coreNotReady = true;
+ core->fileFlagSystemSetFlag("platform", "MacOSX");
+ core->fileFlagSystemSetFlag("part", "Full");
+ core->fileFlagSystemSetFlag("distributor", "DefaultDistributor");
+
+ TeLuaGUI tempGui;
+ tempGui.load("texts/Part.lua");
+ _applicationTitle = tempGui.value("applicationTitle").toString();
+ _versionString = tempGui.value("versionString").toString();
+ _firstWarpPath = tempGui.value("firstWarpPath").toString();
+ _firstZone = tempGui.value("firstZone").toString();
+ _firstScene = tempGui.value("firstScene").toString();
+
+ // TODO: Configure sound manager here?
+ // TODO: Configure freemium things here?
+ // TODO: Start some timer here?
+
+ loadOptions("options.xml");
+}
+
+void Application::create() {
+ warning("TODO: Move mainWindowCamera to mainWindow");
+
+ const int winWidth = g_engine->getDefaultScreenWidth();
+ const int winHeight = g_engine->getDefaultScreenHeight();
+ // See TeMainWindowBase::initCamera
+ _mainWindowCamera.reset(new TeCamera());
+ _mainWindowCamera->_projectionMatrixType = 4;
+ _mainWindowCamera->viewport(0, 0, winWidth, winHeight);
+ _mainWindowCamera->orthogonalParams(winWidth * -0.5f, winWidth * 0.5f, winHeight * 0.5f, winHeight * -0.5f);
+ _mainWindowCamera->_orthNearVal = -2048.0f;
+ _mainWindowCamera->_orthFarVal = 2048.0f;
+
+ _mainWindow.setSize(TeVector3f32(winWidth, winHeight, 100.0));
+ _mainWindow.setSizeType(TeILayout::ABSOLUTE);
+ _mainWindow.setPositionType(TeILayout::ABSOLUTE);
+
+ TeResourceManager *resmgr = g_engine->getResourceManager();
+ _fontComic = resmgr->getResourceNoSearch<TeFont3>("Common/Fonts/ComicRelief.ttf");
+ _fontComic->load("Common/Fonts/ComicRelief.ttf");
+ _fontArgh = resmgr->getResourceNoSearch<TeFont3>("Common/Fonts/Argh.ttf");
+ _fontArgh->load("Common/Fonts/Argh.ttf");
+ _fontArial = resmgr->getResourceNoSearch<TeFont3>("Common/Fonts/arial.ttf");
+ _fontArial->load("Common/Fonts/arial.ttf");
+ _fontChaucer = resmgr->getResourceNoSearch<TeFont3>("Common/Fonts/CHAUCER.TTF");
+ _fontChaucer->load("Common/Fonts/CHAUCER.ttf");
+ _fontColaborate = resmgr->getResourceNoSearch<TeFont3>("Common/Fonts/Colaborate-Regular.otf");
+ _fontColaborate->load("Common/Fonts/Colaborate-Regular.ttf");
+ _fontProDisplay = resmgr->getResourceNoSearch<TeFont3>("Common/Fonts/ProDisplay.ttf");
+ _fontProDisplay->load("Common/Fonts/ProDisplay.ttf");
+
+ // The app prebuilds some fonts.. cover letters, numbers, a few accented chars, and punctuation.
+ // Skip that here.
+ /*
+ TeTextBase2 textBase;
+ textBase.setText("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789/,*?;.:/!\xA7&\xE9\"'(-\xE8_\xE7\xE0)=");
+ textBase.setFont(0, _fontComic);
+ textBase.setRect(TeVector2s32(1, 1));
+ textBase.setFontSize(12);
+ textBase.build();
+ textBase.setFontSize(14);
+ textBase.build();
+ textBase.setFontSize(16);
+ textBase.build();
+ textBase.setFontSize(18);
+ textBase.build();
+ textBase.setFontSize(30);
+ textBase.build();
+ textBase.setFont(0, _fontColaborate);
+ textBase.setFontSize(18);
+ textBase.build();
+ textBase.setFont(0, _fontProDisplay);
+ textBase.setFontSize(24);
+ textBase.build();
+ */
+
+ TeCore *core = g_engine->getCore();
+ static const char allLangs[][3] = {"en", "fr", "de", "es", "it", "ru"};
+ const Common::Path textsPath("texts");
+
+ // Try alternate langs..
+ int i = 0;
+ Common::Path textFilePath;
+ while (i < ARRAYSIZE(allLangs)) {
+ textFilePath = textsPath.join(core->language() + ".xml");
+ if (Common::File::exists(textFilePath))
+ break;
+ core->language(allLangs[i]);
+ i++;
+ }
+ if (i == ARRAYSIZE(allLangs)) {
+ error("Couldn't find texts/[lang].xml for any language.");
+ }
+
+ _loc.load(textFilePath);
+ core->addLoc(&_loc);
+
+ const Common::Path helpMenuPath("menus/help/help_");
+ Common::Path helpMenuFilePath;
+ i = 0;
+ while (i < ARRAYSIZE(allLangs)) {
+ helpMenuFilePath = helpMenuPath.append(core->language() + ".xml");
+ if (Common::File::exists(helpMenuFilePath))
+ break;
+ core->language(allLangs[i]);
+ i++;
+ }
+ if (i == ARRAYSIZE(allLangs)) {
+ error("Couldn't find menus/help/help_[lang].xml for any language.");
+ }
+
+ _helpGui.load(helpMenuFilePath);
+
+ debug("TODO: set TeCore flags here? Do they do anything?");
+
+ // Game calls these here but does nothing with result?
+ //TeGetDeviceDPI();
+ //TeGetDeviceReferenceDPI();
+
+ _backLayout.setName("layoutBack");
+ _backLayout.setSizeType(TeLayout::CoordinatesType::RELATIVE_TO_PARENT);
+ _backLayout.setSize(TeVector3f32(1.0f, 1.0f, 0.0f));
+ _mainWindow.addChild(&_backLayout);
+
+ _frontOrientationLayout.setName("orientationLayoutFront");
+ _frontOrientationLayout.setSizeType(TeLayout::CoordinatesType::RELATIVE_TO_PARENT);
+ _frontOrientationLayout.setSize(TeVector3f32(1.0f, 1.0f, 0.0f));
+ _mainWindow.addChild(&_frontOrientationLayout);
+
+ _frontLayout.setName("layoutFront");
+ _frontLayout.setSizeType(TeLayout::CoordinatesType::RELATIVE_TO_PARENT);
+ _frontLayout.setSize(TeVector3f32(1.0f, 1.0f, 0.0f));
+ _frontOrientationLayout.addChild(&_frontLayout);
+
+ _visFade.init();
+
+ _frontOrientationLayout.addChild(&_visFade._fadeCaptureSprite);
+ _frontOrientationLayout.addChild(&_visFade._blackFadeSprite);
+ _frontOrientationLayout.addChild(&_visFade._buttonLayout);
+
+ _frontLayout.addChild(&_appSpriteLayout);
+ _appSpriteLayout.setSizeType(TeLayout::CoordinatesType::RELATIVE_TO_PARENT);
+ _appSpriteLayout.setSize(TeVector3f32(1.0f, 1.0f, 1.0f));
+ _appSpriteLayout.setVisible(false);
+
+ // Note: The games do some loading of a "version.ver" file here to add a
+ // watermark to the backLayout, but that file doesn't exist in any of the
+ // GOG games so it was probably only used during development.
+ const Common::Path verFilePath("version.ver");
+ if (Common::File::exists(verFilePath)) {
+ warning("Skipping doing anything with version.ver file");
+ }
+
+ _mouseCursorLayout.setName("mouseCursor");
+
+ // Not needed in scummvm:
+ g_system->showMouse(false);
+ //mainWindow->setNativeCursorVisible(false);
+
+ _mouseCursorLayout.load("pictures/cursor.png");
+ _mouseCursorLayout.setAnchor(TeVector3f32(0.3f, 0.1f, 0.0f));
+ _frontOrientationLayout.addChild(&_mouseCursorLayout);
+
+ _lockCursorButton.setName("lockCursorButton");
+ _lockCursorButton.setSizeType(TeLayout::CoordinatesType::RELATIVE_TO_PARENT);
+ _lockCursorButton.setSize(TeVector3f32(2.0f, 0.095f, 0.0f));
+ _lockCursorButton.setPositionType(TeLayout::CoordinatesType::RELATIVE_TO_PARENT);
+ _lockCursorButton.setPosition(TeVector3f32(0.95f, 0.95f, 0.0f));
+ _lockCursorButton.setVisible(false);
+ _frontOrientationLayout.addChild(&_lockCursorButton);
+
+ _lockCursorFromActionButton.setName("lockCursorFromActionButton");
+ _lockCursorFromActionButton.setSizeType(TeLayout::CoordinatesType::RELATIVE_TO_PARENT);
+ _lockCursorFromActionButton.setSize(TeVector3f32(2.0f, 2.0f, 0.0f));
+ _lockCursorFromActionButton.setVisible(false);
+ _frontOrientationLayout.addChild(&_lockCursorFromActionButton);
+
+ _autoSaveIcon1.setName("autosaveIcon");
+ _autoSaveIcon1.setAnchor(TeVector3f32(0.5f, 0.5f, 0.0f));
+ _autoSaveIcon1.setPosition(TeVector3f32(0.2f, 0.9f, 0.0f));
+ _autoSaveIcon1.setSize(TeVector3f32(128.0f, 64.0f, 0.0f));
+ _autoSaveIcon1.load("menus/inGame/autosave_icon.png");
+ _autoSaveIcon1.setVisible(false);
+ _frontOrientationLayout.addChild(&_autoSaveIcon1);
+
+ _autoSaveIconAnim1._runTimer.pausable(false);
+ _autoSaveIconAnim1.pause();
+ _autoSaveIconAnim1._startVal = TeColor(255, 255, 255, 0);
+ _autoSaveIconAnim1._endVal = TeColor(255, 255, 255, 255);
+ Common::Array<float> curve;
+ curve.push_back(0.0f);
+ curve.push_back(1.0f);
+ curve.push_back(1.0f);
+ curve.push_back(0.0f);
+ _autoSaveIconAnim1.setCurve(curve);
+ _autoSaveIconAnim1._duration = 4000.0f;
+ _autoSaveIconAnim1._callbackObj = &_autoSaveIcon1;
+ _autoSaveIconAnim1._callbackMethod = &Te3DObject2::setColor;
+
+ _autoSaveIcon2.setName("autosaveIcon");
+ _autoSaveIcon2.setAnchor(TeVector3f32(0.5f, 0.5f, 0.0f));
+ _autoSaveIcon2.setPosition(TeVector3f32(0.2f, 0.7f, 0.0f));
+ _autoSaveIcon2.setSize(TeVector3f32(68.0f, 86.0f, 0.0f));
+ _autoSaveIcon2.load("menus/inGame/NoCel.png");
+ _autoSaveIcon2.setVisible(false);
+ _frontOrientationLayout.addChild(&_autoSaveIcon2);
+
+ _autoSaveIconAnim2._runTimer.pausable(false);
+ _autoSaveIconAnim2.pause();
+ _autoSaveIconAnim2._startVal = TeColor(255, 255, 255, 0);
+ _autoSaveIconAnim2._endVal = TeColor(255, 255, 255, 255);
+ _autoSaveIconAnim2.setCurve(curve);
+ _autoSaveIconAnim2._duration = 4000.0f;
+ _autoSaveIconAnim2._callbackObj = &_autoSaveIcon2;
+ _autoSaveIconAnim2._callbackMethod = &Te3DObject2::setColor;
+
+ _blackFadeAnimationFinishedSignal.add<Application>(this, &Application::onBlackFadeAnimationFinished);
+
+ g_engine->getInputMgr()->_mouseMoveSignal.add(this, &Application::onMousePositionChanged);
+
+ onMainWindowSizeChanged();
+ _splashScreens.enter();
+ _created = true;
+}
+
+void Application::destroy() {
+ error("TODO: Implement Application::destroy");
+}
+
+void Application::startGame(bool newGame, int difficulty) {
+ _appSpriteLayout.setVisible(false);
+ // TODO: there's another virtual call to appsprite surface here here.. not needed?
+ _appSpriteLayout.unload();
+ if (newGame)
+ _difficulty = difficulty;
+ g_engine->getGame()->enter(newGame);
+}
+
+void Application::resume() {
+ error("TODO: Implement Application::resume");
+}
+
+bool Application::run() {
+ if (_created) {
+ TeTimer::updateAll();
+ if (!_dontUpdateWhenApplicationPaused) {
+ // TODO: finish commented-out bits??
+ // we run the inputmgr separately.. is that ok?
+ //_inputmgr->update();
+ TeAnimation::updateAll();
+ //TeVideo::updateAll();
+ }
+ _captureFade = false;
+
+ TeRenderer *renderer = g_engine->getRenderer();
+ Game *game = g_engine->getGame();
+
+ renderer->reset();
+ game->update();
+ //_soundManager->update(soundmgr);
+ performRender();
+ if (game->_returnToMainMenu) {
+ game->leave(true);
+ if (!game->luaShowOwnerError()) {
+ _mainMenu.enter();
+ } else {
+ _ownerErrorMenu.enter();
+ }
+ game->_returnToMainMenu = false;
+ }
+ if (_finishedGame) {
+ game->leave(false);
+ _mainMenu.enter();
+ if (Common::File::exists("finalURL.lua")) {
+ TeLuaGUI finalGui;
+ finalGui.load("finalURL.lua");
+ /*TeVariant finalVal =*/ finalGui.value("finalURL");
+ debug("TODO: use final URL??");
+ // TODO: Not clear if this variant is ever used in original.
+ finalGui.unload();
+ }
+ _finishedGame = false;
+ }
+ InGameScene::updateScroll();
+ TeObject::deleteNow();
+ }
+ return true;
+}
+
+void Application::suspend() {
+ error("TODO: Implement Application::suspend");
+}
+
+void Application::showNoCellIcon(bool show) {
+ if (!show) {
+ _autoSaveIconAnim2._repeatCount = 1;
+ } else {
+ _autoSaveIcon2.setVisible(true);
+ _autoSaveIcon2.setColor(TeColor(255, 255, 255, 255));
+ _autoSaveIconAnim2._repeatCount = -1;
+ _autoSaveIconAnim2.play();
+ }
+}
+
+void Application::showLoadingIcon(bool show) {
+ if (!show) {
+ _autoSaveIconAnim1._repeatCount = 1;
+ } else {
+ _autoSaveIcon1.setVisible(true);
+ _autoSaveIcon1.setColor(TeColor(255, 255, 255, 255));
+ _autoSaveIconAnim1._repeatCount = -1;
+ _autoSaveIconAnim1.play();
+ }
+}
+
+void Application::saveCorrupted(const Common::String &fname) {
+ error("TODO: Implement Application::showLoadingIcon");
+}
+
+void Application::drawBack() {
+ _mainWindowCamera->apply();
+ _backLayout.draw();
+ TeCamera::restore();
+ g_engine->getRenderer()->loadIdentityMatrix();
+}
+
+void Application::drawFront() {
+ _mainWindowCamera->apply();
+ _frontOrientationLayout.draw();
+ TeCamera::restore();
+ g_engine->getRenderer()->loadIdentityMatrix();
+}
+
+void Application::performRender() {
+ Game *game = g_engine->getGame();
+ TeRenderer *renderer = g_engine->getRenderer();
+
+ if (game->running() && _inGameScene._character && true /*some other ingamescene things*/) {
+ renderer->shadowMode(TeRenderer::ShadowMode1);
+ //_inGameScene._charactersShadow->createTexture(_inGameScene);
+ renderer->shadowMode(TeRenderer::ShadowMode0);
+ error("TODO: Implement characters shadow thing here.");
+ }
+
+ drawBack();
+
+ renderer->renderTransparentMeshes();
+ renderer->clearBuffer(GL_ACCUM);
+
+ if (game->running() && _inGameScene._character && true /*some other ingamescene things*/) {
+ TeIntrusivePtr<TeCamera> currentCamera = _inGameScene.currentCamera();
+ if (currentCamera) {
+ currentCamera->apply();
+ renderer->shadowMode(TeRenderer::ShadowMode2);
+ //_inGameScene._charactersShadow->draw(_inGameScene);
+ renderer->shadowMode(TeRenderer::ShadowMode0);
+ error("TODO: Implement characters shadow thing here.");
+ }
+ game->draw();
+ }
+
+ renderer->renderTransparentMeshes();
+ renderer->clearBuffer(GL_ACCUM);
+ drawFront();
+ renderer->renderTransparentMeshes();
+ // What gets called here??
+ //_inGameScene.removeModel(const Common::String &name)
+ g_system->updateScreen();
+}
+
+//void Application::preloadTextrue(); does nothing..
+
+void Application::fade() {
+ _visFade.animateFade();
+}
+
+void Application::blackFade() {
+ _visFade.animateBlackFade();
+}
+
+void Application::captureFade() {
+ if (_captureFade)
+ return;
+ _captureFade = true;
+ performRender();
+ _visFade.captureFrame();
+}
+
+bool Application::isFading() {
+ warning("Application::isFading: Check field here.");
+ if (true /* field_0xb1e1? */)
+ return _visFade.fading();
+ return false;
+}
+
+bool Application::onBlackFadeAnimationFinished() {
+ error("TODO: Implement Application::onBlackFadeAnimationFinished");
+ return false;
+}
+
+bool Application::onMainWindowSizeChanged() {
+ // This sets HD or SD "definition" in the core depending on device DPI.
+ // For now just default to SD.
+ debug("mainWindowSizeChanged: defaulting to SD.");
+ g_engine->getCore()->fileFlagSystemSetFlag("definition", "SD");
+ return false;
+}
+
+bool Application::onMousePositionChanged(const Common::Point &p) {
+ const TeVector3f32 mainWinSize = _mainWindow.size();
+ const TeVector3f32 newCursorPos(p.x / mainWinSize.x(), p.y / mainWinSize.y(), 0.0);
+ _mouseCursorLayout.setPosition(newCursorPos);
+ return false;
+}
+
+bool Application::isLockCursor() {
+ return _lockCursorButton.visible() || _lockCursorFromActionButton.visible();
+}
+
+bool Application::isLockPad() {
+ error("TODO: Implement Application::isLockPad");
+ return false;
+}
+
+void Application::lockCursor(bool lock) {
+ error("TODO: Implement Application::lockCursor");
+}
+
+void Application::lockCursorFromAction(bool lock) {
+ error("TODO: Implement Application::lockCursorFromAction");
+}
+
+void Application::loadOptions(const Common::String &fname) {
+ // TODO: Maybe load options here - original uses an
+ // xml file but we would want confman.
+ warning("TODO: Implement Application::loadOptions %s", fname.c_str());
+}
+
+void Application::saveOptions(const Common::String &fname) {
+ warning("TODO: Implement Application::saveOptions %s", fname.c_str());
+}
+
+Common::String Application::getHelpText(const Common::String &key) {
+ return _helpGui.value(key);
+}
+
+const char *Application::inAppUnlockFullVersionID() {
+ error("TODO: Implement Application::inAppUnlockFullVersionID");
+}
+
+// TODO: Add more functions here.
+
+} // end namespace Tetraedge
diff --git a/engines/tetraedge/game/application.h b/engines/tetraedge/game/application.h
new file mode 100644
index 00000000000..feebf411639
--- /dev/null
+++ b/engines/tetraedge/game/application.h
@@ -0,0 +1,164 @@
+/* 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 TETRAEDGE_GAME_APPLICATION_H
+#define TETRAEDGE_GAME_APPLICATION_H
+
+#include "common/str.h"
+#include "common/ptr.h"
+
+#include "tetraedge/game/bonus_menu.h"
+#include "tetraedge/game/credits.h"
+#include "tetraedge/game/global_bonus_menu.h"
+#include "tetraedge/game/main_menu.h"
+#include "tetraedge/game/loc_file.h"
+#include "tetraedge/game/owner_error_menu.h"
+#include "tetraedge/game/splash_screens.h"
+#include "tetraedge/game/in_game_scene.h"
+
+#include "tetraedge/te/te_visual_fade.h"
+#include "tetraedge/te/te_music.h"
+#include "tetraedge/te/te_xml_gui.h"
+#include "tetraedge/te/te_font3.h"
+
+namespace Common {
+struct Event;
+}
+
+namespace Tetraedge {
+
+class Application {
+public:
+ Application();
+
+ void create();
+ void destroy();
+
+ void startGame(bool newGame, int difficulty);
+ void resume();
+ bool run();
+ void suspend();
+ void showNoCellIcon(bool show);
+ void showLoadingIcon(bool show);
+ void saveCorrupted(const Common::String &fname);
+
+ void drawBack();
+ void drawFront();
+ void performRender();
+ //void preloadTextrue(); does nothing..
+
+ void fade();
+ void blackFade();
+ void captureFade();
+ bool isFading();
+ bool onBlackFadeAnimationFinished();
+ bool onMainWindowSizeChanged();
+ bool onMousePositionChanged(const Common::Point &p);
+
+ bool isLockCursor();
+ bool isLockPad();
+ void lockCursor(bool lock);
+ void lockCursorFromAction(bool lock);
+
+ void loadOptions(const Common::String &fname);
+ void saveOptions(const Common::String &fname);
+
+ Common::String getHelpText(const Common::String &key);
+
+ const char *inAppUnlockFullVersionID();
+
+ BonusMenu &bonusMenu() { return _bonusMenu; }
+ GlobalBonusMenu &globalBonusMenu() { return _globalBonusMenu; }
+ MainMenu &mainMenu() { return _mainMenu; }
+ TeMusic &music() { return _music; }
+ Credits &credits() { return _credits; }
+ TeVisualFade &visualFade() { return _visFade; }
+ TeSpriteLayout &appSpriteLayout() { return _appSpriteLayout; }
+ TeSpriteLayout &mouseCursorLayout() { return _mouseCursorLayout; }
+ const Common::String getVersionString() const { return _versionString; }
+ TeLayout &getMainWindow() { return _mainWindow; }
+ void setTutoActivated(bool val) { _tutoActivated = val; }
+ TeCamera *mainWindowCamera() { return _mainWindowCamera.get(); }
+ Common::Array<Common::String> &unrecalAnims() { return _unrecalAnims; }
+ int difficulty() const { return _difficulty; }
+
+ // TODO: Add accessors for these and make them private.
+ bool _finishedGame;
+ bool _finishedFremium;
+ TeLayout _frontLayout;
+ TeLayout _frontOrientationLayout;
+ TeLayout _backLayout;
+ TeButtonLayout _lockCursorButton;
+ LocFile _loc;
+ Common::String _firstWarpPath;
+ Common::String _firstZone;
+ Common::String _firstScene;
+
+private:
+ TeVisualFade _visFade;
+ TeMusic _music;
+ TeSpriteLayout _appSpriteLayout;
+ TeSpriteLayout _mouseCursorLayout;
+ TeButtonLayout _lockCursorFromActionButton;
+ TeSpriteLayout _autoSaveIcon1;
+ TeSpriteLayout _autoSaveIcon2;
+
+ Common::String _applicationTitle;
+ Common::String _versionString;
+
+ Common::Array<Common::String> _unrecalAnims;
+
+ TeCurveAnim2<Te3DObject2, TeColor> _autoSaveIconAnim1;
+ TeCurveAnim2<Te3DObject2, TeColor> _autoSaveIconAnim2;
+
+ TeSignal0Param _blackFadeAnimationFinishedSignal;
+
+ Common::SharedPtr<TeCamera> _mainWindowCamera; // TODO: should be part of TeMainWindow.
+ TeLayout _mainWindow; // TODO: should be a specialised class.
+
+ GlobalBonusMenu _globalBonusMenu;
+ BonusMenu _bonusMenu;
+ MainMenu _mainMenu;
+ Credits _credits;
+ OwnerErrorMenu _ownerErrorMenu;
+ SplashScreens _splashScreens;
+ InGameScene _inGameScene;
+
+ TeIntrusivePtr<TeFont3> _fontComic;
+ TeIntrusivePtr<TeFont3> _fontArgh;
+ TeIntrusivePtr<TeFont3> _fontArial;
+ TeIntrusivePtr<TeFont3> _fontChaucer;
+ TeIntrusivePtr<TeFont3> _fontColaborate;
+ TeIntrusivePtr<TeFont3> _fontProDisplay;
+
+ bool _captureFade;
+ bool _created;
+ bool _tutoActivated;
+
+ int _difficulty;
+
+ TeXmlGui _helpGui;
+ static bool _dontUpdateWhenApplicationPaused;
+};
+
+} // end namespace Tetraedge
+
+#endif // TETRAEDGE_GAME_APPLICATION_H
diff --git a/engines/tetraedge/game/billboard.cpp b/engines/tetraedge/game/billboard.cpp
new file mode 100644
index 00000000000..e8529237fe5
--- /dev/null
+++ b/engines/tetraedge/game/billboard.cpp
@@ -0,0 +1,55 @@
+/* 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/textconsole.h"
+#include "tetraedge/game/billboard.h"
+
+namespace Tetraedge {
+
+Billboard::Billboard() {
+}
+
+bool Billboard::load(const Common::String &path) {
+ error("TODO: implement Billboard::load");
+ return false;
+}
+
+void Billboard::calcVertex() {
+ error("TODO: implement Billboard::calcVertex");
+}
+
+void Billboard::position(const TeVector3f32 &pos) {
+ _pos = pos;
+ calcVertex();
+}
+
+void Billboard::position2(const TeVector3f32 &pos) {
+ _pos2 = pos;
+ _hasPos2 = true;
+ calcVertex();
+}
+
+void Billboard::size(const TeVector2f32 &size) {
+ _size = size;
+ calcVertex();
+}
+
+} // end namespace Tetraedge
diff --git a/engines/tetraedge/game/billboard.h b/engines/tetraedge/game/billboard.h
new file mode 100644
index 00000000000..bd39e309de0
--- /dev/null
+++ b/engines/tetraedge/game/billboard.h
@@ -0,0 +1,53 @@
+/* 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 TETRAEDGE_GAME_BILLBOARD_H
+#define TETRAEDGE_GAME_BILLBOARD_H
+
+#include "common/str.h"
+
+#include "tetraedge/te/te_object.h"
+#include "tetraedge/te/te_vector2f32.h"
+#include "tetraedge/te/te_vector3f32.h"
+
+namespace Tetraedge {
+
+class Billboard : public TeObject {
+public:
+ Billboard();
+
+ bool load(const Common::String &path);
+
+ void calcVertex();
+ void position(const TeVector3f32 &pos);
+ void position2(const TeVector3f32 &pos);
+ void size(const TeVector2f32 &size);
+
+private:
+ TeVector3f32 _pos;
+ TeVector3f32 _pos2;
+ TeVector2f32 _size;
+ bool _hasPos2;
+};
+
+} // end namespace Tetraedge
+
+#endif // TETRAEDGE_GAME_BILLBOARD_H
diff --git a/engines/tetraedge/game/bonus_menu.cpp b/engines/tetraedge/game/bonus_menu.cpp
new file mode 100644
index 00000000000..d91c2c66437
--- /dev/null
+++ b/engines/tetraedge/game/bonus_menu.cpp
@@ -0,0 +1,102 @@
+/* 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 "tetraedge/game/bonus_menu.h"
+
+#include "common/textconsole.h"
+#include "tetraedge/tetraedge.h"
+#include "tetraedge/game/application.h"
+//#include "tetraedge/te/te_input_manager"
+
+namespace Tetraedge {
+
+BonusMenu::BonusMenu() {
+}
+
+void BonusMenu::enter(const Common::String &scriptName) {
+ error("TODO: implement me.");
+}
+
+void BonusMenu::enter() {
+ error("TODO: implement me.");
+}
+
+void BonusMenu::leave() {
+ for (auto *s : _saveButtons) {
+ delete s;
+ }
+ _saveButtons.clear();
+ warning("TODO: remove oMouseMove signal from inputmgr.");
+ TeLuaGUI::unload();
+}
+
+bool BonusMenu::onLeftButton() {
+ error("TODO: implement me.");
+ return false;
+}
+
+bool BonusMenu::onMouseMove() {
+ error("TODO: implement me.");
+ return false;
+}
+
+bool BonusMenu::onPictureButton() {
+ error("TODO: implement me.");
+ return false;
+}
+
+bool BonusMenu::onQuitButton() {
+ Application *app = g_engine->getApplication();
+ assert(app);
+
+ app->captureFade();
+ leave();
+ app->globalBonusMenu().enter();
+ app->fade();
+ return true;
+}
+
+bool BonusMenu::onRightButton() {
+ error("TODO: implement me.");
+ return false;
+}
+
+bool BonusMenu::onSideButtonDown() {
+ /*
+ TeInputManager *inputmgr = g_engine->getInputManager();
+ TeVector2s32 mousepos = inputmgr->getMousePos();
+ _slideBtnStartMousePos = mousepos;
+ buttonLayout("slideButton");
+ // TODO set some flag in super (TeLuaGUI)
+ */
+ error("TODO: implement me.");
+ return false;
+}
+
+Common::String BonusMenu::SaveButton::path() const {
+ return Common::String("Backup/") + name() + ".xml";
+}
+
+bool BonusMenu::SaveButton::onLoadSave() {
+ error("TODO: implement me.");
+}
+
+} // end namespace Tetraedge
diff --git a/engines/tetraedge/game/bonus_menu.h b/engines/tetraedge/game/bonus_menu.h
new file mode 100644
index 00000000000..0c87516159b
--- /dev/null
+++ b/engines/tetraedge/game/bonus_menu.h
@@ -0,0 +1,68 @@
+/* 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 TETRAEDGE_GAME_BONUS_MENU_H
+#define TETRAEDGE_GAME_BONUS_MENU_H
+
+#include "common/array.h"
+#include "common/str.h"
+#include "tetraedge/te/te_layout.h"
+#include "tetraedge/te/te_lua_gui.h"
+#include "tetraedge/te/te_vector2s32.h"
+
+namespace Tetraedge {
+
+class BonusMenu : public TeLuaGUI {
+public:
+ BonusMenu();
+
+ class SaveButton : public TeLayout {
+ public:
+ bool onLoadSave();
+ Common::String path() const;
+ };
+
+ virtual void enter() override;
+ virtual void enter(const Common::String &scriptName);
+ void leave() override;
+
+ void loadGame(Common::String &name) {
+ _gameName = name;
+ }
+
+ bool onLeftButton();
+ bool onMouseMove();
+ bool onPictureButton();
+ bool onQuitButton();
+ bool onRightButton();
+ bool onSideButtonDown();
+
+ // empty? bool onLoadGameConfirmed() { };
+
+private:
+ Common::Array<SaveButton *> _saveButtons;
+ TeVector2s32 _slideBtnStartMousePos;
+ Common::String _gameName;
+};
+
+} // end namespace Tetraedge
+
+#endif // TETRAEDGE_GAME_BONUS_MENU_H
diff --git a/engines/tetraedge/game/cellphone.cpp b/engines/tetraedge/game/cellphone.cpp
new file mode 100644
index 00000000000..4f836c1c473
--- /dev/null
+++ b/engines/tetraedge/game/cellphone.cpp
@@ -0,0 +1,145 @@
+/* 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 "tetraedge/tetraedge.h"
+#include "tetraedge/te/te_core.h"
+
+#include "tetraedge/game/cellphone.h"
+#include "tetraedge/te/te_text_layout.h"
+
+namespace Tetraedge {
+
+Cellphone::Cellphone() : _nextNumber(0) {
+}
+
+bool Cellphone::addNumber(const Common::String &num) {
+ for (const Common::String &addedNum : _addedNumbers) {
+ if (addedNum == num)
+ return false;
+ }
+
+ TeTextLayout *layout = new TeTextLayout();
+ static const Common::String namePrefix("numRepertoire");
+ layout->setName(namePrefix + num);
+ layout->setSizeType(RELATIVE_TO_PARENT);
+ layout->setAnchor(TeVector3f32(0.5f, 0.0f, 0.0f));
+ layout->setSize(TeVector3f32(1.0f, 1.0f, 0.0f));
+ layout->setPosition(TeVector3f32(0.5f, 0.08f, 0.0f));
+ layout->setTextSizeType(1);
+ layout->setTextSizeProportionalToWidth(46);
+ Common::String val("Unknown");
+ Common::String *locNum = g_engine->getCore()->loc()->text(num);
+ if (locNum)
+ val = *locNum;
+
+ layout->setText(_gui.value("textAttributs").toString() + val);
+ layout->setVisible(true);
+ _textLayoutArray.push_back(layout);
+ _addedNumbers.push_back(num);
+
+ TeSpriteLayout *sprite = _gui.spriteLayoutChecked("numRepertoire");
+ sprite->addChild(layout);
+ return true;
+}
+
+void Cellphone::currentPage(int offset) {
+ error("TODO: implement Cellphone::currentPage");
+}
+
+void Cellphone::enter() {
+ error("TODO: implement Cellphone::enter");
+}
+
+void Cellphone::leave() {
+ error("TODO: implement Cellphone::leave");
+}
+
+void Cellphone::load() {
+ _nextNumber = 0;
+ TeButtonLayout *btnlayout;
+ _gui.load("menus/cellphone.lua");
+ btnlayout = _gui.buttonLayoutChecked("haut");
+ btnlayout->onMouseClickValidated().add(this, &Cellphone::onPreviousNumber);
+ btnlayout = _gui.buttonLayoutChecked("bas");
+ btnlayout->onMouseClickValidated().add(this, &Cellphone::onNextNumber);
+ btnlayout = _gui.buttonLayoutChecked("appeler");
+ btnlayout->onMouseClickValidated().add(this, &Cellphone::onCallNumberValidated);
+ btnlayout = _gui.buttonLayoutChecked("fermer");
+ btnlayout->onMouseClickValidated().add(this, &Cellphone::onCloseButtonValidated);
+ btnlayout = _gui.buttonLayoutChecked("background");
+ btnlayout->setVisible(false);
+}
+
+void Cellphone::loadFromBackup(const Common::XMLParser::ParserNode *node) {
+ /*
+ basic algorithm:
+ child = node->lastChild;
+ while (child != nullptr) {
+ if (child->type == ELEMENT) {
+ if (if child->userData == "Number") {
+ addNumber(this, child->getAttribute("num"));
+ }
+ }
+ child = child->prev;
+ }*/
+}
+
+bool Cellphone::onCallNumberValidated() {
+ _onCallNumberSignal.call(_addedNumbers[_nextNumber]);
+ return false;
+}
+
+bool Cellphone::onCloseButtonValidated() {
+ _gui.buttonLayoutChecked("background")->setVisible(false);
+ return false;
+}
+
+bool Cellphone::onNextNumber() {
+ error("TODO: work out how the max num works here.");
+ /*
+ int numoffset = _nextNumber + 1;
+ if (numoffset < _maxnum) {
+ currentPage(numoffset);
+ }*/
+ return false;
+}
+
+bool Cellphone::onPreviousNumber() {
+ int numoffset = _nextNumber - 1;
+ if (numoffset >= 0) {
+ currentPage(numoffset);
+ }
+ return false;
+}
+
+void Cellphone::saveToBackup(Common::XMLParser::ParserNode *xmlnode) {
+ error("TODO: implement Cellphone::saveToBackup");
+}
+
+void Cellphone::setVisible(bool visible) {
+ _gui.buttonLayoutChecked("background")->setVisible(visible);
+}
+
+void Cellphone::unload() {
+ leave();
+ _gui.unload();
+}
+} // end namespace Tetraedge
diff --git a/engines/tetraedge/game/cellphone.h b/engines/tetraedge/game/cellphone.h
new file mode 100644
index 00000000000..35c5e68f067
--- /dev/null
+++ b/engines/tetraedge/game/cellphone.h
@@ -0,0 +1,78 @@
+/* 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 TETRAEDGE_GAME_CELLPHONE_H
+#define TETRAEDGE_GAME_CELLPHONE_H
+
+#include "common/array.h"
+#include "common/callback.h"
+#include "common/str.h"
+#include "common/xmlparser.h"
+
+#include "tetraedge/te/te_layout.h"
+#include "tetraedge/te/te_text_layout.h"
+#include "tetraedge/te/te_lua_gui.h"
+
+namespace Tetraedge {
+
+class Cellphone : public TeLayout {
+public:
+ Cellphone();
+
+ bool addNumber(const Common::String &num);
+ void currentPage(int offset);
+
+ void enter();
+ void leave();
+
+ void load();
+ void loadFromBackup(const Common::XMLParser::ParserNode *node);
+
+ bool onCallNumberValidated();
+ bool onCloseButtonValidated();
+ bool onNextNumber();
+ bool onPreviousNumber();
+
+ void saveToBackup(Common::XMLParser::ParserNode *xmlnode);
+ void setVisible(bool visible);
+
+ TeSignal1Param<Common::String> &onCallNumber() {
+ return _onCallNumberSignal;
+ }
+
+ void unload();
+
+ TeLuaGUI &gui() { return _gui; }
+
+private:
+
+ int _nextNumber;
+ Common::Array<TeTextLayout*> _textLayoutArray;
+ Common::Array<Common::String> _addedNumbers;
+
+ TeSignal1Param<Common::String> _onCallNumberSignal;
+
+ TeLuaGUI _gui;
+};
+
+} // end namespace Tetraedge
+
+#endif // TETRAEDGE_GAME_CELLPHONE_H
diff --git a/engines/tetraedge/game/character.cpp b/engines/tetraedge/game/character.cpp
new file mode 100644
index 00000000000..aa05583d4f5
--- /dev/null
+++ b/engines/tetraedge/game/character.cpp
@@ -0,0 +1,431 @@
+/* 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/hashmap.h"
+#include "common/path.h"
+#include "common/file.h"
+#include "common/debug.h"
+
+#include "tetraedge/game/character.h"
+#include "tetraedge/game/character_settings_xml_parser.h"
+#include "tetraedge/te/te_model_animation.h"
+
+namespace Tetraedge {
+
+/*static*/ Common::HashMap<Common::String, Character::CharacterSettings> *Character::_globalCharacterSettings = nullptr;
+
+/*static*/ Common::Array<Character::AnimCacheElement> Character::_animCache;
+uint Character::_animCacheSize = 0;
+
+void Character::CharacterSettings::clear() {
+ _name.clear();
+ _modelFileName.clear();
+ _defaultScale = TeVector3f32();
+ _walkFileName.clear();
+ _walkSettings.clear();
+ _walkSpeed = 0.0f;
+ _cutSceneCurveDemiPosition = TeVector3f32();
+ _defaultEyes.clear();
+ _defaultMouth.clear();
+ _defaultBody.clear();
+}
+
+void Character::WalkSettings::clear() {
+ for (int i = 0; i < 4; i++) {
+ _walkParts[i] = AnimSettings();
+ }
+}
+
+Character::Character() : _curveOffset(0), _lastFrame(-1), _callbacksChanged(false),
+_missingCurrentAnim(false), _someRepeatFlag(false), _walkModeStr("Walk"), _needsSomeUpdate(false),
+_stepSound1("sounds/SFX/PAS_H_BOIS1.ogg"), _stepSound2("sounds/SFX/PAS_H_BOIS2.ogg"),
+_freeMoveZone(nullptr) {
+}
+
+void Character::addCallback(const Common::String &key, const Common::String &s2, float f1, float f2) {
+ /*Callback *c = new Callback();
+ c->x = (int)f1;
+ c->y = (int)f2;
+ c->f = (f2 == -1.0 ? -NAN : 0.0f;*/
+ error("TODO: Implement Character::addCallback");
+}
+
+/*static*/ void Character::animCacheFreeAll() {
+ for (const auto &entry : _animCache)
+ _animCacheSize -= entry._size;
+ _animCache.clear();
+}
+
+/*static*/ void Character::animCacheFreeOldest() {
+ _animCacheSize -= _animCache[_animCache.size() - 1]._size;
+ _animCache.pop_back();
+}
+
+/*static*/ TeIntrusivePtr<TeModelAnimation> Character::animCacheLoad(const Common::Path &path) {
+ static Common::HashMap<Common::String, TeIntrusivePtr<TeModelAnimation>> _cache;
+
+ const Common::String pathStr = path.toString();
+ if (_cache.contains(pathStr))
+ return _cache.getVal(pathStr);
+
+ TeIntrusivePtr<TeModelAnimation> modelAnim = new TeModelAnimation();
+ modelAnim->load(path);
+
+ _cache.setVal(pathStr, modelAnim);
+ return modelAnim;
+}
+
+float Character::animLength(const TeModelAnimation &modelanim, long bone, long lastframe) {
+ int last = modelanim.lastFrame();
+ if (lastframe > last)
+ lastframe = last;
+ int first = modelanim.firstFrame();
+ const TeVector3f32 starttrans = translationVectorFromAnim(modelanim, bone, first);
+ const TeVector3f32 endtrans = translationVectorFromAnim(modelanim, bone, last);
+ const TeVector3f32 secondtrans = translationVectorFromAnim(modelanim, bone, first + 1);
+ return ((endtrans.z() - starttrans.z()) + secondtrans.z()) - starttrans.z();
+}
+
+float Character::animLengthFromFile(const Common::String &animname, uint *pframeCount, uint lastframe) {
+ if (animname.empty()) {
+ *pframeCount = 0;
+ return 0.0f;
+ }
+ TeIntrusivePtr<TeModelAnimation> anim = _model->anim();
+ if (!anim->_loadedPath.toString().contains(animname)) {
+ Common::Path animpath("models/Anims");
+ animpath.joinInPlace(animname);
+ anim = animCacheLoad(animpath);
+ if (!anim)
+ error("Character::animLengthFromFile couldn't load anim %s", animname.c_str());
+ }
+
+ // The "Pere" or "father" bone is the root.
+ float animLen = animLength(*anim, anim->findBone("Pere"), lastframe);
+ int frameCount = anim->lastFrame() + 1 - anim->firstFrame();
+ *pframeCount = frameCount;
+
+ // TODO: Check this maths.. is this really what it does?
+ return animLen * _model->scale().z();
+}
+
+bool Character::blendAnimation(const Common::String &animname, float param_2, bool param_3, bool param_4) {
+ error("TODO: Implement Character::blendAnimation");
+}
+
+TeVector3f32 Character::correctPosition(const TeVector3f32 &pos) {
+ error("TODO: Implement Character::correctPosition");
+}
+
+float Character::curveOffset() {
+ return _curveOffset;
+}
+
+void Character::deleteAllCallback() {
+ _callbacksChanged = true;
+ for (auto &pair : _callbacks) {
+ for (Callback *c : pair._value) {
+ delete c;
+ }
+ }
+ _callbacks.clear();
+}
+
+void Character::deleteAnim() {
+ error("TODO: Implement Character::deleteAnim");
+}
+
+void Character::deleteCallback(const Common::String &str1, const Common::String &str2, float f) {
+ error("TODO: Implement Character::deleteCallback");
+}
+
+//static bool deserialize(TiXmlElement *param_1, Walk *param_2);
+void Character::endMove() {
+ error("TODO: Implement Character::endMove.");
+}
+
+const Character::WalkSettings *Character::getCurrentWalkFiles() {
+ for (const auto & walkSettings : _characterSettings._walkSettings) {
+ if (walkSettings._key == _walkModeStr)
+ return &walkSettings._value;
+ }
+ return nullptr;
+}
+
+bool Character::isFramePassed(uint frameno) {
+ error("TODO: Implement Character::isFramePassed.");
+}
+
+bool Character::isWalkEnd() {
+ error("TODO: Implement Character::isWalkEnd.");
+ return false;
+}
+
+bool Character::leftStepFrame(enum Character::WalkPart walkpart) {
+ error("TODO: Implement Character::leftStepFrame.");
+ return false;
+}
+
+bool Character::rightStepFrame(enum Character::WalkPart walkpart) {
+ error("TODO: Implement Character::rightStepFrame.");
+ return false;
+}
+
+bool Character::loadModel(const Common::String &name, bool param_2) {
+ assert(_globalCharacterSettings);
+ if (_model) {
+ //_model->bonesUpdateSignal().remove(this, &Character::onBonesUpdate);
+ }
+ _model = new TeModel();
+ //_model->bonesUpdateSignal().add(this, &Character::onBonesUpdate);
+
+ if (!_globalCharacterSettings->contains(name))
+ return false;
+
+ _characterSettings = _globalCharacterSettings->getVal(name);
+ _model->_texturePath = Common::Path("models/Textures");
+ _model->_enableLights = true;
+ Common::Path modelPath("models");
+ modelPath.joinInPlace(_characterSettings._modelFileName);
+ if (!_model->load(modelPath))
+ return false;
+
+ _model->setName(name);
+ _model->setScale(_characterSettings._defaultScale);
+
+ for (unsigned int i = 0; i < _model->_meshes.size(); i++)
+ _model->_meshes[i].setVisible(true);
+
+ _model->setVisibleByName("_B_", false);
+ _model->setVisibleByName("_Y_", false);
+
+ _model->setVisibleByName(_characterSettings._defaultEyes, true);
+ _model->setVisibleByName(_characterSettings._defaultMouth, true);
+
+ setAnimation(_characterSettings._walkFileName, true, false, false, -1, 9999);
+
+ _walkPart0AnimLen = animLengthFromFile(walkAnim(WalkPart_Start), &_walkPart0AnimFrameCount, 9999);
+ _walkPart3AnimLen = animLengthFromFile(walkAnim(WalkPart_EndG), &_walkPart3AnimFrameCount, 9999);
+ _walkPart1AnimLen = animLengthFromFile(walkAnim(WalkPart_Loop), &_walkPart1AnimFrameCount, 9999);
+
+ TeIntrusivePtr<Te3DTexture> shadow = new Te3DTexture();
+ shadow->load("models/Textures/simple_shadow_alpha.tga");
+
+ for (int i = 0; i < 2; i++) {
+ TeModel *pmodel = new TeModel();
+ _shadowModel[i] = pmodel;
+ pmodel->setName("Shadow");
+ Common::Array<TeVector3f32> arr;
+ arr.resize(4);
+ arr[0] = TeVector3f32(-60.0, 0.0, -60.0);
+ arr[1] = TeVector3f32(-60.0, 0.0, 60.0);
+ arr[2] = TeVector3f32(60.0, 0.0, -60.0);
+ arr[3] = TeVector3f32(60.0, 0.0, 60.0);
+ pmodel->setQuad(shadow, arr, TeColor(0xff,0xff,0xff,0x50));
+ }
+ return true;
+}
+
+/*static*/ bool Character::loadSettings(const Common::String &path) {
+ CharacterSettingsXmlParser parser;
+ parser.setAllowText();
+ if (_globalCharacterSettings)
+ delete _globalCharacterSettings;
+ _globalCharacterSettings = new Common::HashMap<Common::String, CharacterSettings>();
+ parser.setCharacterSettings(_globalCharacterSettings);
+
+ // WORKAROUND: This file contains invalid comments
+ // eg, <!--------- and a comment-inside-a-comment.
+ // patch them before parsing.
+ Common::File xmlFile;
+ if (!xmlFile.open(path))
+ error("Character::loadSettings: Can't open %s", path.c_str());
+ const uint32 bufsize = xmlFile.size();
+ char *buf = new char[bufsize+1];
+ buf[bufsize] = '\0';
+ xmlFile.read(buf, bufsize);
+ Common::String fixedbuf(buf);
+ uint32 offset = fixedbuf.find("------------");
+ while (offset != Common::String::npos) {
+ fixedbuf.replace(offset, 12, "--");
+ offset = fixedbuf.find("------------");
+ }
+
+ // Big HACK: Remove the embedded comment in this config.
+ offset = fixedbuf.find("<!--<walk>");
+ if (offset != Common::String::npos) {
+ uint32 endOffset = fixedbuf.find(" -->", offset);
+ if (endOffset != Common::String::npos) {
+ uint32 realEndOffset = fixedbuf.find("walk>-->", endOffset);
+ if (realEndOffset != Common::String::npos && realEndOffset > endOffset) {
+ fixedbuf.replace(offset, endOffset - offset, "<!-- ");
+ }
+ }
+ }
+
+ if (!parser.loadBuffer((unsigned char *)fixedbuf.c_str(), bufsize))
+ error("Character::loadSettings: Can't open %s", path.c_str());
+
+ if (!parser.parse())
+ error("Character::loadSettings: Can't parse %s", path.c_str());
+
+ return false;
+}
+
+bool Character::onBonesUpdate(const Common::String ¶m_1, const TeMatrix4x4 *param_2) {
+ error("TODO: Implement Character::onBonesUpdate");
+ return false;
+}
+
+bool Character::onModelAnimationFinished() {
+ error("TODO: Implement Character::onModelAnimationFinished");
+ return false;
+}
+
+void Character::permanentUpdate() {
+ error("TODO: Implement Character::permanentUpdate.");
+}
+
+void Character::placeOnCurve(const TeBezierCurve &curve) {
+ _curve = curve;
+ updatePosition(_curveOffset);
+}
+
+void Character::removeAnim() {
+ if (_curModelAnim) {
+ _curModelAnim->onFinished().remove(this, &Character::onModelAnimationFinished);
+ }
+ _model->removeAnim();
+ if (_curModelAnim) {
+ _curModelAnim.release();
+ }
+}
+
+void Character::removeFromCurve() {
+ error("TODO: Implement Character::removeFromCurve.");
+}
+
+bool Character::setAnimation(const Common::String &name, bool repeat, bool param_3, bool unused, int startFrame, int endFrame) {
+ if (name.empty())
+ return false;
+
+ Common::Path animPath("models/Anims");
+ animPath.joinInPlace(name);
+ bool validAnim = (name.contains(_characterSettings._walkFileName) ||
+ name.contains(walkAnim(WalkPart_Start)) ||
+ name.contains(walkAnim(WalkPart_Loop)) ||
+ name.contains(walkAnim(WalkPart_EndD)) ||
+ name.contains(walkAnim(WalkPart_EndG)));
+ _missingCurrentAnim = !validAnim;
+
+ if (_curModelAnim) {
+ _curModelAnim->onFinished().remove(this, &Character::onModelAnimationFinished);
+ _curModelAnim->unbind();
+ }
+
+ _curModelAnim = animCacheLoad(animPath);
+ _curModelAnim->bind(_model);
+ _curModelAnim->setFrameLimits(startFrame, endFrame);
+ _model->setAnim(_curModelAnim, repeat);
+ _lastFrame = -1;
+ _curModelAnim->play();
+ _setAnimName = name;
+ _curAnimName = name;
+ _someRepeatFlag = !(repeat | !param_3);
+
+ return true;
+}
+
+void Character::setAnimationSound(const Common::String &name, uint param_2) {
+ error("TODO: Implement Character::setAnimationSound.");
+}
+
+void Character::setCurveOffset(float offset) {
+ _curveOffset = offset;
+ updatePosition(offset);
+}
+
+void Character::setFreeMoveZone(const Common::SharedPtr<TeFreeMoveZone> &zone) {
+ _freeMoveZone = zone;
+}
+
+void Character::setStepSound(const Common::String &stepSound1, const Common::String &stepSound2) {
+ _stepSound1 = stepSound1;
+ _stepSound2 = stepSound2;
+}
+
+bool Character::setShadowVisible(bool visible) {
+ _shadowModel[0]->setVisible(visible);
+ _shadowModel[1]->setVisible(visible);
+ return false;
+}
+
+float Character::speedFromAnim(double movepercent) {
+ error("TODO: Implement Character::speedFromAnim");
+ return 0;
+}
+
+float Character::translationFromAnim(const TeModelAnimation &anim, long bone, long param_3) {
+ return translationVectorFromAnim(anim, bone, param_3).z();
+}
+
+TeVector3f32 Character::translationVectorFromAnim(const TeModelAnimation &anim, long bone, long frame) {
+ const TeTRS trs = trsFromAnim(anim, bone, frame);
+ return trs.getTranslation();
+}
+
+TeTRS Character::trsFromAnim(const TeModelAnimation &anim, long bone, long frame) {
+ if (bone == -1)
+ return TeTRS();
+
+ return anim.getTRS(bone, frame, false);
+}
+
+void Character::update(double percentval) {
+ error("TODO: Implement Character::update");
+}
+
+void Character::updateAnimFrame() {
+ error("TODO: Implement Character::updateAnimFrame");
+}
+
+void Character::updatePosition(float curveOffset) {
+ error("TODO: Implement Character::updatePosition");
+}
+
+Common::String Character::walkAnim(Character::WalkPart part) {
+ Common::String result;
+ const Character::WalkSettings *settings = getCurrentWalkFiles();
+ if (settings) {
+ return settings->_walkParts[(int)part]._file;
+ }
+ return result;
+}
+
+void Character::walkMode(const Common::String &mode) {
+ error("TODO: Implement Character::walkMode");
+}
+
+void Character::walkTo(float param_1, bool param_2) {
+ error("TODO: Implement Character::walkTo");
+}
+
+} // end namespace Tetraedge
diff --git a/engines/tetraedge/game/character.h b/engines/tetraedge/game/character.h
new file mode 100644
index 00000000000..2556f305845
--- /dev/null
+++ b/engines/tetraedge/game/character.h
@@ -0,0 +1,197 @@
+/* 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 TETRAEDGE_GAME_CHARACTER_H
+#define TETRAEDGE_GAME_CHARACTER_H
+
+#include "common/array.h"
+#include "common/str.h"
+#include "common/types.h"
+#include "common/ptr.h"
+#include "tetraedge/te/te_animation.h"
+#include "tetraedge/te/te_model_animation.h"
+#include "tetraedge/te/te_vector3f32.h"
+#include "tetraedge/te/te_matrix4x4.h"
+#include "tetraedge/te/te_model.h"
+#include "tetraedge/te/te_bezier_curve.h"
+#include "tetraedge/te/te_free_move_zone.h"
+#include "tetraedge/te/te_trs.h"
+
+namespace Tetraedge {
+
+class Character : public TeAnimation {
+public:
+ Character();
+ virtual ~Character() {}
+
+ struct AnimSettings {
+ AnimSettings() : _stepLeft(0), _stepRight(0) {};
+ Common::String _file;
+ int _stepRight;
+ int _stepLeft;
+ };
+
+ struct WalkSettings {
+ AnimSettings _walkParts[4];
+
+ void clear();
+ };
+
+ struct CharacterSettings {
+ CharacterSettings() : _walkSpeed(0.0f) {}
+
+ Common::String _name;
+ Common::String _modelFileName;
+ TeVector3f32 _defaultScale;
+ Common::String _walkFileName;
+ Common::HashMap<Common::String, WalkSettings> _walkSettings; // keys are "Walk", "Jog", etc
+ float _walkSpeed;
+
+ TeVector3f32 _cutSceneCurveDemiPosition;
+ Common::String _defaultEyes; // Note: Engine supports more, but in practice only one ever used.
+ Common::String _defaultMouth; // Note: Engine supports more, but in practice only one ever used.
+ Common::String _defaultBody; // Note: Engine supports more, but in practice only one ever used.
+
+ void clear();
+ };
+
+ struct AnimCacheElement {
+ TeIntrusivePtr<TeModelAnimation> _modelAnim;
+ int _size;
+ };
+
+ enum WalkPart {
+ WalkPart_Start,
+ WalkPart_Loop,
+ WalkPart_EndD,
+ WalkPart_EndG
+ };
+
+ struct Callback {
+ int x;
+ Common::String s;
+ int y;
+ float f;
+ };
+
+ void addCallback(const Common::String &s1, const Common::String &s2, float f1, float f2);
+
+ static void animCacheFreeAll();
+ static void animCacheFreeOldest();
+ static TeIntrusivePtr<TeModelAnimation> animCacheLoad(const Common::Path &path);
+
+ float animLength(const TeModelAnimation &modelanim, long bone, long lastframe);
+ float animLengthFromFile(const Common::String &animname, uint *pframeCount, uint lastframe);
+ bool blendAnimation(const Common::String &animname, float param_2, bool param_3, bool param_4);
+ TeVector3f32 correctPosition(const TeVector3f32 &pos);
+ float curveOffset();
+ void deleteAllCallback();
+ void deleteAnim();
+ void deleteCallback(const Common::String &str1, const Common::String &str2, float f);
+ //static bool deserialize(TiXmlElement *param_1, Walk *param_2);
+ void endMove();
+
+ const WalkSettings *getCurrentWalkFiles();
+ bool isFramePassed(uint frameno);
+ bool isWalkEnd();
+ bool leftStepFrame(enum WalkPart walkpart);
+ bool rightStepFrame(enum WalkPart walkpart);
+ bool loadModel(const Common::String &name, bool param_2);
+ static bool loadSettings(const Common::String &path);
+
+ bool onBonesUpdate(const Common::String ¶m_1, const TeMatrix4x4 *param_2);
+ bool onModelAnimationFinished();
+ void permanentUpdate();
+ void placeOnCurve(const TeBezierCurve &curve);
+ //void play() // just called TeAnimation::play();
+ void removeAnim();
+ void removeFromCurve();
+ static Common::String rootBone() { return "Pere"; }
+
+ bool setAnimation(const Common::String &name, bool repeat, bool param_3, bool param_4, int startFrame, int endFrame);
+ void setAnimationSound(const Common::String &name, uint param_2);
+ void setCurveOffset(float offset);
+ void setFreeMoveZone(const Common::SharedPtr<TeFreeMoveZone> &zone);
+ bool setShadowVisible(bool visible);
+ void setStepSound(const Common::String &stepSound1, const Common::String &stepSound2);
+ float speedFromAnim(double movepercent);
+ //void stop(); // just maps to TeAnimation::stop();
+ float translationFromAnim(const TeModelAnimation &anim, long bone, long frame);
+ TeVector3f32 translationVectorFromAnim(const TeModelAnimation &anim, long bone, long frame);
+ TeTRS trsFromAnim(const TeModelAnimation &anim, long bone, long frame);
+ void update(double percentval);
+ void updateAnimFrame();
+ void updatePosition(float curveOffset);
+ Common::String walkAnim(WalkPart part);
+ void walkMode(const Common::String &mode);
+ void walkTo(float param_1, bool param_2);
+
+ TeIntrusivePtr<TeModel> _model;
+ TeIntrusivePtr<TeModel> _shadowModel[2];
+ TeSignal1Param<const Common::String &> _characterAnimPlayerFinishedSignal;
+ TeSignal1Param<const Common::String &> _onCharacterAnimFinishedSignal;
+
+ const CharacterSettings &characterSettings() const { return _characterSettings; }
+ const Common::String walkModeStr() const { return _walkModeStr; }
+ const Common::String curAnimName() const { return _curAnimName; }
+ bool needsSomeUpdate() const { return _needsSomeUpdate; }
+
+private:
+ float _curveOffset;
+ TeBezierCurve _curve;
+ Common::SharedPtr<TeFreeMoveZone> _freeMoveZone;
+ Common::String _stepSound1;
+ Common::String _stepSound2;
+ Common::String _walkModeStr; // Walk or Jog
+
+ TeIntrusivePtr<TeModelAnimation> _curModelAnim;
+
+ CharacterSettings _characterSettings;
+
+ int _walkPart0AnimLen;
+ int _walkPart1AnimLen;
+ int _walkPart3AnimLen;
+
+ uint32 _walkPart0AnimFrameCount;
+ uint32 _walkPart1AnimFrameCount;
+ uint32 _walkPart3AnimFrameCount;
+
+ int _lastFrame;
+ bool _missingCurrentAnim;
+ bool _someRepeatFlag; // TODO: what is this?
+ bool _callbacksChanged;
+ bool _needsSomeUpdate; // TODO: what is this? Field 0x85.
+
+ // TODO: work out how these are different
+ Common::String _setAnimName;
+ Common::String _curAnimName;
+
+ Common::HashMap<Common::String, Common::Array<Callback *>> _callbacks;
+
+ static Common::Array<AnimCacheElement> _animCache;
+ static uint _animCacheSize;
+ static Common::HashMap<Common::String, CharacterSettings> *_globalCharacterSettings;
+
+};
+
+} // end namespace Tetraedge
+
+#endif // TETRAEDGE_GAME_CHARACTER_H
diff --git a/engines/tetraedge/game/character_settings_xml_parser.cpp b/engines/tetraedge/game/character_settings_xml_parser.cpp
new file mode 100644
index 00000000000..2c306c32351
--- /dev/null
+++ b/engines/tetraedge/game/character_settings_xml_parser.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 "tetraedge/game/character_settings_xml_parser.h"
+
+namespace Tetraedge {
+
+bool CharacterSettingsXmlParser::parserCallback_ModelsSettings(ParserNode *node) {
+ return true;
+}
+
+bool CharacterSettingsXmlParser::parserCallback_Model(ParserNode *node) {
+ const Character::CharacterSettings emptySettings;
+ const Common::String &name = node->values["name"];
+ _characterSettings->setVal(name, emptySettings);
+ _curCharacter = &_characterSettings->getVal(name);
+ _curCharacter->_name = name;
+ assert(_characterSettings != nullptr);
+ return true;
+}
+
+bool CharacterSettingsXmlParser::parserCallback_modelFileName(ParserNode *node) {
+ _curTextTag = TagModelFileName;
+ return true;
+}
+
+bool CharacterSettingsXmlParser::parserCallback_defaultScale(ParserNode *node) {
+ _curTextTag = TagDefaultScale;
+ return true;
+}
+
+bool CharacterSettingsXmlParser::parserCallback_walk(ParserNode *node) {
+ return true;
+}
+
+bool CharacterSettingsXmlParser::parserCallback_animationFileName(ParserNode *node) {
+ _curTextTag = TagAnimationFileName;
+ return true;
+}
+
+bool CharacterSettingsXmlParser::parserCallback_walkType(ParserNode *node) {
+ Common::String walkName = node->values["name"];
+ _curWalkSettings = &(_curCharacter->_walkSettings[walkName]);
+ return true;
+}
+
+Character::AnimSettings CharacterSettingsXmlParser::parseWalkAnimSettings(const ParserNode *node) const {
+ Character::AnimSettings settings;
+ const Common::StringMap &map = node->values;
+ settings._file = map["file"];
+ if (map.contains("stepRight"))
+ settings._stepRight = map["stepRight"].asUint64();
+
+ if (map.contains("stepLeft"))
+ settings._stepLeft = map["stepLeft"].asUint64();
+
+ return settings;
+}
+
+bool CharacterSettingsXmlParser::parserCallback_start(ParserNode *node) {
+ _curWalkSettings->_walkParts[0] = parseWalkAnimSettings(node);
+ return true;
+}
+
+bool CharacterSettingsXmlParser::parserCallback_loop(ParserNode *node) {
+ _curWalkSettings->_walkParts[1] = parseWalkAnimSettings(node);
+ return true;
+}
+
+bool CharacterSettingsXmlParser::parserCallback_endD(ParserNode *node) {
+ _curWalkSettings->_walkParts[2] = parseWalkAnimSettings(node);
+ return true;
+}
+
+bool CharacterSettingsXmlParser::parserCallback_endG(ParserNode *node) {
+ _curWalkSettings->_walkParts[3] = parseWalkAnimSettings(node);
+ return true;
+}
+
+bool CharacterSettingsXmlParser::parserCallback_speed(ParserNode *node) {
+ _curTextTag = TagSpeed;
+ return true;
+}
+
+bool CharacterSettingsXmlParser::parserCallback_cutSceneCurveDemi(ParserNode *node) {
+ // Handled in the "position" callback.
+ return true;
+}
+
+bool CharacterSettingsXmlParser::parserCallback_position(ParserNode *node) {
+ _curTextTag = TagPosition;
+ return true;
+}
+
+bool CharacterSettingsXmlParser::parserCallback_face(ParserNode *node) {
+ // Handled in "face" and "eyes" callbacks.
+ return true;
+}
+
+bool CharacterSettingsXmlParser::parserCallback_eyes(ParserNode *node) {
+ _curTextTag = TagEyes;
+ return true;
+}
+
+bool CharacterSettingsXmlParser::parserCallback_mouth(ParserNode *node) {
+ _curTextTag = TagMouth;
+ return true;
+}
+
+bool CharacterSettingsXmlParser::parserCallback_body(ParserNode *node) {
+ if (node->values["name"] != "default")
+ error("CharacterSettingsXmlParser: Only default body supported.");
+ _curTextTag = TagBody;
+ return true;
+}
+
+bool CharacterSettingsXmlParser::textCallback(const Common::String &val) {
+ switch (_curTextTag) {
+ case TagModelFileName:
+ _curCharacter->_modelFileName = val;
+ break;
+ case TagDefaultScale:
+ _curCharacter->_defaultScale.parse(val);
+ break;
+ case TagAnimationFileName:
+ _curCharacter->_walkFileName = val;
+ break;
+ case TagEyes:
+ _curCharacter->_defaultEyes = val;
+ break;
+ case TagMouth:
+ _curCharacter->_defaultMouth = val;
+ break;
+ case TagSpeed:
+ _curCharacter->_walkSpeed = atof(val.c_str());
+ break;
+ case TagPosition:
+ _curCharacter->_cutSceneCurveDemiPosition.parse(val);
+ break;
+ case TagBody:
+ _curCharacter->_defaultBody = val;
+ break;
+ default:
+ break;
+ }
+ return true;
+}
+
+} // end namespace Tetraedge
diff --git a/engines/tetraedge/game/character_settings_xml_parser.h b/engines/tetraedge/game/character_settings_xml_parser.h
new file mode 100644
index 00000000000..3d6ae90b288
--- /dev/null
+++ b/engines/tetraedge/game/character_settings_xml_parser.h
@@ -0,0 +1,133 @@
+/* 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 TETRAEDGE_GAME_CHARACTER_SETTINGS_XML_PARSER_H
+#define TETRAEDGE_GAME_CHARACTER_SETTINGS_XML_PARSER_H
+
+#include "common/xmlparser.h"
+#include "tetraedge/game/character.h"
+#include "tetraedge/te/te_vector3f32.h"
+
+namespace Tetraedge {
+
+class CharacterSettingsXmlParser : public Common::XMLParser {
+public:
+ void setCharacterSettings(Common::HashMap<Common::String, Character::CharacterSettings> *settings) {
+ _characterSettings = settings;
+ };
+
+ // Parser
+ CUSTOM_XML_PARSER(CharacterSettingsXmlParser) {
+ XML_KEY(ModelsSettings)
+ XML_KEY(Model)
+ XML_PROP(name, true)
+ XML_KEY(modelFileName)
+ KEY_END()
+ XML_KEY(defaultScale)
+ KEY_END()
+ XML_KEY(walk)
+ XML_KEY(animationFileName)
+ KEY_END()
+ XML_KEY(walkType)
+ XML_PROP(name, true)
+ XML_KEY(start)
+ XML_PROP(file, true)
+ XML_PROP(stepRight, false)
+ XML_PROP(stepLeft, false)
+ KEY_END()
+ XML_KEY(loop)
+ XML_PROP(file, true)
+ XML_PROP(stepRight, false)
+ XML_PROP(stepLeft, false)
+ KEY_END()
+ XML_KEY(endD)
+ XML_PROP(file, true)
+ KEY_END()
+ XML_KEY(endG)
+ XML_PROP(file, true)
+ KEY_END()
+ KEY_END()
+ XML_KEY(speed)
+ KEY_END()
+ KEY_END()
+ XML_KEY(cutSceneCurveDemi)
+ XML_KEY(position)
+ KEY_END()
+ KEY_END()
+ XML_KEY(face)
+ XML_PROP(name, true)
+ XML_KEY(eyes)
+ KEY_END()
+ XML_KEY(mouth)
+ KEY_END()
+ KEY_END()
+ XML_KEY(body)
+ XML_PROP(name, true)
+ KEY_END()
+ KEY_END()
+ KEY_END()
+ } PARSER_END()
+
+ // Parser callback methods
+ bool parserCallback_ModelsSettings(ParserNode *node);
+ bool parserCallback_Model(ParserNode *node);
+ bool parserCallback_modelFileName(ParserNode *node);
+ bool parserCallback_defaultScale(ParserNode *node);
+ bool parserCallback_walk(ParserNode *node);
+ bool parserCallback_animationFileName(ParserNode *node);
+ bool parserCallback_walkType(ParserNode *node);
+ bool parserCallback_start(ParserNode *node); // walk anim
+ bool parserCallback_loop(ParserNode *node); // walk anim
+ bool parserCallback_endD(ParserNode *node); // for walk anim
+ bool parserCallback_endG(ParserNode *node); // for walk anim
+ bool parserCallback_speed(ParserNode *node); // walk speed
+ bool parserCallback_cutSceneCurveDemi(ParserNode *node);
+ bool parserCallback_position(ParserNode *node); // position of cutSceneCurveDemi
+ bool parserCallback_face(ParserNode *node);
+ bool parserCallback_eyes(ParserNode *node);
+ bool parserCallback_mouth(ParserNode *node);
+ bool parserCallback_body(ParserNode *node);
+ bool textCallback(const Common::String &val) override;
+
+private:
+ Character::AnimSettings parseWalkAnimSettings(const ParserNode *node) const;
+
+ enum TextTagType {
+ TagModelFileName,
+ TagDefaultScale,
+ TagAnimationFileName,
+ TagEyes,
+ TagMouth,
+ TagSpeed,
+ TagPosition,
+ TagBody
+ };
+
+ TextTagType _curTextTag;
+ // TODO add private members
+ Character::CharacterSettings *_curCharacter;
+ Character::WalkSettings *_curWalkSettings;
+ Common::HashMap<Common::String, Character::CharacterSettings> *_characterSettings;
+};
+
+} // end namespace Tetraedge
+
+#endif // TETRAEDGE_GAME_CHARACTER_SETTINGS_XML_PARSER_H
diff --git a/engines/tetraedge/game/characters_shadow.cpp b/engines/tetraedge/game/characters_shadow.cpp
new file mode 100644
index 00000000000..46b1abefd64
--- /dev/null
+++ b/engines/tetraedge/game/characters_shadow.cpp
@@ -0,0 +1,51 @@
+/* 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 "tetraedge/tetraedge.h"
+#include "tetraedge/game/characters_shadow.h"
+#include "tetraedge/te/te_renderer.h"
+
+namespace Tetraedge {
+
+CharactersShadow::CharactersShadow() {
+}
+
+void CharactersShadow::create(InGameScene *scene) {
+ error("TODO: Implement me");
+}
+
+void CharactersShadow::createTexture(InGameScene *scene) {
+ error("TODO: Implement me");
+}
+
+void CharactersShadow::destroy() {
+ TeRenderer *renderer = g_engine->getRenderer();
+ renderer->disableTexture();
+ //glBindTexture(GL_TEXTURE_2D, 0);
+ //glDeleteTextures(1, (uint *)this);
+ error("TODO: Finish implementation here");
+}
+
+void CharactersShadow::draw(InGameScene *scene) {
+ error("TODO: Implement me");
+}
+
+} // end namespace Tetraedge
diff --git a/engines/tetraedge/game/characters_shadow.h b/engines/tetraedge/game/characters_shadow.h
new file mode 100644
index 00000000000..a6809f6414a
--- /dev/null
+++ b/engines/tetraedge/game/characters_shadow.h
@@ -0,0 +1,46 @@
+/* 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 TETRAEDGE_GAME_CHARACTERS_SHADOW_H
+#define TETRAEDGE_GAME_CHARACTERS_SHADOW_H
+
+#include "tetraedge/game/in_game_scene.h"
+
+namespace Tetraedge {
+
+class CharactersShadow {
+public:
+ CharactersShadow();
+
+ void create(InGameScene *scene);
+ void createTexture(InGameScene *scene);
+ void destroy();
+ void draw(InGameScene *scene);
+ //void drawTexture(); // empty?
+
+private:
+ // TODO add private members
+
+};
+
+} // end namespace Tetraedge
+
+#endif // TETRAEDGE_GAME_CHARACTERS_SHADOW_H
diff --git a/engines/tetraedge/game/confirm.cpp b/engines/tetraedge/game/confirm.cpp
new file mode 100644
index 00000000000..5ba7cbeec5c
--- /dev/null
+++ b/engines/tetraedge/game/confirm.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 "tetraedge/game/confirm.h"
+#include "tetraedge/game/application.h"
+#include "tetraedge/tetraedge.h"
+
+#include "tetraedge/te/te_text_layout.h"
+
+namespace Tetraedge {
+
+Confirm::Confirm() {
+}
+
+void Confirm::enter(const Common::String &guiPath, const Common::String &y) {
+ _gui.load(guiPath);
+ TeLayout *backgroundLayout = _gui.layoutChecked("background");
+ backgroundLayout->setRatioMode(TeILayout::RATIO_MODE_NONE);
+
+ Application *app = g_engine->getApplication();
+ TeButtonLayout *confirmButtonLayout = _gui.buttonLayout("confirm");
+ app->_frontOrientationLayout.addChild(confirmButtonLayout);
+
+ TeButtonLayout *yesButtonLayout = _gui.buttonLayout("yes");
+ if (yesButtonLayout)
+ yesButtonLayout->onMouseClickValidated().add<Confirm>(this, &Confirm::onButtonYes);
+
+ TeButtonLayout *noButtonLayout = _gui.buttonLayout("no");
+ if (noButtonLayout)
+ noButtonLayout->onMouseClickValidated().add<Confirm>(this, &Confirm::onButtonNo);
+
+ TeLayout *textLayout = _gui.layout("text");
+ if (textLayout) {
+ const Common::String textAttributs = _gui.value("textAttributs").toString();
+ const Common::String textAttributsDown = _gui.value("textAttributsDown").toString();
+ const Common::String *okButtonLoc = app->_loc.value("okButton");
+ const Common::String *cancelButtonLoc = app->_loc.value("cancelButton");
+
+ TeTextLayout *textTextLayout = dynamic_cast<TeTextLayout *>(textLayout->child(0));
+ textTextLayout->setText(textAttributs + *app->_loc.value(textTextLayout->name()));
+
+ if (!okButtonLoc || !cancelButtonLoc) {
+ error("Missing translations for ok and cancel");
+ }
+
+ TeTextLayout *yesUpLayout = _gui.textLayout("yesUpLayout");
+ if (yesUpLayout)
+ yesUpLayout->setText(textAttributs + *okButtonLoc);
+
+ TeTextLayout *yesDownLayout = _gui.textLayout("yesDownLayout");
+ if (yesDownLayout)
+ yesDownLayout->setText(textAttributsDown + *okButtonLoc);
+
+ TeTextLayout *yesRollOverLayout = _gui.textLayout("yesRollOverLayout");
+ if (yesRollOverLayout)
+ yesRollOverLayout->setText(textAttributs + *okButtonLoc);
+
+ TeTextLayout *noUpLayout = _gui.textLayout("noUpLayout");
+ if (noUpLayout)
+ noUpLayout->setText(textAttributs + *cancelButtonLoc);
+
+ TeTextLayout *noDownLayout = _gui.textLayout("noDownLayout");
+ if (noDownLayout)
+ noDownLayout->setText(textAttributsDown + *cancelButtonLoc);
+
+ TeTextLayout *noRollOverLayout = _gui.textLayout("noRollOverLayout");
+ if (noRollOverLayout)
+ noRollOverLayout->setText(textAttributs + *cancelButtonLoc);
+ }
+
+ // Make sure the mouse cursor is back on top.
+ app->_frontOrientationLayout.removeChild(&app->mouseCursorLayout());
+ app->_frontOrientationLayout.addChild(&app->mouseCursorLayout());
+}
+
+void Confirm::leave() {
+ Application *app = g_engine->getApplication();
+ TeButtonLayout *confirmButtonLayout = _gui.buttonLayout("confirm");
+ if (confirmButtonLayout) {
+ app->_frontLayout.removeChild(confirmButtonLayout);
+ }
+ _gui.unload();
+}
+
+bool Confirm::onButtonNo() {
+ Application *app = g_engine->getApplication();
+ app->captureFade();
+ leave();
+ _onButtonNoSignal.call();
+ app->fade();
+ return true;
+}
+
+bool Confirm::onButtonYes() {
+ Application *app = g_engine->getApplication();
+ app->captureFade();
+ leave();
+ _onButtonYesSignal.call();
+ app->fade();
+ return true;
+}
+
+} // end namespace Tetraedge
diff --git a/engines/tetraedge/game/confirm.h b/engines/tetraedge/game/confirm.h
new file mode 100644
index 00000000000..af21e62d15c
--- /dev/null
+++ b/engines/tetraedge/game/confirm.h
@@ -0,0 +1,49 @@
+/* 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 TETRAEDGE_GAME_CONFIRM_H
+#define TETRAEDGE_GAME_CONFIRM_H
+
+#include "common/str.h"
+
+#include "tetraedge/te/te_signal.h"
+#include "tetraedge/te/te_lua_gui.h"
+
+namespace Tetraedge {
+
+class Confirm {
+public:
+ Confirm();
+
+ void enter(const Common::String &guiPath, const Common::String &y);
+ void leave();
+
+ bool onButtonNo();
+ bool onButtonYes();
+
+ TeSignal0Param _onButtonNoSignal;
+ TeSignal0Param _onButtonYesSignal;
+ TeLuaGUI _gui;
+};
+
+} // end namespace Tetraedge
+
+#endif // TETRAEDGE_GAME_CONFIRM_H
diff --git a/engines/tetraedge/game/credits.cpp b/engines/tetraedge/game/credits.cpp
new file mode 100644
index 00000000000..572acc67079
--- /dev/null
+++ b/engines/tetraedge/game/credits.cpp
@@ -0,0 +1,66 @@
+/* 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/textconsole.h"
+#include "tetraedge/game/credits.h"
+
+namespace Tetraedge {
+
+Credits::Credits() {
+}
+
+void Credits::enter(bool flag) {
+ error("TODO: Implement Credits::enter");
+}
+
+void Credits::leave() {
+ error("TODO: Implement Credits::leave");
+}
+
+bool Credits::onAnimFinished() {
+ leave();
+ return false;
+}
+
+bool Credits::onBackgroundAnimFinished() {
+ //TeLayout *buttonsLayout = _gui.layout("buttons");
+ error("TODO: Implement Credits::onBackgroundAnimFinished");
+}
+
+bool Credits::onPadButtonUp(uint button) {
+ // Original calls this function here but it seems unnecessary?
+ //TeLayout *buttonsLayout = _gui.layout("buttons");
+ if (button & 2) // TODO; which button is 2?
+ leave();
+ return false;
+}
+
+bool Credits::onQuitButton() {
+ TeCurveAnim2<TeI3DObject2, TeVector3f32> *anim1 = _gui.layoutPositionLinearAnimation("scrollTextPositionAnim");
+ anim1->stop();
+ TeCurveAnim2<TeI3DObject2, TeVector3f32> *anim2 = _gui.layoutPositionLinearAnimation("scrollTextAnchorAnim");
+ anim2->stop();
+ leave();
+ return true;
+}
+
+
+} // end namespace Tetraedge
diff --git a/engines/tetraedge/game/credits.h b/engines/tetraedge/game/credits.h
new file mode 100644
index 00000000000..fada8eefdaa
--- /dev/null
+++ b/engines/tetraedge/game/credits.h
@@ -0,0 +1,55 @@
+/* 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 TETRAEDGE_GAME_CREDITS_H
+#define TETRAEDGE_GAME_CREDITS_H
+
+#include "tetraedge/te/te_lua_gui.h"
+#include "tetraedge/te/te_curve_anim2.h"
+#include "tetraedge/te/te_color.h"
+#include "tetraedge/te/te_3d_object2.h"
+
+namespace Tetraedge {
+
+class Credits {
+public:
+ Credits();
+
+ void enter(bool flag);
+ void leave();
+
+ bool onAnimFinished();
+ bool onBackgroundAnimFinished();
+ bool onPadButtonUp(uint button);
+ bool onQuitButton();
+
+private:
+ TeTimer _timer;
+ TeLuaGUI _gui;
+ TeCurveAnim2<Te3DObject2, TeColor> _curveAnim;
+ TeColor _col1;
+ TeColor _col2;
+ Common::Array<double> _doubleArr;
+};
+
+} // end namespace Tetraedge
+
+#endif // TETRAEDGE_GAME_CREDITS_H
diff --git a/engines/tetraedge/game/dialog2.cpp b/engines/tetraedge/game/dialog2.cpp
new file mode 100644
index 00000000000..6be1ece06e5
--- /dev/null
+++ b/engines/tetraedge/game/dialog2.cpp
@@ -0,0 +1,147 @@
+/* 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 "tetraedge/game/dialog2.h"
+#include "tetraedge/te/te_button_layout.h"
+
+namespace Tetraedge {
+
+Dialog2::Dialog2() {
+ _music.onStopSignal().add(this, &Dialog2::onSoundFinished);
+ _minimumTimeTimer.alarmSignal().add(this, &Dialog2::onMinimumTimeTimer);
+}
+
+bool Dialog2::isDialogPlaying() {
+ TeButtonLayout *lockbtn = _gui.buttonLayout("dialogLockButton");
+
+ if (lockbtn)
+ return lockbtn->visible();
+
+ return false;
+}
+
+void Dialog2::launchNextDialog() {
+ error("TODO: Implement Dialog2::launchNextDialog.");
+}
+
+void Dialog2::load() {
+ setName("dialog2");
+ setSizeType(RELATIVE_TO_PARENT);
+ TeVector3f32 usersz = userSize();
+ setSize(TeVector3f32(1.0f, 1.0f, usersz.z()));
+ size(); // refresh size.. seems to do nothing with result?
+ _music.repeat(false);
+ _gui.load("menus/dialog.lua");
+ TeButtonLayout *dialogLockBtn = _gui.buttonLayoutChecked("dialogLockButton");
+
+ dialogLockBtn->setVisible(false);
+ addChild(dialogLockBtn);
+
+ TeButtonLayout *dialogBtn = _gui.buttonLayoutChecked("dialog");
+ dialogBtn->onMouseClickValidated().add(this, &Dialog2::onSkipButton);
+
+ TeCurveAnim2<TeLayout,TeVector3f32> *dialogAnimUp = _gui.layoutAnchorLinearAnimation("dialogAnimationUp");
+ TeCurveAnim2<TeLayout,TeVector3f32> *dialogAnimDown = _gui.layoutAnchorLinearAnimation("dialogAnimationDown");
+ if (!dialogAnimUp || !dialogAnimDown)
+ error("Dialog2::load: didn't get dialogAnimUp or dialogAnimationDown");
+
+ dialogAnimUp->_callbackObj = dialogBtn;
+ dialogAnimUp->_callbackMethod = &TeLayout::setAnchor;
+ dialogAnimUp->onFinished().add(this, &Dialog2::onAnimationUpFinished);
+
+ dialogAnimDown->_callbackObj = dialogBtn;
+ dialogAnimDown->_callbackMethod = &TeLayout::setAnchor;
+ dialogAnimDown->onFinished().add(this, &Dialog2::onAnimationDownFinished);
+}
+
+void Dialog2::loadFromBackup() {
+ // seems to do nothing useful? just iterates the children..
+}
+
+bool Dialog2::onAnimationDownFinished() {
+ Common::String param(_animDownFinishedResultString);
+ launchNextDialog();
+ _onAnimationDownFinishedSignal.call(param);
+ return false;
+}
+
+bool Dialog2::onAnimationUpFinished() {
+ // Seems like this just prints a debug value??
+ TeButtonLayout *dialogButton = _gui.buttonLayout("dialog");
+ dialogButton->anchor();
+ return false;
+}
+
+bool Dialog2::onMinimumTimeTimer() {
+ _minimumTimeTimer.stop();
+ if (!_music.isPlaying())
+ startDownAnimation();
+ return false;
+}
+
+bool Dialog2::onSkipButton() {
+ const TeCurveAnim2<TeLayout,TeVector3f32> *dialogAnimUp = _gui.layoutAnchorLinearAnimation("dialogAnimationUp");
+ if (!dialogAnimUp->_runTimer._stopped) {
+ const TeCurveAnim2<TeLayout,TeVector3f32> *dialogAnimDown = _gui.layoutAnchorLinearAnimation("dialogAnimationDown");
+ if (dialogAnimDown->_runTimer._stopped) {
+ startDownAnimation();
+ _music.stop();
+ }
+ }
+ return false;
+}
+
+bool Dialog2::onSoundFinished() {
+ if (_minimumTimeTimer._stopped)
+ startDownAnimation();
+ return false;
+}
+
+void Dialog2::pushDialog(const Common::String ¶m_1, const Common::String ¶m_2, const Common::String ¶m_3, int param_4) {
+ error("TODO: Implement Dialog2::pushDialog");
+}
+
+void Dialog2::pushDialog(const Common::String ¶m_1, const Common::String ¶m_2, const Common::String ¶m_3,
+ const Common::String ¶m_4, const Common::String ¶m_5, float param_6) {
+ error("TODO: Implement Dialog2::pushDialog");
+}
+
+//void saveToBackup(TiXmlNode *node)
+
+void Dialog2::startDownAnimation() {
+ _minimumTimeTimer.stop();
+ TeCurveAnim2<TeLayout,TeVector3f32> *dialogAnimDown = _gui.layoutAnchorLinearAnimation("dialogAnimationDown");
+ dialogAnimDown->play();
+}
+
+void Dialog2::unload() {
+ TeCurveAnim2<TeLayout,TeVector3f32> *dialogAnimUp = _gui.layoutAnchorLinearAnimation("dialogAnimationUp");
+ dialogAnimUp->stop();
+ TeCurveAnim2<TeLayout,TeVector3f32> *dialogAnimDown = _gui.layoutAnchorLinearAnimation("dialogAnimationDown");
+ dialogAnimDown->stop();
+ _music.close();
+ _gui.unload();
+ error("TODO: Finish Dialog2::unload");
+ //_dialogDataList.clear();
+ //_minimumTimeTimer.stop();
+}
+
+} // end namespace Tetraedge
diff --git a/engines/tetraedge/game/dialog2.h b/engines/tetraedge/game/dialog2.h
new file mode 100644
index 00000000000..9e2a8f025ad
--- /dev/null
+++ b/engines/tetraedge/game/dialog2.h
@@ -0,0 +1,74 @@
+/* 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 TETRAEDGE_GAME_DIALOG2_H
+#define TETRAEDGE_GAME_DIALOG2_H
+
+#include "tetraedge/te/te_timer.h"
+#include "tetraedge/te/te_music.h"
+#include "tetraedge/te/te_lua_gui.h"
+
+namespace Tetraedge {
+
+class Dialog2 : public TeLayout {
+public:
+ Dialog2();
+
+ class DialogData {
+ bool operator=(const DialogData &other);
+ };
+
+ bool isDialogPlaying();
+ void launchNextDialog();
+ void load();
+ void loadFromBackup(); // seems to do nothing useful? just iterates the children..
+ bool onAnimationDownFinished();
+ bool onAnimationUpFinished();
+ bool onMinimumTimeTimer();
+ bool onSkipButton();
+ bool onSoundFinished();
+
+ void pushDialog(const Common::String ¶m_1, const Common::String ¶m_2, const Common::String ¶m_3, int param_4);
+ void pushDialog(const Common::String ¶m_1, const Common::String ¶m_2, const Common::String ¶m_3,
+ const Common::String ¶m_4, const Common::String ¶m_5, float param_6);
+ //void saveToBackup(TiXmlNode *node)
+ void startDownAnimation();
+ void unload();
+
+ TeLuaGUI &gui() { return _gui; }
+
+ Common::String prevSceneName() { return _prevSceneName; };
+
+private:
+ TeTimer _minimumTimeTimer;
+
+ Common::String _prevSceneName;
+ Common::String _animDownFinishedResultString;
+
+ TeLuaGUI _gui;
+ TeMusic _music;
+
+ TeSignal1Param<const Common::String &> _onAnimationDownFinishedSignal;
+};
+
+} // end namespace Tetraedge
+
+#endif // TETRAEDGE_GAME_DIALOG2_H
diff --git a/engines/tetraedge/game/document.cpp b/engines/tetraedge/game/document.cpp
new file mode 100644
index 00000000000..be6ccd15604
--- /dev/null
+++ b/engines/tetraedge/game/document.cpp
@@ -0,0 +1,31 @@
+/* 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 "tetraedge/game/document.h"
+
+namespace Tetraedge {
+
+Document::Document() {
+}
+
+// TODO: Add more functions here.
+
+} // end namespace Tetraedge
diff --git a/engines/tetraedge/game/document.h b/engines/tetraedge/game/document.h
new file mode 100644
index 00000000000..9c6bbeb8a65
--- /dev/null
+++ b/engines/tetraedge/game/document.h
@@ -0,0 +1,53 @@
+/* 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 TETRAEDGE_GAME_DOCUMENT_H
+#define TETRAEDGE_GAME_DOCUMENT_H
+
+#include "common/str.h"
+
+namespace Tetraedge {
+
+class Document {
+public:
+ Document();
+ ~Document() {
+ unload();
+ // TODO: check for other destructor things.
+ }
+
+ void load(const Common::String &name);
+ //void loadFromBackup(TiXmlElement &node) {
+ // load(node->Attribute("id");
+ //}
+ bool onButtonDown();
+ //void saveToBackup(TiXmlElement &node);
+ Common::String spritePath() const;
+ void unload();
+
+private:
+ // TODO add private members
+
+};
+
+} // end namespace Tetraedge
+
+#endif // TETRAEDGE_GAME_DOCUMENT_H
diff --git a/engines/tetraedge/game/documents_browser.cpp b/engines/tetraedge/game/documents_browser.cpp
new file mode 100644
index 00000000000..5762275900f
--- /dev/null
+++ b/engines/tetraedge/game/documents_browser.cpp
@@ -0,0 +1,112 @@
+/* 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 "tetraedge/game/documents_browser.h"
+
+namespace Tetraedge {
+
+DocumentsBrowser::DocumentsBrowser() {
+ _timer.alarmSignal().add(this, &DocumentsBrowser::onQuitDocumentDoubleClickTimer);
+}
+
+void DocumentsBrowser::enter() {
+ setVisible(true);
+ currentPage(_curPage);
+}
+
+void DocumentsBrowser::leave() {
+ _timer.stop();
+ setVisible(false);
+}
+
+void DocumentsBrowser::load() {
+ setVisible(false);
+ setName("documentsBrowser");
+
+ setSizeType(RELATIVE_TO_PARENT);
+ const TeVector3f32 userSz = TeLayout::userSize();
+ setSize(TeVector3f32(1.0f, 1.0f, userSz.z()));
+
+ TeLuaGUI::load("DocumentsBrowser/DocumentsBrowser.lua");
+
+ TeLayout *docBrowser = TeLuaGUI::layout("documentBrowser");
+ if (docBrowser)
+ addChild(docBrowser);
+
+ TeButtonLayout *button = buttonLayout("previousPage");
+ button->onMouseClickValidated().add(this, &DocumentsBrowser::onPreviousPage);
+ button = buttonLayout("nextPage");
+ button->onMouseClickValidated().add(this, &DocumentsBrowser::onNextPage);
+ button = TeLuaGUI::buttonLayout("zoomed");
+ button->onMouseClickValidated().add(this, &DocumentsBrowser::onZoomedButton);
+ button = TeLuaGUI::buttonLayout("zoomed");
+ button->setVisible(false);
+
+ // Game tries to load a file that doesn't exist..
+ debug("TODO?? DocumentsBrowser::load: Game opens Documents.xml here.");
+ _timer.start();
+}
+
+void DocumentsBrowser::loadZoomed() {
+ _zoomedLayout.setSizeType(RELATIVE_TO_PARENT);
+ TeVector3f32 usersz = userSize();
+ _zoomedLayout.setSize(TeVector3f32(1.0f, 1.0f, usersz.z()));
+ TeLayout *zoomedChild = layout("zoomed");
+ _zoomedLayout.addChild(zoomedChild);
+}
+
+void DocumentsBrowser::currentPage(long page) {
+ const Common::String pageName = Common::String::format("page%ld", page);
+ TeLayout *pageLayout = layout(pageName);
+ if (!pageLayout)
+ return;
+
+ _curPage = page;
+
+ error("TODO: Implement DocumentsBrowser::currentPage");
+}
+
+bool DocumentsBrowser::onQuitDocumentDoubleClickTimer() {
+ error("TODO: Implement DocumentsBrowser::onQuitDocumentDoubleClickTimer");
+}
+
+bool DocumentsBrowser::onNextPage() {
+ currentPage(_curPage + 1);
+ return false;
+}
+
+bool DocumentsBrowser::onPreviousPage() {
+ currentPage(_curPage - 1);
+ return false;
+}
+
+bool DocumentsBrowser::onZoomedButton() {
+ error("TODO: Implement DocumentsBrowser::onZoomedButton");
+}
+
+void DocumentsBrowser::showDocument(const Common::String &str, long n) {
+ error("TODO: Implement DocumentsBrowser::showDocument");
+}
+
+
+// TODO: Add more functions here.
+
+} // end namespace Tetraedge
diff --git a/engines/tetraedge/game/documents_browser.h b/engines/tetraedge/game/documents_browser.h
new file mode 100644
index 00000000000..0331cb2cb28
--- /dev/null
+++ b/engines/tetraedge/game/documents_browser.h
@@ -0,0 +1,97 @@
+/* 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 TETRAEDGE_GAME_DOCUMENTS_BROWSER_H
+#define TETRAEDGE_GAME_DOCUMENTS_BROWSER_H
+
+#include "common/str.h"
+#include "tetraedge/game/document.h"
+#include "tetraedge/te/te_lua_gui.h"
+
+namespace Tetraedge {
+
+class DocumentsBrowser : public TeLuaGUI, public TeLayout {
+public:
+ DocumentsBrowser();
+
+ void addDocument(Document *document);
+ void addDocument(const Common::String &str);
+
+ void currentPage(long page);
+ int documentCount(const Common::String &str) { // never used?
+ return 1;
+ }
+
+ Common::String documentDescription(const Common::String &name);
+ Common::String documentName(const Common::String &name);
+
+ void enter();
+ void hideDocument();
+ void leave();
+ void load();
+ // void loadFromBackup(TiXmlNode *node);
+ void loadZoomed();
+ // void saveToBackup(TiXmlNode *node);
+
+ void onDocumentSelected(Document *doc);
+ bool onNextPage();
+ bool onPreviousPage();
+ bool onQuitDocumentDoubleClickTimer();
+ bool onZoomedButton();
+
+ // Sorry, this is how the original does it...
+ bool onShowedDocumentButton0();
+ bool onShowedDocumentButton1();
+ bool onShowedDocumentButton2();
+ bool onShowedDocumentButton3();
+ bool onShowedDocumentButton4();
+ bool onShowedDocumentButton5();
+ bool onShowedDocumentButton6();
+ bool onShowedDocumentButton7();
+ bool onShowedDocumentButton8();
+ bool onShowedDocumentButton9();
+ bool onShowedDocumentButton10();
+ bool onShowedDocumentButton11();
+ bool onShowedDocumentButton12();
+ bool onShowedDocumentButton13();
+ bool onShowedDocumentButton14();
+ bool onShowedDocumentButton15();
+ bool onShowedDocumentButton16();
+ bool onShowedDocumentButton17();
+ bool onShowedDocumentButton18();
+ bool onShowedDocumentButton19();
+
+ void showDocument(const Common::String &str, long n);
+ void unload();
+
+ TeLayout &zoomedLayout() { return _zoomedLayout; }
+
+private:
+ TeTimer _timer;
+ TeLayout _zoomedLayout;
+ unsigned long _curPage;
+ // TODO add private members
+ // TiXmlDocument _xmldoc;
+};
+
+} // end namespace Tetraedge
+
+#endif // TETRAEDGE_GAME_DOCUMENTS_BROWSER_H
diff --git a/engines/tetraedge/game/gallery_menu.cpp b/engines/tetraedge/game/gallery_menu.cpp
new file mode 100644
index 00000000000..935443f1c8b
--- /dev/null
+++ b/engines/tetraedge/game/gallery_menu.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 "tetraedge/tetraedge.h"
+#include "tetraedge/game/application.h"
+#include "tetraedge/game/gallery_menu.h"
+
+namespace Tetraedge {
+
+GalleryMenu::GalleryMenu() {
+}
+
+bool GalleryMenu::onLockVideoButtonValidated() {
+ onSkipVideoButtonValidated();
+ return false;
+}
+
+bool GalleryMenu::onSkipVideoButtonValidated() {
+ error("TODO: Implement onSkipVideoButtonValidated");
+ return false;
+}
+
+bool GalleryMenu::onQuitButton() {
+ Application *app = g_engine->getApplication();
+ app->captureFade();
+ leave();
+ app->mainMenu().enter();
+ app->fade();
+ return true;
+}
+
+bool GalleryMenu::onVideoFinished() {
+ if (_loaded) {
+ Application *app = g_engine->getApplication();
+ app->captureFade();
+ onSkipVideoButtonValidated();
+ app->music().play();
+ app->fade();
+ }
+ return false;
+}
+
+void GalleryMenu::enter() {
+ error("TODO: implement GalleryMenu::enter");
+}
+
+void GalleryMenu::leave() {
+ error("TODO: implement GalleryMenu::leave");
+}
+
+} // end namespace Tetraedge
diff --git a/engines/tetraedge/game/gallery_menu.h b/engines/tetraedge/game/gallery_menu.h
new file mode 100644
index 00000000000..50dd39ee656
--- /dev/null
+++ b/engines/tetraedge/game/gallery_menu.h
@@ -0,0 +1,54 @@
+/* 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 TETRAEDGE_GAME_GALLERY_MENU_H
+#define TETRAEDGE_GAME_GALLERY_MENU_H
+
+#include "common/array.h"
+#include "tetraedge/te/te_music.h"
+#include "tetraedge/te/te_lua_gui.h"
+
+namespace Tetraedge {
+
+class GalleryMenu : public TeLuaGUI {
+public:
+ GalleryMenu();
+
+ class GalleryBtnObject {
+ bool OnValidated();
+ };
+
+ void enter();
+ void leave();
+
+ bool onQuitButton();
+ bool onLockVideoButtonValidated();
+ bool onSkipVideoButtonValidated();
+ bool onVideoFinished();
+
+private:
+ TeMusic _music;
+ Common::Array<GalleryBtnObject *> _btnObjects;
+};
+
+} // end namespace Tetraedge
+
+#endif // TETRAEDGE_GAME_GALLERY_MENU_H
diff --git a/engines/tetraedge/game/game.cpp b/engines/tetraedge/game/game.cpp
new file mode 100644
index 00000000000..9d4ee36803f
--- /dev/null
+++ b/engines/tetraedge/game/game.cpp
@@ -0,0 +1,1034 @@
+/* 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/file.h"
+#include "common/path.h"
+#include "common/str-array.h"
+#include "common/system.h"
+
+#include "tetraedge/tetraedge.h"
+#include "tetraedge/game/application.h"
+#include "tetraedge/game/character.h"
+#include "tetraedge/game/in_game_scene.h"
+#include "tetraedge/game/game.h"
+#include "tetraedge/game/game_achievements.h"
+#include "tetraedge/game/lua_binds.h"
+#include "tetraedge/game/object3d.h"
+#include "tetraedge/te/te_core.h"
+#include "tetraedge/te/te_input_mgr.h"
+#include "tetraedge/te/te_variant.h"
+
+namespace Tetraedge {
+
+Game::Game() : _objectsTakenVal(0), _score(0), _entered(false), _gameLoadState(0),
+_noScaleLayout(nullptr), _noScaleLayout2(nullptr), _warped(false), _saveRequested(false),
+_firstInventory(true) {
+ for (int i = 0; i < NUM_OBJECTS_TAKEN_IDS; i++) {
+ _objectsTakenBits[i] = false;
+ }
+}
+
+/*static*/ const char *Game::OBJECTS_TAKEN_IDS[5] = {
+ "BCylindreBarr",
+ "VCylindreMusique",
+ "VCylindreVal",
+ "CCylindreCite",
+ "VPoupeeMammouth"
+};
+
+bool Game::addAnimToSet(const Common::String &anim) {
+ // Get path to lua script, eg scenes/ValVoralberg/14040/Set14040.lua
+ const Common::Path animPath(Common::String("scenes/") + anim + "/");
+
+ bool retval = false;
+ if (Common::File::exists(animPath)) {
+ Common::StringArray parts = TetraedgeEngine::splitString(anim, '/');
+ assert(parts.size() >= 2);
+
+ Common::String layoutName = parts[1];
+ Common::String path = Common::String("scenes/") + parts[0] + "/" + parts[1] + "/Set" + parts[1];
+
+ _gui2.load(path + ".lua");
+ /*
+ TeILayout *layout = _gui2.layout("root");
+ TeSpriteLayout *spriteLayout2 = findSpriteLayoutByName(layout, layoutName);
+
+ TeLayout *layout2 = TeLuaGUI::layout(&(this->scene).field_0x170,"root");
+ long lVar5 = 0;
+ if (spriteLayout2) {
+ lVar5 = (long)plVar3 + *(long *)(*plVar3 + -0x198);
+ }
+ (**(code **)(*(long *)((long)&pTVar2->vptr + (long)pTVar2->vptr[-0x33]) + 0x30))
+ ((long)&pTVar2->vptr + (long)pTVar2->vptr[-0x33],lVar5);
+ */
+ retval = true;
+ }
+
+ return retval;
+}
+
+void Game::addArtworkUnlocked(const Common::String &name, bool notify) {
+ if (_unlockedArtwork.contains(name))
+ return;
+ _unlockedArtwork[name] = true;
+ if (notify) {
+ _notifier.push("BONUS!", "Inventory/Objects/VPapierCrayon.png");
+ }
+}
+
+void Game::addNoScale2Child(TeLayout *layout) {
+ if (_noScaleLayout2 && layout) {
+ _noScaleLayout2->addChild(layout);
+ }
+}
+
+void Game::addNoScale2Children() {
+ if (!_noScaleLayout2)
+ return;
+
+ TeLayout *vidbtn = _gui4.layout("videoButtonLayout");
+ if (vidbtn)
+ _noScaleLayout2->addChild(vidbtn);
+
+ TeLayout *bg = _inventory.cellphone()->gui().layout("background");
+ if (bg)
+ _noScaleLayout2->addChild(bg);
+
+ TeButtonLayout *bgbtn = _objectif.gui1().buttonLayout("background");
+ if (bgbtn)
+ _noScaleLayout2->addChild(bgbtn);
+}
+
+void Game::addNoScaleChildren() {
+ if (!_noScaleLayout)
+ return;
+ TeLayout *inGame = _gui4.layout("inGame");
+ if (inGame)
+ _noScaleLayout->addChild(inGame);
+
+ _noScaleLayout->addChild(&_question2);
+
+ Application *app = g_engine->getApplication();
+ app->_frontLayout.addChild(&_dialog2);
+
+ _noScaleLayout->addChild(&_inventory);
+ _noScaleLayout->addChild(&_inventoryMenu);
+ _noScaleLayout->addChild(&_documentsBrowser);
+ _noScaleLayout->addChild(&_documentsBrowser.zoomedLayout());
+}
+
+void Game::addRandomSound(const Common::String &s1, const Common::String &s2, float f1, float f2) {
+ warning("TODO: Implemet Game::addRandomSound %s %s %f %f", s1.c_str(), s1.c_str(), f1, f2);
+}
+
+void Game::addToBag(const Common::String &objname) {
+ if (_inventory.objectCount(objname) != 0)
+ return;
+ _inventory.addObject(objname);
+ Common::String imgpath("Inventory/Objects/");
+ imgpath += _inventory.objectName(objname);
+ imgpath += ".png";
+ _notifier.push(objname, imgpath);
+ for (int i = 0; i < NUM_OBJECTS_TAKEN_IDS; i++) {
+ if (objname == OBJECTS_TAKEN_IDS[i] && !_objectsTakenBits[i]) {
+ _objectsTakenBits[i] = true;
+ _objectsTakenVal++;
+ }
+ }
+ // Seeems strange as we're already in Game, but that's what original does?
+ Game *game = g_engine->getGame();
+ game->_score += 10;
+ debug("Updated score: %d", game->_score);
+}
+
+void Game::addToHand(const Common::String &objname) {
+ _inventory.addObject(objname);
+ _inventory.selectedObject(objname);
+}
+
+void Game::addToScore(int score) {
+ _score += score;
+}
+
+bool Game::changeWarp(const Common::String &zone, const Common::String &scene, bool fadeFlag) {
+ Application *app = g_engine->getApplication();
+ if (fadeFlag) {
+ app->blackFade();
+ } else {
+ app->captureFade();
+ }
+ _warpZone = zone;
+ _warpScene = scene;
+ _warpFadeFlag = fadeFlag;
+ _warped = true;
+ return true;
+}
+
+bool Game::changeWarp2(const Common::String &zone, const Common::String &scene, bool fadeFlag) {
+ error("TODO: Implemet me");
+}
+
+void Game::deleteNoScale() {
+ error("TODO: Implemet me");
+}
+
+void Game::draw() {
+ if (_running) {
+ _frameCounter++;
+ _scene.draw();
+ }
+}
+
+void Game::enter(bool newgame) {
+ warning("TODO: Game::enter set field_0x42f0 true here");
+ _entered = true;
+ _luaShowOwnerError = false;
+ _score = 0;
+ Application *app = g_engine->getApplication();
+ app->visualFade().init();
+ Common::SharedPtr<TeCallback1Param<Game, const Common::Point &>> callbackptr(new TeCallback1Param<Game, const Common::Point &>(this, &Game::onMouseClick, -1000.0f));
+ g_engine->getInputMgr()->_mouseLUpSignal.insert(callbackptr);
+ warning("TODO: Game::enter set some other fields here");
+ _sceneCharacterVisibleFromLoad = false;
+ Character::loadSettings("models/ModelsSettings.xml");
+ Object3D::loadSettings("objects/ObjectsSettings.xml");
+ if (_scene._character) {
+ _scene._character->onFinished().remove(this, &Game::onDisplacementFinished);
+ _scene.unloadCharacter(_scene._character->_model->name());
+ }
+ bool loaded = loadPlayerCharacter("Kate");
+ if (!loaded)
+ error("[Game::enter] Can't load player character");
+
+ _scene._character->_model->setVisible(true);
+ _running = true;
+ _luaContext.create();
+ GameAchievements::registerAchievements(_luaContext);
+
+ _luaContext.setGlobal("BUTTON_VALID", 1);
+ _luaContext.setGlobal("BUTTON_CANCEL", 2);
+ _luaContext.setGlobal("BUTTON_EXTRA1", 4);
+ _luaContext.setGlobal("BUTTON_EXTRA2", 8);
+ _luaContext.setGlobal("BUTTON_L1", 0x10);
+ _luaContext.setGlobal("BUTTON_R1", 0x20);
+ _luaContext.setGlobal("BUTTON_START", 0x40);
+ _luaContext.setGlobal("BUTTON_UP", 0x80);
+ _luaContext.setGlobal("BUTTON_DOWN", 0x100);
+ _luaContext.setGlobal("BUTTON_LEFT", 0x200);
+ _luaContext.setGlobal("BUTTON_RIGHT", 0x400);
+ _luaContext.setGlobal("BUTTON_LS_CLIC", 0x800);
+ _luaContext.setGlobal("BUTTON_RS_CLIC", 0x1000);
+ _luaContext.setGlobal("BUTTON_BACK", 0x2000);
+ _luaContext.setGlobal("BUTTON_SELECT", 0x4000);
+ _luaContext.setGlobal("BUTTON_L2", 0x8000);
+ _luaContext.setGlobal("BUTTON_R2", 0x10000);
+ _luaContext.setGlobal("BUTTON_LS_UP", 0x20000);
+ _luaContext.setGlobal("BUTTON_LS_DOWN", 0x40000);
+ _luaContext.setGlobal("BUTTON_LS_LEFT", 0x80000);
+ _luaContext.setGlobal("BUTTON_LS_RIGHT", 0x100000);
+ _luaContext.setGlobal("BUTTON_RS_UP", 0x200000);
+ _luaContext.setGlobal("BUTTON_RS_DOWN", 0x400000);
+ _luaContext.setGlobal("BUTTON_RS_LEFT", 0x800000);
+ _luaContext.setGlobal("BUTTON_RS_RIGHT", 0x1000000);
+
+ _luaScript.attachToContext(&_luaContext);
+
+ if (!_objectif.gui1().loaded()) {
+ _objectif.load();
+ }
+ _question2.load();
+ _dialog2.load();
+ _documentsBrowser.load();
+ _documentsBrowser.loadZoomed();
+ _inventory.load();
+
+ _inventory.cellphone()->onCallNumber().add(this, &Game::onCallNumber);
+
+ if (!newgame) {
+ loadBackup(_loadName);
+ } else {
+ _gameLoadState = 1;
+ onFinishedLoadingBackup("");
+ }
+ _sceneCharacterVisibleFromLoad = true;
+ _scene._character->onFinished().remove(this, &Game::onDisplacementFinished);
+ _scene._character->onFinished().add(this, &Game::onDisplacementFinished);
+ _dialog2.prevSceneName().clear();
+ _notifier.load();
+}
+
+/*static*/ TeI3DObject2 *Game::findLayoutByName(TeLayout *parent, const Common::String &name) {
+ error("TODO: Implement me - although maybe this is never used?");
+}
+
+/*static*/ TeSpriteLayout *Game::findSpriteLayoutByName(TeLayout *parent, const Common::String &name) {
+ if (!parent)
+ return nullptr;
+
+ if (parent->name() == name)
+ return dynamic_cast<TeSpriteLayout *>(parent);
+
+ for (auto &child : parent->childList()) {
+ TeSpriteLayout *val = findSpriteLayoutByName(dynamic_cast<TeLayout *>(child), name);
+ if (val)
+ return val;
+ }
+
+ return nullptr;
+}
+
+void Game::finishFreemium() {
+ Application *app = g_engine->getApplication();
+ app->_finishedGame = true;
+ app->_finishedFremium = true;
+}
+
+void Game::finishGame() {
+ Application *app = g_engine->getApplication();
+ app->_finishedGame = true;
+ _playedTimer.stop();
+ /* Game does this but does nothing with result?
+ if (app->difficulty() == 2) {
+ _playedTimer.getTimeFromStart();
+ } */
+ app->credits().enter(false);
+}
+
+void Game::initLoadedBackupData() {
+ if (!_loadName.empty()) {
+ error("TODO: Implemet Game::initLoadedBackupData loading part");
+ }
+ Application *app = g_engine->getApplication();
+ const Common::String firstWarpPath = app->_firstWarpPath;
+ _currentScene = app->_firstScene;
+ _currentZone = app->_firstZone;
+ _playedTimer.start();
+ _objectsTakenVal = 0;
+ for (int i = 0; i < ARRAYSIZE(_objectsTakenBits); i++) {
+ _objectsTakenBits[i] = 0;
+ }
+ _dialogsTold = 0;
+ if (_loadName == "NO_OWNER")
+ _luaShowOwnerError = true;
+ _gameLoadState = 0;
+ app->showLoadingIcon(false);
+ _loadName.clear();
+ initScene(true, firstWarpPath);
+}
+
+void Game::initNoScale() {
+ if (!_noScaleLayout) {
+ _noScaleLayout = new TeLayout();
+ _noScaleLayout->setName("noScaleLayout");
+ _noScaleLayout->setSizeType(TeILayout::RELATIVE_TO_PARENT);
+ _noScaleLayout->setSize(TeVector3f32(1.0f, 1.0f, 0.0f));
+ }
+
+ if (!_noScaleLayout2) {
+ _noScaleLayout2 = new TeLayout();
+ _noScaleLayout2->setName("noScaleLayout2");
+ _noScaleLayout2->setSizeType(TeILayout::RELATIVE_TO_PARENT);
+ _noScaleLayout2->setSize(TeVector3f32(1.0f, 1.0f, 0.0f));
+ }
+}
+
+void Game::initScene(bool fade, const Common::String &scenePath) {
+ _luaContext.setGlobal("SHOW_OWNER_ERROR", _luaShowOwnerError);
+ initWarp(_currentZone, _currentScene, fade);
+ loadScene(scenePath);
+ if (_scene._character->_model.get() && !_scene.findKate()) {
+ _scene.models().push_back(_scene._character->_model);
+ }
+ _scene._character->_model->setVisible(true);
+}
+
+void Game::initWarp(const Common::String &zone, const Common::String &scene, bool fadeFlag) {
+ _inventoryMenu.unload();
+ _gui4.unload();
+ warning("Game::initWarp: set field_0x4248 false here");
+ _sceneCharacterVisibleFromLoad = true;
+
+ if (_scene._character) {
+ _scene._character->_model->setVisible(false);
+ _scene._character->deleteAllCallback();
+ _scene._character->stop();
+ _scene._character->setAnimation(_scene._character->characterSettings()._walkFileName, true, false, false, -1, 9999);
+ if (!_scene.findKate()) {
+ _scene.models().push_back(_scene._character->_model);
+ _scene.models().push_back(_scene._character->_shadowModel[0]);
+ _scene.models().push_back(_scene._character->_shadowModel[1]);
+ }
+ }
+
+ _currentZone = zone;
+ _currentScene = scene;
+
+ _scene.loadBlockers();
+ Common::Path scenePath("scenes");
+ scenePath.joinInPlace(zone);
+ scenePath.joinInPlace(scene);
+ _sceneZonePath = scenePath;
+
+ const Common::Path intLuaPath = scenePath.join(Common::String::format("Int%s.lua", scene.c_str()));
+ const Common::Path logicLuaPath = scenePath.join(Common::String::format("Logic%s.lua", scene.c_str()));
+ const Common::Path setLuaPath = scenePath.join(Common::String::format("Set%s.lua", scene.c_str()));
+ const Common::Path forLuaPath = scenePath.join(Common::String::format("For%s.lua", scene.c_str()));
+ const Common::Path markerLuaPath = scenePath.join(Common::String::format("Marker%s.lua", scene.c_str()));
+
+ bool intLuaExists = Common::File::exists(intLuaPath);
+ bool logicLuaExists = Common::File::exists(logicLuaPath);
+ bool setLuaExists = Common::File::exists(setLuaPath);
+ bool forLuaExists = Common::File::exists(forLuaPath);
+ bool markerLuaExists = Common::File::exists(markerLuaPath);
+
+ if (!intLuaExists && !logicLuaExists && !setLuaExists && !forLuaExists && !markerLuaExists) {
+ debug("No lua scripts for scene %s zone %s", scene.c_str(), zone.c_str());
+ return;
+ }
+
+ warning("TODO: Game::initWarp: stop game sounds");
+
+ if (logicLuaExists) {
+ _luaContext.addBindings(LuaBinds::LuaOpenBinds);
+ _luaScript.attachToContext(&_luaContext);
+ _luaScript.load("menus/help/help.lua");
+ _luaScript.load(logicLuaPath);
+ }
+
+ if (_gui3.loaded())
+ _gui3.unload();
+
+ _scene.reset();
+ _scene.bgGui().unload();
+ _gui2.unload();
+ Common::Path geomPath(Common::String::format("scenes/%s/Geometry/%s.bin",
+ zone.c_str(), zone.c_str()));
+ _scene.load(geomPath);
+ _scene.loadBackground(setLuaPath);
+
+ Application *app = g_engine->getApplication();
+ if (forLuaExists) {
+ _gui3.load(forLuaPath);
+ TeLayout *bg = _gui3.layout("background");
+ bg->setRatioMode(TeILayout::RATIO_MODE_NONE);
+ app->_frontLayout.addChild(bg);
+ TeLayout *cellbg = _inventory.cellphone()->gui().buttonLayout("background");
+ app->_frontLayout.removeChild(cellbg);
+ app->_frontLayout.addChild(cellbg);
+ _objectif.reattachLayout(&app->_frontLayout);
+ }
+
+ if (intLuaExists) {
+ _scene.loadInteractions(intLuaPath);
+ warning("TODO: Game::initWarp: Finish interactions.");
+ }
+
+ _inventoryMenu.load();
+ _gui4.load("InGame.lua");
+
+ TeButtonLayout *skipbtn = _gui4.buttonLayout("skipVideoButton");
+ skipbtn->setVisible(false);
+ skipbtn->onMouseClickValidated().remove(this, &Game::onSkipVideoButtonValidated);
+ skipbtn->onMouseClickValidated().add(this, &Game::onSkipVideoButtonValidated);
+
+ TeButtonLayout *vidbgbtn = _gui4.buttonLayout("videoBackgroundButton");
+ vidbgbtn->setVisible(false);
+ vidbgbtn->onMouseClickValidated().remove(this, &Game::onLockVideoButtonValidated);
+ vidbgbtn->onMouseClickValidated().add(this, &Game::onLockVideoButtonValidated);
+
+ TeSpriteLayout *video = _gui4.spriteLayout("video");
+ video->setVisible(false);
+ video->_tiledSurfacePtr->_frameAnim.onFinished().remove(this, &Game::onVideoFinished);
+ video->_tiledSurfacePtr->_frameAnim.onFinished().add(this, &Game::onVideoFinished);
+
+ TeButtonLayout *invbtn = _gui4.buttonLayout("inventoryButton");
+ invbtn->setSizeType(TeILayout::RELATIVE_TO_PARENT); // TODO: Double-check if this is the right virt fn.
+ invbtn->onMouseClickValidated().remove(this, &Game::onInventoryButtonValidated);
+ invbtn->onMouseClickValidated().add(this, &Game::onInventoryButtonValidated);
+
+ const TeVector3f32 winSize = app->getMainWindow().size();
+ if (g_engine->getCore()->fileFlagSystemFlag("definition") == "SD") {
+ invbtn->setSize(TeVector3f32(0.12, (4.0 / ((winSize.y() / winSize.x()) * 4.0)) * 0.12, 0.0));
+ } else {
+ invbtn->setSize(TeVector3f32(0.08, (4.0 / ((winSize.y() / winSize.x()) * 4.0)) * 0.08, 0.0));
+ }
+
+ TeCheckboxLayout *markersCheckbox = _gui4.checkboxLayout("markersVisibleButton");
+ markersCheckbox->setVisible(!_markersVisible);
+ markersCheckbox->onStateChangedSignal().add(this, &Game::onMarkersVisible);
+
+ initNoScale();
+ removeNoScale2Children();
+ app->_frontLayout.removeChild(_noScaleLayout2);
+
+ TeLayout *vidLayout = _gui4.layout("videoLayout");
+ app->_frontLayout.removeChild(vidLayout);
+ removeNoScaleChildren();
+ app->_frontLayout.removeChild(_noScaleLayout);
+
+ app->_frontLayout.addChild(_noScaleLayout);
+ addNoScaleChildren();
+ app->_frontLayout.addChild(vidLayout);
+ app->_frontLayout.addChild(_noScaleLayout2);
+ addNoScale2Children();
+ if (!fadeFlag) {
+ if (_inventory.selectedObject().size()) {
+ _inventory.selectedObject(*_inventory.selectedInventoryObject());
+ }
+ _inventory.setVisible(true);
+ _objectif.setVisibleObjectif(false);
+ _objectif.setVisibleButtonHelp(true);
+ _running = true;
+ loadScene("save.xml");
+ }
+
+ app->_backLayout.addChild(_scene.background());
+
+ if (markerLuaExists) {
+ TeLayout *bg = _gui2.layout("background");
+ app->_frontLayout.addChild(bg);
+ }
+
+ Common::String camname = Common::String("Camera") + scene;
+ _scene.setCurrentCamera(camname);
+
+ // Special hacks for certain scenes (don't blame me, original does this..)
+ if (scene == "14050") {
+ TeIntrusivePtr<TeCamera> curcamera = _scene.currentCamera();
+ const TeVector3f32 coords(1200.6f,-1937.5f,1544.1f);
+ curcamera->setPosition(coords);
+ } else if (scene == "34610") {
+ TeIntrusivePtr<TeCamera> curcamera = _scene.currentCamera();
+ const TeVector3f32 coords(-328.243f,340.303f,-1342.84f);
+ curcamera->setPosition(coords);
+ const TeQuaternion rot(0.003194, 0.910923, -0.009496, -0.412389);
+ curcamera->setRotation(rot);
+ }
+
+ if (logicLuaExists) {
+ _exitZone.clear();
+ _luaScript.execute();
+ _luaScript.execute("OnEnter", _prevSceneName);
+ _luaScript.execute("OnSelectedObject", _inventory.selectedObject());
+ }
+
+ //for (auto & sound : _gameSounds) {
+ warning("TODO: Game::initWarp: Do game sound stuff here");
+
+ _scene.initScroll();
+}
+
+bool Game::isDocumentOpened() {
+ TeLayout *layout = _documentsBrowser.layout("zoomed");
+ return layout->visible();
+}
+
+bool Game::isMoviePlaying() {
+ TeButtonLayout *vidButton = _gui4.buttonLayout("videoBackgroundButton");
+ if (vidButton)
+ return vidButton->visible();
+ return false;
+}
+
+bool Game::launchDialog(const Common::String ¶m_1, uint param_2, const Common::String ¶m_3,
+ const Common::String ¶m_4, float param_5) {
+ error("TODO: Implemet Game::launchDialog");
+}
+
+void Game::leave(bool flag) {
+ error("TODO: Implemet Game::leave");
+}
+
+bool Game::loadBackup(const Common::String &path) {
+ error("TODO: Implemet Game::loadBackup");
+}
+
+bool Game::loadCharacter(const Common::String &name) {
+ bool result = true;
+ Character *character = _scene.character(name);
+ if (!character) {
+ result = false;
+ bool loaded = _scene.loadCharacter(name);
+ if (loaded) {
+ character = _scene.character(name);
+ character->_onCharacterAnimFinishedSignal.remove<Game>(this, &Game::onCharacterAnimationFinished);
+ character->_onCharacterAnimFinishedSignal.add<Game>(this, &Game::onCharacterAnimationFinished);
+ character->onFinished().add<Game>(this, &Game::onDisplacementFinished);
+ }
+ }
+ return result;
+}
+
+bool Game::loadPlayerCharacter(const Common::String &name) {
+ bool result = _scene.loadPlayerCharacter(name);
+ if (result) {
+ _scene._character->_characterAnimPlayerFinishedSignal.remove<Game>(this, &Game::onCharacterAnimationPlayerFinished);
+ _scene._character->_characterAnimPlayerFinishedSignal.add<Game>(this, &Game::onCharacterAnimationPlayerFinished);
+ _scene._character->onFinished().remove<Game>(this, &Game::onDisplacementFinished);
+ _scene._character->onFinished().add<Game>(this, &Game::onDisplacementFinished);
+ }
+ return result;
+}
+
+bool Game::loadScene(const Common::String &name) {
+ _luaScript.load("scenes/OnGameEnter.lua");
+ _luaScript.execute();
+ Character *character = _scene._character;
+ if (character && character->_model->visible()) {
+ _sceneCharacterVisibleFromLoad = true;
+ }
+ return false;
+}
+
+bool Game::onAnswered(const Common::String &val) {
+ _luaScript.execute("OnAnswered", TeVariant(val));
+ return false;
+}
+
+bool Game::onCallNumber(Common::String val) {
+ _luaScript.execute("OnCallNumber", TeVariant(val));
+ return false;
+}
+
+bool Game::onCharacterAnimationFinished(const Common::String &val) {
+ error("TODO: Implemet me");
+}
+
+bool Game::onCharacterAnimationPlayerFinished(const Common::String &val) {
+ error("TODO: Implemet me");
+}
+
+bool Game::onDialogFinished(const Common::String &val) {
+ error("TODO: Implemet me");
+}
+
+bool Game::onDisplacementFinished() {
+ error("TODO: Implemet me");
+}
+
+bool Game::onFinishedCheckBackup(bool result) {
+ if (_gameLoadState == 1) {
+ _gameLoadState = 0;
+ return true;
+ }
+ return false;
+}
+
+bool Game::onFinishedLoadingBackup(const Common::String &val) {
+ if (_gameLoadState == 1) {
+ _loadName = val;
+ _gameLoadState = 2;
+ return true;
+ }
+ return false;
+}
+
+bool Game::onFinishedSavingBackup(int something) {
+ if (something) {
+ g_engine->getGame()->_returnToMainMenu = true;
+ }
+ g_engine->getApplication()->showLoadingIcon(false);
+ return true;
+}
+
+bool Game::onInventoryButtonValidated() {
+ _inventoryMenu.enter();
+ return false;
+}
+
+bool Game::onLockVideoButtonValidated() {
+ TeButtonLayout *btn = _gui4.buttonLayoutChecked("skipVideoButton");
+ btn->setVisible(!btn->visible());
+ return true;
+}
+
+bool Game::onMarkersVisible(TeCheckboxLayout::State state) {
+ _markersVisible = (state == 0);
+ showMarkers(state == 0);
+ return false;
+}
+
+bool Game::onMouseClick(const Common::Point &pt) {
+ Application *app = g_engine->getApplication();
+
+ if (app->isFading())
+ return true;
+
+ _posPlayer = TeVector3f32(-1.0f, -1.0f, -1.0f);
+ if (_previousMousePos == TeVector2s32(-1, -1)) {
+ _previousMousePos = pt;
+ } else {
+ TeVector3f32 winSize = app->getMainWindow().size();
+ TeVector2s32 lastMousePos = _previousMousePos;
+ _previousMousePos = pt;
+ float xdist = pt.x / winSize.x() - lastMousePos._x / winSize.x();
+ float ydist = pt.y / winSize.y() - lastMousePos._y / winSize.y();
+ float sqrdist = xdist * xdist + ydist * ydist;
+ if (sqrdist > 0.0001 && (_walkTimer._stopped || _walkTimer.timeElapsed() > 300000.0
+ || (_scene._character && _scene._character->walkModeStr() != "Walk"))) {
+ return false;
+ // Double-click, but already jogging
+ }
+ }
+
+ if (!app->_frontLayout.isMouseIn(pt))
+ return false;
+
+ TeIntrusivePtr<TeCamera> curCamera = _scene.currentCamera();
+ //TePickMesh2 *nearestMesh = findNearestMesh(curCamera, _scene._pickMeshes, nullptr, false);
+
+ warning("TODO: Finish Game::onMouseClick");
+ return false;
+}
+
+// Note: None of these cursor files seem to be actually shipped with the game
+// but the logic is reproduced here just in case there's some different
+// version that uses them.
+static const char cursorsTable[][2][80] = {
+ {"H000", "pictures/F000.png"},
+ {"H045", "pictures/F045.png"},
+ {"H090", "pictures/F090.png"},
+ {"H135", "pictures/F135.png"},
+ {"H180", "pictures/F180.png"},
+ {"H225", "pictures/F225.png"},
+ {"H270", "pictures/F270.png"},
+ {"H315", "pictures/F315.png"},
+ {"Main", "pictures/Main.png"},
+ {"Action", "pictures/Action.png"},
+ {"Parler", "pictures/Cursor_Large/Anim_Cursor_Talking.anim"},
+ {"Type01", "pictures/Type01.png"},
+ {"Type02", "pictures/Type02.png"},
+ {"Type03", "pictures/Type03.png"},
+ {"Type04", "pictures/Type04.png"},
+ {"Type05", "pictures/Type05.png"}
+};
+
+bool Game::onMouseMove() {
+ if (!_entered)
+ return false;
+
+ static const Common::Path DEFAULT_CURSOR("pictures/cursor.png");
+
+ Application *app = g_engine->getApplication();
+
+ if (app->isLockCursor()) {
+ app->mouseCursorLayout().load(DEFAULT_CURSOR);
+ return false;
+ }
+
+ TeVector2s32 mouseLoc = g_engine->getInputMgr()->lastMousePos();
+ bool skipFullSearch = false;
+
+ TeLayout *cellphone = _inventory.cellphone()->gui().layoutChecked("cellphone");
+ TeLayout *cellbg = _inventory.cellphone()->gui().layoutChecked("background");
+ if (cellphone->isMouseIn(mouseLoc)) {
+ skipFullSearch = true;
+ if (!cellbg->visible() && _objectif.isMouseIn(mouseLoc)) {
+ app->mouseCursorLayout().load(DEFAULT_CURSOR);
+ return false;
+ }
+ }
+ if (_dialog2.gui().layout("imgDialog")) {
+ warning("TODO: Finish Game::onMouseMove");
+ }
+
+ bool checkedCursor = false;
+ for (unsigned int i = 0; i < cellbg->childCount(); i++) {
+ TeLayout *childlayout = dynamic_cast<TeLayout *>(cellbg->child(i));
+ if (childlayout && childlayout->isMouseIn(mouseLoc) && childlayout->visible()) {
+ for (int i = 0; i < ARRAYSIZE(cursorsTable); i++) {
+ if (childlayout->name().contains(cursorsTable[i][0])) {
+ app->mouseCursorLayout().load(cursorsTable[i][1]);
+ if (Common::String(cursorsTable[i][0]).contains(".anim")) {
+ app->mouseCursorLayout()._tiledSurfacePtr->_frameAnim._loopCount = -1;
+ app->mouseCursorLayout()._tiledSurfacePtr->_frameAnim.play();
+ }
+ }
+ }
+ checkedCursor = true;
+ }
+ }
+
+ if (!checkedCursor)
+ app->mouseCursorLayout().load(DEFAULT_CURSOR);
+ return false;
+}
+
+bool Game::onSkipVideoButtonValidated() {
+ TeSpriteLayout *sprite = _gui4.spriteLayoutChecked("video");
+ TeButtonLayout *btn = _gui4.buttonLayoutChecked("videoBackgroundButton");
+ sprite->stop();
+ btn->setVisible(false);
+ return false;
+}
+
+bool Game::onVideoFinished() {
+ if (!_gui4.loaded())
+ return false;
+
+ Application *app = g_engine->getApplication();
+
+ app->captureFade();
+
+ TeSpriteLayout *video = _gui4.spriteLayoutChecked("video");
+ TeButtonLayout *btn = _gui4.buttonLayoutChecked("videoBackgroundButton");
+ btn->setVisible(false);
+ btn = _gui4.buttonLayoutChecked("skipVideoButton");
+ btn->setVisible(false);
+ video->setVisible(false);
+ _music.stop();
+ _running = true;
+ warning("TODO: Game::onVideoFinished: update yieldedCallbacks");
+ _luaScript.execute("OnMovieFinished", video->_tiledSurfacePtr->path().toString());
+ app->fade();
+ return false;
+}
+
+void Game::pauseMovie() {
+ _music.pause();
+ TeSpriteLayout *sprite = _gui4.spriteLayoutChecked("video");
+ sprite->pause();
+}
+
+void Game::playMovie(const Common::String &vidPath, const Common::String &musicPath) {
+ Application *app = g_engine->getApplication();
+ app->captureFade();
+ TeButtonLayout *videoBackgroundButton = _gui4.buttonLayoutChecked("videoBackgroundButton");
+ videoBackgroundButton->setVisible(true);
+
+ TeButtonLayout *skipVideoButton = _gui4.buttonLayoutChecked("skipVideoButton");
+ skipVideoButton->setVisible(false);
+
+ TeMusic &music = app->music();
+ music.stop();
+ music.setChannelName("video");
+ music.repeat(false);
+ music.volume(1.0f);
+ music.load(musicPath);
+
+ _running = false;
+
+ TeSpriteLayout *videoSpriteLayout = _gui4.spriteLayoutChecked("video");
+ videoSpriteLayout->load(vidPath);
+ videoSpriteLayout->setVisible(true);
+ music.play();
+ videoSpriteLayout->play();
+
+ app->fade();
+}
+
+void Game::playRandomSound(const Common::String &name) {
+ error("TODO: Implemet Game::playRandomSound");
+}
+
+void Game::playSound(const Common::String &name, int param_2, float param_3) {
+ error("TODO: Implemet Game::playSound");
+}
+
+void Game::removeNoScale2Child(TeLayout *layout) {
+ if (!_noScaleLayout2 || !layout)
+ return;
+ _noScaleLayout2->removeChild(layout);
+}
+
+void Game::removeNoScale2Children() {
+ if (!_noScaleLayout2)
+ return;
+
+ TeLayout *vidbtn = _gui4.layout("videoButtonLayout");
+ if (vidbtn)
+ _noScaleLayout2->removeChild(vidbtn);
+
+ TeLayout *bg = _inventory.cellphone()->gui().layout("background");
+ if (bg)
+ _noScaleLayout2->removeChild(bg);
+
+ TeButtonLayout *bgbtn = _objectif.gui1().buttonLayout("background");
+ if (bgbtn)
+ _noScaleLayout2->removeChild(bgbtn);
+
+ TeLayout *notifier = _notifier.gui().layout("notifier");
+ if (notifier)
+ _noScaleLayout2->removeChild(notifier);
+}
+
+void Game::removeNoScaleChildren() {
+ if (!_noScaleLayout)
+ return;
+ _noScaleLayout->removeChild(&_question2);
+ Application *app = g_engine->getApplication();
+ app->_frontLayout.removeChild(&_dialog2);
+ _noScaleLayout->removeChild(&_inventory);
+ _noScaleLayout->removeChild(&_inventoryMenu);
+ _noScaleLayout->removeChild(&_documentsBrowser);
+ _noScaleLayout->removeChild(&_documentsBrowser.zoomedLayout());
+}
+
+void Game::resetPreviousMousePos() {
+ _previousMousePos = TeVector2s32(-1, -1);
+}
+
+void Game::resumeMovie() {
+ _music.play();
+ _gui4.spriteLayout("video")->play();
+}
+
+void Game::saveBackup(const Common::String &saveName) {
+ error("TODO: Implemet me");
+}
+
+void Game::setBackground(const Common::String &name) {
+ _scene.changeBackground(name);
+}
+
+void Game::setCurrentObjectSprite(const Common::String &spritePath) {
+ TeSpriteLayout *currentSprite = _gui4.spriteLayout("currentObjectSprite");
+ if (currentSprite) {
+ if (!spritePath.empty()) {
+ currentSprite->unload();
+ } else {
+ currentSprite->load(spritePath);
+ }
+ }
+}
+
+bool Game::showMarkers(bool val) {
+ error("TODO: Implemet me");
+}
+
+bool Game::startAnimation(const Common::String &animName, int param_2, bool param_3) {
+ error("TODO: Implemet me");
+}
+
+void Game::stopSound(const Common::String &name) {
+ error("TODO: Implemet me");
+}
+
+bool Game::unloadCharacter(const Common::String &charname) {
+ Character *c = _scene.character(charname);
+ if (!c)
+ return false;
+
+ for (unsigned int i = 0; i < _scene.models().size(); i++) {
+ if (_scene.models()[i] == c->_model) {
+ _scene.models().remove_at(i);
+ break;
+ }
+ }
+ c->_onCharacterAnimFinishedSignal.remove(this, &Game::onCharacterAnimationFinished);
+ c->removeAnim();
+ c->onFinished().remove(this, &Game::onDisplacementFinished);
+ _scene.unloadCharacter(charname);
+ return true;
+}
+
+bool Game::unloadCharacters() {
+ // Loop will update the array, take a copy first.
+ Common::Array<Character *> chars = _scene._characters;
+ for (Character *c : chars) {
+ unloadCharacter(c->_model->name());
+ }
+ return true;
+}
+
+bool Game::unloadPlayerCharacter(const Common::String &character) {
+ _scene.unloadPlayerCharacter(character);
+ return true;
+}
+
+void Game::update() {
+ if (!_entered)
+ return;
+
+ TeTextLayout *debugTimeTextLayout = _gui4.textLayout("debugTimeText1");
+ if (debugTimeTextLayout) {
+ warning("TODO: Game::update: Fill out debugTimeTextLayout");
+ }
+
+ if (!_warped) {
+ if (_gameLoadState == 2) {
+ initLoadedBackupData();
+ return;
+ } else if (_gameLoadState != 0) {
+ return;
+ }
+
+ Application *app = g_engine->getApplication();
+
+ if (_scene._character) {
+ if (!_scene._character->_model->visible())
+ app->_lockCursorButton.setVisible(false);
+ }
+
+ TeButtonLayout *invbtn = _gui4.buttonLayout("inventoryButton");
+ if (invbtn)
+ invbtn->setVisible(!app->isLockCursor() && !_dialog2.isDialogPlaying());
+ else
+ warning("Game::update: InventoryButton is null.");
+
+ if (_scene._character) {
+ TeIntrusivePtr<TeModel> model = _scene._character->_model;
+ bool modelVisible = model->visible();
+ if (!model->anim().get())
+ _scene._character->permanentUpdate();
+ if (modelVisible) {
+ if (_scene._character->needsSomeUpdate()) {
+ Game *game = g_engine->getGame();
+ game->_sceneCharacterVisibleFromLoad = false;
+ error("TODO: Game::update: Finish bit after permanentUpdate");
+ }
+
+ const Common::String &charAnim = _scene._character->curAnimName();
+ bool lockCursor = (charAnim == _scene._character->walkAnim(Character::WalkPart_Start) ||
+ charAnim == _scene._character->walkAnim(Character::WalkPart_Loop) ||
+ charAnim == _scene._character->walkAnim(Character::WalkPart_EndD) ||
+ charAnim == _scene._character->walkAnim(Character::WalkPart_EndG) ||
+ charAnim == _scene._character->characterSettings()._walkFileName);
+ app->lockCursor(lockCursor);
+ }
+ }
+
+ Common::Array<Character *> characters = _scene._characters;
+ for (Character *c : characters) {
+ if (!c->_model->anim().get())
+ c->permanentUpdate();
+ }
+
+ Common::Point mousePos = g_engine->getInputMgr()->lastMousePos();
+ if (_lastUpdateMousePos != mousePos) {
+ onMouseMove();
+ _lastUpdateMousePos = mousePos;
+ }
+ if (_saveRequested) {
+ _saveRequested = false;
+ error("TODO: Game::update: Save game");
+ }
+
+ _luaScript.execute("Update");
+ _objectif.update();
+ _scene.update();
+ } else {
+ warning("TODO: Game::update: Stop sounds before warping");
+ changeWarp2(_warpZone, _warpScene, _warpFadeFlag);
+ }
+}
+
+} // end namespace Tetraedge
diff --git a/engines/tetraedge/game/game.h b/engines/tetraedge/game/game.h
new file mode 100644
index 00000000000..62906a4ee61
--- /dev/null
+++ b/engines/tetraedge/game/game.h
@@ -0,0 +1,233 @@
+/* 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 TETRAEDGE_GAME_GAME_H
+#define TETRAEDGE_GAME_GAME_H
+
+#include "common/types.h"
+#include "common/str.h"
+#include "tetraedge/game/documents_browser.h"
+#include "tetraedge/game/inventory.h"
+#include "tetraedge/game/inventory_menu.h"
+#include "tetraedge/game/in_game_scene.h"
+#include "tetraedge/game/notifier.h"
+#include "tetraedge/game/cellphone.h"
+#include "tetraedge/game/objectif.h"
+#include "tetraedge/game/question2.h"
+#include "tetraedge/game/dialog2.h"
+#include "tetraedge/te/te_lua_gui.h"
+#include "tetraedge/te/te_music.h"
+#include "tetraedge/te/te_checkbox_layout.h"
+#include "tetraedge/te/te_vector2s32.h"
+
+namespace Tetraedge {
+
+class Game {
+public:
+ Game();
+
+ class HitObject {
+ byte OnChangeWarp();
+ byte OnDown();
+ byte OnUp();
+ byte OnValidated();
+ //byte OnVisible(); empty never used?
+ };
+
+ class RandomSound {
+ public:
+ Common::Path _path;
+ Common::String _str;
+ TeMusic _music;
+ float f1;
+ float f2;
+ byte onSoundFinished();
+ };
+
+ //enum EGameScoreID {}; // Not needed?
+
+ bool addAnimToSet(const Common::String &path);
+ void addArtworkUnlocked(const Common::String &name, bool notify);
+ void addNoScale2Child(TeLayout *layout);
+ void addNoScale2Children();
+ void addNoScaleChildren();
+ void addRandomSound(const Common::String &s1, const Common::String &s2, float f1, float f2);
+ void addToBag(const Common::String &objname);
+ void addToHand(const Common::String &objname);
+ void addToScore(int score);
+ void attachButtonsLayoutGoto() {}; // does nothing?
+ void createButtonsLayoutGoto() {}; // does nothing?
+ void deleteButtonsLayoutGoto() {}; // does nothing?
+
+ bool changeWarp(const Common::String &zone, const Common::String &scene, bool fadeFlag);
+ bool changeWarp2(const Common::String &zone, const Common::String &scene, bool fadeFlag);
+
+ void deleteNoScale();
+ void draw();
+ void enter(bool newgame);
+ // Note: game uses ILayouts here..
+ static TeI3DObject2 *findLayoutByName(TeLayout *layout, const Common::String &name);
+ static TeSpriteLayout *findSpriteLayoutByName(TeLayout *layout, const Common::String &name);
+
+ void finishFreemium();
+ void finishGame();
+ void initLoadedBackupData();
+ void initNoScale();
+ void initScene(bool param_1, const Common::String &scenePath);
+ void initWarp(const Common::String &zone, const Common::String &scene, bool fadeFlag);
+ bool isDocumentOpened();
+ bool isMouse() { return false; }
+ bool isMoviePlaying();
+ bool launchDialog(const Common::String ¶m_1, uint param_2, const Common::String ¶m_3,
+ const Common::String ¶m_4, float param_5);
+ void leave(bool flag);
+ bool loadBackup(const Common::String &path);
+ bool loadCharacter(const Common::String &name);
+ bool loadPlayerCharacter(const Common::String &name);
+ bool loadScene(const Common::String &name);
+
+ bool onAnswered(const Common::String &val);
+ bool onCallNumber(Common::String val);
+ bool onCharacterAnimationFinished(const Common::String &val);
+ bool onCharacterAnimationPlayerFinished(const Common::String &val);
+ bool onDialogFinished(const Common::String &val);
+ bool onDisplacementFinished();
+ bool onFinishedCheckBackup(bool result);
+ bool onFinishedLoadingBackup(const Common::String &val);
+ bool onFinishedSavingBackup(int something);
+ bool onInventoryButtonValidated();
+ bool onLockVideoButtonValidated();
+ bool onMarkersVisible(TeCheckboxLayout::State state);
+ bool onMouseClick(const Common::Point &pt);
+ bool onMouseMove();
+ bool onSkipVideoButtonValidated();
+ bool onVideoFinished();
+
+ void pauseMovie();
+ void pauseSounds() {}; // does nothing?
+ void playMovie(const Common::String &vidPath, const Common::String &musicPath);
+ void playRandomSound(const Common::String &name);
+ void playSound(const Common::String &name, int param_2, float param_3);
+ void removeNoScale2Child(TeLayout *layout);
+ void removeNoScale2Children();
+ void removeNoScaleChildren();
+ void resetPreviousMousePos();
+ void resumeMovie();
+ void resumeSounds() {}; // does nothing?
+ void saveBackup(const Common::String &saveName);
+ void setBackground(const Common::String &name);
+ void setCurrentObjectSprite(const Common::String &spritePath);
+ bool showMarkers(bool val);
+ bool startAnimation(const Common::String &animName, int param_2, bool param_3);
+ void startAnimationPart(const Common::String ¶m_1, int param_2, int param_3, int param_4, bool param_5) {};
+ void stopSound(const Common::String &name);
+ bool unloadCharacter(const Common::String &character);
+ bool unloadCharacters();
+ bool unloadPlayerCharacter(const Common::String &character);
+ void update();
+
+ InventoryMenu &inventoryMenu() { return _inventoryMenu; }
+ Inventory &inventory() { return _inventory; }
+ DocumentsBrowser &documentsBrowser() { return _documentsBrowser; }
+ bool entered() const { return _entered; }
+ bool running() const { return _running; }
+ bool luaShowOwnerError() const { return _luaShowOwnerError; }
+
+ bool _returnToMainMenu;
+ bool _firstInventory;
+
+ const Common::String ¤tZone() { return _currentZone; }
+ const Common::String ¤tScene() { return _currentScene; }
+ TeLuaScript &luaScript() { return _luaScript; }
+ InGameScene &scene() { return _scene; }
+
+private:
+ bool _luaShowOwnerError;
+ bool _running;
+ bool _entered;
+
+ TeLuaGUI _gui1;
+ TeLuaGUI _gui2;
+ TeLuaGUI _gui3;
+ TeLuaGUI _gui4;
+
+ Inventory _inventory;
+ InventoryMenu _inventoryMenu;
+ int _score;
+
+ int _frameCounter;
+
+ InGameScene _scene;
+
+ static char **_objectsTakenIDs;
+
+ TeVector2s32 _previousMousePos;
+
+ Common::String _warpZone;
+ Common::String _warpScene;
+ bool _warpFadeFlag;
+ bool _warped;
+
+ Common::String _currentZone;
+ Common::String _currentScene;
+ Common::String _exitZone;
+ Common::String _prevSceneName;
+ Common::Path _sceneZonePath;
+
+ Common::String _loadName;
+
+ Common::HashMap<Common::String, bool> _unlockedArtwork;
+
+ int _gameLoadState;
+
+ TeTimer _playedTimer;
+ TeTimer _walkTimer;
+ TeLuaScript _luaScript;
+ TeLuaContext _luaContext;
+ TeMusic _music;
+ Notifier _notifier;
+ DocumentsBrowser _documentsBrowser;
+
+ Question2 _question2;
+ Dialog2 _dialog2;
+ Objectif _objectif;
+
+ static const int NUM_OBJECTS_TAKEN_IDS = 5;
+ static const char *OBJECTS_TAKEN_IDS[NUM_OBJECTS_TAKEN_IDS];
+ bool _objectsTakenBits[NUM_OBJECTS_TAKEN_IDS];
+ int _objectsTakenVal;
+ int _dialogsTold;
+
+ bool _sceneCharacterVisibleFromLoad;
+ bool _markersVisible;
+ bool _saveRequested;
+
+ TeLayout *_noScaleLayout;
+ TeLayout *_noScaleLayout2;
+
+ TeVector3f32 _posPlayer;
+
+ Common::Point _lastUpdateMousePos;
+};
+
+} // end namespace Tetraedge
+
+#endif // TETRAEDGE_GAME_GAME_H
diff --git a/engines/tetraedge/game/game_achievements.cpp b/engines/tetraedge/game/game_achievements.cpp
new file mode 100644
index 00000000000..5a28713f797
--- /dev/null
+++ b/engines/tetraedge/game/game_achievements.cpp
@@ -0,0 +1,59 @@
+/* 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 "tetraedge/game/game_achievements.h"
+#include "tetraedge/te/te_lua_context.h"
+
+namespace Tetraedge {
+
+GameAchievements::GameAchievements() {
+}
+
+/*static*/ void GameAchievements::registerAchievements(TeLuaContext &context) {
+ context.setGlobal("PS3_Welcome", 0);
+ context.setGlobal("PS3_Legacy", -1);
+ context.setGlobal("PS3_Graduate", -2);
+ context.setGlobal("PS3_Easten", -3);
+ context.setGlobal("PS3_Odyssey", -4);
+ context.setGlobal("PS3_Code", -5);
+ context.setGlobal("PS3_Escape", -6);
+ context.setGlobal("PS3_Amerzone", -7);
+ context.setGlobal("PS3_Music", -8);
+ context.setGlobal("PS3_OnWay", -9);
+ context.setGlobal("PS3_Gossip", -10);
+ context.setGlobal("PS3_Snoop", -0xb);
+ context.setGlobal("PS3_School", -0xc);
+ context.setGlobal("XBOX_Welcome", 1);
+ context.setGlobal("XBOX_Legacy", 2);
+ context.setGlobal("XBOX_Graduate", 3);
+ context.setGlobal("XBOX_Easten", 4);
+ context.setGlobal("XBOX_Odyssey", 5);
+ context.setGlobal("XBOX_Code", 6);
+ context.setGlobal("XBOX_Escape", 7);
+ context.setGlobal("XBOX_Amerzone", 8);
+ context.setGlobal("XBOX_Music", 9);
+ context.setGlobal("XBOX_OnWay", 10);
+ context.setGlobal("XBOX_Gossip", 0xb);
+ context.setGlobal("XBOX_Snoop", 0xc);
+ context.setGlobal("XBOX_School", 0xd);
+}
+
+} // end namespace Tetraedge
diff --git a/engines/tetraedge/game/game_achievements.h b/engines/tetraedge/game/game_achievements.h
new file mode 100644
index 00000000000..c9cf6b9e75d
--- /dev/null
+++ b/engines/tetraedge/game/game_achievements.h
@@ -0,0 +1,44 @@
+/* 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 TETRAEDGE_GAME_GAME_ACHIEVEMENTS_H
+#define TETRAEDGE_GAME_GAME_ACHIEVEMENTS_H
+
+
+namespace Tetraedge {
+
+class TeLuaContext;
+
+class GameAchievements {
+public:
+ GameAchievements();
+
+ static void registerAchievements(TeLuaContext &context);
+ // TODO add public members
+
+private:
+ // TODO add private members
+
+};
+
+} // end namespace Tetraedge
+
+#endif // TETRAEDGE_GAME_GAME_ACHIEVEMENTS_H
diff --git a/engines/tetraedge/game/game_sound.cpp b/engines/tetraedge/game/game_sound.cpp
new file mode 100644
index 00000000000..257f2b89d33
--- /dev/null
+++ b/engines/tetraedge/game/game_sound.cpp
@@ -0,0 +1,31 @@
+/* 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 "tetraedge/game/game_sound.h"
+
+namespace Tetraedge {
+
+GameSound::GameSound() {
+}
+
+// TODO: Add more functions here.
+
+} // end namespace Tetraedge
diff --git a/engines/tetraedge/game/game_sound.h b/engines/tetraedge/game/game_sound.h
new file mode 100644
index 00000000000..2ea73e8edfd
--- /dev/null
+++ b/engines/tetraedge/game/game_sound.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 TETRAEDGE_GAME_GAME_SOUND_H
+#define TETRAEDGE_GAME_GAME_SOUND_H
+
+#include "common/str.h"
+#include "tetraedge/te/te_music.h"
+
+namespace Tetraedge {
+
+class GameSound : public TeMusic {
+public:
+ GameSound();
+
+ void onSoundStopped();
+
+private:
+ Common::String _name;
+
+};
+
+} // end namespace Tetraedge
+
+#endif // TETRAEDGE_GAME_GAME_SOUND_H
diff --git a/engines/tetraedge/game/global_bonus_menu.cpp b/engines/tetraedge/game/global_bonus_menu.cpp
new file mode 100644
index 00000000000..610e79884a3
--- /dev/null
+++ b/engines/tetraedge/game/global_bonus_menu.cpp
@@ -0,0 +1,96 @@
+/* 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 "tetraedge/tetraedge.h"
+#include "tetraedge/game/application.h"
+#include "tetraedge/game/global_bonus_menu.h"
+
+namespace Tetraedge {
+
+GlobalBonusMenu::GlobalBonusMenu() : _entered(false) {
+}
+
+void GlobalBonusMenu::enter() {
+ error("TODO: Finish implementing GlobalBonusMenu::enter");
+ //Application *app = g_engine->getApplication();
+ //todo: call some virtual function on a field in app
+ //app->captureFade();
+ //_entered = true;
+ //load("menus/bonusmenu/GlobalBonusMenu.lua");
+ //TeLayout *menu = layout("menu");
+ //if (menu) {
+ // ...
+ //}
+}
+
+void GlobalBonusMenu::leave() {
+ if (_entered != 0) {
+ Application *app = g_engine->getApplication();
+ app->captureFade();
+ TeLuaGUI::unload();
+ app->fade();
+ _entered = false;
+ }
+}
+
+bool GlobalBonusMenu::onSomeButtonValidated(const char *script) {
+ Application *app = g_engine->getApplication();
+ app->captureFade();
+ leave();
+ app->bonusMenu().enter(script);
+ app->fade();
+ return false;
+}
+
+bool GlobalBonusMenu::onAraButtonValidated() {
+ return onSomeButtonValidated("menus/bonusmenu/Ara.lua");
+}
+
+bool GlobalBonusMenu::onBarButtonValidated() {
+ return onSomeButtonValidated("menus/bonusmenu/Bar.lua");
+}
+
+bool GlobalBonusMenu::onCitButtonValidated() {
+ return onSomeButtonValidated("menus/bonusmenu/Cit.lua");
+}
+
+bool GlobalBonusMenu::onSyb2ButtonValidated() {
+ return onSomeButtonValidated("menus/bonusmenu/Syb2.lua");
+}
+
+bool GlobalBonusMenu::onSyb3ButtonValidated() {
+ return onSomeButtonValidated("menus/bonusmenu/Syb3.lua");
+}
+
+bool GlobalBonusMenu::onValButtonValidated() {
+ return onSomeButtonValidated("menus/bonusmenu/Val.lua");
+}
+
+bool GlobalBonusMenu::onQuitButton() {
+ Application *app = g_engine->getApplication();
+ app->captureFade();
+ leave();
+ app->mainMenu().enter();
+ app->fade();
+ return true;
+}
+
+} // end namespace Tetraedge
diff --git a/engines/tetraedge/game/global_bonus_menu.h b/engines/tetraedge/game/global_bonus_menu.h
new file mode 100644
index 00000000000..d1b10d7344d
--- /dev/null
+++ b/engines/tetraedge/game/global_bonus_menu.h
@@ -0,0 +1,54 @@
+/* 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 TETRAEDGE_GAME_GLOBAL_BONUS_MENU_H
+#define TETRAEDGE_GAME_GLOBAL_BONUS_MENU_H
+
+#include "tetraedge/te/te_lua_gui.h"
+
+namespace Tetraedge {
+
+class GlobalBonusMenu : public TeLuaGUI {
+public:
+ GlobalBonusMenu();
+
+ void enter() override;
+ void leave() override;
+
+ bool onAraButtonValidated();
+ bool onBarButtonValidated();
+ bool onCitButtonValidated();
+ bool onSyb2ButtonValidated();
+ bool onSyb3ButtonValidated();
+ bool onValButtonValidated();
+
+ bool onQuitButton();
+
+private:
+ bool onSomeButtonValidated(const char *script);
+
+ bool _entered;
+
+};
+
+} // end namespace Tetraedge
+
+#endif // TETRAEDGE_GAME_GLOBAL_BONUS_MENU_H
diff --git a/engines/tetraedge/game/help_option_menu.cpp b/engines/tetraedge/game/help_option_menu.cpp
new file mode 100644
index 00000000000..0e17ec9c287
--- /dev/null
+++ b/engines/tetraedge/game/help_option_menu.cpp
@@ -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/>.
+ *
+ */
+
+#include "tetraedge/tetraedge.h"
+#include "tetraedge/game/application.h"
+#include "tetraedge/game/help_option_menu.h"
+
+namespace Tetraedge {
+
+HelpOptionMenu::HelpOptionMenu() : _entered(false) {
+}
+
+void HelpOptionMenu::enter() {
+ if (!_entered) {
+ Application *app = g_engine->getApplication();
+ app->captureFade();
+ load("menus/helpoptionMenu/optionsMenu.lua");
+ error("TODO: finish implementation of HelpOptionMenu::enter");
+ }
+}
+
+void HelpOptionMenu::leave() {
+ Application *app = g_engine->getApplication();
+ app->captureFade();
+ unload();
+ app->fade();
+ _entered = false;
+}
+
+// TODO: Add more functions here.
+
+} // end namespace Tetraedge
diff --git a/engines/tetraedge/game/help_option_menu.h b/engines/tetraedge/game/help_option_menu.h
new file mode 100644
index 00000000000..056c0cccc34
--- /dev/null
+++ b/engines/tetraedge/game/help_option_menu.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 TETRAEDGE_GAME_HELP_OPTION_MENU_H
+#define TETRAEDGE_GAME_HELP_OPTION_MENU_H
+
+#include "tetraedge/te/te_lua_gui.h"
+
+namespace Tetraedge {
+
+class HelpOptionMenu : public TeLuaGUI {
+public:
+ HelpOptionMenu();
+
+ void enter() override;
+ void leave() override;
+
+private:
+ bool _entered;
+
+};
+
+} // end namespace Tetraedge
+
+#endif // TETRAEDGE_GAME_HELP_OPTION_MENU_H
diff --git a/engines/tetraedge/game/how_to.cpp b/engines/tetraedge/game/how_to.cpp
new file mode 100644
index 00000000000..a863d4e8729
--- /dev/null
+++ b/engines/tetraedge/game/how_to.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 "tetraedge/game/how_to.h"
+
+namespace Tetraedge {
+
+HowTo::HowTo() : _entered(false) {
+}
+
+void HowTo::leave() {
+
+}
+
+void HowTo::enter() {
+
+}
+// TODO: Add more functions here.
+
+} // end namespace Tetraedge
diff --git a/engines/tetraedge/game/how_to.h b/engines/tetraedge/game/how_to.h
new file mode 100644
index 00000000000..d4ce9211887
--- /dev/null
+++ b/engines/tetraedge/game/how_to.h
@@ -0,0 +1,47 @@
+/* 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 TETRAEDGE_GAME_HOW_TO_H
+#define TETRAEDGE_GAME_HOW_TO_H
+
+#include "tetraedge/te/te_lua_gui.h"
+
+namespace Tetraedge {
+
+class HowTo : public TeLuaGUI {
+public:
+ HowTo();
+
+ void enter() override;
+ void leave() override;
+
+ bool onDefaultPadButtonUp(uint32 flags);
+
+private:
+ bool updateDisplay(uint oldval, uint newval);
+
+ bool _entered;
+ uint _val;
+};
+
+} // end namespace Tetraedge
+
+#endif // TETRAEDGE_GAME_HOW_TO_H
diff --git a/engines/tetraedge/game/in_game_scene.cpp b/engines/tetraedge/game/in_game_scene.cpp
new file mode 100644
index 00000000000..92f4eb2f52c
--- /dev/null
+++ b/engines/tetraedge/game/in_game_scene.cpp
@@ -0,0 +1,239 @@
+/* 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/file.h"
+#include "common/path.h"
+#include "common/textconsole.h"
+
+#include "tetraedge/tetraedge.h"
+#include "tetraedge/game/application.h"
+#include "tetraedge/game/billboard.h"
+#include "tetraedge/game/game.h"
+#include "tetraedge/game/in_game_scene.h"
+#include "tetraedge/game/character.h"
+#include "tetraedge/game/object3d.h"
+
+namespace Tetraedge {
+
+InGameScene::InGameScene() : _character(nullptr) {
+}
+
+void InGameScene::draw() {
+ error("TODO: implement InGameScene::draw");
+}
+
+bool InGameScene::changeBackground(const Common::String &name) {
+ if (Common::File::exists(name)) {
+ TeSpriteLayout *spriteLayout = _bgGui.spriteLayout("root");
+ assert(spriteLayout);
+ spriteLayout->load(name);
+ return true;
+ }
+ return false;
+}
+
+
+/*static*/ float InGameScene::angularDistance(float a1, float a2) {
+ float result;
+
+ result = a2 - a1;
+ if (result >= -3.141593 && result > 3.141593) {
+ result = result + -6.283185;
+ } else {
+ result = result + 6.283185;
+ }
+ return result;
+}
+
+TeLayout *InGameScene::background() {
+ return _bgGui.layout("background");
+}
+
+void InGameScene::close() {
+ reset();
+ error("TODO: Implement InGameScene::close");
+}
+
+void InGameScene::reset() {
+ if (_character)
+ _character->setFreeMoveZone(Common::SharedPtr<TeFreeMoveZone>());
+ freeSceneObjects();
+ _bgGui.unload();
+ unloadSpriteLayouts();
+ _gui2.unload();
+ _gui3.unload();
+}
+
+void InGameScene::deleteAllCallback() {
+ warning("TODO: implement InGameScene::deleteAllCallback");
+}
+
+
+void InGameScene::freeSceneObjects() {
+ if (_character) {
+ warning("TODO: InGameScene::freeSceneObjects: Set field on character here");
+ _character->deleteAllCallback();
+ }
+ if (_characters.size() == 1) {
+ _characters[0]->deleteAllCallback();
+ }
+
+ Game *game = g_engine->getGame();
+ game->unloadCharacters();
+
+ _characters.clear();
+
+ for (Object3D *obj : _object3Ds) {
+ obj->deleteLater();
+ }
+ _object3Ds.clear();
+
+ for (Billboard *bb : _billboards) {
+ bb->deleteLater();
+ }
+ _billboards.clear();
+
+ for (TeSpriteLayout *sprite : _sprites) {
+ sprite->deleteLater();
+ }
+ _sprites.clear();
+
+ deleteAllCallback();
+ _markers.clear();
+
+ for (InGameScene::AnchorZone *zone : _anchorZones) {
+ delete zone;
+ }
+ _anchorZones.clear();
+}
+
+void InGameScene::unloadSpriteLayouts() {
+ for (auto *animobj : _animObjects) {
+ delete animobj;
+ }
+ _animObjects.clear();
+}
+
+Character *InGameScene::character(const Common::String &name) {
+ error("TODO: Implement InGameScene::character");
+}
+
+bool InGameScene::loadCharacter(const Common::String &name) {
+ error("TODO: Implement InGameScene::loadCharacter");
+}
+
+bool InGameScene::loadPlayerCharacter(const Common::String &name) {
+ if (_character == nullptr) {
+ _character = new Character();
+ if (!_character->loadModel(name, true)) {
+ _playerCharacterModel.release();
+ return false;
+ }
+
+ _playerCharacterModel = _character->_model;
+
+ if (!findKate()) {
+ Common::Array<TeIntrusivePtr<TeModel>> &ms = models();
+ ms.push_back(_character->_model);
+ ms.push_back(_character->_shadowModel[0]);
+ ms.push_back(_character->_shadowModel[1]);
+ }
+ }
+
+ _character->_model->setVisible(true);
+ return true;
+}
+
+void InGameScene::unloadPlayerCharacter(const Common::String &name) {
+ error("TODO: Implement InGameScene::unloadPlayerCharacter %s", name.c_str());
+}
+
+void InGameScene::unloadCharacter(const Common::String &name) {
+ warning("TODO: Implement InGameScene::unloadCharacter %s", name.c_str());
+}
+
+bool InGameScene::findKate() {
+ for (auto &m : models()) {
+ if (m->name() == "Kate")
+ return true;
+ }
+ return false;
+}
+
+Common::Path InGameScene::getBlockersFileName() {
+ Game *game = g_engine->getGame();
+ Common::Path retval("scenes");
+ retval.joinInPlace(game->currentZone());
+ retval.joinInPlace(game->currentScene());
+ retval.joinInPlace("blockers.bin");
+ return retval;
+}
+
+void InGameScene::loadBlockers() {
+ _blockers.clear();
+ _rectBlockers.clear();
+ const Common::Path blockersPath = getBlockersFileName();
+ if (Common::File::exists(blockersPath)) {
+ error("TODO: Implement InGameScene::loadBlockers");
+ }
+}
+
+void InGameScene::loadBackground(const Common::Path &path) {
+ _bgGui.load(path);
+ TeLayout *bg = _bgGui.layout("background");
+ TeLayout *root = _bgGui.layout("root");
+ bg->setRatioMode(TeILayout::RATIO_MODE_NONE);
+ root->setRatioMode(TeILayout::RATIO_MODE_NONE);
+ TeCamera *wincam = g_engine->getApplication()->mainWindowCamera();
+ bg->disableAutoZ();
+ bg->setZPosition(wincam->_orthNearVal);
+
+ for (auto layoutEntry : _bgGui.spriteLayouts()) {
+ AnimObject *animobj = new AnimObject();
+ animobj->_name = layoutEntry._key;
+ animobj->_layout = layoutEntry._value;
+ animobj->_layout->_tiledSurfacePtr->_frameAnim.onFinished().add<AnimObject>(animobj, &AnimObject::onFinished);
+ if (animobj->_name != "root")
+ animobj->_layout->setVisible(false);
+ _animObjects.push_back(animobj);
+ }
+}
+
+void InGameScene::loadInteractions(const Common::Path &path) {
+ error("TODO: Implement InGameScene::loadInteractions");
+}
+
+void InGameScene::setStep(const Common::String &scene, const Common::String &step1, const Common::String &step2) {
+ SoundStep ss;
+ ss._stepSound1 = step1;
+ ss._stepSound2 = step2;
+ _soundSteps[scene] = ss;
+}
+
+void InGameScene::initScroll() {
+ _someScrollVector = TeVector2f32(0.5f, 0.0f);
+}
+
+bool InGameScene::AnimObject::onFinished() {
+ error("TODO: Implement InGameScene::AnimObject::onFinished");
+}
+
+} // end namespace Tetraedge
diff --git a/engines/tetraedge/game/in_game_scene.h b/engines/tetraedge/game/in_game_scene.h
new file mode 100644
index 00000000000..d0e73c94eeb
--- /dev/null
+++ b/engines/tetraedge/game/in_game_scene.h
@@ -0,0 +1,131 @@
+/* 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 TETRAEDGE_GAME_IN_GAME_SCENE_H
+#define TETRAEDGE_GAME_IN_GAME_SCENE_H
+
+#include "common/array.h"
+#include "common/str.h"
+#include "common/hashmap.h"
+
+#include "tetraedge/game/object3d.h"
+#include "tetraedge/game/billboard.h"
+#include "tetraedge/te/te_scene.h"
+#include "tetraedge/te/te_lua_gui.h"
+
+namespace Tetraedge {
+
+class Character;
+class TeLayout;
+
+class InGameScene : public TeScene {
+public:
+ InGameScene();
+
+ struct AnimObject {
+ bool onFinished();
+
+ Common::String _name;
+ TeSpriteLayout *_layout;
+ };
+
+ struct SoundStep {
+ Common::String _stepSound1;
+ Common::String _stepSound2;
+ };
+
+ class AnchorZone {
+ };
+
+ class TeMarker {
+ };
+
+ void activateAnchorZone(const Common::String &name, bool param_2);
+ void addAnchorZone(const Common::String ¶m_1, const Common::String ¶m_2, float param_3);
+ void addBlockingObject(const Common::String &obj) {
+ _blockingObjects.push_back(obj);
+ }
+ void addCallbackAnimation2D(const Common::String ¶m_1, const Common::String ¶m_2, float param_3);
+ void addMarker(const Common::String &name, const Common::String ¶m_2, float param_3, float param_4, const Common::String ¶m_5, const Common::String ¶m_6);
+ static float angularDistance(float a1, float a2);
+ bool aroundAnchorZone(const AnchorZone *zone);
+ TeLayout *background();
+ void loadBackground(const Common::Path &path);
+ void loadInteractions(const Common::Path &path);
+ void initScroll();
+
+ void draw();
+ Character *character(const Common::String &name);
+ bool loadCharacter(const Common::String &name);
+ bool loadPlayerCharacter(const Common::String &name);
+ bool changeBackground(const Common::String &name);
+ void unloadPlayerCharacter(const Common::String &character);
+ void unloadCharacter(const Common::String &name);
+
+ void close();
+ void reset();
+ void freeSceneObjects();
+ void unloadSpriteLayouts();
+ void deleteAllCallback();
+
+ void setStep(const Common::String &scene, const Common::String &step1, const Common::String &step2);
+
+ void loadBlockers();
+ Common::Path getBlockersFileName();
+
+ // Does nothing, but to keep calls from original..
+ static void updateScroll() {};
+
+ bool findKate();
+
+ Character *_character;
+ Common::Array<Character *> _characters;
+
+ TeLuaGUI &bgGui() { return _bgGui; }
+
+private:
+ struct TeBlocker {};
+ struct TeRectBlocker {};
+
+ Common::Array<TeBlocker> _blockers;
+ Common::Array<TeRectBlocker> _rectBlockers;
+ Common::Array<TeMarker *> _markers;
+ Common::Array<AnchorZone *> _anchorZones;
+ Common::Array<AnimObject *> _animObjects;
+ Common::Array<Object3D *> _object3Ds;
+ Common::Array<Billboard *> _billboards;
+ Common::Array<TeSpriteLayout *> _sprites;
+
+ Common::HashMap<Common::String, SoundStep> _soundSteps;
+
+ TeIntrusivePtr<TeModel> _playerCharacterModel;
+ Common::Array<Common::String> _blockingObjects;
+ TeLuaGUI _bgGui;
+ TeLuaGUI _gui2; // TODO: find a better name.
+ TeLuaGUI _gui3; // TODO: find a better name.
+ // TODO add private members
+
+ TeVector2f32 _someScrollVector;
+};
+
+} // end namespace Tetraedge
+
+#endif // TETRAEDGE_GAME_IN_GAME_SCENE_H
diff --git a/engines/tetraedge/game/inventory.cpp b/engines/tetraedge/game/inventory.cpp
new file mode 100644
index 00000000000..ee1be431277
--- /dev/null
+++ b/engines/tetraedge/game/inventory.cpp
@@ -0,0 +1,309 @@
+/* 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/textconsole.h"
+
+#include "tetraedge/tetraedge.h"
+#include "tetraedge/game/application.h"
+#include "tetraedge/game/cellphone.h"
+#include "tetraedge/game/character.h"
+#include "tetraedge/game/game.h"
+#include "tetraedge/game/inventory.h"
+#include "tetraedge/game/inventory_object.h"
+#include "tetraedge/game/inventory_objects_xml_parser.h"
+
+#include "tetraedge/te/te_core.h"
+
+namespace Tetraedge {
+
+Inventory::Inventory() : _cellphone(nullptr), _selectedObject(nullptr) {
+}
+
+void Inventory::enter() {
+ setVisible(true);
+ Game *game = g_engine->getGame();
+ Character *character = game->scene()._character;
+ character->stop();
+ character->setAnimation(character->characterSettings()._walkFileName, true, false, false, -1, 9999);
+ _gui.layoutChecked("textObject")->setVisible(false);
+
+ if (!game->_firstInventory) {
+ _gui.buttonLayoutChecked("Aide")->setVisible(false);
+ } else {
+ game->_firstInventory = false;
+ }
+
+ if (_selectedObject)
+ selectedObject(*_selectedObject);
+}
+
+void Inventory::leave() {
+ setVisible(false);
+ if (_selectedObject) {
+ Game *game = g_engine->getGame();
+ if (game->entered())
+ game->luaScript().execute("OnSelectedObject", _selectedObject->name());
+ }
+}
+
+void Inventory::load() {
+ setName("inventory");
+ setSizeType(RELATIVE_TO_PARENT);
+ setSize(TeVector3f32(1.0f, 1.0f, userSize().z()));
+ _gui.load("Inventory/Inventory.lua");
+ TeLayout *invlayout = _gui.layout("inventory");
+ if (!invlayout)
+ error("Inventory::load: Couldn't find inventory layout after loading");
+ addChild(invlayout);
+
+ TeButtonLayout *btn;
+ btn = _gui.buttonLayoutChecked("cellphone");
+ btn->onMouseClickValidated().add(this, &Inventory::onVisibleCellphone);
+
+ btn = _gui.buttonLayoutChecked("prendre");
+ btn->setVisible(false);
+ btn->onMouseClickValidated().add(this, &Inventory::onTakeObjectSelected);
+
+ btn = _gui.buttonLayoutChecked("lire");
+ btn->setVisible(false);
+ btn->setEnable(false);
+ btn->onMouseClickValidated().add(this, &Inventory::onZoomed);
+
+ btn = _gui.buttonLayoutChecked("quitButton");
+ btn->setVisible(true);
+ btn->onMouseClickValidated().add(this, &Inventory::onQuitButton);
+
+ btn = _gui.buttonLayoutChecked("quitBackground");
+ btn->setVisible(true);
+ btn->onMouseClickValidated().add(this, &Inventory::onQuitButton);
+
+ btn = _gui.buttonLayoutChecked("mainMenuButton");
+ btn->setVisible(true);
+ btn->onMouseClickValidated().add(this, &Inventory::onMainMenuButton);
+
+ _selectedObject = nullptr;
+ loadCellphone();
+
+ const Common::Path objectsPathPrefix("Inventory/Objects/Objects_");
+ const Common::String &lang = g_engine->getCore()->language();
+ Common::Path langXmlPath = objectsPathPrefix.append(lang).appendInPlace(".xml");
+ if (!Common::File::exists(langXmlPath)) {
+ langXmlPath = objectsPathPrefix.append(".xml");
+ if (!Common::File::exists(langXmlPath)) {
+ langXmlPath = objectsPathPrefix.append("en.xml");
+ if (!Common::File::exists(langXmlPath)) {
+ error("Inventory::load Couldn't find inventory objects xml.");
+ }
+ }
+ }
+
+ loadXMLFile(langXmlPath);
+
+ TeLayout *layout = _gui.layout("selectionSprite");
+ layout->setVisible(false);
+
+ setVisible(false);
+}
+
+void Inventory::loadXMLFile(const Common::Path &path) {
+ Common::File xmlfile;
+ xmlfile.open(path);
+ int64 fileLen = xmlfile.size();
+ char *buf = new char[fileLen + 1];
+ buf[fileLen] = '\0';
+ xmlfile.read(buf, fileLen);
+ const Common::String xmlContents = Common::String::format("<?xml version=\"1.0\" encoding=\"UTF-8\"?><document>%s</document>", buf);
+ delete [] buf;
+ xmlfile.close();
+
+ InventoryObjectsXmlParser parser;
+ if (!parser.loadBuffer((byte *)xmlContents.c_str(), xmlContents.size()))
+ error("Couldn't load inventory xml.");
+ if (!parser.parse())
+ error("Couldn't parse inventory xml.");
+ _objectData = parser._objects;
+}
+
+void Inventory::unload() {
+ int pageNo = 0;
+ while (true) {
+ const Common::String pageStr = Common::String::format("page%d", pageNo);
+ if (_gui.layout(pageStr)) {
+ int slotNo = 0;
+ while (true) {
+ const Common::String slotStr = Common::String::format("page%dSlot%d", pageNo, slotNo);
+ TeLayout *slotLayout = _gui.layout(slotStr);
+ if (slotLayout) {
+ // Take a copy of the list as we may be deleting some
+ // and that removes them from the parent.
+ Common::Array<Te3DObject2 *> children = slotLayout->childList();
+ for (Te3DObject2 *child : children) {
+ InventoryObject *invObj = dynamic_cast<InventoryObject *>(child);
+ if (invObj)
+ delete invObj;
+ }
+ slotNo++;
+ } else {
+ break;
+ }
+ }
+ pageNo++;
+ } else {
+ break;
+ }
+ }
+}
+
+void Inventory::loadCellphone() {
+ _cellphone = new Cellphone();
+ _cellphone->load();
+}
+
+//void loadFromBackup(TiXmlNode *node);
+//void saveToBackup(TiXmlNode *node);
+
+void Inventory::addObject(const Common::String &objId) {
+ InventoryObject *newobj = new InventoryObject();
+ newobj->load(objId);
+ if (!addObject(*newobj))
+ delete newobj;
+}
+
+bool Inventory::addObject(InventoryObject &obj) {
+ error("TODO: implement Inventory::addObject.");
+}
+
+bool Inventory::isDocument(const Common::String &objId) {
+ if (!_objectData.contains(objId))
+ return false;
+ return _objectData.getVal(objId)._isDocument;
+}
+
+int Inventory::objectCount(const Common::String &objId) {
+ for (const InventoryObject *obj : _invObjects) {
+ if (obj->name() == objId)
+ return 1;
+ }
+ return 0;
+}
+
+Common::String Inventory::objectDescription(const Common::String &objId) {
+ // Note: The game XML files don't actually include descriptions.
+ return "";
+}
+
+Common::String Inventory::objectName(const Common::String &objId) {
+ if (!_objectData.contains(objId))
+ return "";
+ return _objectData.getVal(objId)._name;
+}
+
+bool Inventory::onMainMenuButton() {
+ leave();
+ Game *game = g_engine->getGame();
+ game->leave(false);
+ Application *app = g_engine->getApplication();
+ app->mainMenu().enter();
+ return true;
+}
+
+bool Inventory::onObjectSelected(InventoryObject &obj) {
+ selectedObject(obj);
+ if (!_selectedTimer._stopped) {
+ if (_selectedTimer.timeElapsed() < 300000)
+ g_engine->getGame()->inventoryMenu().leave();
+ } else {
+ _selectedTimer.start();
+ }
+ return false;
+}
+
+bool Inventory::onQuitButton() {
+ Game *game = g_engine->getGame();
+ game->inventoryMenu().leave();
+ return true;
+}
+
+bool Inventory::onTakeObjectSelected() {
+ Game *game = g_engine->getGame();
+ game->inventoryMenu().leave();
+ return false;
+}
+
+bool Inventory::onVisibleCellphone() {
+ _cellphone->enter();
+ Game *game = g_engine->getGame();
+ game->inventoryMenu().leave();
+ leave();
+ return false;
+}
+
+bool Inventory::onZoomed() {
+ const Common::String &selected = selectedObject();
+ if (!selected.empty()) {
+ Game *game = g_engine->getGame();
+ game->documentsBrowser().showDocument(selected, 0);
+ }
+ return false;
+}
+
+void Inventory::pauseAnims() {
+ error("TODO: implement Inventory::pauseAnims");
+}
+
+void Inventory::unPauseAnims() {
+ error("TODO: implement Inventory::unPauseAnims");
+}
+
+void Inventory::removeObject(const Common::String &objname) {
+ error("TODO: implement Inventory::removeObject");
+}
+
+void Inventory::removeSelectedObject() {
+ error("TODO: implement Inventory::removeSelectedObject");
+}
+
+InventoryObject *Inventory::selectedInventoryObject() {
+ return _selectedObject;
+}
+
+void Inventory::selectedObject(const Common::String &objname) {
+ error("TODO: implement Inventory::selectedObject");
+}
+
+void Inventory::selectedObject(InventoryObject &obj) {
+ error("TODO: implement Inventory::selectedObject");
+}
+
+const Common::String &Inventory::selectedObject() {
+ static const Common::String blank;
+ if (_selectedObject == nullptr)
+ return blank;
+ else
+ return _selectedObject->name();
+}
+
+bool Inventory::updateLayout() {
+ error("TODO: implement Inventory::updateLayout");
+}
+
+
+} // end namespace Tetraedge
diff --git a/engines/tetraedge/game/inventory.h b/engines/tetraedge/game/inventory.h
new file mode 100644
index 00000000000..aa81722db0e
--- /dev/null
+++ b/engines/tetraedge/game/inventory.h
@@ -0,0 +1,97 @@
+/* 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 TETRAEDGE_GAME_INVENTORY_H
+#define TETRAEDGE_GAME_INVENTORY_H
+
+#include "common/str.h"
+#include "tetraedge/game/inventory_object.h"
+#include "tetraedge/te/te_layout.h"
+#include "tetraedge/te/te_lua_gui.h"
+
+namespace Tetraedge {
+
+class Cellphone;
+
+class Inventory : public TeLayout {
+public:
+ struct InventoryObjectData {
+ Common::String _id;
+ Common::String _name;
+ bool _isDocument;
+ };
+
+ Inventory();
+
+ void enter();
+ void leave();
+ void load();
+ void unload();
+ void loadCellphone();
+
+ //void loadFromBackup(TiXmlNode *node);
+ //void saveToBackup(TiXmlNode *node);
+
+ void addObject(const Common::String &objname);
+ bool addObject(InventoryObject &obj);
+ bool isDocument(const Common::String &objname);
+
+ int objectCount(const Common::String &objname);
+ Common::String objectDescription(const Common::String &objname);
+ Common::String objectName(const Common::String &objname);
+
+ bool onMainMenuButton();
+ bool onObjectSelected(InventoryObject &obj);
+ bool onQuitButton();
+ bool onTakeObjectSelected();
+ bool onVisibleCellphone();
+ bool onZoomed();
+
+ void pauseAnims();
+ void unPauseAnims();
+
+ void removeObject(const Common::String &objname);
+ void removeSelectedObject();
+
+ InventoryObject *selectedInventoryObject();
+ void selectedObject(const Common::String &objname);
+ void selectedObject(InventoryObject &obj);
+ const Common::String &selectedObject();
+
+ bool updateLayout();
+
+ Cellphone *cellphone() { return _cellphone; }
+
+private:
+ void loadXMLFile(const Common::Path &path);
+
+ TeLuaGUI _gui;
+ Common::Array<InventoryObject *> _invObjects;
+ Cellphone *_cellphone;
+ InventoryObject *_selectedObject;
+ Common::HashMap<Common::String, InventoryObjectData> _objectData;
+
+ TeTimer _selectedTimer;
+};
+
+} // end namespace Tetraedge
+
+#endif // TETRAEDGE_GAME_INVENTORY_H
diff --git a/engines/tetraedge/game/inventory_menu.cpp b/engines/tetraedge/game/inventory_menu.cpp
new file mode 100644
index 00000000000..31f0294eb29
--- /dev/null
+++ b/engines/tetraedge/game/inventory_menu.cpp
@@ -0,0 +1,123 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "tetraedge/tetraedge.h"
+#include "tetraedge/game/application.h"
+#include "tetraedge/game/game.h"
+#include "tetraedge/game/inventory_menu.h"
+
+namespace Tetraedge {
+
+InventoryMenu::InventoryMenu() {
+}
+
+void InventoryMenu::enter() {
+ Application *app = g_engine->getApplication();
+ app->mouseCursorLayout().load("pictures/cursor.png");
+
+ _gui.layoutChecked("inventoryMenu")->setVisible(true);
+ onInventoryButton();
+}
+
+void InventoryMenu::leave() {
+ Game *game = g_engine->getGame();
+ game->inventory().leave();
+ game->documentsBrowser().leave();
+ TeLayout *invMenu = _gui.layout("inventoryMenu");
+ if (invMenu) {
+ invMenu->setVisible(false);
+ }
+}
+
+void InventoryMenu::load() {
+ setName("inventoryMenu");
+ setSizeType(RELATIVE_TO_PARENT);
+ TeVector3f32 usersz = userSize();
+ setSize(TeVector3f32(1.0f, 1.0f, usersz.z()));
+ _gui.load("InventoryMenu/InventoryMenu.lua");
+ TeLayout *menu = _gui.layoutChecked("inventoryMenu");
+ addChild(menu);
+ TeButtonLayout *btn;
+ btn = _gui.buttonLayoutChecked("quitButton");
+ btn->onMouseClickValidated().add(this, &InventoryMenu::onQuitButton);
+ btn = _gui.buttonLayoutChecked("quitBackground");
+ btn->onMouseClickValidated().add(this, &InventoryMenu::onQuitButton);
+ btn = _gui.buttonLayoutChecked("mainMenuButton");
+ btn->onMouseClickValidated().add(this, &InventoryMenu::onMainMenuButton);
+ btn = _gui.buttonLayoutChecked("documentsButton");
+ btn->onMouseClickValidated().add(this, &InventoryMenu::onDocumentsButton);
+ btn = _gui.buttonLayoutChecked("inventoryButton");
+ btn->onMouseClickValidated().add(this, &InventoryMenu::onInventoryButton);
+
+ TeLayout *invmenu = _gui.layoutChecked("inventoryMenu");
+ invmenu->setVisible(false);
+ setVisible(false);
+}
+
+void InventoryMenu::unload() {
+ leave();
+ _gui.unload();
+}
+
+bool InventoryMenu::isVisible() {
+ TeLayout *menuLayout = _gui.layout("inventoryMenu");
+ return menuLayout->visible();
+}
+
+bool InventoryMenu::onDocumentsButton() {
+ _gui.buttonLayoutChecked("mainMenuButton")->setEnable(true);
+ _gui.buttonLayoutChecked("documentsButton")->setEnable(false);
+ _gui.buttonLayoutChecked("inventoryButton")->setEnable(true);
+ Game *game = g_engine->getGame();
+ game->inventory().leave();
+ game->documentsBrowser().enter();
+ return false;
+}
+
+bool InventoryMenu::onInventoryButton() {
+ _gui.buttonLayoutChecked("mainMenuButton")->setEnable(true);
+ _gui.buttonLayoutChecked("documentsButton")->setEnable(true);
+ _gui.buttonLayoutChecked("inventoryButton")->setEnable(false);
+ Game *game = g_engine->getGame();
+ game->inventory().enter();
+ game->documentsBrowser().leave();
+ return false;
+}
+
+bool InventoryMenu::onMainMenuButton() {
+ Application *app = g_engine->getApplication();
+ app->captureFade();
+ Game *game = g_engine->getGame();
+ game->_returnToMainMenu = true;
+ app->fade();
+ return false;
+}
+
+bool InventoryMenu::onQuitButton() {
+ leave();
+ return false;
+}
+
+bool InventoryMenu::onSaveButton(){
+ return false;
+}
+
+} // end namespace Tetraedge
diff --git a/engines/tetraedge/game/inventory_menu.h b/engines/tetraedge/game/inventory_menu.h
new file mode 100644
index 00000000000..349a2a6105c
--- /dev/null
+++ b/engines/tetraedge/game/inventory_menu.h
@@ -0,0 +1,53 @@
+/* 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 TETRAEDGE_GAME_INVENTORY_MENU_H
+#define TETRAEDGE_GAME_INVENTORY_MENU_H
+
+#include "tetraedge/te/te_layout.h"
+
+namespace Tetraedge {
+
+class InventoryMenu : public TeLayout {
+public:
+ InventoryMenu();
+
+ void enter();
+ void leave();
+ void load();
+ void unload();
+
+ bool isVisible();
+
+ bool onDocumentsButton();
+ bool onInventoryButton();
+ bool onMainMenuButton();
+ bool onQuitButton();
+ bool onSaveButton();
+
+private:
+ TeLuaGUI _gui;
+
+};
+
+} // end namespace Tetraedge
+
+#endif // TETRAEDGE_GAME_INVENTORY_MENU_H
diff --git a/engines/tetraedge/game/inventory_object.cpp b/engines/tetraedge/game/inventory_object.cpp
new file mode 100644
index 00000000000..af214d5969c
--- /dev/null
+++ b/engines/tetraedge/game/inventory_object.cpp
@@ -0,0 +1,35 @@
+/* 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 "tetraedge/game/inventory_object.h"
+
+namespace Tetraedge {
+
+InventoryObject::InventoryObject() {
+}
+
+void InventoryObject::load(const Common::String &name) {
+ error("TODO: Implement InventoryObject::load");
+}
+
+// TODO: Add more functions here.
+
+} // end namespace Tetraedge
diff --git a/engines/tetraedge/game/inventory_object.h b/engines/tetraedge/game/inventory_object.h
new file mode 100644
index 00000000000..8a9ae452f7b
--- /dev/null
+++ b/engines/tetraedge/game/inventory_object.h
@@ -0,0 +1,44 @@
+/* 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 TETRAEDGE_GAME_INVENTORY_OBJECT_H
+#define TETRAEDGE_GAME_INVENTORY_OBJECT_H
+
+#include "common/str.h"
+
+#include "tetraedge/te/te_lua_gui.h"
+
+namespace Tetraedge {
+
+class InventoryObject : TeLuaGUI {
+public:
+ InventoryObject();
+
+ void load(const Common::String &name);
+ const Common::String &name() const { return _name; }
+private:
+ Common::String _name;
+
+};
+
+} // end namespace Tetraedge
+
+#endif // TETRAEDGE_GAME_INVENTORY_OBJECT_H
diff --git a/engines/tetraedge/game/inventory_objects_xml_parser.cpp b/engines/tetraedge/game/inventory_objects_xml_parser.cpp
new file mode 100644
index 00000000000..7467dc6e490
--- /dev/null
+++ b/engines/tetraedge/game/inventory_objects_xml_parser.cpp
@@ -0,0 +1,35 @@
+/* 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 "tetraedge/game/inventory_objects_xml_parser.h"
+
+namespace Tetraedge {
+
+bool InventoryObjectsXmlParser::parserCallback_Object(ParserNode *node) {
+ Inventory::InventoryObjectData data;
+ data._id = node->values["id"];
+ data._name = node->values["name"];
+ data._isDocument = node->values.contains("isDocument");
+ _objects.setVal(data._id, data);
+ return true;
+};
+
+} // end namespace Tetraedge
diff --git a/engines/tetraedge/game/inventory_objects_xml_parser.h b/engines/tetraedge/game/inventory_objects_xml_parser.h
new file mode 100644
index 00000000000..6f86575527d
--- /dev/null
+++ b/engines/tetraedge/game/inventory_objects_xml_parser.h
@@ -0,0 +1,55 @@
+/* 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/hashmap.h"
+#include "common/str.h"
+#include "common/xmlparser.h"
+#include "tetraedge/game/inventory.h"
+
+#ifndef TETRAEDGE_GAME_INVENTORY_OBJECTS_XML_PARSER_H
+#define TETRAEDGE_GAME_INVENTORY_OBJECTS_XML_PARSER_H
+
+namespace Tetraedge {
+
+class InventoryObjectsXmlParser : public Common::XMLParser {
+public:
+ // Parser
+ CUSTOM_XML_PARSER(InventoryObjectsXmlParser) {
+ XML_KEY(document)
+ XML_KEY(Object)
+ XML_PROP(id, true)
+ XML_PROP(name, true)
+ XML_PROP(isDocument, false)
+ KEY_END()
+ KEY_END()
+ } PARSER_END()
+
+ bool parserCallback_document(ParserNode *node) { return true; };
+ bool parserCallback_Object(ParserNode *node);
+
+public:
+ Common::HashMap<Common::String, Inventory::InventoryObjectData> _objects;
+
+};
+
+} // end namespace Tetraedge
+
+#endif // TETRAEDGE_GAME_INVENTORY_OBJECTS_XML_PARSER_H
diff --git a/engines/tetraedge/game/loading_menu.cpp b/engines/tetraedge/game/loading_menu.cpp
new file mode 100644
index 00000000000..d8bc4a53afb
--- /dev/null
+++ b/engines/tetraedge/game/loading_menu.cpp
@@ -0,0 +1,31 @@
+/* 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 "tetraedge/game/loading_menu.h"
+
+namespace Tetraedge {
+
+LoadingMenu::LoadingMenu() {
+}
+
+// TODO: Add more functions here.
+
+} // end namespace Tetraedge
diff --git a/engines/tetraedge/game/loading_menu.h b/engines/tetraedge/game/loading_menu.h
new file mode 100644
index 00000000000..34021f76d43
--- /dev/null
+++ b/engines/tetraedge/game/loading_menu.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 TETRAEDGE_GAME_LOADING_MENU_H
+#define TETRAEDGE_GAME_LOADING_MENU_H
+
+namespace Tetraedge {
+
+class LoadingMenu {
+public:
+ LoadingMenu();
+
+ // TODO add public members
+
+private:
+ // TODO add private members
+
+};
+
+} // end namespace Tetraedge
+
+#endif // TETRAEDGE_GAME_LOADING_MENU_H
diff --git a/engines/tetraedge/game/loc_file.cpp b/engines/tetraedge/game/loc_file.cpp
new file mode 100644
index 00000000000..3e511527187
--- /dev/null
+++ b/engines/tetraedge/game/loc_file.cpp
@@ -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/>.
+ *
+ */
+
+#include "common/file.h"
+#include "common/textconsole.h"
+#include "common/xmlparser.h"
+
+#include "tetraedge/game/loc_file.h"
+#include "tetraedge/te/te_name_val_xml_parser.h"
+
+namespace Tetraedge {
+
+LocFile::LocFile() {
+}
+
+void LocFile::load(const Common::Path &path) {
+ TeNameValXmlParser parser;
+ static const Common::String xmlHeader("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
+ Common::File locFile;
+ if (!locFile.open(path))
+ error("LocFile::load: failed to open %s.", path.toString().c_str());
+
+ int64 fileLen = locFile.size();
+ char *buf = new char[fileLen + 1];
+ buf[fileLen] = '\0';
+ locFile.read(buf, fileLen);
+ const Common::String xmlContents = xmlHeader + buf;
+ delete [] buf;
+ locFile.close();
+ if (!parser.loadBuffer((const byte *)xmlContents.c_str(), xmlContents.size()))
+ error("LocFile::load: failed to load %s.", path.toString().c_str());
+
+ if (!parser.parse())
+ error("LocFile::load: failed to parse %s.", path.toString().c_str());
+
+ _map = parser.getMap();
+}
+
+const Common::String *LocFile::value(const Common::String &key) {
+ return text(key);
+}
+
+} // end namespace Tetraedge
diff --git a/engines/tetraedge/game/loc_file.h b/engines/tetraedge/game/loc_file.h
new file mode 100644
index 00000000000..31c49104be6
--- /dev/null
+++ b/engines/tetraedge/game/loc_file.h
@@ -0,0 +1,47 @@
+/* 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 TETRAEDGE_GAME_LOC_FILE_H
+#define TETRAEDGE_GAME_LOC_FILE_H
+
+#include "common/str.h"
+#include "common/path.h"
+
+#include "tetraedge/te/te_i_loc.h"
+
+namespace Tetraedge {
+
+class LocFile : public TeILoc {
+public:
+ LocFile();
+
+ //const Common::String *avatar(const Common::String &key);
+ void load(const Common::Path &path);
+ const Common::String *value(const Common::String &key);
+
+private:
+ // TODO add private members
+
+};
+
+} // end namespace Tetraedge
+
+#endif // TETRAEDGE_GAME_LOC_FILE_H
diff --git a/engines/tetraedge/game/lua_binds.cpp b/engines/tetraedge/game/lua_binds.cpp
new file mode 100644
index 00000000000..a3f95d08d18
--- /dev/null
+++ b/engines/tetraedge/game/lua_binds.cpp
@@ -0,0 +1,312 @@
+/* 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 "tetraedge/tetraedge.h"
+
+#include "tetraedge/game/application.h"
+#include "tetraedge/game/game.h"
+#include "tetraedge/game/lua_binds.h"
+#include "tetraedge/to_lua.h"
+
+namespace Tetraedge {
+
+namespace LuaBinds {
+
+using namespace ToLua;
+
+static void PlayMovie(const Common::String &vidpath, const Common::String &musicpath) {
+ Application *app = g_engine->getApplication();
+ app->mouseCursorLayout().load("pictures/cursor.png");
+ Game *game = g_engine->getGame();
+ game->playMovie(vidpath, musicpath);
+}
+
+static int tolua_ExportedFunctions_PlayMovie00(lua_State *L) {
+tolua_Error err;
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isstring(L, 2, 0, &err) && tolua_isnoobj(L, 3, &err)) {
+ Common::String s1(tolua_tostring(L, 1, nullptr));
+ Common::String s2(tolua_tostring(L, 2, nullptr));
+ PlayMovie(s1, s2);
+ return 0;
+ }
+ error("#ferror in function 'PlayMovie': %d %d %s", err.index, err.array, err.type);
+}
+
+static void AddRandomSound(const Common::String &s1, const Common::String &s2, float f1, float f2){
+ Game *game = g_engine->getGame();
+ game->addRandomSound(s1, s2, f1, f2);
+}
+
+static int tolua_ExportedFunctions_AddRandomSound00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isstring(L, 2, 0, &err)
+ && tolua_isnumber(L, 3, 0, &err) && tolua_isnumber(L, 4, 0, &err)
+ && tolua_isnoobj(L, 5, &err)) {
+ Common::String s1(tolua_tostring(L, 1, nullptr));
+ Common::String s2(tolua_tostring(L, 2, nullptr));
+ float f1 = tolua_tonumber(L, 3, 0.0);
+ float f2 = tolua_tonumber(L, 4, 1.0);
+ AddRandomSound(s1, s2, f1, f2);
+ return 0;
+ }
+ error("#ferror in function 'AddRandomSound': %d %d %s", err.index, err.array, err.type);
+}
+
+static void SetSoundStep(const Common::String &scene, const Common::String &step1, const Common::String &step2) {
+ Game *game = g_engine->getGame();
+ game->scene().setStep(scene, step1, step2);
+}
+
+static int tolua_ExportedFunctions_SetSoundStep00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isstring(L, 2, 0, &err)
+ && tolua_isstring(L, 3, 0, &err) && tolua_isnoobj(L, 4, &err)) {
+ Common::String s1(tolua_tostring(L, 1, nullptr));
+ Common::String s2(tolua_tostring(L, 2, nullptr));
+ Common::String s3(tolua_tostring(L, 3, nullptr));
+ SetSoundStep(s1, s2, s3);
+ return 0;
+ }
+ error("#ferror in function 'SetSoundStep': %d %d %s", err.index, err.array, err.type);
+}
+
+static void AddNumber(const Common::String &number) {
+ Game *game = g_engine->getGame();
+ if (!game->inventory().cellphone()->addNumber(number))
+ warning("[AddNumber] Number \"%s\" already exist.", number.c_str());
+}
+
+static int tolua_ExportedFunctions_AddNumber00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isnoobj(L, 2, &err)) {
+ Common::String s1(tolua_tostring(L, 1, nullptr));
+ AddNumber(s1);
+ return 0;
+ }
+ error("#ferror in function 'AddNumber': %d %d %s", err.index, err.array, err.type);
+}
+
+static void AddUnrecalAnim(const Common::String &newanim) {
+ Application *app = g_engine->getApplication();
+ Common::Array<Common::String> &anims = app->unrecalAnims();
+ for (const Common::String &anim : anims) {
+ if (anim == newanim)
+ return;
+ }
+ anims.push_back(newanim);
+}
+
+static int tolua_ExportedFunctions_AddUnrecalAnim00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isnoobj(L, 2, &err)) {
+ Common::String s1(tolua_tostring(L, 1, nullptr));
+ AddUnrecalAnim(s1);
+ return 0;
+ }
+ error("#ferror in function 'AddUnrecalAnim': %d %d %s", err.index, err.array, err.type);
+}
+
+static void UnlockArtwork(const Common::String &name) {
+ Game *game = g_engine->getGame();
+ game->addArtworkUnlocked(name, true);
+ Application *app = g_engine->getApplication();
+ app->saveOptions("options.xml");
+}
+
+static int tolua_ExportedFunctions_UnlockArtwork00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isnoobj(L, 2, &err)) {
+ Common::String s1(tolua_tostring(L, 1, nullptr));
+ UnlockArtwork(s1);
+ return 0;
+ }
+ error("#ferror in function 'UnlockArtwork': %d %d %s", err.index, err.array, err.type);
+}
+
+static void ChangeWarp(const Common::String &scene, const Common::String &zone) {
+}
+
+static int tolua_ExportedFunctions_ChangeWarp00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isstring(L, 2, 0, &err) && tolua_isnoobj(L, 3, &err)) {
+ Common::String s1(tolua_tostring(L, 1, nullptr));
+ Common::String s2(tolua_tostring(L, 2, nullptr));
+ ChangeWarp(s1, s2);
+ return 0;
+ }
+ error("#ferror in function 'ChangeWarp': %d %d %s", err.index, err.array, err.type);
+}
+
+
+void LuaOpenBinds(lua_State *L) {
+ tolua_open(L);
+ tolua_module(L, 0, 0);
+ tolua_beginmodule(L, 0);
+ /*
+ tolua_function(L, "LoadObjectMaterials", tolua_ExportedFunctions_LoadObjectMaterials00);
+ tolua_function(L, "LoadObjectMaterials", tolua_ExportedFunctions_LoadObjectMaterials01);
+ tolua_function(L, "HideObject", tolua_ExportedFunctions_HideObject00);
+ tolua_function(L, "ShowObject", tolua_ExportedFunctions_ShowObject00);
+ tolua_function(L, "ShowAllObjects", tolua_ExportedFunctions_ShowAllObjects00);
+ tolua_function(L, "SetBackground", tolua_ExportedFunctions_SetBackground00);
+ tolua_function(L, "AddBlockingObject", tolua_ExportedFunctions_AddBlockingObject00);
+ tolua_function(L, "RemoveBlockingObject", tolua_ExportedFunctions_RemoveBlockingObject00);*/
+ tolua_function(L, "ChangeWarp", tolua_ExportedFunctions_ChangeWarp00);
+ tolua_function(L, "PlayMovie", tolua_ExportedFunctions_PlayMovie00);
+ /*tolua_function(L, "PlayMovieAndWaitForEnd", tolua_ExportedFunctions_PlayMovieAndWaitForEnd00);
+ tolua_function(L, "StartAnimationPart", tolua_ExportedFunctions_StartAnimationPart00);
+ tolua_function(L, "StartAnimation", tolua_ExportedFunctions_StartAnimation00);
+ tolua_function(L, "StartAnimationAndWaitForEnd",
+ tolua_ExportedFunctions_StartAnimationAndWaitForEnd00);
+ tolua_function(L, "AddAnimToSet", tolua_ExportedFunctions_AddAnimToSet00);
+ tolua_function(L, "RequestAutoSave", tolua_ExportedFunctions_RequestAutoSave00);
+ tolua_function(L, "SetVisibleButtonZoomed", tolua_ExportedFunctions_SetVisibleButtonZoomed00);
+ tolua_function(L, "AddMarker", tolua_ExportedFunctions_AddMarker00);
+ tolua_function(L, "SetVisibleMarker", tolua_ExportedFunctions_SetVisibleMarker00);
+ tolua_function(L, "DeleteMarker", tolua_ExportedFunctions_DeleteMarker00);
+ tolua_function(L, "SetVisibleCellphone", tolua_ExportedFunctions_SetVisibleCellphone00);
+ tolua_function(L, "DisabledZone", tolua_ExportedFunctions_DisabledZone00);
+ tolua_function(L, "DisabledInt", tolua_ExportedFunctions_DisabledInt00);
+ tolua_function(L, "LockCursor", tolua_ExportedFunctions_LockCursor00);
+ tolua_function(L, "SetCondition", tolua_ExportedFunctions_SetCondition00);
+ tolua_function(L, "UnsetCondition", tolua_ExportedFunctions_UnsetCondition00);
+ tolua_function(L, "TutoActive", tolua_ExportedFunctions_TutoActive00);
+ tolua_function(L, "LaunchDialog", tolua_ExportedFunctions_LaunchDialog00);
+ tolua_function(L, "LaunchDialogAndWaitForEnd", tolua_ExportedFunctions_LaunchDialogAndWaitForEnd00);
+ tolua_function(L, "PushAnswer", tolua_ExportedFunctions_PushAnswer00);
+ tolua_function(L, "HideAnswers", tolua_ExportedFunctions_HideAnswers00);
+ tolua_function(L, "PushTask", tolua_ExportedFunctions_PushTask00);
+ tolua_function(L, "DeleteTask", tolua_ExportedFunctions_DeleteTask00);
+ tolua_function(L, "SetVisibleButtonHelp", tolua_ExportedFunctions_SetVisibleButtonHelp00);
+ tolua_function(L, "HideTasks", tolua_ExportedFunctions_HideTasks00);
+ tolua_function(L, "PlaySound", tolua_ExportedFunctions_PlaySound00);
+ tolua_function(L, "PlaySoundAndWaitForEnd", tolua_ExportedFunctions_PlaySoundAndWaitForEnd00);
+ tolua_function(L, "StopSound", tolua_ExportedFunctions_StopSound00);*/
+ tolua_function(L, "AddRandomSound", tolua_ExportedFunctions_AddRandomSound00);
+ /*tolua_function(L, "PlayRandomSound", tolua_ExportedFunctions_PlayRandomSound00);
+ tolua_function(L, "PlayMusic", tolua_ExportedFunctions_PlayMusic00);*/
+ tolua_function(L, "SetSoundStep", tolua_ExportedFunctions_SetSoundStep00);
+ /*tolua_function(L, "Selected", tolua_ExportedFunctions_Selected00);
+ tolua_function(L, "TakeObject", tolua_ExportedFunctions_TakeObject00);
+ tolua_function(L, "TakeObjectInHand", tolua_ExportedFunctions_TakeObjectInHand00);
+ tolua_function(L, "RemoveObject", tolua_ExportedFunctions_RemoveObject00);
+ tolua_function(L, "RemoveObject", tolua_ExportedFunctions_RemoveObject01);*/
+ tolua_function(L, "AddNumber", tolua_ExportedFunctions_AddNumber00);
+ /*tolua_function(L, "ShowDocument", tolua_ExportedFunctions_ShowDocument00);
+ tolua_function(L, "ShowDocumentAndWaitForEnd", tolua_ExportedFunctions_ShowDocumentAndWaitForEnd00);
+ tolua_function(L, "HideDocument", tolua_ExportedFunctions_HideDocument00);
+ tolua_function(L, "AddDocument", tolua_ExportedFunctions_AddDocument00);
+ tolua_function(L, "LoadCharacter", tolua_ExportedFunctions_LoadCharacter00);
+ tolua_function(L, "UnloadCharacter", tolua_ExportedFunctions_UnloadCharacter00);
+ tolua_function(L, "GetRotationCharacter", tolua_ExportedFunctions_GetRotationCharacter00);
+ tolua_function(L, "GetXPositionCharacter", tolua_ExportedFunctions_GetXPositionCharacter00);
+ tolua_function(L, "GetYPositionCharacter", tolua_ExportedFunctions_GetYPositionCharacter00);
+ tolua_function(L, "GetZPositionCharacter", tolua_ExportedFunctions_GetZPositionCharacter00);
+ tolua_function(L, "MoveCharacterTo", tolua_ExportedFunctions_MoveCharacterTo00);
+ tolua_function(L, "MoveCharacterToAndWaitForEnd",
+ tolua_ExportedFunctions_MoveCharacterToAndWaitForEnd00);
+ tolua_function(L, "MoveCharacterPlayerTo", tolua_ExportedFunctions_MoveCharacterPlayerTo00);
+ tolua_function(L, "MoveCharacterPlayerToAndWaitForEnd",
+ tolua_ExportedFunctions_MoveCharacterPlayerToAndWaitForEnd00);
+ tolua_function(L, "MoveCharacterPlayerAtTo", tolua_ExportedFunctions_MoveCharacterPlayerAtTo00);
+ tolua_function(L, "SetCharacterPosition", tolua_ExportedFunctions_SetCharacterPosition00);
+ tolua_function(L, "PlaceCharacterOnDummy", tolua_ExportedFunctions_PlaceCharacterOnDummy00);
+ tolua_function(L, "SetCharacterRotation", tolua_ExportedFunctions_SetCharacterRotation00);
+ tolua_function(L, "SetCharacterOrientation", tolua_ExportedFunctions_SetCharacterOrientation00);
+ tolua_function(L, "SetCharacterAnimation", tolua_ExportedFunctions_SetCharacterAnimation00);
+ tolua_function(L, "SetCharacterAnimationAndWaitForEnd",
+ tolua_ExportedFunctions_SetCharacterAnimationAndWaitForEnd00);
+ tolua_function(L, "BlendCharacterAnimation", tolua_ExportedFunctions_BlendCharacterAnimation00);
+ tolua_function(L, "BlendCharacterAnimationAndWaitForEnd",
+ tolua_ExportedFunctions_BlendCharacterAnimationAndWaitForEnd00);
+ tolua_function(L, "CurrentCharacterAnimation", tolua_ExportedFunctions_CurrentCharacterAnimation00);
+ tolua_function(L, "SetCharacterPlayerVisible", tolua_ExportedFunctions_SetCharacterPlayerVisible00);
+ tolua_function(L, "MoveCharacterPlayerDisabled",
+ tolua_ExportedFunctions_MoveCharacterPlayerDisabled00);
+ tolua_function(L, "SetRunMode", tolua_ExportedFunctions_SetRunMode00);
+ tolua_function(L, "SetRunMode2", tolua_ExportedFunctions_SetRunMode200);
+ tolua_function(L, "SetCharacterColor", tolua_ExportedFunctions_SetCharacterColor00);
+ tolua_function(L, "SetCharacterSound", tolua_ExportedFunctions_SetCharacterSound00);
+ tolua_function(L, "SetCharacterShadow", tolua_ExportedFunctions_SetCharacterShadow00);
+ tolua_function(L, "AddCallback", tolua_ExportedFunctions_AddCallback00);
+ tolua_function(L, "AddCallbackPlayer", tolua_ExportedFunctions_AddCallbackPlayer00);
+ tolua_function(L, "AddCallbackAnimation2D", tolua_ExportedFunctions_AddCallbackAnimation2D00);
+ tolua_function(L, "DeleteCallback", tolua_ExportedFunctions_DeleteCallback00);
+ tolua_function(L, "DeleteCallbackPlayer", tolua_ExportedFunctions_DeleteCallbackPlayer00);
+ tolua_function(L, "DeleteCallbackAnimation2D", tolua_ExportedFunctions_DeleteCallbackAnimation2D00);
+ tolua_function(L, "SetObjectOnCharacter", tolua_ExportedFunctions_SetObjectOnCharacter00);
+ tolua_function(L, "SetObjectRotation", tolua_ExportedFunctions_SetObjectRotation00);
+ tolua_function(L, "SetObjectTranslation", tolua_ExportedFunctions_SetObjectTranslation00);
+ tolua_function(L, "SetObjectScale", tolua_ExportedFunctions_SetObjectScale00);
+ tolua_function(L, "SetObjectFrames", tolua_ExportedFunctions_SetObjectFrames00);
+ tolua_function(L, "LoadObject", tolua_ExportedFunctions_LoadObject00);
+ tolua_function(L, "UnloadObject", tolua_ExportedFunctions_UnloadObject00);
+ tolua_function(L, "SetGroundObjectPosition", tolua_ExportedFunctions_SetGroundObjectPosition00);
+ tolua_function(L, "SetGroundObjectRotation", tolua_ExportedFunctions_SetGroundObjectRotation00);
+ tolua_function(L, "TranslateGroundObject", tolua_ExportedFunctions_TranslateGroundObject00);
+ tolua_function(L, "RotateGroundObject", tolua_ExportedFunctions_RotateGroundObject00);
+ tolua_function(L, "SetLightPlayerCharacter", tolua_ExportedFunctions_SetLightPlayerCharacter00);
+ tolua_function(L, "SetLightPos", tolua_ExportedFunctions_SetLightPos00);
+ tolua_function(L, "EnableLight", tolua_ExportedFunctions_EnableLight00);
+ tolua_function(L, "SetLightDiffuse", tolua_ExportedFunctions_SetLightDiffuse00);
+ tolua_function(L, "SetLightAmbient", tolua_ExportedFunctions_SetLightAmbient00);
+ tolua_function(L, "SetLightSpecular", tolua_ExportedFunctions_SetLightSpecular00);
+ tolua_function(L, "LoadBillBoard", tolua_ExportedFunctions_LoadBillBoard00);
+ tolua_function(L, "SetBillboardPosition", tolua_ExportedFunctions_SetBillboardPosition00);
+ tolua_function(L, "SetBillboardPosition2", tolua_ExportedFunctions_SetBillboardPosition200);
+ tolua_function(L, "SetBillboardSize", tolua_ExportedFunctions_SetBillboardSize00);
+ tolua_function(L, "ShowBillboard", tolua_ExportedFunctions_ShowBillboard00);
+ tolua_function(L, "HideBillboard", tolua_ExportedFunctions_HideBillboard00);
+ tolua_function(L, "UnlockAchievement", tolua_ExportedFunctions_UnlockAchievement00);
+ tolua_function(L, "Save", tolua_ExportedFunctions_Save00);
+ tolua_function(L, "Wait", tolua_ExportedFunctions_Wait00);
+ tolua_function(L, "WaitAndWaitForEnd", tolua_ExportedFunctions_WaitAndWaitForEnd00);
+ tolua_function(L, "OpenFinalURL", tolua_ExportedFunctions_OpenFinalURL00);
+ tolua_function(L, "FinishGame", tolua_ExportedFunctions_FinishGame00);
+ tolua_function(L, "RequestMainMenu", tolua_ExportedFunctions_RequestMainMenu00);
+ tolua_function(L, "BFGRateImmediately", tolua_ExportedFunctions_BFGRateImmediately00);
+ tolua_function(L, "BFGReportEvent", tolua_ExportedFunctions_BFGReportEvent00);
+ tolua_function(L, "BFGReportEventWithValue", tolua_ExportedFunctions_BFGReportEventWithValue00);
+ tolua_function(L, "BFGReachedFreemiumLimit", tolua_ExportedFunctions_BFGReachedFreemiumLimit00);
+ tolua_function(L, "TestFileFlagSystemFlag", tolua_ExportedFunctions_TestFileFlagSystemFlag00);
+ tolua_function(L, "PrintDebugMessage", tolua_ExportedFunctions_PrintDebugMessage00);
+ tolua_function(L, "ExitZone", tolua_ExportedFunctions_ExitZone00);
+ tolua_function(L, "EnableRectBlocker", tolua_ExportedFunctions_EnableRectBlocker00);
+ tolua_function(L, "EnableBlocker", tolua_ExportedFunctions_EnableBlocker00);
+ tolua_function(L, "AddAnchorZone", tolua_ExportedFunctions_AddAnchorZone00);
+ tolua_function(L, "ActivateAnchorZone", tolua_ExportedFunctions_ActivateAnchorZone00);
+ tolua_function(L, "SetCharacterAnchor", tolua_ExportedFunctions_SetCharacterAnchor00);
+ tolua_function(L, "SetCharacterLookChar", tolua_ExportedFunctions_SetCharacterLookChar00);
+ tolua_function(L, "Random", tolua_ExportedFunctions_Random00);
+ tolua_function(L, "SetCharacterMeshVisible", tolua_ExportedFunctions_SetCharacterMeshVisible00);
+ tolua_function(L, "SetRecallageY", tolua_ExportedFunctions_SetRecallageY00);
+ tolua_function(L, "IsFreemiumUnlocked", tolua_ExportedFunctions_IsFreemiumUnlocked00);
+ tolua_function(L, "ReachedFreemiumLimit", tolua_ExportedFunctions_ReachedFreemiumLimit00);*/
+ tolua_function(L, "AddUnrecalAnim", tolua_ExportedFunctions_AddUnrecalAnim00);
+ tolua_function(L, "UnlockArtwork", tolua_ExportedFunctions_UnlockArtwork00);
+
+ tolua_endmodule(L);
+}
+
+
+}
+
+} // end namespace Tetraedge
diff --git a/engines/tetraedge/game/lua_binds.h b/engines/tetraedge/game/lua_binds.h
new file mode 100644
index 00000000000..c22f39eeeeb
--- /dev/null
+++ b/engines/tetraedge/game/lua_binds.h
@@ -0,0 +1,37 @@
+/* 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 TETRAEDGE_GAME_LUA_BINDS_H
+#define TETRAEDGE_GAME_LUA_BINDS_H
+
+struct lua_State;
+
+namespace Tetraedge {
+
+namespace LuaBinds {
+
+void LuaOpenBinds(lua_State *L);
+
+};
+
+} // end namespace Tetraedge
+
+#endif // TETRAEDGE_GAME_LUA_BINDS_H
diff --git a/engines/tetraedge/game/main_menu.cpp b/engines/tetraedge/game/main_menu.cpp
new file mode 100644
index 00000000000..7fb93fbd6c1
--- /dev/null
+++ b/engines/tetraedge/game/main_menu.cpp
@@ -0,0 +1,309 @@
+/* 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/config-manager.h"
+#include "common/system.h"
+#include "common/events.h"
+#include "common/savefile.h"
+
+#include "tetraedge/tetraedge.h"
+#include "tetraedge/game/confirm.h"
+#include "tetraedge/game/game.h"
+#include "tetraedge/game/main_menu.h"
+#include "tetraedge/game/application.h"
+
+#include "tetraedge/te/te_button_layout.h"
+#include "tetraedge/te/te_sprite_layout.h"
+#include "tetraedge/te/te_text_layout.h"
+#include "tetraedge/te/te_music.h"
+
+
+namespace Tetraedge {
+
+static const char *LAST_SAVE_CONF = "lastSaveSlot";
+
+MainMenu::MainMenu() : _entered(false), _confirmingTuto(false) {
+ _newGameConfirm._onButtonYesSignal.add(this, &MainMenu::onNewGameConfirmed);
+ _tutoConfirm._onButtonYesSignal.add(this, &MainMenu::onActivedTuto);
+ _tutoConfirm._onButtonNoSignal.add(this, &MainMenu::onDisabledTuto);
+ _quitConfirm._onButtonYesSignal.add(this, &MainMenu::onQuit);
+ onFacebookLoggedSignal.add(this, &MainMenu::onFacebookLogged);
+}
+
+void MainMenu::enter() {
+ Application *app = g_engine->getApplication();
+ TeSpriteLayout &appSpriteLayout = app->appSpriteLayout();
+ appSpriteLayout.setVisible(true);
+ if (appSpriteLayout._tiledSurfacePtr->_frameAnim._runTimer._stopped) {
+ appSpriteLayout.load("menus/menu.ogv");
+ appSpriteLayout._tiledSurfacePtr->_frameAnim._loopCount = -1;
+ appSpriteLayout._tiledSurfacePtr->play();
+ }
+ app->captureFade();
+
+ _entered = true;
+ load("menus/mainMenu/mainMenu.lua");
+
+ TeLayout *menuLayout = layout("menu");
+ appSpriteLayout.addChild(menuLayout);
+
+ app->mouseCursorLayout().setVisible(true);
+ app->mouseCursorLayout().load("pictures/cursor.png");
+
+ TeMusic &music = app->music();
+ if (music.isPlaying()) {
+ // TODO: something here??
+ }
+ music.load(value("musicPath").toString());
+ music.play();
+ music.volume(1.0f);
+
+ TeButtonLayout *newGameButton = buttonLayout("newGameButton");
+ if (newGameButton)
+ newGameButton->onMouseClickValidated().add(this, &MainMenu::onNewGameButtonValidated);
+
+ TeButtonLayout *continueGameButton = buttonLayout("continueGameButton");
+ if (continueGameButton) {
+ continueGameButton->onMouseClickValidated().add(this, &MainMenu::onContinueGameButtonValidated);
+ continueGameButton->setEnable(ConfMan.hasKey(LAST_SAVE_CONF));
+ }
+
+ TeButtonLayout *loadGameButton = buttonLayout("loadGameButton");
+ if (loadGameButton)
+ loadGameButton->onMouseClickValidated().add(this, &MainMenu::onLoadGameButtonValidated);
+
+ TeButtonLayout *optionsButton = buttonLayout("optionsButton");
+ if (optionsButton)
+ optionsButton->onMouseClickValidated().add(this, &MainMenu::onOptionsButtonValidated);
+
+ TeButtonLayout *galleryButton = buttonLayout("galleryButton");
+ if (galleryButton)
+ galleryButton->onMouseClickValidated().add(this, &MainMenu::onGalleryButtonValidated);
+
+ TeButtonLayout *quitButton = buttonLayout("quitButton");
+ if (quitButton)
+ quitButton->onMouseClickValidated().add(this, &MainMenu::onQuitButtonValidated);
+
+ // TODO: confirmation (menus/confirm/confirmNotSound.lua)
+ // if TeSoundManager is not valid.
+
+ _confirmingTuto = false;
+ TeLayout *panel = layout("panel");
+
+ if (panel) {
+ const Common::String panelTypoVal = value("panelTypo").toString();
+ for (auto *child : panel->childList()) {
+ TeTextLayout *childText = dynamic_cast<TeTextLayout *>(child);
+ if (!childText)
+ continue;
+ childText->setName(panelTypoVal + childText->name());
+ }
+ }
+ setCenterButtonsVisibility(true);
+ TeTextLayout *versionNum = textLayout("versionNumber");
+ if (versionNum) {
+ const Common::String versionSectionStr("<section style=\"left\" /><color r=\"255\" g=\"255\" b=\"255\"/><font file=\"Common/Fonts/arial.ttf\" size=\"12\" />");
+ versionNum->setText(versionSectionStr + app->getVersionString());
+ }
+}
+
+void MainMenu::leave() {
+ if (!_entered)
+ return;
+
+ Application *app = g_engine->getApplication();
+ app->captureFade();
+ warning("TODO: MainMenu::leave Stop some game sounds here.");
+ //Game *game = g_engine->getGame();
+ //game->stopSound("sounds/Ambiances/b_automatebike.ogg");
+ //game->stopSound("sounds/Ambiances/b_engrenagebg.ogg");
+ TeLuaGUI::unload();
+ app->fade();
+ _entered= false;
+}
+
+bool MainMenu::deleteFile(const Common::String &name) {
+ error("TODO: Implement MainMenu::deleteFile");
+}
+
+bool MainMenu::onActivedTuto() {
+ Application *app = g_engine->getApplication();
+ app->setTutoActivated(true);
+ // TODO: Set game val false too?
+ app->captureFade();
+ leave();
+ app->startGame(true, 1);
+ app->fade();
+ return false;
+}
+
+bool MainMenu::onBFGRateIt2ButtonValidated() {
+ error("TODO: Implement MainMenu::onBFGRateIt2ButtonValidated");
+}
+
+bool MainMenu::onBFGRateItButtonValidated() {
+ error("TODO: Implement MainMenu::onBFGRateItButtonValidated");
+}
+
+bool MainMenu::onBFGRateItQuitButtonValidated() {
+ error("TODO: Implement MainMenu function");
+}
+
+bool MainMenu::onBFGUnlockGameButtonValidated() {
+ error("TODO: Implement MainMenu function");
+}
+
+void MainMenu::tryDisableButton(const Common::String &btnName) {
+ TeButtonLayout *button = buttonLayout(btnName);
+ if (button)
+ button->setEnable(false);
+}
+
+bool MainMenu::onContinueGameButtonValidated() {
+ Application *app = g_engine->getApplication();
+ const Common::String lastSave = ConfMan.get(LAST_SAVE_CONF);
+ if (!lastSave.empty()) {
+ int saveSlot = lastSave.asUint64();
+ g_engine->loadGameState(saveSlot);
+ return false;
+ }
+
+ tryDisableButton("newGameButton");
+ tryDisableButton("continueGameButton");
+ tryDisableButton("loadGameButton");
+ tryDisableButton("optionsButton");
+ tryDisableButton("galleryButton");
+ tryDisableButton("quitButton");
+
+ if (_confirmingTuto)
+ return false;
+
+ app->captureFade();
+ leave();
+ app->startGame(false, 1);
+ app->fade();
+ return false;
+}
+
+bool MainMenu::onDisabledTuto() {
+ Application *app = g_engine->getApplication();
+ app->setTutoActivated(false);
+ g_engine->getGame()->_firstInventory = false;
+ app->captureFade();
+ leave();
+ app->startGame(true, 1);
+ app->fade();
+ return false;
+}
+
+bool MainMenu::onEnterGameRotateAnimFinished() {
+ error("TODO: Implement MainMenu function");
+}
+
+bool MainMenu::onGalleryButtonValidated() {
+ error("TODO: Implement MainMenu function");
+}
+
+bool MainMenu::onHowToButtonValidated() {
+ onContinueGameButtonValidated();
+ _confirmingTuto = false;
+ return false;
+}
+
+bool MainMenu::onLoadGameButtonValidated() {
+ g_engine->loadGameDialog();
+ return false;
+}
+
+bool MainMenu::onNewGameButtonValidated() {
+ // Note: Original confirms whether to start new game here
+ // with "menus/confirm/confirmNewGame.lua"
+ // because only one save is allowed. We just clear last
+ // save slot number and go ahead and start.
+ ConfMan.set(LAST_SAVE_CONF, "");
+ onNewGameConfirmed();
+ return false;
+}
+
+bool MainMenu::onNewGameConfirmed() {
+ // Note: Original game deletes saves here. Don't do that..
+ _confirmingTuto = true;
+ _tutoConfirm.enter("menus/confirm/confirmTuto.lua", "");
+ onContinueGameButtonValidated();
+ return false;
+}
+
+bool MainMenu::onOptionsButtonValidated() {
+ g_engine->openConfigDialog();
+ return true;
+}
+
+bool MainMenu::onQuit() {
+ g_engine->quitGame();
+ leave();
+ return false;
+}
+
+bool MainMenu::onQuitButtonValidated() {
+ //Confirm::enter("menus/confirm/confirmQuit.lua", "");
+ error("TODO: Implement MainMenu::onQuitButtonValidated");
+}
+
+bool MainMenu::onUnlockGameButtonValidated() {
+ error("TODO: Implement MainMenu::onUnlockGameButtonValidated");
+}
+
+void MainMenu::refresh() {
+ // TODO: get a real value
+ bool haveSave = false;
+ TeButtonLayout *continueGameButton = buttonLayout("continueGameButton");
+ if (continueGameButton) {
+ continueGameButton->setEnable(haveSave);
+ }
+}
+
+void MainMenu::setCenterButtonsVisibility(bool visible) {
+ bool haveSave = false;
+
+ TeButtonLayout *continuegameunlockButton = buttonLayout("continuegameunlockButton");
+ if (continuegameunlockButton) {
+ continuegameunlockButton->setVisible(haveSave & visible);
+ }
+
+ TeButtonLayout *newGameUnlockButton = buttonLayout("newgameunlockButton");
+ if (newGameUnlockButton) {
+ newGameUnlockButton->setVisible(visible & !haveSave);
+ }
+
+ TeButtonLayout *unlockgameButton = buttonLayout("unlockgameButton");
+ if (unlockgameButton) {
+ unlockgameButton->setVisible(false);
+ }
+
+ TeLayout *rateItButton = layout("rateItButton");
+ if (rateItButton) {
+ rateItButton->setVisible(false);
+ }
+}
+
+
+
+} // end namespace Tetraedge
diff --git a/engines/tetraedge/game/main_menu.h b/engines/tetraedge/game/main_menu.h
new file mode 100644
index 00000000000..4d256465c89
--- /dev/null
+++ b/engines/tetraedge/game/main_menu.h
@@ -0,0 +1,85 @@
+/* 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 TETRAEDGE_GAME_MAIN_MENU_H
+#define TETRAEDGE_GAME_MAIN_MENU_H
+
+#include "common/str.h"
+#include "tetraedge/game/confirm.h"
+#include "tetraedge/te/te_signal.h"
+
+namespace Tetraedge {
+
+class MainMenu : public TeLuaGUI {
+public:
+ MainMenu();
+
+ void enter() override;
+ void leave() override;
+
+ bool deleteFile(const Common::String &name);
+ bool onActivedTuto();
+ bool onBFGFreeGamesButtonValidated() { return false; }
+ bool onBFGRateIt2ButtonValidated();
+ bool onBFGRateItButtonValidated();
+ bool onBFGRateItQuitButtonValidated();
+ bool onBFGSplashButtonUpdated() { return false; }
+ bool onBFGSplashButtonValidated() { return false; }
+ bool onBFGTellAFriendButtonValidated() { return false; }
+ bool onBFGUnlockGameButtonValidated();
+ bool onContinueGameButtonValidated();
+ bool onDisabledTuto();
+ bool onEnterGameRotateAnimFinished();
+ bool onFacebookButtonValidated() { return false; }
+ bool onFacebookLogged() { return false; }
+ bool onGalleryButtonValidated();
+ bool onHowToButtonValidated();
+ bool onLoadGameButtonValidated();
+ bool onNewGameButtonValidated();
+ bool onNewGameConfirmed();
+ bool onOptionsButtonValidated();
+ bool onQuit();
+ bool onQuitButtonValidated();
+ bool onUnlockGameButtonValidated();
+ bool onWalkThroughButtonValidated() { return false; };
+
+ void refresh();
+ void setCenterButtonsVisibility(bool visible);
+
+private:
+
+ void tryDisableButton(const Common::String &btnName);
+
+ Confirm _newGameConfirm;
+ Confirm _tutoConfirm;
+ Confirm _quitConfirm;
+
+ // TODO add private members
+ TeSignal0Param onFacebookLoggedSignal;
+
+ bool _entered;
+ bool _confirmingTuto;
+
+};
+
+} // end namespace Tetraedge
+
+#endif // TETRAEDGE_GAME_MAIN_MENU_H
diff --git a/engines/tetraedge/game/notifier.cpp b/engines/tetraedge/game/notifier.cpp
new file mode 100644
index 00000000000..9e1533b5b17
--- /dev/null
+++ b/engines/tetraedge/game/notifier.cpp
@@ -0,0 +1,86 @@
+/* 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 "tetraedge/tetraedge.h"
+#include "tetraedge/game/game.h"
+#include "tetraedge/game/notifier.h"
+#include "tetraedge/te/te_layout.h"
+
+namespace Tetraedge {
+
+Notifier::Notifier() {
+}
+
+void Notifier::launchNextnotifier() {
+ TeCurveAnim2<Te3DObject2, TeColor> *fadeInAnim = _gui.colorLinearAnimation("fadeIn");
+ if (fadeInAnim->_runTimer._stopped) {
+ warning("TODO: Implement Notifier::launchNextnotifier");
+ }
+}
+
+void Notifier::load() {
+ _gui.load("menus/Notifier.lua");
+ TeLayout *notifierLayout = _gui.layout("notifier");
+ Game *game = g_engine->getGame();
+ game->addNoScale2Child(notifierLayout);
+ notifierLayout->setVisible(false);
+
+ TeCurveAnim2<Te3DObject2, TeColor> *fadeIn = _gui.colorLinearAnimation("fadeIn");
+ fadeIn->onFinished().add(this, &Notifier::onFadeInFinished);
+
+ TeCurveAnim2<Te3DObject2, TeColor> *visible = _gui.colorLinearAnimation("visible");
+ visible->onFinished().add(this, &Notifier::onVisibleFinished);
+
+ TeCurveAnim2<Te3DObject2, TeColor> *fadeOut = _gui.colorLinearAnimation("fadeOut");
+ fadeOut->onFinished().add(this, &Notifier::onFadeOutFinished);
+}
+
+bool Notifier::onFadeInFinished() {
+ //TeCurveAnim2<Te3DObject2, TeColor> *visible = _gui.colorLinearAnimation("visible");
+ error("TODO: Implement me.");
+}
+
+bool Notifier::onFadeOutFinished() {
+ TeLayout *notifierLayout = _gui.layout("notifier");
+ notifierLayout->setVisible(false);
+ launchNextnotifier();
+ return false;
+}
+
+bool Notifier::onVisibleFinished() {
+ error("TODO: Implement me.");
+}
+
+void Notifier::push(const Common::String &name, const Common::String &imgpath) {
+ notifierData n = {name, imgpath};
+ _notifierDataArray.push_back(n);
+ launchNextnotifier();
+}
+
+void Notifier::unload() {
+ TeLayout *layout = _gui.layout("notifier");
+ g_engine->getGame()->removeNoScale2Child(layout);
+ _gui.unload();
+}
+
+
+
+} // end namespace Tetraedge
diff --git a/engines/tetraedge/game/notifier.h b/engines/tetraedge/game/notifier.h
new file mode 100644
index 00000000000..b277f907ead
--- /dev/null
+++ b/engines/tetraedge/game/notifier.h
@@ -0,0 +1,57 @@
+/* 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 TETRAEDGE_GAME_NOTIFIER_H
+#define TETRAEDGE_GAME_NOTIFIER_H
+
+#include "common/str.h"
+
+namespace Tetraedge {
+
+class Notifier {
+public:
+ Notifier();
+
+ void launchNextnotifier();
+ void load();
+ bool onFadeInFinished();
+ bool onFadeOutFinished();
+ bool onVisibleFinished();
+
+ void push(const Common::String &name, const Common::String &imgpath);
+ void unload();
+
+ TeLuaGUI &gui() { return _gui; }
+
+private:
+ struct notifierData {
+ Common::String name;
+ Common::String imgpath;
+ };
+ Common::Array<notifierData> _notifierDataArray;
+ TeLuaGUI _gui;
+ // TODO add private members
+
+};
+
+} // end namespace Tetraedge
+
+#endif // TETRAEDGE_GAME_NOTIFIER_H
diff --git a/engines/tetraedge/game/object3d.cpp b/engines/tetraedge/game/object3d.cpp
new file mode 100644
index 00000000000..eb95daa4d34
--- /dev/null
+++ b/engines/tetraedge/game/object3d.cpp
@@ -0,0 +1,58 @@
+/* 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/textconsole.h"
+#include "tetraedge/game/object3d.h"
+#include "tetraedge/game/object_settings_xml_parser.h"
+
+namespace Tetraedge {
+
+/*static*/ Common::HashMap<Common::String, Object3D::ObjectSettings> *Object3D::_objectSettings = nullptr;
+
+
+Object3D::Object3D() {
+}
+
+/*static*/ bool Object3D::loadSettings(const Common::String &path) {
+ ObjectSettingsXmlParser parser;
+ parser.setAllowText();
+
+ if (_objectSettings)
+ delete _objectSettings;
+ _objectSettings = new Common::HashMap<Common::String, ObjectSettings>();
+ parser.setObjectSettings(_objectSettings);
+
+ if (!parser.loadFile(path))
+ error("Object3D::loadSettings: Can't load %s", path.c_str());
+ if (!parser.parse())
+ error("Object3D::loadSettings: Can't parse %s", path.c_str());
+
+ return false;
+}
+
+void Object3D::ObjectSettings::clear() {
+ _name.clear();
+ _modelFileName.clear();
+ _defaultScale = TeVector3f32();
+}
+
+
+} // end namespace Tetraedge
diff --git a/engines/tetraedge/game/object3d.h b/engines/tetraedge/game/object3d.h
new file mode 100644
index 00000000000..ae248fd581a
--- /dev/null
+++ b/engines/tetraedge/game/object3d.h
@@ -0,0 +1,60 @@
+/* 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 TETRAEDGE_GAME_OBJECT3D_H
+#define TETRAEDGE_GAME_OBJECT3D_H
+
+#include "common/str.h"
+#include "common/hashmap.h"
+
+#include "tetraedge/te/te_object.h"
+#include "tetraedge/te/te_model.h"
+#include "tetraedge/te/te_vector3f32.h"
+
+namespace Tetraedge {
+
+class Object3D : public TeObject {
+public:
+ struct ObjectSettings {
+ Common::String _name;
+ Common::String _modelFileName;
+ TeVector3f32 _defaultScale;
+
+ void clear();
+ };
+
+ Object3D();
+
+ bool loadModel(const Common::String &name);
+
+ static bool loadSettings(const Common::String &path);
+
+private:
+ static Common::HashMap<Common::String, ObjectSettings> *_objectSettings;
+
+ TeIntrusivePtr<TeModel> _modelPtr;
+ Common::String _modelFileName;
+ TeVector3f32 _defaultScale;
+};
+
+} // end namespace Tetraedge
+
+#endif // TETRAEDGE_GAME_OBJECT3D_H
diff --git a/engines/tetraedge/game/object_settings_xml_parser.cpp b/engines/tetraedge/game/object_settings_xml_parser.cpp
new file mode 100644
index 00000000000..906978068a1
--- /dev/null
+++ b/engines/tetraedge/game/object_settings_xml_parser.cpp
@@ -0,0 +1,63 @@
+/* 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 "tetraedge/game/object_settings_xml_parser.h"
+
+namespace Tetraedge {
+
+bool ObjectSettingsXmlParser::parserCallback_ObjectsSettings(ParserNode *node) {
+ // Nothing to do, data handled in the child keys.
+ return true;
+}
+
+bool ObjectSettingsXmlParser::parserCallback_Object(ParserNode *node) {
+ const Common::String &objname = node->values["name"];
+ _curObject._name = objname;
+ _objectSettings->setVal(objname, _curObject);
+ _curObject.clear();
+ return true;
+}
+
+bool ObjectSettingsXmlParser::parserCallback_modelFileName(ParserNode *node) {
+ _textTagType = TagModelFileName;
+ return true;
+}
+
+bool ObjectSettingsXmlParser::parserCallback_defaultScale(ParserNode *node) {
+ _textTagType = TagDefaultScale;
+ return true;
+}
+
+bool ObjectSettingsXmlParser::textCallback(const Common::String &val) {
+ switch (_textTagType) {
+ case TagModelFileName:
+ _curObject._modelFileName = val;
+ break;
+ case TagDefaultScale:
+ _curObject._defaultScale.parse(val);
+ break;
+ default:
+ error("should only see text for model file name or scale");
+ }
+ return true;
+}
+
+} // end namespace Tetraedge
diff --git a/engines/tetraedge/game/object_settings_xml_parser.h b/engines/tetraedge/game/object_settings_xml_parser.h
new file mode 100644
index 00000000000..c759156018b
--- /dev/null
+++ b/engines/tetraedge/game/object_settings_xml_parser.h
@@ -0,0 +1,70 @@
+/* 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 TETRAEDGE_GAME_OBJECT_SETTINGS_XML_PARSER_H
+#define TETRAEDGE_GAME_OBJECT_SETTINGS_XML_PARSER_H
+
+#include "common/xmlparser.h"
+#include "tetraedge/game/object3d.h"
+#include "tetraedge/te/te_vector3f32.h"
+
+namespace Tetraedge {
+
+class ObjectSettingsXmlParser : public Common::XMLParser {
+public:
+ void setObjectSettings(Common::HashMap<Common::String, Object3D::ObjectSettings> *settings) {
+ _objectSettings = settings;
+ }
+
+ // Parser
+ CUSTOM_XML_PARSER(ObjectSettingsXmlParser) {
+ XML_KEY(ObjectsSettings)
+ XML_KEY(Object)
+ XML_PROP(name, true)
+ XML_KEY(modelFileName)
+ KEY_END()
+ XML_KEY(defaultScale)
+ KEY_END()
+ KEY_END()
+ KEY_END()
+ } PARSER_END()
+
+ // Parser callback methods
+ bool parserCallback_ObjectsSettings(ParserNode *node);
+ bool parserCallback_Object(ParserNode *node);
+ bool parserCallback_modelFileName(ParserNode *node);
+ bool parserCallback_defaultScale(ParserNode *node);
+ bool textCallback(const Common::String &val) override;
+
+private:
+ enum TextTagType {
+ TagModelFileName,
+ TagDefaultScale
+ };
+
+ TextTagType _textTagType;
+ Object3D::ObjectSettings _curObject;
+ Common::HashMap<Common::String, Object3D::ObjectSettings> *_objectSettings;
+};
+
+} // end namespace Tetraedge
+
+#endif // TETRAEDGE_GAME_OBJECT_SETTINGS_XML_PARSER_H
diff --git a/engines/tetraedge/game/objectif.cpp b/engines/tetraedge/game/objectif.cpp
new file mode 100644
index 00000000000..825042955f1
--- /dev/null
+++ b/engines/tetraedge/game/objectif.cpp
@@ -0,0 +1,213 @@
+/* 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/textconsole.h"
+
+#include "tetraedge/tetraedge.h"
+#include "tetraedge/game/application.h"
+#include "tetraedge/game/game.h"
+#include "tetraedge/game/objectif.h"
+#include "tetraedge/te/te_vector2f32.h"
+
+namespace Tetraedge {
+
+/*static*/
+bool Objectif::_layoutsDirty = false;
+
+Objectif::Objectif() : _helpButtonVisible(false) {
+}
+
+void Objectif::enter() {
+ _gui1.buttonLayoutChecked("helpButton")->setVisible(true);
+ _helpButtonVisible = true;
+}
+
+bool Objectif::isMouseIn(const TeVector2s32 &mousept) {
+ TeLayout *bg = _gui1.layoutChecked("background");
+ if (bg->visible()) {
+ TeLayout *calepin = _gui1.layoutChecked("Calepin");
+ if (calepin->isMouseIn(mousept))
+ return true;
+ // otherwise check the helpButton
+ }
+ TeButtonLayout *btn = _gui2.buttonLayoutChecked("helpButton");
+ if (btn->visible())
+ return btn->isMouseIn(mousept);
+ return false;
+}
+
+void Objectif::load() {
+ Application *app = g_engine->getApplication();
+ _gui1.load("menus/objectif.lua");
+ _gui2.load("menus/helpButton.lua");
+
+ TeButtonLayout *btn = _gui2.buttonLayoutChecked("helpButton");
+ app->_frontLayout.addChild(btn);
+ btn->setVisible(true);
+ _helpButtonVisible = true;
+ btn->onMouseClickValidated().add(this, &Objectif::onHelpButtonValidated);
+
+ btn = _gui1.buttonLayoutChecked("helpQuit");
+ btn->onMouseClickValidated().add(this, &Objectif::onHelpButtonValidated);
+
+ _gui1.buttonLayoutChecked("background")->setVisible(false);
+
+ _gui2.spriteLayoutChecked("newUp")->setVisible(false);
+ _gui2.spriteLayoutChecked("newDown")->setVisible(false);
+ _gui2.spriteLayoutChecked("notNewUp")->setVisible(true);
+ _gui2.spriteLayoutChecked("notNewDown")->setVisible(true);
+
+ _layoutsDirty = true;
+}
+
+void Objectif::leave() {
+ TeLayout *layout;
+ layout = _gui1.layout("background");
+ if (layout)
+ layout->setVisible(false);
+ layout = _gui2.layout("helpButton");
+ if (layout) {
+ layout->setVisible(false);
+ _helpButtonVisible = false;
+ }
+}
+
+bool Objectif::onHelpButtonValidated() {
+ if (!_helpButtonVisible) {
+ _gui1.buttonLayoutChecked("background")->setVisible(false);
+ _gui2.buttonLayoutChecked("helpButton")->setVisible(true);
+ _helpButtonVisible = true;
+ } else {
+ _gui1.buttonLayoutChecked("background")->setVisible(true);
+ _gui2.spriteLayoutChecked("newUp")->setVisible(false);
+ _gui2.spriteLayoutChecked("newDown")->setVisible(false);
+ _gui2.spriteLayoutChecked("notNewUp")->setVisible(true);
+ _gui2.spriteLayoutChecked("notNewUp")->setVisible(true);
+ _gui2.spriteLayoutChecked("helpButton")->setVisible(false);
+ _helpButtonVisible = false;
+ }
+ return false;
+}
+
+void Objectif::reattachLayout(TeLayout *layout) {
+ TeButtonLayout *btn;
+
+ btn = _gui1.buttonLayout("background");
+ if (btn) {
+ layout->removeChild(btn);
+ layout->addChild(btn);
+ }
+
+ btn = _gui2.buttonLayout("helpButton");
+ if (btn) {
+ layout->removeChild(btn);
+ layout->addChild(btn);
+ }
+}
+
+void Objectif::removeChildren() {
+ TeLayout *tasks = _gui1.layoutChecked("tasks");
+ while (tasks->childCount()) {
+ Te3DObject2 *child = tasks->child(0);
+ TeTextLayout *text = dynamic_cast<TeTextLayout*>(child);
+ tasks->removeChild(child);
+ if (text)
+ delete text;
+ }
+ _layoutsDirty = true;
+}
+
+void Objectif::update() {
+ Game *game = g_engine->getGame();
+ game->luaScript().execute("UpdateHelp");
+ if (_layoutsDirty) {
+ TeLayout *tasks = _gui1.layoutChecked("tasks");
+ removeChildren();
+
+ int last_i = -1;
+ for (unsigned int i = 0; i < _tasks.size(); i++) {
+ if (!_tasks[i]._taskFlag)
+ continue;
+ if (last_i != -1 && _tasks[i]._headTask == _tasks[last_i]._headTask)
+ continue;
+ last_i = i;
+ createChildLayout(tasks, _tasks[i]._headTask, false);
+ // Creating the subtasks for this head
+ for (unsigned int j = 0; j < _tasks.size(); j++) {
+ if (_tasks[j]._taskFlag && _tasks[j]._headTask == _tasks[i]._headTask && _tasks[j]._subTask != "")
+ createChildLayout(tasks, _tasks[j]._subTask, true);
+ }
+ }
+
+ warning("TODO: Finish main part of Objectif::update");
+ }
+ _layoutsDirty = false;
+}
+
+void Objectif::createChildLayout(TeLayout *layout, Common::String const &taskId, bool isSubTask) {
+ TeTextLayout *text = new TeTextLayout();
+ text->setName(taskId);
+ text->setAnchor(TeVector3f32(0.0f, 0.0f, 0.0f));
+ text->setPositionType(TeILayout::RELATIVE_TO_PARENT);
+ text->setSizeType(TeILayout::RELATIVE_TO_PARENT);
+ Application *app = g_engine->getApplication();
+ // No help at difficulty 2.
+ if (app->difficulty() != 2) {
+ Common::String textVal;
+ if (!isSubTask) {
+ text->setSize(TeVector3f32(0.8f, 1.0f, 0.1f));
+ text->setPosition(TeVector3f32(0.1f, 0.0f, 0.1f));
+ textVal = "<section style=\"left\" /><color r=\"39\" g=\"85\" b=\"97\"/><font file=\"Common/Fonts/ComicRelief.ttf\" size=\"12\"/>";
+ } else {
+ text->setSize(TeVector3f32(0.75f, 1.0f, 0.1f));
+ text->setPosition(TeVector3f32(0.15f, 0.0f, 0.1f));
+ if (app->difficulty() == 0) {
+ textVal = "<section style=\"left\" /><color r=\"0\" g=\"0\" b=\"0\"/><font file=\"Common/Fonts/ComicRelief.ttf\" size=\"12\"/>\t";
+ } else {
+ textVal = "<section style=\"left\" /><color r=\"0\" g=\"0\" b=\"0\"/><font file=\"Common/Fonts/arial.ttf\" size=\"16\"/>";
+ }
+ }
+ textVal += app->getHelpText(taskId);
+ text->setText(textVal);
+ }
+
+ layout->addChild(text);
+}
+
+
+void Objectif::unload() {
+ removeChildren();
+ leave();
+ _gui1.unload();
+ _gui2.unload();
+ _tasks.clear();
+}
+
+void Objectif::setVisibleButtonHelp(bool visible) {
+ _gui2.buttonLayoutChecked("helpButton")->setVisible(visible);
+ _helpButtonVisible = visible;
+}
+
+void Objectif::setVisibleObjectif(bool visible) {
+ _gui1.buttonLayoutChecked("background")->setVisible(visible);
+}
+
+} // end namespace Tetraedge
diff --git a/engines/tetraedge/game/objectif.h b/engines/tetraedge/game/objectif.h
new file mode 100644
index 00000000000..2584462d2fe
--- /dev/null
+++ b/engines/tetraedge/game/objectif.h
@@ -0,0 +1,70 @@
+/* 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 TETRAEDGE_GAME_OBJECTIF_H
+#define TETRAEDGE_GAME_OBJECTIF_H
+
+#include "tetraedge/te/te_vector2f32.h"
+#include "tetraedge/te/te_lua_gui.h"
+
+namespace Tetraedge {
+
+class Objectif {
+public:
+ struct Task {
+ Common::String _headTask;
+ Common::String _subTask;
+ bool _taskFlag;
+ };
+
+ Objectif();
+
+ void createChildLayout(TeLayout *layout, Common::String const &taskId, bool isSubTask);
+ void enter();
+ bool hideBouton();
+ bool isMouseIn(const TeVector2s32 &mousept);
+ bool isVisibleObjectif();
+ void leave();
+ void load();
+ bool onHelpButtonValidated();
+ void reattachLayout(TeLayout *layout);
+ void removeChildren();
+ // void save()
+ void setVisibleButtonHelp(bool visible);
+ void setVisibleObjectif(bool visible);
+ // TODO add public members
+ void unload();
+ void update();
+
+ TeLuaGUI &gui1() { return _gui1; }
+
+private:
+ TeLuaGUI _gui1;
+ TeLuaGUI _gui2;
+ Common::Array<Task> _tasks;
+ bool _helpButtonVisible;
+
+ static bool _layoutsDirty;
+};
+
+} // end namespace Tetraedge
+
+#endif // TETRAEDGE_GAME_OBJECTIF_H
diff --git a/engines/tetraedge/game/options_menu.cpp b/engines/tetraedge/game/options_menu.cpp
new file mode 100644
index 00000000000..904445178e9
--- /dev/null
+++ b/engines/tetraedge/game/options_menu.cpp
@@ -0,0 +1,39 @@
+/* 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 "tetraedge/game/options_menu.h"
+
+namespace Tetraedge {
+
+OptionsMenu::OptionsMenu() {
+}
+
+void OptionsMenu::enter() {
+
+}
+
+void OptionsMenu::leave() {
+
+}
+
+// TODO: Add more functions here.
+
+} // end namespace Tetraedge
diff --git a/engines/tetraedge/game/options_menu.h b/engines/tetraedge/game/options_menu.h
new file mode 100644
index 00000000000..075e24bf7c4
--- /dev/null
+++ b/engines/tetraedge/game/options_menu.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 TETRAEDGE_GAME_OPTIONS_MENU_H
+#define TETRAEDGE_GAME_OPTIONS_MENU_H
+
+#include "tetraedge/te/te_lua_gui.h"
+#include "tetraedge/te/te_music.h"
+
+namespace Tetraedge {
+
+class OptionsMenu : public TeLuaGUI {
+public:
+ OptionsMenu();
+
+ void enter() override;
+ void leave() override;
+
+ bool onCloseTuto();
+ bool onCreditsButton();
+ bool onDialogVolumeMinusButton();
+ bool onDialogVolumePlusButton();
+ bool onMusicVolumeMinusButton();
+ bool onMusicVolumePlusButton();
+ bool onPrivacyPolicyButton();
+ bool onQuitButton();
+ bool onSFXVolumeMinusButton();
+ bool onSFXVolumePlusButton();
+ bool onSupportButton();
+ bool onTermsOfServiceButton();
+ bool onVideoVolumeMinusButton();
+ bool onVideoVolumePlusButton();
+ bool onVisibleTuto();
+ bool onVisibleTutoNextPage();
+
+ void updateDialogVolumeJauge();
+ void updateMusicVolumeJauge();
+ void updateSFXVolumeJauge();
+ void updateVideoVolumeJauge();
+
+private:
+
+ // TODO: work out virtual thing here TeLuaGUI _gui2;
+
+ TeMusic _music1;
+ TeMusic _music2;
+};
+
+} // end namespace Tetraedge
+
+#endif // TETRAEDGE_GAME_OPTIONS_MENU_H
diff --git a/engines/tetraedge/game/owner_error_menu.cpp b/engines/tetraedge/game/owner_error_menu.cpp
new file mode 100644
index 00000000000..52aef50351d
--- /dev/null
+++ b/engines/tetraedge/game/owner_error_menu.cpp
@@ -0,0 +1,53 @@
+/* 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/path.h"
+#include "tetraedge/tetraedge.h"
+#include "tetraedge/game/application.h"
+#include "tetraedge/game/owner_error_menu.h"
+
+namespace Tetraedge {
+
+OwnerErrorMenu::OwnerErrorMenu() : _entered(false) {
+}
+
+void OwnerErrorMenu::enter() {
+ _entered = true;
+ static const Common::Path luaPath("menus/ownerError/ownerError.lua");
+ load(luaPath.toString());
+ error("TODO: Finish implementation of OwnerErrorMenu::enter");
+ /*
+ Application *app = g_engine->getApplication();
+ TeLayout *menuLayout = TeLuaGUI::layout("menu");
+ ...
+ */
+}
+
+void OwnerErrorMenu::leave() {
+ Application *app = g_engine->getApplication();
+ app->captureFade();
+ TeLuaGUI::unload();
+ _entered = false;
+ app->mainMenu().enter();
+ app->fade();
+}
+
+} // end namespace Tetraedge
diff --git a/engines/tetraedge/game/owner_error_menu.h b/engines/tetraedge/game/owner_error_menu.h
new file mode 100644
index 00000000000..f935bb013da
--- /dev/null
+++ b/engines/tetraedge/game/owner_error_menu.h
@@ -0,0 +1,42 @@
+/* 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 TETRAEDGE_GAME_OWNER_ERROR_MENU_H
+#define TETRAEDGE_GAME_OWNER_ERROR_MENU_H
+
+#include "tetraedge/te/te_lua_gui.h"
+
+namespace Tetraedge {
+
+class OwnerErrorMenu : public TeLuaGUI {
+public:
+ OwnerErrorMenu();
+
+ void enter() override;
+ void leave() override;
+
+private:
+ bool _entered;
+};
+
+} // end namespace Tetraedge
+
+#endif // TETRAEDGE_GAME_OWNER_ERROR_MENU_H
diff --git a/engines/tetraedge/game/question2.cpp b/engines/tetraedge/game/question2.cpp
new file mode 100644
index 00000000000..fbc55be9189
--- /dev/null
+++ b/engines/tetraedge/game/question2.cpp
@@ -0,0 +1,156 @@
+/* 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 "tetraedge/game/application.h"
+#include "tetraedge/game/question2.h"
+#include "tetraedge/game/game.h"
+#include "tetraedge/tetraedge.h"
+
+namespace Tetraedge {
+
+Question2::Question2() {
+}
+
+Question2::~Question2() {
+ // Should have been cleared in leave() but just in case..
+ for (Answer *answer : _answers) {
+ delete answer;
+ }
+}
+
+void Question2::enter() {
+ TeButtonLayout *backgroundButton = _gui.buttonLayout("background");
+ if (backgroundButton)
+ backgroundButton->setVisible(true);
+ g_engine->getGame()->showMarkers(true);
+}
+
+void Question2::leave() {
+ TeLayout *background = _gui.layout("background");
+ if (!background)
+ return;
+
+ background->setVisible(false);
+
+ TeSpriteLayout *calepinLayout = _gui.spriteLayout("Calepin");
+ if (!calepinLayout)
+ error("Question2::leave: can't find Calepin.");
+
+ for (Answer *answer : _answers) {
+ TeLayout *alayout = answer->layout();
+ if (alayout == nullptr)
+ continue;
+ calepinLayout->removeChild(alayout);
+ answer->unload();
+ // TODO: original uses TeObject::deleteLater here.. should we
+ // do the same? why defer it?
+ delete answer;
+ }
+ _answers.clear();
+}
+
+void Question2::load() {
+ setName("dialog2");
+ setSizeType(RELATIVE_TO_PARENT);
+ const TeVector3f32 usersz = userSize();
+ setSize(TeVector3f32(1.0, 1.0, usersz.z()));
+ _gui.load("menus/answer.lua");
+
+ TeButtonLayout *backgroundButton = _gui.buttonLayout("background");
+ if (backgroundButton) {
+ addChild(backgroundButton);
+ backgroundButton->setVisible(false);
+ }
+}
+
+bool Question2::onAnswerValidated(Answer &answer) {
+ _onAnswerSignal.call(answer._str);
+ g_engine->getGame()->showMarkers(false);
+ leave();
+ return false;
+}
+
+void Question2::pushAnswer(const Common::String &name, const Common::String &unk, const Common::String &path) {
+ Answer *answer = new Answer();
+ answer->load(name, unk, path);
+ answer->_onButtonValidatedSignal.add(this, &Question2::onAnswerValidated);
+ TeLayout *alayout = answer->layout();
+ if (!alayout)
+ error("No Answer layout after loading %s!", path.c_str());
+ TeButtonLayout *blayout = dynamic_cast<TeButtonLayout *>(alayout);
+ if (!blayout)
+ error("No Answer button layout after loading %s!", path.c_str());
+
+ blayout->setState(TeButtonLayout::BUTTON_STATE_UP);
+ _answers.push_back(answer);
+
+ float xpos;
+ blayout->setPositionType(RELATIVE_TO_PARENT);
+ if (!path.contains("Cal_FIN.lua")) {
+ setSize(TeVector3f32(0.45f, 0.065f, 1.0f));
+ xpos = 0.3f;
+ } else {
+ setSize(TeVector3f32(0.15f, 0.065f, 1.0f));
+ xpos = 0.15f;
+ }
+ setPosition(TeVector3f32(xpos, _answers.size() * 0.08f + 0.06f, 1.0f));
+
+ blayout->_upLayout->setSizeType(RELATIVE_TO_PARENT);
+ blayout->_upLayout->setSize(TeVector3f32(1.0f, 1.0f, 1.0f));
+ blayout->_downLayout->setSizeType(RELATIVE_TO_PARENT);
+ blayout->_downLayout->setSize(TeVector3f32(1.0f, 1.0f, 1.0f));
+
+ TeSpriteLayout *calepinLayout = _gui.spriteLayout("Calepin");
+ if (calepinLayout)
+ calepinLayout->setParent(alayout);
+
+ enter();
+}
+
+void Question2::unload() {
+ leave();
+ _gui.unload();
+}
+
+TeLayout *Question2::Answer::layout() {
+ return _gui.layout("answer");
+}
+
+void Question2::Answer::load(const Common::String &name, const Common::String &unk, const Common::String &path) {
+ _str = name;
+ _gui.load(path);
+ TeButtonLayout *answerButton = _gui.buttonLayout("answer");
+ if (answerButton) {
+ answerButton->onMouseClickValidated().add(this, &Question2::Answer::onButtonValidated);
+ answerButton->_someClickFlag = false;
+ }
+}
+
+void Question2::Answer::unload() {
+ _gui.unload();
+}
+
+bool Question2::Answer::onButtonValidated() {
+ _onButtonValidatedSignal.call(*this);
+ return false;
+}
+
+} // end namespace Tetraedge
diff --git a/engines/tetraedge/game/question2.h b/engines/tetraedge/game/question2.h
new file mode 100644
index 00000000000..6bf9f408560
--- /dev/null
+++ b/engines/tetraedge/game/question2.h
@@ -0,0 +1,64 @@
+/* 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 TETRAEDGE_GAME_QUESTION2_H
+#define TETRAEDGE_GAME_QUESTION2_H
+
+#include "tetraedge/te/te_lua_gui.h"
+#include "tetraedge/te/te_layout.h"
+
+
+namespace Tetraedge {
+
+class Question2 : public TeLayout {
+public:
+ Question2();
+ ~Question2();
+
+ class Answer {
+ public:
+ TeLayout *layout();
+ void load(const Common::String &name, const Common::String &unk, const Common::String &path);
+ void unload();
+ bool onButtonValidated();
+
+ TeLuaGUI _gui;
+ Common::String _str;
+ TeSignal1Param<Question2::Answer &> _onButtonValidatedSignal;
+ };
+
+ void enter();
+ void leave();
+ void load();
+ bool onAnswerValidated(Answer &answer);
+ void pushAnswer(const Common::String &name, const Common::String &unk, const Common::String &path);
+ void unload();
+
+private:
+ TeLuaGUI _gui;
+ Common::Array<Answer *> _answers;
+ TeSignal1Param<const Common::String &> _onAnswerSignal;
+
+};
+
+} // end namespace Tetraedge
+
+#endif // TETRAEDGE_GAME_QUESTION2_H
diff --git a/engines/tetraedge/game/splash_screens.cpp b/engines/tetraedge/game/splash_screens.cpp
new file mode 100644
index 00000000000..a14519a9b96
--- /dev/null
+++ b/engines/tetraedge/game/splash_screens.cpp
@@ -0,0 +1,95 @@
+/* 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/config-manager.h"
+#include "common/file.h"
+#include "common/path.h"
+
+#include "tetraedge/tetraedge.h"
+#include "tetraedge/game/application.h"
+#include "tetraedge/game/splash_screens.h"
+
+namespace Tetraedge {
+
+SplashScreens::SplashScreens() : _splashNo(0), _entered(false) {
+ _timer.alarmSignal().add(this, &SplashScreens::onAlarm);
+}
+
+void SplashScreens::enter() {
+ if (!_entered) {
+ _entered = true;
+ _splashNo = 0;
+ static const Common::Path scriptPath("menus/splashes/splash0.lua");
+ if (Common::File::exists(scriptPath)) {
+ TeLuaGUI::load(scriptPath.toString());
+ Application *app = g_engine->getApplication();
+ TeLayout *splash = layout("splash");
+ app->_frontLayout.addChild(splash);
+ app->performRender();
+ }
+ onAlarm();
+ }
+}
+
+bool SplashScreens::onAlarm() {
+ Application *app = g_engine->getApplication();
+ app->visualFade().init();
+ app->captureFade();
+ TeLuaGUI::unload();
+ const Common::String scriptName = Common::String::format("menus/splashes/splash%d.lua", _splashNo);
+ _splashNo++;
+
+ if (ConfMan.get("skipsplash") == "true") {
+ onQuitSplash();
+ return true;
+ }
+
+ if (!Common::File::exists(scriptName)) {
+ onQuitSplash();
+ } else {
+ load(scriptName);
+
+ TeButtonLayout *btnLayout = buttonLayout("splash");
+ btnLayout->onMouseClickValidated().add<SplashScreens>(this, &SplashScreens::onQuitSplash);
+
+ TeLayout *splash = layout("splash");
+ app->_frontLayout.addChild(splash);
+
+ _timer.start();
+ _timer.setAlarmIn(1500000);
+ }
+
+ app->fade();
+ return true;
+}
+
+bool SplashScreens::onQuitSplash() {
+ _timer.stop();
+ Application *app = g_engine->getApplication();
+ app->captureFade();
+ TeLuaGUI::unload();
+ _entered = false;
+ app->mainMenu().enter();
+ app->fade();
+ return false;
+}
+
+} // end namespace Tetraedge
diff --git a/engines/tetraedge/game/splash_screens.h b/engines/tetraedge/game/splash_screens.h
new file mode 100644
index 00000000000..b393dca3991
--- /dev/null
+++ b/engines/tetraedge/game/splash_screens.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 TETRAEDGE_GAME_SPLASH_SCREENS_H
+#define TETRAEDGE_GAME_SPLASH_SCREENS_H
+
+#include "tetraedge/te/te_lua_gui.h"
+#include "tetraedge/te/te_timer.h"
+
+namespace Tetraedge {
+
+class SplashScreens : public TeLuaGUI {
+public:
+ SplashScreens();
+
+ void enter() override;
+ void leave() override {
+ _entered = false;
+ }
+
+ bool onAlarm();
+ bool onQuitSplash();
+
+private:
+ bool _entered;
+ TeTimer _timer;
+ int _splashNo;
+};
+
+} // end namespace Tetraedge
+
+#endif // TETRAEDGE_GAME_SPLASH_SCREENS_H
diff --git a/engines/tetraedge/metaengine.cpp b/engines/tetraedge/metaengine.cpp
new file mode 100644
index 00000000000..ea4c2035e6c
--- /dev/null
+++ b/engines/tetraedge/metaengine.cpp
@@ -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/>.
+ *
+ */
+
+#include "tetraedge/metaengine.h"
+#include "tetraedge/detection.h"
+#include "tetraedge/tetraedge.h"
+
+const char *TetraedgeMetaEngine::getName() const {
+ return "tetraedge";
+}
+
+Common::Error TetraedgeMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const {
+ *engine = new Tetraedge::TetraedgeEngine(syst, desc);
+ return Common::kNoError;
+}
+
+bool TetraedgeMetaEngine::hasFeature(MetaEngineFeature f) const {
+ return
+ (f == kSavesUseExtendedFormat) ||
+ (f == kSimpleSavesNames) ||
+ (f == kSupportsListSaves) ||
+ (f == kSupportsDeleteSave) ||
+ (f == kSavesSupportMetaInfo) ||
+ (f == kSavesSupportThumbnail) ||
+ (f == kSupportsLoadingDuringStartup);
+}
+
+#if PLUGIN_ENABLED_DYNAMIC(TETRAEDGE)
+REGISTER_PLUGIN_DYNAMIC(TETRAEDGE, PLUGIN_TYPE_ENGINE, TetraedgeMetaEngine);
+#else
+REGISTER_PLUGIN_STATIC(TETRAEDGE, PLUGIN_TYPE_ENGINE, TetraedgeMetaEngine);
+#endif
diff --git a/engines/tetraedge/metaengine.h b/engines/tetraedge/metaengine.h
new file mode 100644
index 00000000000..13a43c89711
--- /dev/null
+++ b/engines/tetraedge/metaengine.h
@@ -0,0 +1,42 @@
+/* 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 TETRAEDGE_METAENGINE_H
+#define TETRAEDGE_METAENGINE_H
+
+#include "common/achievements.h"
+#include "engines/advancedDetector.h"
+
+class TetraedgeMetaEngine : public AdvancedMetaEngine {
+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;
+};
+
+#endif
diff --git a/engines/tetraedge/module.mk b/engines/tetraedge/module.mk
new file mode 100644
index 00000000000..9873d9ceabf
--- /dev/null
+++ b/engines/tetraedge/module.mk
@@ -0,0 +1,126 @@
+MODULE := engines/tetraedge
+
+MODULE_OBJS := \
+ tetraedge.o \
+ to_lua.o \
+ game/application.o \
+ game/billboard.o \
+ game/bonus_menu.o \
+ game/cellphone.o \
+ game/character.o \
+ game/character_settings_xml_parser.o \
+ game/characters_shadow.o \
+ game/confirm.o \
+ game/credits.o \
+ game/dialog2.o \
+ game/document.o \
+ game/documents_browser.o \
+ game/gallery_menu.o \
+ game/game.o \
+ game/game_achievements.o \
+ game/game_sound.o \
+ game/global_bonus_menu.o \
+ game/help_option_menu.o \
+ game/how_to.o \
+ game/in_game_scene.o \
+ game/inventory.o \
+ game/inventory_menu.o \
+ game/inventory_object.o \
+ game/inventory_objects_xml_parser.o \
+ game/loading_menu.o \
+ game/loc_file.o \
+ game/lua_binds.o \
+ game/main_menu.o \
+ game/notifier.o \
+ game/object3d.o \
+ game/object_settings_xml_parser.o \
+ game/objectif.o \
+ game/options_menu.o \
+ game/owner_error_menu.o \
+ game/question2.o \
+ game/splash_screens.o \
+ te/micropather.o \
+ te/te_3d_object2.o \
+ te/te_3d_texture.o \
+ te/te_animation.o \
+ te/te_bezier_curve.o \
+ te/te_button_layout.o \
+ te/te_camera.o \
+ te/te_checkbox_layout.o \
+ te/te_clip_layout.o \
+ te/te_color.o \
+ te/te_core.o \
+ te/te_extended_text_layout.o \
+ te/te_fee_move_zone.o \
+ te/te_font3.o \
+ te/te_frame_anim.o \
+ te/te_free_move_zone.o \
+ te/te_i_3d_object2.o \
+ te/te_i_layout.o \
+ te/te_i_loc.o \
+ te/te_image.o \
+ te/te_input_mgr.o \
+ te/te_interpolation.o \
+ te/te_jpeg.o \
+ te/te_layout.o \
+ te/te_light.o \
+ te/te_list_layout.o \
+ te/te_lua_context.o \
+ te/te_lua_gui.o \
+ te/te_lua_gui_lua_callbacks.o \
+ te/te_lua_script.o \
+ te/te_lua_thread.o \
+ te/te_material.o \
+ te/te_matricies_stack.o \
+ te/te_matrix4x4.o \
+ te/te_mesh.o \
+ te/te_model.o \
+ te/te_model_animation.o \
+ te/te_model_vertex_animation.o \
+ te/te_music.o \
+ te/te_name_val_xml_parser.o \
+ te/te_object.o \
+ te/te_obp.o \
+ te/te_palette.o \
+ te/te_pick_mesh2.o \
+ te/te_png.o \
+ te/te_quaternion.o \
+ te/te_real_timer.o \
+ te/te_renderer.o \
+ te/te_resource.o \
+ te/te_resource_manager.o \
+ te/te_scene.o \
+ te/te_screen.o \
+ te/te_scrolling_layout.o \
+ te/te_scummvm_codec.o \
+ te/te_sfx.o \
+ te/te_sound_manager.o \
+ te/te_sprite_layout.o \
+ te/te_text_base2.o \
+ te/te_text_layout.o \
+ te/te_text_layout_xml_parser.o \
+ te/te_tga.o \
+ te/te_theora.o \
+ te/te_tiled_surface.o \
+ te/te_tiled_texture.o \
+ te/te_timer.o \
+ te/te_trs.o \
+ te/te_variant.o \
+ te/te_vector2f32.o \
+ te/te_vector2s32.o \
+ te/te_vector3f32.o \
+ te/te_visual_fade.o \
+ te/te_xml_gui.o \
+ console.o \
+ metaengine.o
+
+# This module can be built as a plugin
+ifeq ($(ENABLE_TETRAEDGE), DYNAMIC_PLUGIN)
+PLUGIN := 1
+endif
+
+# Include common rules
+include $(srcdir)/rules.mk
+
+# Detection objects
+DETECT_OBJS += $(MODULE)/detection.o
diff --git a/engines/tetraedge/te/micropather.cpp b/engines/tetraedge/te/micropather.cpp
new file mode 100644
index 00000000000..2e469d6791f
--- /dev/null
+++ b/engines/tetraedge/te/micropather.cpp
@@ -0,0 +1,1101 @@
+/* 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/>.
+ *
+ */
+
+/*
+
+This is a lightly modified version of MicroPather, from
+github.com/leethomason/MicroPather. Modifications were made to fit with
+ScummVM coding style and APIs.
+
+The original copyright message is:
+
+-------
+Copyright (c) 2000-2009 Lee Thomason (www.grinninglizard.com)
+
+Grinning Lizard Utilities.
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any
+damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any
+purpose, including commercial applications, and to alter it and
+redistribute it freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must
+not claim that you wrote the original software. If you use this
+software in a product, an acknowledgment in the product documentation
+would be appreciated but is not required.
+
+2. Altered source versions must be plainly marked as such, and
+must not be misrepresented as being the original software.
+
+3. This notice may not be removed or altered from any source
+distribution.
+*/
+
+#define MPASSERT assert
+
+//#define DEBUG_PATH
+//#define DEBUG_PATH_DEEP
+//#define TRACK_COLLISION
+//#define DEBUG_CACHING
+
+//#ifdef DEBUG_CACHING
+//#include "../grinliz/gldebug.h"
+//#endif
+
+#include "micropather.h"
+
+using namespace Tetraedge::micropather;
+
+class OpenQueue
+{
+ public:
+ OpenQueue( Graph* _graph )
+ {
+ graph = _graph;
+ sentinel = (PathNode*) sentinelMem;
+ sentinel->InitSentinel();
+ #ifdef DEBUG
+ sentinel->CheckList();
+ #endif
+ }
+ ~OpenQueue() {}
+
+ void Push( PathNode* pNode );
+ PathNode* Pop();
+ void Update( PathNode* pNode );
+
+ bool Empty() { return sentinel->next == sentinel; }
+
+ private:
+ OpenQueue( const OpenQueue& ); // undefined and unsupported
+ void operator=( const OpenQueue& );
+
+ PathNode* sentinel;
+ int sentinelMem[ ( sizeof( PathNode ) + sizeof( int ) ) / sizeof( int ) ];
+ Graph* graph; // for debugging
+};
+
+
+void OpenQueue::Push( PathNode* pNode )
+{
+
+ MPASSERT( pNode->inOpen == 0 );
+ MPASSERT( pNode->inClosed == 0 );
+
+#ifdef DEBUG_PATH_DEEP
+ debug( "Open Push: " );
+ graph->PrintStateInfo( pNode->state );
+ debug( " total=%.1f\n", pNode->totalCost );
+#endif
+
+ // Add sorted. Lowest to highest cost path. Note that the sentinel has
+ // a value of FLT_MAX, so it should always be sorted in.
+ MPASSERT( pNode->totalCost < FLT_MAX );
+ PathNode* iter = sentinel->next;
+ while ( true )
+ {
+ if ( pNode->totalCost < iter->totalCost ) {
+ iter->AddBefore( pNode );
+ pNode->inOpen = 1;
+ break;
+ }
+ iter = iter->next;
+ }
+ MPASSERT( pNode->inOpen ); // make sure this was actually added.
+#ifdef DEBUG
+ sentinel->CheckList();
+#endif
+}
+
+PathNode* OpenQueue::Pop()
+{
+ MPASSERT( sentinel->next != sentinel );
+ PathNode* pNode = sentinel->next;
+ pNode->Unlink();
+#ifdef DEBUG
+ sentinel->CheckList();
+#endif
+
+ MPASSERT( pNode->inClosed == 0 );
+ MPASSERT( pNode->inOpen == 1 );
+ pNode->inOpen = 0;
+
+#ifdef DEBUG_PATH_DEEP
+ debug( "Open Pop: " );
+ graph->PrintStateInfo( pNode->state );
+ debug( " total=%.1f\n", pNode->totalCost );
+#endif
+
+ return pNode;
+}
+
+void OpenQueue::Update( PathNode* pNode )
+{
+#ifdef DEBUG_PATH_DEEP
+ debug( "Open Update: " );
+ graph->PrintStateInfo( pNode->state );
+ debug( " total=%.1f\n", pNode->totalCost );
+#endif
+
+ MPASSERT( pNode->inOpen );
+
+ // If the node now cost less than the one before it,
+ // move it to the front of the list.
+ if ( pNode->prev != sentinel && pNode->totalCost < pNode->prev->totalCost ) {
+ pNode->Unlink();
+ sentinel->next->AddBefore( pNode );
+ }
+
+ // If the node is too high, move to the right.
+ if ( pNode->totalCost > pNode->next->totalCost ) {
+ PathNode* it = pNode->next;
+ pNode->Unlink();
+
+ while ( pNode->totalCost > it->totalCost )
+ it = it->next;
+
+ it->AddBefore( pNode );
+#ifdef DEBUG
+ sentinel->CheckList();
+#endif
+ }
+}
+
+
+class ClosedSet
+{
+ public:
+ ClosedSet( Graph* _graph ) { this->graph = _graph; }
+ ~ClosedSet() {}
+
+ void Add( PathNode* pNode )
+ {
+ #ifdef DEBUG_PATH_DEEP
+ debug( "Closed add: " );
+ graph->PrintStateInfo( pNode->state );
+ debug( " total=%.1f\n", pNode->totalCost );
+ #endif
+ #ifdef DEBUG
+ MPASSERT( pNode->inClosed == 0 );
+ MPASSERT( pNode->inOpen == 0 );
+ #endif
+ pNode->inClosed = 1;
+ }
+
+ void Remove( PathNode* pNode )
+ {
+ #ifdef DEBUG_PATH_DEEP
+ debug( "Closed remove: " );
+ graph->PrintStateInfo( pNode->state );
+ debug( " total=%.1f\n", pNode->totalCost );
+ #endif
+ MPASSERT( pNode->inClosed == 1 );
+ MPASSERT( pNode->inOpen == 0 );
+
+ pNode->inClosed = 0;
+ }
+
+ private:
+ ClosedSet( const ClosedSet& );
+ void operator=( const ClosedSet& );
+ Graph* graph;
+};
+
+
+PathNodePool::PathNodePool( unsigned _allocate, unsigned _typicalAdjacent )
+ : firstBlock( 0 ),
+ blocks( 0 ),
+#if defined( MICROPATHER_STRESS )
+ allocate( 32 ),
+#else
+ allocate( _allocate ),
+#endif
+ nAllocated( 0 ),
+ nAvailable( 0 )
+{
+ freeMemSentinel.InitSentinel();
+
+ cacheCap = allocate * _typicalAdjacent;
+ cacheSize = 0;
+ cache = (NodeCost*)malloc(cacheCap * sizeof(NodeCost));
+
+ // Want the behavior that if the actual number of states is specified, the cache
+ // will be at least that big.
+ hashShift = 3; // 8 (only useful for stress testing)
+#if !defined( MICROPATHER_STRESS )
+ while( HashSize() < allocate )
+ ++hashShift;
+#endif
+ hashTable = (PathNode**)calloc( HashSize(), sizeof(PathNode*) );
+
+ blocks = firstBlock = NewBlock();
+// debug( "HashSize=%d allocate=%d\n", HashSize(), allocate );
+ totalCollide = 0;
+}
+
+
+PathNodePool::~PathNodePool()
+{
+ Clear();
+ free( firstBlock );
+ free( cache );
+ free( hashTable );
+#ifdef TRACK_COLLISION
+ debug( "Total collide=%d HashSize=%d HashShift=%d\n", totalCollide, HashSize(), hashShift );
+#endif
+}
+
+
+bool PathNodePool::PushCache( const NodeCost* nodes, int nNodes, int* start ) {
+ *start = -1;
+ if ( nNodes+cacheSize <= cacheCap ) {
+ for( int i=0; i<nNodes; ++i ) {
+ cache[i+cacheSize] = nodes[i];
+ }
+ *start = cacheSize;
+ cacheSize += nNodes;
+ return true;
+ }
+ return false;
+}
+
+
+void PathNodePool::GetCache( int start, int nNodes, NodeCost* nodes ) {
+ MPASSERT( start >= 0 && start < cacheCap );
+ MPASSERT( nNodes > 0 );
+ MPASSERT( start + nNodes <= cacheCap );
+ memcpy( nodes, &cache[start], sizeof(NodeCost)*nNodes );
+}
+
+
+void PathNodePool::Clear()
+{
+#ifdef TRACK_COLLISION
+ // Collision tracking code.
+ int collide=0;
+ for( unsigned i=0; i<HashSize(); ++i ) {
+ if ( hashTable[i] && (hashTable[i]->child[0] || hashTable[i]->child[1]) )
+ ++collide;
+ }
+ //debug( "PathNodePool %d/%d collision=%d %.1f%%\n", nAllocated, HashSize(), collide, 100.0f*(float)collide/(float)HashSize() );
+ totalCollide += collide;
+#endif
+
+ Block* b = blocks;
+ while( b ) {
+ Block* temp = b->nextBlock;
+ if ( b != firstBlock ) {
+ free( b );
+ }
+ b = temp;
+ }
+ blocks = firstBlock; // Don't delete the first block (we always need at least that much memory.)
+
+ // Set up for new allocations (but don't do work we don't need to. Reset/Clear can be called frequently.)
+ if ( nAllocated > 0 ) {
+ freeMemSentinel.next = &freeMemSentinel;
+ freeMemSentinel.prev = &freeMemSentinel;
+
+ memset( hashTable, 0, sizeof(PathNode*)*HashSize() );
+ for( unsigned i=0; i<allocate; ++i ) {
+ freeMemSentinel.AddBefore( &firstBlock->pathNode[i] );
+ }
+ }
+ nAvailable = allocate;
+ nAllocated = 0;
+ cacheSize = 0;
+}
+
+
+PathNodePool::Block* PathNodePool::NewBlock()
+{
+ Block* block = (Block*) calloc( 1, sizeof(Block) + sizeof(PathNode)*(allocate-1) );
+ block->nextBlock = 0;
+
+ nAvailable += allocate;
+ for( unsigned i=0; i<allocate; ++i ) {
+ freeMemSentinel.AddBefore( &block->pathNode[i] );
+ }
+ return block;
+}
+
+
+unsigned PathNodePool::Hash( void* voidval )
+{
+ /*
+ Spent quite some time on this, and the result isn't quite satifactory. The
+ input set is the size of a void*, and is generally (x,y) pairs or memory pointers.
+
+ FNV resulting in about 45k collisions in a (large) test and some other approaches
+ about the same.
+
+ Simple folding reduces collisions to about 38k - big improvement. However, that may
+ be an artifact of the (x,y) pairs being well distributed. And for either the x,y case
+ or the pointer case, there are probably very poor hash table sizes that cause "overlaps"
+ and grouping. (An x,y encoding with a hashShift of 8 is begging for trouble.)
+
+ The best tested results are simple folding, but that seems to beg for a pathelogical case.
+ FNV-1a was the next best choice, without obvious pathelogical holes.
+
+ Finally settled on h%HashMask(). Simple, but doesn't have the obvious collision cases of folding.
+ */
+ /*
+ // Time: 567
+ // FNV-1a
+ // http://isthe.com/chongo/tech/comp/fnv/
+ // public domain.
+ MP_UPTR val = (MP_UPTR)(voidval);
+ const unsigned char *p = (unsigned char *)(&val);
+ unsigned int h = 2166136261;
+
+ for( size_t i=0; i<sizeof(MP_UPTR); ++i, ++p ) {
+ h ^= *p;
+ h *= 16777619;
+ }
+ // Fold the high bits to the low bits. Doesn't (generally) use all
+ // the bits since the shift is usually < 16, but better than not
+ // using the high bits at all.
+ return ( h ^ (h>>hashShift) ^ (h>>(hashShift*2)) ^ (h>>(hashShift*3)) ) & HashMask();
+ */
+ /*
+ // Time: 526
+ MP_UPTR h = (MP_UPTR)(voidval);
+ return ( h ^ (h>>hashShift) ^ (h>>(hashShift*2)) ^ (h>>(hashShift*3)) ) & HashMask();
+ */
+
+ // Time: 512
+ // The HashMask() is used as the divisor. h%1024 has lots of common
+ // repetitions, but h%1023 will move things out more.
+ MP_UPTR h = (MP_UPTR)(voidval);
+ return h % HashMask();
+}
+
+
+
+PathNode* PathNodePool::Alloc()
+{
+ if ( freeMemSentinel.next == &freeMemSentinel ) {
+ MPASSERT( nAvailable == 0 );
+
+ Block* b = NewBlock();
+ b->nextBlock = blocks;
+ blocks = b;
+ MPASSERT( freeMemSentinel.next != &freeMemSentinel );
+ }
+ PathNode* pathNode = freeMemSentinel.next;
+ pathNode->Unlink();
+
+ ++nAllocated;
+ MPASSERT( nAvailable > 0 );
+ --nAvailable;
+ return pathNode;
+}
+
+
+void PathNodePool::AddPathNode( unsigned key, PathNode* root )
+{
+ if ( hashTable[key] ) {
+ PathNode* p = hashTable[key];
+ while( true ) {
+ int dir = (root->state < p->state) ? 0 : 1;
+ if ( p->child[dir] ) {
+ p = p->child[dir];
+ }
+ else {
+ p->child[dir] = root;
+ break;
+ }
+ }
+ }
+ else {
+ hashTable[key] = root;
+ }
+}
+
+
+PathNode* PathNodePool::FetchPathNode( void* state )
+{
+ unsigned key = Hash( state );
+
+ PathNode* root = hashTable[key];
+ while( root ) {
+ if ( root->state == state ) {
+ break;
+ }
+ root = ( state < root->state ) ? root->child[0] : root->child[1];
+ }
+ MPASSERT( root );
+ return root;
+}
+
+
+PathNode* PathNodePool::GetPathNode( unsigned frame, void* _state, float _costFromStart, float _estToGoal, PathNode* _parent )
+{
+ unsigned key = Hash( _state );
+
+ PathNode* root = hashTable[key];
+ while( root ) {
+ if ( root->state == _state ) {
+ if ( root->frame == frame ) // This is the correct state and correct frame.
+ break;
+ // Correct state, wrong frame.
+ root->Init( frame, _state, _costFromStart, _estToGoal, _parent );
+ break;
+ }
+ root = ( _state < root->state ) ? root->child[0] : root->child[1];
+ }
+ if ( !root ) {
+ // allocate new one
+ root = Alloc();
+ root->Clear();
+ root->Init( frame, _state, _costFromStart, _estToGoal, _parent );
+ AddPathNode( key, root );
+ }
+ return root;
+}
+
+
+void PathNode::Init( unsigned _frame,
+ void* _state,
+ float _costFromStart,
+ float _estToGoal,
+ PathNode* _parent )
+{
+ state = _state;
+ costFromStart = _costFromStart;
+ estToGoal = _estToGoal;
+ CalcTotalCost();
+ parent = _parent;
+ frame = _frame;
+ inOpen = 0;
+ inClosed = 0;
+}
+
+
+void PathNode::Clear()
+{
+ memset( this, 0, sizeof( PathNode ) );
+ numAdjacent = -1;
+ cacheIndex = -1;
+}
+
+MicroPather::MicroPather( Graph* _graph, unsigned allocate, unsigned typicalAdjacent, bool cache )
+ : pathNodePool( allocate, typicalAdjacent ),
+ graph( _graph ),
+ frame( 0 )
+{
+ MPASSERT( allocate );
+ MPASSERT( typicalAdjacent );
+ pathCache = 0;
+ if ( cache ) {
+ pathCache = new PathCache( allocate*4 ); // untuned arbitrary constant
+ }
+}
+
+
+MicroPather::~MicroPather()
+{
+ delete pathCache;
+}
+
+
+void MicroPather::Reset()
+{
+ pathNodePool.Clear();
+ if ( pathCache ) {
+ pathCache->Reset();
+ }
+ frame = 0;
+}
+
+
+void MicroPather::GoalReached( PathNode* node, void* start, void* end, Common::Array< void* > *_path )
+{
+ Common::Array< void* >& path = *_path;
+ path.clear();
+
+ // We have reached the goal.
+ // How long is the path? Used to allocate the vector which is returned.
+ int count = 1;
+ PathNode* it = node;
+ while( it->parent )
+ {
+ ++count;
+ it = it->parent;
+ }
+
+ // Now that the path has a known length, allocate
+ // and fill the vector that will be returned.
+ if ( count < 3 )
+ {
+ // Handle the short, special case.
+ path.resize(2);
+ path[0] = start;
+ path[1] = end;
+ }
+ else
+ {
+ path.resize(count);
+
+ path[0] = start;
+ path[count-1] = end;
+ count-=2;
+ it = node->parent;
+
+ while ( it->parent )
+ {
+ path[count] = it->state;
+ it = it->parent;
+ --count;
+ }
+ }
+
+ if ( pathCache ) {
+ costVec.clear();
+
+ PathNode* pn0 = pathNodePool.FetchPathNode( path[0] );
+ PathNode* pn1 = 0;
+ for( unsigned i=0; i<path.size()-1; ++i ) {
+ pn1 = pathNodePool.FetchPathNode( path[i+1] );
+ nodeCostVec.clear();
+ GetNodeNeighbors( pn0, &nodeCostVec );
+ for( unsigned j=0; j<nodeCostVec.size(); ++j ) {
+ if ( nodeCostVec[j].node == pn1 ) {
+ costVec.push_back( nodeCostVec[j].cost );
+ break;
+ }
+ }
+ MPASSERT( costVec.size() == i+1 );
+ pn0 = pn1;
+ }
+ pathCache->Add( path, costVec );
+ }
+
+ #ifdef DEBUG_PATH
+ debug( "Path: " );
+ int counter=0;
+ #endif
+ for ( unsigned k=0; k<path.size(); ++k )
+ {
+ #ifdef DEBUG_PATH
+ graph->PrintStateInfo( path[k] );
+ debug( " " );
+ ++counter;
+ if ( counter == 8 )
+ {
+ debug( "\n" );
+ counter = 0;
+ }
+ #endif
+ }
+ #ifdef DEBUG_PATH
+ debug( "Cost=%.1f Checksum %d\n", node->costFromStart, checksum );
+ #endif
+}
+
+
+void MicroPather::GetNodeNeighbors( PathNode* node, Common::Array< NodeCost >* pNodeCost )
+{
+ if ( node->numAdjacent == 0 ) {
+ // it has no neighbors.
+ pNodeCost->resize( 0 );
+ }
+ else if ( node->cacheIndex < 0 )
+ {
+ // Not in the cache. Either the first time or just didn't fit. We don't know
+ // the number of neighbors and need to call back to the client.
+ stateCostVec.resize( 0 );
+ graph->AdjacentCost( node->state, &stateCostVec );
+
+ #ifdef DEBUG
+ {
+ // If this assert fires, you have passed a state
+ // as its own neighbor state. This is impossible --
+ // bad things will happen.
+ for ( unsigned i=0; i<stateCostVec.size(); ++i )
+ MPASSERT( stateCostVec[i].state != node->state );
+ }
+ #endif
+
+ pNodeCost->resize( stateCostVec.size() );
+ node->numAdjacent = stateCostVec.size();
+
+ if ( node->numAdjacent > 0 ) {
+ // Now convert to pathNodes.
+ // Note that the microsoft std library is actually pretty slow.
+ // Move things to temp vars to help.
+ const unsigned stateCostVecSize = stateCostVec.size();
+ const StateCost* stateCostVecPtr = &stateCostVec[0];
+ NodeCost* pNodeCostPtr = &(*pNodeCost)[0];
+
+ for( unsigned i=0; i<stateCostVecSize; ++i ) {
+ void* state = stateCostVecPtr[i].state;
+ pNodeCostPtr[i].cost = stateCostVecPtr[i].cost;
+ pNodeCostPtr[i].node = pathNodePool.GetPathNode( frame, state, FLT_MAX, FLT_MAX, 0 );
+ }
+
+ // Can this be cached?
+ int start = 0;
+ if ( pNodeCost->size() > 0 && pathNodePool.PushCache( pNodeCostPtr, pNodeCost->size(), &start ) ) {
+ node->cacheIndex = start;
+ }
+ }
+ }
+ else {
+ // In the cache!
+ pNodeCost->resize( node->numAdjacent );
+ NodeCost* pNodeCostPtr = &(*pNodeCost)[0];
+ pathNodePool.GetCache( node->cacheIndex, node->numAdjacent, pNodeCostPtr );
+
+ // A node is uninitialized (even if memory is allocated) if it is from a previous frame.
+ // Check for that, and Init() as necessary.
+ for( int i=0; i<node->numAdjacent; ++i ) {
+ PathNode* pNode = pNodeCostPtr[i].node;
+ if ( pNode->frame != frame ) {
+ pNode->Init( frame, pNode->state, FLT_MAX, FLT_MAX, 0 );
+ }
+ }
+ }
+}
+
+
+#ifdef DEBUG
+/*
+void MicroPather::DumpStats()
+{
+ int hashTableEntries = 0;
+ for( int i=0; i<HASH_SIZE; ++i )
+ if ( hashTable[i] )
+ ++hashTableEntries;
+
+ int pathNodeBlocks = 0;
+ for( PathNode* node = pathNodeMem; node; node = node[ALLOCATE-1].left )
+ ++pathNodeBlocks;
+ debug( "HashTableEntries=%d/%d PathNodeBlocks=%d [%dk] PathNodes=%d SolverCalled=%d\n",
+ hashTableEntries, HASH_SIZE, pathNodeBlocks,
+ pathNodeBlocks*ALLOCATE*sizeof(PathNode)/1024,
+ pathNodeCount,
+ frame );
+}
+*/
+#endif
+
+
+void MicroPather::StatesInPool( Common::Array< void* >* stateVec )
+{
+ stateVec->clear();
+ pathNodePool.AllStates( frame, stateVec );
+}
+
+
+void PathNodePool::AllStates( unsigned frame, Common::Array< void* >* stateVec )
+{
+ for ( Block* b=blocks; b; b=b->nextBlock )
+ {
+ for( unsigned i=0; i<allocate; ++i )
+ {
+ if ( b->pathNode[i].frame == frame )
+ stateVec->push_back( b->pathNode[i].state );
+ }
+ }
+}
+
+
+PathCache::PathCache( int _allocated )
+{
+ mem = new Item[_allocated];
+ memset( mem, 0, sizeof(*mem)*_allocated );
+ allocated = _allocated;
+ nItems = 0;
+ hit = 0;
+ miss = 0;
+}
+
+
+PathCache::~PathCache()
+{
+ delete [] mem;
+}
+
+
+void PathCache::Reset()
+{
+ if ( nItems ) {
+ memset( mem, 0, sizeof(*mem)*allocated );
+ nItems = 0;
+ hit = 0;
+ miss = 0;
+ }
+}
+
+
+void PathCache::Add( const Common::Array< void* >& path, const Common::Array< float >& cost )
+{
+ if ( nItems + (int)path.size() > allocated*3/4 ) {
+ return;
+ }
+
+ for( unsigned i=0; i<path.size()-1; ++i ) {
+ // example: a->b->c->d
+ // Huge memory saving to only store 3 paths to 'd'
+ // Can put more in cache with also adding path to b, c, & d
+ // But uses much more memory. Experiment with this commented
+ // in and out and how to set.
+
+ void* end = path[path.size()-1];
+ Item item = { path[i], end, path[i+1], cost[i] };
+ AddItem( item );
+ }
+}
+
+
+void PathCache::AddNoSolution( void* end, void* states[], int count )
+{
+ if ( count + nItems > allocated*3/4 ) {
+ return;
+ }
+
+ for( int i=0; i<count; ++i ) {
+ Item item = { states[i], end, 0, FLT_MAX };
+ AddItem( item );
+ }
+}
+
+
+int PathCache::Solve( void* start, void* end, Common::Array< void* >* path, float* totalCost )
+{
+ const Item* item = Find( start, end );
+ if ( item ) {
+ if ( item->cost == FLT_MAX ) {
+ ++hit;
+ return MicroPather::NO_SOLUTION;
+ }
+
+ path->clear();
+ path->push_back( start );
+ *totalCost = 0;
+
+ for ( ;start != end; start=item->next, item=Find(start, end) ) {
+ MPASSERT( item );
+ *totalCost += item->cost;
+ path->push_back( item->next );
+ }
+ ++hit;
+ return MicroPather::SOLVED;
+ }
+ ++miss;
+ return MicroPather::NOT_CACHED;
+}
+
+
+void PathCache::AddItem( const Item& item )
+{
+ MPASSERT( allocated );
+ int index = item.Hash() % allocated;
+ while( true ) {
+ if ( mem[index].Empty() ) {
+ mem[index] = item;
+ ++nItems;
+#ifdef DEBUG_CACHING
+ GLOUTPUT(( "Add: start=%x next=%x end=%x\n", item.start, item.next, item.end ));
+#endif
+ break;
+ }
+ else if ( mem[index].KeyEqual( item ) ) {
+ MPASSERT( (mem[index].next && item.next) || (mem[index].next==0 && item.next == 0) );
+ // do nothing; in cache
+ break;
+ }
+ ++index;
+ if ( index == allocated )
+ index = 0;
+ }
+}
+
+
+const PathCache::Item* PathCache::Find( void* start, void* end )
+{
+ MPASSERT( allocated );
+ Item fake = { start, end, 0, 0 };
+ int index = fake.Hash() % allocated;
+ while( true ) {
+ if ( mem[index].Empty() ) {
+ return 0;
+ }
+ if ( mem[index].KeyEqual( fake )) {
+ return mem + index;
+ }
+ ++index;
+ if ( index == allocated )
+ index = 0;
+ }
+}
+
+
+void MicroPather::GetCacheData( CacheData* data )
+{
+ memset( data, 0, sizeof(*data) );
+
+ if ( pathCache ) {
+ data->nBytesAllocated = pathCache->AllocatedBytes();
+ data->nBytesUsed = pathCache->UsedBytes();
+ data->memoryFraction = (float)( (double)data->nBytesUsed / (double)data->nBytesAllocated );
+
+ data->hit = pathCache->hit;
Commit: d07187a1a445806042937be1cc4145ae5c9c3c1b
https://github.com/scummvm/scummvm/commit/d07187a1a445806042937be1cc4145ae5c9c3c1b
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2023-01-16T17:36:43+01:00
Commit Message:
TETRAEDGE: More progress on WIP engine.
Changed paths:
A engines/tetraedge/game/scene_lights_xml_parser.cpp
A engines/tetraedge/game/scene_lights_xml_parser.h
A engines/tetraedge/te/te_act_zone.cpp
A engines/tetraedge/te/te_act_zone.h
engines/tetraedge/game/application.cpp
engines/tetraedge/game/application.h
engines/tetraedge/game/billboard.cpp
engines/tetraedge/game/billboard.h
engines/tetraedge/game/cellphone.cpp
engines/tetraedge/game/character.cpp
engines/tetraedge/game/character.h
engines/tetraedge/game/characters_shadow.cpp
engines/tetraedge/game/characters_shadow.h
engines/tetraedge/game/dialog2.cpp
engines/tetraedge/game/gallery_menu.cpp
engines/tetraedge/game/gallery_menu.h
engines/tetraedge/game/game.cpp
engines/tetraedge/game/game.h
engines/tetraedge/game/global_bonus_menu.cpp
engines/tetraedge/game/help_option_menu.cpp
engines/tetraedge/game/in_game_scene.cpp
engines/tetraedge/game/in_game_scene.h
engines/tetraedge/game/inventory_menu.cpp
engines/tetraedge/game/lua_binds.cpp
engines/tetraedge/game/main_menu.h
engines/tetraedge/game/notifier.cpp
engines/tetraedge/game/notifier.h
engines/tetraedge/game/object_settings_xml_parser.h
engines/tetraedge/game/objectif.cpp
engines/tetraedge/game/question2.h
engines/tetraedge/module.mk
engines/tetraedge/te/micropather.h
engines/tetraedge/te/te_3d_object2.cpp
engines/tetraedge/te/te_3d_object2.h
engines/tetraedge/te/te_3d_texture.cpp
engines/tetraedge/te/te_3d_texture.h
engines/tetraedge/te/te_animation.cpp
engines/tetraedge/te/te_animation.h
engines/tetraedge/te/te_bezier_curve.cpp
engines/tetraedge/te/te_bezier_curve.h
engines/tetraedge/te/te_button_layout.cpp
engines/tetraedge/te/te_callback.h
engines/tetraedge/te/te_camera.cpp
engines/tetraedge/te/te_camera.h
engines/tetraedge/te/te_checkbox_layout.cpp
engines/tetraedge/te/te_checkbox_layout.h
engines/tetraedge/te/te_free_move_zone.cpp
engines/tetraedge/te/te_free_move_zone.h
engines/tetraedge/te/te_i_3d_object2.h
engines/tetraedge/te/te_image.cpp
engines/tetraedge/te/te_image.h
engines/tetraedge/te/te_intrusive_ptr.h
engines/tetraedge/te/te_layout.cpp
engines/tetraedge/te/te_light.cpp
engines/tetraedge/te/te_light.h
engines/tetraedge/te/te_lua_gui.cpp
engines/tetraedge/te/te_lua_gui_lua_callbacks.cpp
engines/tetraedge/te/te_matrix4x4.cpp
engines/tetraedge/te/te_matrix4x4.h
engines/tetraedge/te/te_mesh.cpp
engines/tetraedge/te/te_mesh.h
engines/tetraedge/te/te_model.cpp
engines/tetraedge/te/te_model.h
engines/tetraedge/te/te_model_animation.cpp
engines/tetraedge/te/te_model_animation.h
engines/tetraedge/te/te_model_vertex_animation.cpp
engines/tetraedge/te/te_model_vertex_animation.h
engines/tetraedge/te/te_obp.cpp
engines/tetraedge/te/te_pick_mesh2.cpp
engines/tetraedge/te/te_pick_mesh2.h
engines/tetraedge/te/te_scene.cpp
engines/tetraedge/te/te_scene.h
engines/tetraedge/te/te_text_base2.cpp
engines/tetraedge/te/te_vector3f32.cpp
engines/tetraedge/te/te_vector3f32.h
engines/tetraedge/te/te_visual_fade.cpp
engines/tetraedge/to_lua.cpp
diff --git a/engines/tetraedge/game/application.cpp b/engines/tetraedge/game/application.cpp
index fbb337d8b1d..9345f2d11af 100644
--- a/engines/tetraedge/game/application.cpp
+++ b/engines/tetraedge/game/application.cpp
@@ -29,6 +29,8 @@
#include "tetraedge/tetraedge.h"
#include "tetraedge/game/game.h"
#include "tetraedge/game/application.h"
+#include "tetraedge/game/characters_shadow.h"
+#include "tetraedge/game/in_game_scene.h"
#include "tetraedge/te/te_core.h"
#include "tetraedge/te/te_resource_manager.h"
#include "tetraedge/te/te_renderer.h"
@@ -380,11 +382,12 @@ void Application::performRender() {
Game *game = g_engine->getGame();
TeRenderer *renderer = g_engine->getRenderer();
- if (game->running() && _inGameScene._character && true /*some other ingamescene things*/) {
+ if (game->running() && game->scene()._character
+ && game->scene()._shadowLightNo != -1
+ && game->scene()._charactersShadow != nullptr) {
renderer->shadowMode(TeRenderer::ShadowMode1);
- //_inGameScene._charactersShadow->createTexture(_inGameScene);
+ game->scene()._charactersShadow->createTexture(&game->scene());
renderer->shadowMode(TeRenderer::ShadowMode0);
- error("TODO: Implement characters shadow thing here.");
}
drawBack();
@@ -392,14 +395,17 @@ void Application::performRender() {
renderer->renderTransparentMeshes();
renderer->clearBuffer(GL_ACCUM);
- if (game->running() && _inGameScene._character && true /*some other ingamescene things*/) {
- TeIntrusivePtr<TeCamera> currentCamera = _inGameScene.currentCamera();
- if (currentCamera) {
- currentCamera->apply();
- renderer->shadowMode(TeRenderer::ShadowMode2);
- //_inGameScene._charactersShadow->draw(_inGameScene);
- renderer->shadowMode(TeRenderer::ShadowMode0);
- error("TODO: Implement characters shadow thing here.");
+ if (game->running()) {
+ if (game->scene()._character
+ && game->scene()._shadowLightNo != -1
+ && game->scene()._charactersShadow != nullptr) {
+ TeIntrusivePtr<TeCamera> currentCamera = game->scene().currentCamera();
+ if (currentCamera) {
+ currentCamera->apply();
+ renderer->shadowMode(TeRenderer::ShadowMode2);
+ game->scene()._charactersShadow->createTexture(&game->scene());
+ renderer->shadowMode(TeRenderer::ShadowMode0);
+ }
}
game->draw();
}
@@ -409,7 +415,7 @@ void Application::performRender() {
drawFront();
renderer->renderTransparentMeshes();
// What gets called here??
- //_inGameScene.removeModel(const Common::String &name)
+ game->scene().drawPath();
g_system->updateScreen();
}
@@ -463,16 +469,20 @@ bool Application::isLockCursor() {
}
bool Application::isLockPad() {
- error("TODO: Implement Application::isLockPad");
- return false;
+ Game *game = g_engine->getGame();
+ bool result = isLockCursor() || game->dialog2().isDialogPlaying() || game->isMoviePlaying()
+ || game->question2().gui().layoutChecked("background")->visible()
+ || game->isDocumentOpened();
+ return result;
}
void Application::lockCursor(bool lock) {
- error("TODO: Implement Application::lockCursor");
+ _lockCursorButton.setVisible(lock);
}
void Application::lockCursorFromAction(bool lock) {
- error("TODO: Implement Application::lockCursorFromAction");
+ _lockCursorFromActionButton.setVisible(lock);
+ g_engine->getGame()->showMarkers(lock);
}
void Application::loadOptions(const Common::String &fname) {
diff --git a/engines/tetraedge/game/application.h b/engines/tetraedge/game/application.h
index feebf411639..7ffb34901eb 100644
--- a/engines/tetraedge/game/application.h
+++ b/engines/tetraedge/game/application.h
@@ -140,7 +140,6 @@ private:
Credits _credits;
OwnerErrorMenu _ownerErrorMenu;
SplashScreens _splashScreens;
- InGameScene _inGameScene;
TeIntrusivePtr<TeFont3> _fontComic;
TeIntrusivePtr<TeFont3> _fontArgh;
diff --git a/engines/tetraedge/game/billboard.cpp b/engines/tetraedge/game/billboard.cpp
index e8529237fe5..eef7974e0b1 100644
--- a/engines/tetraedge/game/billboard.cpp
+++ b/engines/tetraedge/game/billboard.cpp
@@ -20,7 +20,10 @@
*/
#include "common/textconsole.h"
+
+#include "tetraedge/tetraedge.h"
#include "tetraedge/game/billboard.h"
+#include "tetraedge/game/game.h"
namespace Tetraedge {
@@ -28,11 +31,21 @@ Billboard::Billboard() {
}
bool Billboard::load(const Common::String &path) {
- error("TODO: implement Billboard::load");
+ _model = new TeModel();
+ TeIntrusivePtr<Te3DTexture> texture = new Te3DTexture();
+ Game *game = g_engine->getGame();
+ Common::Path texpath = game->sceneZonePath().join(path);
+ texture->load(texpath);
+ _model->setName(texpath.toString());
+ Common::Array<TeVector3f32> quad;
+ quad.resize(4);
+ _model->setQuad(texture, quad, TeColor(0xff, 0xff, 0xff, 0xff));
+ game->scene().models().push_back(_model);
return false;
}
void Billboard::calcVertex() {
+ //Game *game = g_engine->getGame();
error("TODO: implement Billboard::calcVertex");
}
diff --git a/engines/tetraedge/game/billboard.h b/engines/tetraedge/game/billboard.h
index bd39e309de0..4fc376fac99 100644
--- a/engines/tetraedge/game/billboard.h
+++ b/engines/tetraedge/game/billboard.h
@@ -25,6 +25,8 @@
#include "common/str.h"
#include "tetraedge/te/te_object.h"
+#include "tetraedge/te/te_intrusive_ptr.h"
+#include "tetraedge/te/te_model.h"
#include "tetraedge/te/te_vector2f32.h"
#include "tetraedge/te/te_vector3f32.h"
@@ -42,6 +44,7 @@ public:
void size(const TeVector2f32 &size);
private:
+ TeIntrusivePtr<TeModel> _model;
TeVector3f32 _pos;
TeVector3f32 _pos2;
TeVector2f32 _size;
diff --git a/engines/tetraedge/game/cellphone.cpp b/engines/tetraedge/game/cellphone.cpp
index 4f836c1c473..0228fd3a17d 100644
--- a/engines/tetraedge/game/cellphone.cpp
+++ b/engines/tetraedge/game/cellphone.cpp
@@ -61,15 +61,28 @@ bool Cellphone::addNumber(const Common::String &num) {
}
void Cellphone::currentPage(int offset) {
- error("TODO: implement Cellphone::currentPage");
+ if (_textLayoutArray.empty())
+ return;
+
+ _nextNumber = offset;
+ TeLayout *repertoire = _gui.layoutChecked("numRepertoire");
+ for (int i = 0; i < repertoire->childCount(); i++) {
+ repertoire->child(i)->setVisible(i == offset);
+ }
}
void Cellphone::enter() {
- error("TODO: implement Cellphone::enter");
+ _gui.buttonLayoutChecked("background")->setVisible(true);
+ currentPage(_nextNumber);
}
void Cellphone::leave() {
- error("TODO: implement Cellphone::leave");
+ _gui.buttonLayoutChecked("background")->setVisible(false);
+ for (TeTextLayout *text : _textLayoutArray) {
+ text->deleteLater();
+ }
+ _textLayoutArray.clear();
+ _addedNumbers.clear();
}
void Cellphone::load() {
@@ -89,6 +102,7 @@ void Cellphone::load() {
}
void Cellphone::loadFromBackup(const Common::XMLParser::ParserNode *node) {
+ error("TODO: implement Cellphone::loadFromBackup");
/*
basic algorithm:
child = node->lastChild;
@@ -113,12 +127,10 @@ bool Cellphone::onCloseButtonValidated() {
}
bool Cellphone::onNextNumber() {
- error("TODO: work out how the max num works here.");
- /*
- int numoffset = _nextNumber + 1;
- if (numoffset < _maxnum) {
+ unsigned int numoffset = _nextNumber + 1;
+ if (numoffset < _textLayoutArray.size()) {
currentPage(numoffset);
- }*/
+ }
return false;
}
@@ -142,4 +154,5 @@ void Cellphone::unload() {
leave();
_gui.unload();
}
+
} // end namespace Tetraedge
diff --git a/engines/tetraedge/game/character.cpp b/engines/tetraedge/game/character.cpp
index aa05583d4f5..9aabbf0220c 100644
--- a/engines/tetraedge/game/character.cpp
+++ b/engines/tetraedge/game/character.cpp
@@ -57,7 +57,8 @@ void Character::WalkSettings::clear() {
Character::Character() : _curveOffset(0), _lastFrame(-1), _callbacksChanged(false),
_missingCurrentAnim(false), _someRepeatFlag(false), _walkModeStr("Walk"), _needsSomeUpdate(false),
_stepSound1("sounds/SFX/PAS_H_BOIS1.ogg"), _stepSound2("sounds/SFX/PAS_H_BOIS2.ogg"),
-_freeMoveZone(nullptr) {
+_freeMoveZone(nullptr), _animSoundOffset(0), _lastAnimFrame(0), _charLookingAt(nullptr) {
+ _curModelAnim.setDeleteFn(&TeModelAnimation::deleteLater);
}
void Character::addCallback(const Common::String &key, const Common::String &s2, float f1, float f2) {
@@ -127,12 +128,37 @@ float Character::animLengthFromFile(const Common::String &animname, uint *pframe
return animLen * _model->scale().z();
}
-bool Character::blendAnimation(const Common::String &animname, float param_2, bool param_3, bool param_4) {
- error("TODO: Implement Character::blendAnimation");
+bool Character::blendAnimation(const Common::String &animname, float amount, bool repeat, bool param_4) {
+ Common::Path animpath("models/Anims");
+ animpath.joinInPlace(animname);
+
+ _missingCurrentAnim = !(animname.contains(_characterSettings._walkFileName)
+ || animname.contains(walkAnim(WalkPart_Start))
+ || animname.contains(walkAnim(WalkPart_Loop))
+ || animname.contains(walkAnim(WalkPart_EndG))
+ || animname.contains(walkAnim(WalkPart_EndD)));
+
+ if (_curModelAnim)
+ _curModelAnim->onFinished().remove(this, &Character::onModelAnimationFinished);
+
+ _curModelAnim = animCacheLoad(animpath);
+ _curModelAnim->onFinished().add(this, &Character::onModelAnimationFinished);
+
+ _curModelAnim->bind(_model);
+ _model->blendAnim(_curModelAnim, amount, repeat);
+ _lastFrame = -1;
+ _curModelAnim->play();
+ _curAnimName = animname;
+ warning("TODO: Set field 0x2d1 in Character::blendAnimation");
+ return true;
}
TeVector3f32 Character::correctPosition(const TeVector3f32 &pos) {
- error("TODO: Implement Character::correctPosition");
+ bool flag;
+ TeVector3f32 result = _freeMoveZone->correctCharacterPosition(pos, &flag, true);
+ if (!flag)
+ result = _model->position();
+ return result;
}
float Character::curveOffset() {
@@ -150,7 +176,12 @@ void Character::deleteAllCallback() {
}
void Character::deleteAnim() {
- error("TODO: Implement Character::deleteAnim");
+ if (_curModelAnim) {
+ _curModelAnim->onFinished().remove(this, &Character::onModelAnimationFinished);
+ _curModelAnim->unbind();
+ }
+ _model->removeAnim();
+ _curModelAnim.release();
}
void Character::deleteCallback(const Common::String &str1, const Common::String &str2, float f) {
@@ -159,7 +190,11 @@ void Character::deleteCallback(const Common::String &str1, const Common::String
//static bool deserialize(TiXmlElement *param_1, Walk *param_2);
void Character::endMove() {
- error("TODO: Implement Character::endMove.");
+ if (_model->name() == "Kate")
+ walkMode("Walk");
+
+ _onFinishedSignal.call();
+ stop();
}
const Character::WalkSettings *Character::getCurrentWalkFiles() {
@@ -170,23 +205,34 @@ const Character::WalkSettings *Character::getCurrentWalkFiles() {
return nullptr;
}
-bool Character::isFramePassed(uint frameno) {
- error("TODO: Implement Character::isFramePassed.");
+bool Character::isFramePassed(int frameno) {
+ return (frameno > _lastAnimFrame && _model->anim()->curFrame2() >= frameno);
}
bool Character::isWalkEnd() {
- error("TODO: Implement Character::isWalkEnd.");
+ Common::String animFile = _model->anim()->_loadedPath.getLastComponent().toString();
+ for (const auto & walkSettings : _characterSettings._walkSettings) {
+ if (walkSettings._value._walkParts[WalkPart_EndD]._file.contains(animFile)
+ || walkSettings._value._walkParts[WalkPart_EndG]._file.contains(animFile))
+ return true;
+ }
return false;
}
-bool Character::leftStepFrame(enum Character::WalkPart walkpart) {
- error("TODO: Implement Character::leftStepFrame.");
- return false;
+int Character::leftStepFrame(enum Character::WalkPart walkpart) {
+ const Character::WalkSettings *settings = getCurrentWalkFiles();
+ if (settings) {
+ return settings->_walkParts[(int)walkpart]._stepLeft;
+ }
+ return -1;
}
-bool Character::rightStepFrame(enum Character::WalkPart walkpart) {
- error("TODO: Implement Character::rightStepFrame.");
- return false;
+int Character::rightStepFrame(enum Character::WalkPart walkpart) {
+ const Character::WalkSettings *settings = getCurrentWalkFiles();
+ if (settings) {
+ return settings->_walkParts[(int)walkpart]._stepRight;
+ }
+ return -1;
}
bool Character::loadModel(const Common::String &name, bool param_2) {
@@ -290,7 +336,7 @@ bool Character::loadModel(const Common::String &name, bool param_2) {
return false;
}
-bool Character::onBonesUpdate(const Common::String ¶m_1, const TeMatrix4x4 *param_2) {
+bool Character::onBonesUpdate(const Common::String &boneName, const TeMatrix4x4 ¶m_2) {
error("TODO: Implement Character::onBonesUpdate");
return false;
}
@@ -304,7 +350,7 @@ void Character::permanentUpdate() {
error("TODO: Implement Character::permanentUpdate.");
}
-void Character::placeOnCurve(const TeBezierCurve &curve) {
+void Character::placeOnCurve(TeIntrusivePtr<TeBezierCurve> &curve) {
_curve = curve;
updatePosition(_curveOffset);
}
@@ -320,10 +366,10 @@ void Character::removeAnim() {
}
void Character::removeFromCurve() {
- error("TODO: Implement Character::removeFromCurve.");
+ _curve.release();
}
-bool Character::setAnimation(const Common::String &name, bool repeat, bool param_3, bool unused, int startFrame, int endFrame) {
+bool Character::setAnimation(const Common::String &name, bool repeat, bool param_3, bool unused, int startFrame, int endFrame) {
if (name.empty())
return false;
@@ -354,8 +400,10 @@ bool Character::setAnimation(const Common::String &name, bool repeat, bool param
return true;
}
-void Character::setAnimationSound(const Common::String &name, uint param_2) {
- error("TODO: Implement Character::setAnimationSound.");
+void Character::setAnimationSound(const Common::String &name, uint offset) {
+ warning("TODO: Set field 0x2f8 to 0 in Character::setAnimationSound.");
+ _animSound = name;
+ _animSoundOffset = offset;
}
void Character::setCurveOffset(float offset) {
@@ -363,7 +411,7 @@ void Character::setCurveOffset(float offset) {
updatePosition(offset);
}
-void Character::setFreeMoveZone(const Common::SharedPtr<TeFreeMoveZone> &zone) {
+void Character::setFreeMoveZone(TeFreeMoveZone *zone) {
_freeMoveZone = zone;
}
@@ -387,23 +435,26 @@ float Character::translationFromAnim(const TeModelAnimation &anim, long bone, lo
return translationVectorFromAnim(anim, bone, param_3).z();
}
-TeVector3f32 Character::translationVectorFromAnim(const TeModelAnimation &anim, long bone, long frame) {
+TeVector3f32 Character::translationVectorFromAnim(const TeModelAnimation &anim, long bone, long frame) {
const TeTRS trs = trsFromAnim(anim, bone, frame);
return trs.getTranslation();
}
-TeTRS Character::trsFromAnim(const TeModelAnimation &anim, long bone, long frame) {
+TeTRS Character::trsFromAnim(const TeModelAnimation &anim, long bone, long frame) {
if (bone == -1)
return TeTRS();
return anim.getTRS(bone, frame, false);
}
-void Character::update(double percentval) {
+void Character::update(double percentval) {
error("TODO: Implement Character::update");
}
-void Character::updateAnimFrame() {
+void Character::updateAnimFrame() {
+ if (_model->anim()) {
+ _lastAnimFrame = _model->anim()->curFrame2();
+ }
error("TODO: Implement Character::updateAnimFrame");
}
@@ -411,7 +462,7 @@ void Character::updatePosition(float curveOffset) {
error("TODO: Implement Character::updatePosition");
}
-Common::String Character::walkAnim(Character::WalkPart part) {
+Common::String Character::walkAnim(Character::WalkPart part) {
Common::String result;
const Character::WalkSettings *settings = getCurrentWalkFiles();
if (settings) {
diff --git a/engines/tetraedge/game/character.h b/engines/tetraedge/game/character.h
index 2556f305845..dd0d9b13329 100644
--- a/engines/tetraedge/game/character.h
+++ b/engines/tetraedge/game/character.h
@@ -45,8 +45,8 @@ public:
struct AnimSettings {
AnimSettings() : _stepLeft(0), _stepRight(0) {};
Common::String _file;
- int _stepRight;
int _stepLeft;
+ int _stepRight;
};
struct WalkSettings {
@@ -100,7 +100,7 @@ public:
float animLength(const TeModelAnimation &modelanim, long bone, long lastframe);
float animLengthFromFile(const Common::String &animname, uint *pframeCount, uint lastframe);
- bool blendAnimation(const Common::String &animname, float param_2, bool param_3, bool param_4);
+ bool blendAnimation(const Common::String &animname, float amount, bool repeat, bool param_4);
TeVector3f32 correctPosition(const TeVector3f32 &pos);
float curveOffset();
void deleteAllCallback();
@@ -110,26 +110,26 @@ public:
void endMove();
const WalkSettings *getCurrentWalkFiles();
- bool isFramePassed(uint frameno);
+ bool isFramePassed(int frameno);
bool isWalkEnd();
- bool leftStepFrame(enum WalkPart walkpart);
- bool rightStepFrame(enum WalkPart walkpart);
+ int leftStepFrame(enum WalkPart walkpart);
+ int rightStepFrame(enum WalkPart walkpart);
bool loadModel(const Common::String &name, bool param_2);
static bool loadSettings(const Common::String &path);
- bool onBonesUpdate(const Common::String ¶m_1, const TeMatrix4x4 *param_2);
+ bool onBonesUpdate(const Common::String &boneName, const TeMatrix4x4 ¶m_2);
bool onModelAnimationFinished();
void permanentUpdate();
- void placeOnCurve(const TeBezierCurve &curve);
+ void placeOnCurve(TeIntrusivePtr<TeBezierCurve> &curve);
//void play() // just called TeAnimation::play();
void removeAnim();
void removeFromCurve();
static Common::String rootBone() { return "Pere"; }
bool setAnimation(const Common::String &name, bool repeat, bool param_3, bool param_4, int startFrame, int endFrame);
- void setAnimationSound(const Common::String &name, uint param_2);
+ void setAnimationSound(const Common::String &name, uint offset);
void setCurveOffset(float offset);
- void setFreeMoveZone(const Common::SharedPtr<TeFreeMoveZone> &zone);
+ void setFreeMoveZone(TeFreeMoveZone *zone);
bool setShadowVisible(bool visible);
void setStepSound(const Common::String &stepSound1, const Common::String &stepSound2);
float speedFromAnim(double movepercent);
@@ -153,14 +153,20 @@ public:
const Common::String walkModeStr() const { return _walkModeStr; }
const Common::String curAnimName() const { return _curAnimName; }
bool needsSomeUpdate() const { return _needsSomeUpdate; }
+ void setCharLookingAt(Character *other) { _charLookingAt = other; }
private:
float _curveOffset;
- TeBezierCurve _curve;
- Common::SharedPtr<TeFreeMoveZone> _freeMoveZone;
+ TeIntrusivePtr<TeBezierCurve> _curve;
+ TeFreeMoveZone *_freeMoveZone;
Common::String _stepSound1;
Common::String _stepSound2;
Common::String _walkModeStr; // Walk or Jog
+ Common::String _animSound;
+
+ Character *_charLookingAt;
+
+ uint _animSoundOffset;
TeIntrusivePtr<TeModelAnimation> _curModelAnim;
@@ -175,6 +181,7 @@ private:
uint32 _walkPart3AnimFrameCount;
int _lastFrame;
+ int _lastAnimFrame;
bool _missingCurrentAnim;
bool _someRepeatFlag; // TODO: what is this?
bool _callbacksChanged;
diff --git a/engines/tetraedge/game/characters_shadow.cpp b/engines/tetraedge/game/characters_shadow.cpp
index 46b1abefd64..2ed2fba9c5b 100644
--- a/engines/tetraedge/game/characters_shadow.cpp
+++ b/engines/tetraedge/game/characters_shadow.cpp
@@ -19,33 +19,64 @@
*
*/
+#include "graphics/opengl/system_headers.h"
+
#include "tetraedge/tetraedge.h"
#include "tetraedge/game/characters_shadow.h"
+#include "tetraedge/te/te_light.h"
#include "tetraedge/te/te_renderer.h"
+#include "tetraedge/te/te_3d_texture.h"
namespace Tetraedge {
+/*static*/
+Te3DObject2 *CharactersShadow::_camTarget = nullptr;
+
CharactersShadow::CharactersShadow() {
}
void CharactersShadow::create(InGameScene *scene) {
- error("TODO: Implement me");
+ _texSize = 720;
+ _camTarget = new Te3DObject2();
+ TeRenderer *renderer = g_engine->getRenderer();
+ renderer->enableTexture();
+ _camera = new TeCamera();
+ _camera->_projectionMatrixType = 2;
+ // TODO: set camera field 0x130 to 1.0?
+ _camera->viewport(0, 0, _texSize, _texSize);
+ Te3DTexture::unbind();
+ glGenTextures(1, &_glTex);
+ glBindTexture(GL_TEXTURE_2D, _glTex);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, _texSize, _texSize, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, nullptr);
+ renderer->disableTexture();
}
void CharactersShadow::createTexture(InGameScene *scene) {
- error("TODO: Implement me");
+ TeRenderer *renderer = g_engine->getRenderer();
+ renderer->enableTexture();
+ //TeLight *light = scene->shadowLight();
+ error("TODO: Implement CharactersShadow::createTexture");
}
void CharactersShadow::destroy() {
TeRenderer *renderer = g_engine->getRenderer();
renderer->disableTexture();
- //glBindTexture(GL_TEXTURE_2D, 0);
- //glDeleteTextures(1, (uint *)this);
- error("TODO: Finish implementation here");
+ glBindTexture(GL_TEXTURE_2D, 0);
+ glDeleteTextures(1, &_glTex);
+ if (_camera)
+ _camera = nullptr;
+ if (_camTarget) {
+ delete _camTarget;
+ _camTarget = nullptr;
+ }
}
void CharactersShadow::draw(InGameScene *scene) {
- error("TODO: Implement me");
+ error("TODO: Implement CharactersShadow::draw");
}
} // end namespace Tetraedge
diff --git a/engines/tetraedge/game/characters_shadow.h b/engines/tetraedge/game/characters_shadow.h
index a6809f6414a..e0b8c51efe7 100644
--- a/engines/tetraedge/game/characters_shadow.h
+++ b/engines/tetraedge/game/characters_shadow.h
@@ -26,6 +26,8 @@
namespace Tetraedge {
+class InGameScene;
+
class CharactersShadow {
public:
CharactersShadow();
@@ -37,8 +39,10 @@ public:
//void drawTexture(); // empty?
private:
- // TODO add private members
-
+ uint _glTex;
+ int _texSize;
+ TeIntrusivePtr<TeCamera> _camera;
+ static Te3DObject2 *_camTarget;
};
} // end namespace Tetraedge
diff --git a/engines/tetraedge/game/dialog2.cpp b/engines/tetraedge/game/dialog2.cpp
index 6be1ece06e5..1d46d18f5b0 100644
--- a/engines/tetraedge/game/dialog2.cpp
+++ b/engines/tetraedge/game/dialog2.cpp
@@ -140,6 +140,7 @@ void Dialog2::unload() {
_music.close();
_gui.unload();
error("TODO: Finish Dialog2::unload");
+
//_dialogDataList.clear();
//_minimumTimeTimer.stop();
}
diff --git a/engines/tetraedge/game/gallery_menu.cpp b/engines/tetraedge/game/gallery_menu.cpp
index 935443f1c8b..7403f62ec18 100644
--- a/engines/tetraedge/game/gallery_menu.cpp
+++ b/engines/tetraedge/game/gallery_menu.cpp
@@ -21,10 +21,14 @@
#include "tetraedge/tetraedge.h"
#include "tetraedge/game/application.h"
+#include "tetraedge/game/game.h"
#include "tetraedge/game/gallery_menu.h"
namespace Tetraedge {
+static const char *AMBIENT_SND_BIKE = "sounds/Ambiances/b_automatebike.ogg";
+static const char *AMBIENT_SND_ENGR = "sounds/Ambiances/b_engrenagebg.ogg";
+
GalleryMenu::GalleryMenu() {
}
@@ -34,7 +38,22 @@ bool GalleryMenu::onLockVideoButtonValidated() {
}
bool GalleryMenu::onSkipVideoButtonValidated() {
- error("TODO: Implement onSkipVideoButtonValidated");
+ Application *app = g_engine->getApplication();
+ app->music().play();
+ Game *game = g_engine->getGame();
+
+ game->stopSound(AMBIENT_SND_BIKE);
+ game->playSound(AMBIENT_SND_BIKE, -1, 0.1);
+
+ game->stopSound(AMBIENT_SND_ENGR);
+ game->playSound(AMBIENT_SND_ENGR, -1, 0.09);
+
+ TeSpriteLayout *video = spriteLayoutChecked("video");
+ video->stop();
+ video->setVisible(false);
+ buttonLayoutChecked("videoBackgroundButton")->setVisible(false);
+ buttonLayoutChecked("skipVideoButton")->setVisible(false);
+ _music.stop();
return false;
}
@@ -59,11 +78,44 @@ bool GalleryMenu::onVideoFinished() {
}
void GalleryMenu::enter() {
- error("TODO: implement GalleryMenu::enter");
+ Application *app = g_engine->getApplication();
+ Game *game = g_engine->getGame();
+
+ load("menus/galleryMenu/galleryMenu.lua");
+ TeLayout *menu = layoutChecked("galleryMenu");
+ app->_frontLayout.addChild(menu);
+
+ game->stopSound(AMBIENT_SND_BIKE);
+ game->playSound(AMBIENT_SND_BIKE, -1, 0.1);
+
+ game->stopSound(AMBIENT_SND_ENGR);
+ game->playSound(AMBIENT_SND_ENGR, -1, 0.09);
+
+ TeButtonLayout *btn = buttonLayoutChecked("quitButton");
+ btn->onMouseClickValidated().add(this, &GalleryMenu::onQuitButton);
+
+ //TeLayout *list = layoutChecked("galleryList");
+
+ error("TODO: Finish GalleryMenu::enter");
}
void GalleryMenu::leave() {
- error("TODO: implement GalleryMenu::leave");
+ if (!_loaded)
+ return;
+
+ Game *game = g_engine->getGame();
+ game->stopSound(AMBIENT_SND_BIKE);
+ game->stopSound(AMBIENT_SND_ENGR);
+ unload();
+ for (GalleryBtnObject *btn : _btnObjects) {
+ delete btn;
+ }
+ _btnObjects.clear();
+}
+
+bool GalleryMenu::GalleryBtnObject::onValidated() {
+ error("TODO: Implement GalleryMenu::GalleryBtnObject::onValidated");
}
+
} // end namespace Tetraedge
diff --git a/engines/tetraedge/game/gallery_menu.h b/engines/tetraedge/game/gallery_menu.h
index 50dd39ee656..cb974f424b6 100644
--- a/engines/tetraedge/game/gallery_menu.h
+++ b/engines/tetraedge/game/gallery_menu.h
@@ -32,8 +32,12 @@ class GalleryMenu : public TeLuaGUI {
public:
GalleryMenu();
- class GalleryBtnObject {
- bool OnValidated();
+ struct GalleryBtnObject {
+ bool onValidated();
+
+ Common::String _audioPath;
+ Common::String _moviePath;
+ GalleryMenu *_owner;
};
void enter();
@@ -43,6 +47,7 @@ public:
bool onLockVideoButtonValidated();
bool onSkipVideoButtonValidated();
bool onVideoFinished();
+ TeMusic &music();
private:
TeMusic _music;
diff --git a/engines/tetraedge/game/game.cpp b/engines/tetraedge/game/game.cpp
index 9d4ee36803f..427a56abbf4 100644
--- a/engines/tetraedge/game/game.cpp
+++ b/engines/tetraedge/game/game.cpp
@@ -40,7 +40,7 @@ namespace Tetraedge {
Game::Game() : _objectsTakenVal(0), _score(0), _entered(false), _gameLoadState(0),
_noScaleLayout(nullptr), _noScaleLayout2(nullptr), _warped(false), _saveRequested(false),
-_firstInventory(true) {
+_firstInventory(true), _movePlayerCharacterDisabled(false) {
for (int i = 0; i < NUM_OBJECTS_TAKEN_IDS; i++) {
_objectsTakenBits[i] = false;
}
@@ -183,11 +183,56 @@ bool Game::changeWarp(const Common::String &zone, const Common::String &scene, b
}
bool Game::changeWarp2(const Common::String &zone, const Common::String &scene, bool fadeFlag) {
- error("TODO: Implemet me");
+ _warped = false;
+ _movePlayerCharacterDisabled = false;
+ _sceneCharacterVisibleFromLoad = false;
+ // TODO: set 3 other fields here (0x3f40 = -1, 0x4249 = 1, 0x424b = 0)
+ Common::Path luapath("scenes");
+ luapath.joinInPlace(zone);
+ luapath.joinInPlace(scene);
+ luapath.joinInPlace("Logic");
+ luapath.appendInPlace(zone);
+ luapath.appendInPlace(".lua");
+
+ if (Common::File::exists(luapath)) {
+ _luaScript.execute("OnLeave");
+ _luaContext.removeGlobal("On");
+ _luaContext.removeGlobal("OnEnter");
+ _luaContext.removeGlobal("OnWarpObjectHit");
+ _luaContext.removeGlobal("OnButtonDown");
+ _luaContext.removeGlobal("OnButtonUp");
+ _luaContext.removeGlobal("OnFinishedAnim");
+ _luaContext.removeGlobal("OnCharacterAnimationFinished");
+ _luaContext.removeGlobal("OnCharacterAnimationPlayerFinished");
+ _luaContext.removeGlobal("OnDisplacementFinished");
+ _luaContext.removeGlobal("OnFreeSoundFinished");
+ _luaContext.removeGlobal("OnDocumentClosed");
+ _luaContext.removeGlobal("OnSelectedObject");
+ _luaContext.removeGlobal("OnDialogFinished");
+ _luaContext.removeGlobal("OnAnswered");
+ _luaContext.removeGlobal("OnLeave");
+ _luaScript.unload();
+ }
+
+ _gui3.unload();
+ _prevSceneName = _currentScene;
+ if (fadeFlag)
+ g_engine->getApplication()->fade();
+
+ return initWarp(zone, scene, false);
}
void Game::deleteNoScale() {
- error("TODO: Implemet me");
+ if (_noScaleLayout) {
+ removeNoScaleChildren();
+ delete _noScaleLayout;
+ _noScaleLayout = nullptr;
+ }
+ if (_noScaleLayout2) {
+ removeNoScale2Children();
+ delete _noScaleLayout2;
+ _noScaleLayout2 = nullptr;
+ }
}
void Game::draw() {
@@ -206,6 +251,7 @@ void Game::enter(bool newgame) {
app->visualFade().init();
Common::SharedPtr<TeCallback1Param<Game, const Common::Point &>> callbackptr(new TeCallback1Param<Game, const Common::Point &>(this, &Game::onMouseClick, -1000.0f));
g_engine->getInputMgr()->_mouseLUpSignal.insert(callbackptr);
+ _movePlayerCharacterDisabled = false;
warning("TODO: Game::enter set some other fields here");
_sceneCharacterVisibleFromLoad = false;
Character::loadSettings("models/ModelsSettings.xml");
@@ -360,10 +406,10 @@ void Game::initScene(bool fade, const Common::String &scenePath) {
_scene._character->_model->setVisible(true);
}
-void Game::initWarp(const Common::String &zone, const Common::String &scene, bool fadeFlag) {
+bool Game::initWarp(const Common::String &zone, const Common::String &scene, bool fadeFlag) {
_inventoryMenu.unload();
_gui4.unload();
- warning("Game::initWarp: set field_0x4248 false here");
+ _movePlayerCharacterDisabled = false;
_sceneCharacterVisibleFromLoad = true;
if (_scene._character) {
@@ -401,10 +447,11 @@ void Game::initWarp(const Common::String &zone, const Common::String &scene, boo
if (!intLuaExists && !logicLuaExists && !setLuaExists && !forLuaExists && !markerLuaExists) {
debug("No lua scripts for scene %s zone %s", scene.c_str(), zone.c_str());
- return;
+ return false;
}
- warning("TODO: Game::initWarp: stop game sounds");
+ if (!_gameSounds.empty())
+ warning("TODO: Game::initWarp: stop game sounds");
if (logicLuaExists) {
_luaContext.addBindings(LuaBinds::LuaOpenBinds);
@@ -451,8 +498,9 @@ void Game::initWarp(const Common::String &zone, const Common::String &scene, boo
TeButtonLayout *vidbgbtn = _gui4.buttonLayout("videoBackgroundButton");
vidbgbtn->setVisible(false);
- vidbgbtn->onMouseClickValidated().remove(this, &Game::onLockVideoButtonValidated);
- vidbgbtn->onMouseClickValidated().add(this, &Game::onLockVideoButtonValidated);
+ /* TODO: Restore the original behavior here (onLockVideoButtonValidated) */
+ vidbgbtn->onMouseClickValidated().remove(this, &Game::onSkipVideoButtonValidated);
+ vidbgbtn->onMouseClickValidated().add(this, &Game::onSkipVideoButtonValidated);
TeSpriteLayout *video = _gui4.spriteLayout("video");
video->setVisible(false);
@@ -530,10 +578,14 @@ void Game::initWarp(const Common::String &zone, const Common::String &scene, boo
_luaScript.execute("OnSelectedObject", _inventory.selectedObject());
}
- //for (auto & sound : _gameSounds) {
- warning("TODO: Game::initWarp: Do game sound stuff here");
+ if (!_gameSounds.empty()) {
+ //for (auto & sound : _gameSounds) {
+ warning("TODO: Game::initWarp: Do game sound stuff here");
+ }
+ // TODO: Also do random sound stuff here.
_scene.initScroll();
+ return true;
}
bool Game::isDocumentOpened() {
@@ -549,7 +601,7 @@ bool Game::isMoviePlaying() {
}
bool Game::launchDialog(const Common::String ¶m_1, uint param_2, const Common::String ¶m_3,
- const Common::String ¶m_4, float param_5) {
+ const Common::String ¶m_4, float param_5) {
error("TODO: Implemet Game::launchDialog");
}
@@ -666,7 +718,7 @@ bool Game::onMarkersVisible(TeCheckboxLayout::State state) {
return false;
}
-bool Game::onMouseClick(const Common::Point &pt) {
+bool Game::onMouseClick(const Common::Point &pt) {
Application *app = g_engine->getApplication();
if (app->isFading())
@@ -832,6 +884,10 @@ void Game::playMovie(const Common::String &vidPath, const Common::String &musicP
music.play();
videoSpriteLayout->play();
+ // FIXME TODO!! Stop the movie and soundearly for testing.
+ videoSpriteLayout->_tiledSurfacePtr->_frameAnim._nbFrames = 10;
+ music.stop();
+
app->fade();
}
@@ -950,7 +1006,7 @@ bool Game::unloadCharacters() {
}
bool Game::unloadPlayerCharacter(const Common::String &character) {
- _scene.unloadPlayerCharacter(character);
+ _scene.unloadCharacter(character);
return true;
}
diff --git a/engines/tetraedge/game/game.h b/engines/tetraedge/game/game.h
index 62906a4ee61..d65a9fc7d36 100644
--- a/engines/tetraedge/game/game.h
+++ b/engines/tetraedge/game/game.h
@@ -30,6 +30,7 @@
#include "tetraedge/game/in_game_scene.h"
#include "tetraedge/game/notifier.h"
#include "tetraedge/game/cellphone.h"
+#include "tetraedge/game/game_sound.h"
#include "tetraedge/game/objectif.h"
#include "tetraedge/game/question2.h"
#include "tetraedge/game/dialog2.h"
@@ -44,12 +45,16 @@ class Game {
public:
Game();
- class HitObject {
+ struct HitObject {
byte OnChangeWarp();
byte OnDown();
byte OnUp();
byte OnValidated();
//byte OnVisible(); empty never used?
+
+ Common::String _name;
+ Game *_game;
+ TeButtonLayout *_button;
};
class RandomSound {
@@ -92,7 +97,7 @@ public:
void initLoadedBackupData();
void initNoScale();
void initScene(bool param_1, const Common::String &scenePath);
- void initWarp(const Common::String &zone, const Common::String &scene, bool fadeFlag);
+ bool initWarp(const Common::String &zone, const Common::String &scene, bool fadeFlag);
bool isDocumentOpened();
bool isMouse() { return false; }
bool isMoviePlaying();
@@ -156,8 +161,11 @@ public:
const Common::String ¤tZone() { return _currentZone; }
const Common::String ¤tScene() { return _currentScene; }
+ const Common::Path &sceneZonePath() { return _sceneZonePath; }
TeLuaScript &luaScript() { return _luaScript; }
InGameScene &scene() { return _scene; }
+ Dialog2 &dialog2() { return _dialog2; }
+ Question2 &question2() { return _question2; }
private:
bool _luaShowOwnerError;
@@ -194,6 +202,8 @@ private:
Common::String _loadName;
+ Common::Array<GameSound *> _gameSounds;
+
Common::HashMap<Common::String, bool> _unlockedArtwork;
int _gameLoadState;
@@ -219,6 +229,7 @@ private:
bool _sceneCharacterVisibleFromLoad;
bool _markersVisible;
bool _saveRequested;
+ bool _movePlayerCharacterDisabled;
TeLayout *_noScaleLayout;
TeLayout *_noScaleLayout2;
diff --git a/engines/tetraedge/game/global_bonus_menu.cpp b/engines/tetraedge/game/global_bonus_menu.cpp
index 610e79884a3..dfabd6a27dc 100644
--- a/engines/tetraedge/game/global_bonus_menu.cpp
+++ b/engines/tetraedge/game/global_bonus_menu.cpp
@@ -29,26 +29,48 @@ GlobalBonusMenu::GlobalBonusMenu() : _entered(false) {
}
void GlobalBonusMenu::enter() {
- error("TODO: Finish implementing GlobalBonusMenu::enter");
- //Application *app = g_engine->getApplication();
- //todo: call some virtual function on a field in app
- //app->captureFade();
- //_entered = true;
- //load("menus/bonusmenu/GlobalBonusMenu.lua");
- //TeLayout *menu = layout("menu");
- //if (menu) {
- // ...
- //}
+ Application *app = g_engine->getApplication();
+ app->appSpriteLayout().setVisible(true);
+ app->captureFade();
+ _entered = true;
+ load("menus/bonusmenu/GlobalBonusMenu.lua");
+ TeLayout *menu = layoutChecked("menu");
+ app->_frontLayout.addChild(menu);
+
+ // Original checks each layout's existence
+ TeButtonLayout *btn;
+ btn = buttonLayoutChecked("Val");
+ if (btn)
+ btn->onMouseClickValidated().add(this, &GlobalBonusMenu::onValButtonValidated);
+ btn = buttonLayoutChecked("Bar");
+ if (btn)
+ btn->onMouseClickValidated().add(this, &GlobalBonusMenu::onBarButtonValidated);
+ btn = buttonLayoutChecked("Cit");
+ if (btn)
+ btn->onMouseClickValidated().add(this, &GlobalBonusMenu::onCitButtonValidated);
+ btn = buttonLayoutChecked("Ara");
+ if (btn)
+ btn->onMouseClickValidated().add(this, &GlobalBonusMenu::onAraButtonValidated);
+ btn = buttonLayoutChecked("Syb2");
+ if (btn)
+ btn->onMouseClickValidated().add(this, &GlobalBonusMenu::onSyb2ButtonValidated);
+ btn = buttonLayoutChecked("Syb3");
+ if (btn)
+ btn->onMouseClickValidated().add(this, &GlobalBonusMenu::onSyb3ButtonValidated);
+ btn = buttonLayoutChecked("Back");
+ if (btn)
+ btn->onMouseClickValidated().add(this, &GlobalBonusMenu::onQuitButton);
}
void GlobalBonusMenu::leave() {
- if (_entered != 0) {
- Application *app = g_engine->getApplication();
- app->captureFade();
- TeLuaGUI::unload();
- app->fade();
- _entered = false;
- }
+ if (!_entered)
+ return;
+
+ Application *app = g_engine->getApplication();
+ app->captureFade();
+ TeLuaGUI::unload();
+ app->fade();
+ _entered = false;
}
bool GlobalBonusMenu::onSomeButtonValidated(const char *script) {
diff --git a/engines/tetraedge/game/help_option_menu.cpp b/engines/tetraedge/game/help_option_menu.cpp
index 0e17ec9c287..1c3cd972e1e 100644
--- a/engines/tetraedge/game/help_option_menu.cpp
+++ b/engines/tetraedge/game/help_option_menu.cpp
@@ -33,7 +33,10 @@ void HelpOptionMenu::enter() {
Application *app = g_engine->getApplication();
app->captureFade();
load("menus/helpoptionMenu/optionsMenu.lua");
- error("TODO: finish implementation of HelpOptionMenu::enter");
+
+ TeLayout *menu = layoutChecked("menu");
+ app->appSpriteLayout().addChild(menu);
+ app->fade();
}
}
diff --git a/engines/tetraedge/game/in_game_scene.cpp b/engines/tetraedge/game/in_game_scene.cpp
index 92f4eb2f52c..9c88e98f9dc 100644
--- a/engines/tetraedge/game/in_game_scene.cpp
+++ b/engines/tetraedge/game/in_game_scene.cpp
@@ -29,29 +29,67 @@
#include "tetraedge/game/game.h"
#include "tetraedge/game/in_game_scene.h"
#include "tetraedge/game/character.h"
+#include "tetraedge/game/characters_shadow.h"
#include "tetraedge/game/object3d.h"
+#include "tetraedge/game/scene_lights_xml_parser.h"
+
+#include "tetraedge/te/te_bezier_curve.h"
+#include "tetraedge/te/te_camera.h"
+#include "tetraedge/te/te_free_move_zone.h"
+#include "tetraedge/te/te_light.h"
+#include "tetraedge/te/te_renderer.h"
namespace Tetraedge {
-InGameScene::InGameScene() : _character(nullptr) {
+InGameScene::InGameScene() : _character(nullptr), _charactersShadow(nullptr), _shadowLightNo(-1) {
+}
+
+void InGameScene::activateAnchorZone(const Common::String &name, bool val) {
+ for (AnchorZone *zone : _anchorZones) {
+ if (zone->_name == name)
+ zone->_activated = val;
+ }
}
void InGameScene::draw() {
- error("TODO: implement InGameScene::draw");
+ TeScene::draw();
+
+ if (currentCameraIndex() >= (int)cameras().size())
+ return;
+
+ currentCamera()->apply();
+ TeLight::updateGlobal();
+ for (unsigned int i = 0; i < _lights.size(); i++)
+ _lights[i].update(i);
+
+ currentCamera()->restore();
+}
+
+void InGameScene::drawPath() {
+ if (currentCameraIndex() >= (int)cameras().size())
+ return;
+
+ currentCamera()->apply();
+ g_engine->getRenderer()->disableZBuffer();
+
+ warning("TODO: Do free move zones in InGameScene::drawPath");
+ //for (unsigned int i = 0; i < _freeMoveZones.size(); i++)
+ // _freeMoveZones[i]->
+
+ g_engine->getRenderer()->enableZBuffer();
}
+
bool InGameScene::changeBackground(const Common::String &name) {
if (Common::File::exists(name)) {
- TeSpriteLayout *spriteLayout = _bgGui.spriteLayout("root");
- assert(spriteLayout);
- spriteLayout->load(name);
+ _bgGui.spriteLayoutChecked("root")->load(name);
return true;
}
return false;
}
-
-/*static*/ float InGameScene::angularDistance(float a1, float a2) {
+/*static*/
+float InGameScene::angularDistance(float a1, float a2) {
float result;
result = a2 - a1;
@@ -74,7 +112,7 @@ void InGameScene::close() {
void InGameScene::reset() {
if (_character)
- _character->setFreeMoveZone(Common::SharedPtr<TeFreeMoveZone>());
+ _character->setFreeMoveZone(nullptr);
freeSceneObjects();
_bgGui.unload();
unloadSpriteLayouts();
@@ -86,10 +124,9 @@ void InGameScene::deleteAllCallback() {
warning("TODO: implement InGameScene::deleteAllCallback");
}
-
void InGameScene::freeSceneObjects() {
if (_character) {
- warning("TODO: InGameScene::freeSceneObjects: Set field on character here");
+ _character->setCharLookingAt(nullptr);
_character->deleteAllCallback();
}
if (_characters.size() == 1) {
@@ -136,10 +173,212 @@ Character *InGameScene::character(const Common::String &name) {
error("TODO: Implement InGameScene::character");
}
+bool InGameScene::load(const Common::Path &path) {
+ _actZones.clear();
+ Common::File actzonefile;
+ if (actzonefile.open(getActZoneFileName())) {
+ if (Te3DObject2::loadAndCheckFourCC(actzonefile, "0TCA")) {
+ uint32 count = actzonefile.readUint32LE();
+ if (count > 1000000)
+ error("Improbable number of actzones %d", count);
+ _actZones.resize(count);
+ for (unsigned int i = 0; i < _actZones.size(); i++) {
+ _actZones[i].s1 = Te3DObject2::deserializeString(actzonefile);
+ _actZones[i].s2 = Te3DObject2::deserializeString(actzonefile);
+ for (int j = 0; j < 4; j++)
+ TeVector2f32::deserialize(actzonefile, _actZones[i].points[j]);
+ _actZones[i].flag1 = (actzonefile.readByte() != 0);
+ _actZones[i].flag2 = true;
+ }
+ }
+ }
+ if (!_lights.empty()) {
+ TeLight::disableAll();
+ for (unsigned int i = 0; i < _lights.size(); i++) {
+ _lights[i].disable(i);
+ }
+ _lights.clear();
+ }
+ _shadowLightNo = -1;
+
+ const Common::Path lightspath = getLightsFileName();
+ if (Common::File::exists(lightspath))
+ loadLights(lightspath);
+
+ if (!Common::File::exists(path))
+ return false;
+
+ TeScene::close();
+ _loadedPath = path;
+ Common::File scenefile;
+ if (!scenefile.open(path))
+ return false;
+
+ uint32 ncameras = scenefile.readUint32LE();
+ for (unsigned int i = 0; i < ncameras; i++) {
+ TeIntrusivePtr<TeCamera> cam = new TeCamera();
+ deserializeCam(scenefile, cam);
+ cameras().push_back(cam);
+ }
+
+ uint32 nobjects = scenefile.readUint32LE();
+ for (unsigned int i = 0; i < nobjects; i++) {
+ TeIntrusivePtr<TeModel> model = new TeModel();
+ const Common::String modelname = Te3DObject2::deserializeString(scenefile);
+ model->setName(modelname);
+ const Common::String objname = Te3DObject2::deserializeString(scenefile);
+ TePickMesh2 *pickmesh = new TePickMesh2();
+ deserializeModel(scenefile, model, pickmesh);
+ if (modelname.contains("Clic")) {
+ _hitObjects.push_back(model);
+ // TODO: double-check this, probably right?
+ model->setVisible(false);
+ model->setColor(TeColor(0, 0xff, 0, 0xff));
+ models().push_back(model);
+ pickmesh->setName(modelname);
+ } else {
+ delete pickmesh;
+ if (modelname.substr(0, 2) != "ZB") {
+ if (objname.empty()) {
+ warning("[InGameScene::load] Unknown type of object named : %s", modelname.c_str());
+ } else {
+ InGameScene::Object obj;
+ obj._name = objname;
+ obj._model = model;
+ _objects.push_back(obj);
+ model->setVisible(false);
+ models().push_back(model);
+ }
+ }
+ }
+ }
+
+ uint32 nfreemovezones = scenefile.readUint32LE();
+ for (unsigned int i = 0; i < nfreemovezones; i++) {
+ TeFreeMoveZone *zone = new TeFreeMoveZone();
+ TeFreeMoveZone::deserialize(scenefile, *zone, &_blockers, &_rectBlockers, &_actZones);
+
+ }
+
+ uint32 ncurves = scenefile.readUint32LE();
+ for (unsigned int i = 0; i < ncurves; i++) {
+ TeIntrusivePtr<TeBezierCurve> curve = new TeBezierCurve();
+ TeBezierCurve::deserialize(scenefile, *curve);
+ curve->setVisible(true);
+ _bezierCurves.push_back(curve);
+ }
+
+ uint32 ndummies = scenefile.readUint32LE();
+ for (unsigned int i = 0; i < ndummies; i++) {
+ InGameScene::Dummy dummy;
+ TeVector3f32 vec;
+ TeQuaternion rot;
+ dummy._name = Te3DObject2::deserializeString(scenefile);
+ TeVector3f32::deserialize(scenefile, vec);
+ dummy._position = vec;
+ TeQuaternion::deserialize(scenefile, rot);
+ dummy._rotation = rot;
+ TeVector3f32::deserialize(scenefile, vec);
+ dummy._scale = vec;
+ _dummies.push_back(dummy);
+ }
+
+ for (TeFreeMoveZone *zone : _freeMoveZones) {
+ convertPathToMesh(zone);
+ }
+ _charactersShadow = new CharactersShadow();
+ _charactersShadow->create(this);
+ onMainWindowSizeChanged();
+ return true;
+}
+
+void InGameScene::convertPathToMesh(TeFreeMoveZone *zone) {
+ error("TODO: Implement InGameScene::convertPathToMesh");
+}
+
+void InGameScene::onMainWindowSizeChanged() {
+ error("TODO: Implement InGameScene::onMainWindowSizeChanged");
+}
+
+bool InGameScene::loadLights(const Common::Path &path) {
+ SceneLightsXmlParser parser;
+
+ parser.setLightArray(&_lights);
+
+ if (!parser.loadFile(path.toString()))
+ error("InGameScene::loadLights: Can't load %s", path.toString().c_str());
+ if (!parser.parse())
+ error("InGameScene::loadLights: Can't parse %s", path.toString().c_str());
+
+ _shadowColor = parser.getShadowColor();
+ _shadowLightNo = parser.getShadowLightNo();
+ _shadowFarPlane = parser.getShadowFarPlane();
+ _shadowNearPlane = parser.getShadowNearPlane();
+ _shadowFov = parser.getShadowFov();
+
+ return true;
+}
+
bool InGameScene::loadCharacter(const Common::String &name) {
error("TODO: Implement InGameScene::loadCharacter");
}
+void InGameScene::deserializeCam(Common::ReadStream &stream, TeIntrusivePtr<TeCamera> &cam) {
+ cam->_projectionMatrixType = 2;
+ cam->viewport(0, 0, _viewportSize.getX(), _viewportSize.getY());
+ Te3DObject2::deserialize(stream, *cam);
+ cam->_focalLenMaybe = stream.readFloatLE();
+ cam->_somePerspectiveVal = stream.readFloatLE();
+ cam->_orthNearVal = stream.readFloatLE();
+ cam->_orthFarVal = 3000.0;
+}
+
+void InGameScene::deserializeModel(Common::ReadStream &stream, TeIntrusivePtr<TeModel> &model, TePickMesh2 *pickmesh) {
+ TeVector3f32 vec;
+ TeVector2f32 vec2;
+ TeQuaternion rot;
+ TeColor col;
+ TeMesh mesh;
+
+ TeVector3f32::deserialize(stream, vec);
+ model->setPosition(vec);
+ pickmesh->setPosition(vec);
+ TeQuaternion::deserialize(stream, rot);
+ model->setRotation(rot);
+ pickmesh->setRotation(rot);
+ TeVector3f32::deserialize(stream, vec);
+ model->setScale(vec);
+ pickmesh->setScale(vec);
+ uint32 indexcount = stream.readUint32LE();
+ uint32 vertexcount = stream.readUint32LE();
+
+ mesh.setConf(vertexcount, indexcount, TeMesh::MeshMode_Triangles, 0, 0);
+ for (unsigned int i = 0; i < indexcount; i++)
+ mesh.setIndex(i, stream.readUint32LE());
+ for (unsigned int i = 0; i < vertexcount; i++) {
+ TeVector3f32::deserialize(stream, vec);
+ mesh.setVertex(i, vec);
+ }
+ for (unsigned int i = 0; i < vertexcount; i++) {
+ TeVector3f32::deserialize(stream, vec);
+ mesh.setNormal(i, vec);
+ }
+ for (unsigned int i = 0; i < vertexcount; i++) {
+ TeVector2f32::deserialize(stream, vec2);
+ mesh.setTextureUV(i, vec2);
+ }
+ for (unsigned int i = 0; i < vertexcount; i++) {
+ col.deserialize(stream);
+ mesh.setColor(i, col);
+ }
+ pickmesh->setNbTriangles(indexcount / 3);
+ for (unsigned int i = 0; i < indexcount; i++) {
+ vec = mesh.vertex(mesh.index(i));
+ pickmesh->verticies().push_back(vec);
+ }
+ model->addMesh(mesh);
+}
+
bool InGameScene::loadPlayerCharacter(const Common::String &name) {
if (_character == nullptr) {
_character = new Character();
@@ -162,10 +401,6 @@ bool InGameScene::loadPlayerCharacter(const Common::String &name) {
return true;
}
-void InGameScene::unloadPlayerCharacter(const Common::String &name) {
- error("TODO: Implement InGameScene::unloadPlayerCharacter %s", name.c_str());
-}
-
void InGameScene::unloadCharacter(const Common::String &name) {
warning("TODO: Implement InGameScene::unloadCharacter %s", name.c_str());
}
@@ -178,21 +413,62 @@ bool InGameScene::findKate() {
return false;
}
-Common::Path InGameScene::getBlockersFileName() {
+static Common::Path _sceneFileNameBase() {
Game *game = g_engine->getGame();
Common::Path retval("scenes");
retval.joinInPlace(game->currentZone());
retval.joinInPlace(game->currentScene());
- retval.joinInPlace("blockers.bin");
return retval;
}
+Common::Path InGameScene::getLightsFileName() const {
+ return _sceneFileNameBase().joinInPlace("lights.xml");
+}
+
+Common::Path InGameScene::getActZoneFileName() const {
+ return _sceneFileNameBase().joinInPlace("actions.bin");
+}
+
+Common::Path InGameScene::getBlockersFileName() const {
+ return _sceneFileNameBase().joinInPlace("blockers.bin");
+}
+
void InGameScene::loadBlockers() {
_blockers.clear();
_rectBlockers.clear();
const Common::Path blockersPath = getBlockersFileName();
- if (Common::File::exists(blockersPath)) {
- error("TODO: Implement InGameScene::loadBlockers");
+ if (!Common::File::exists(blockersPath))
+ return;
+
+ Common::File blockersfile;
+ if (!blockersfile.open(blockersPath)) {
+ warning("Couldn't open blockers file %s.", blockersPath.toString().c_str());
+ return;
+ }
+
+ bool hasHeader = Te3DObject2::loadAndCheckFourCC(blockersfile, "BLK0");
+ if (!hasHeader)
+ blockersfile.seek(0);
+
+ uint32 nblockers = blockersfile.readUint32LE();
+ _blockers.resize(nblockers);
+ for (unsigned int i = 0; i < nblockers; i++) {
+ _blockers[i]._s = Te3DObject2::deserializeString(blockersfile);
+ TeVector2f32::deserialize(blockersfile, _blockers[i]._pts[0]);
+ TeVector2f32::deserialize(blockersfile, _blockers[i]._pts[1]);
+ _blockers[i]._x = 1;
+ }
+
+ if (hasHeader) {
+ uint32 nrectblockers = blockersfile.readUint32LE();
+ _rectBlockers.resize(nrectblockers);
+ for (unsigned int i = 0; i < nrectblockers; i++) {
+ _rectBlockers[i]._s = Te3DObject2::deserializeString(blockersfile);
+ for (unsigned int j = 0; j < 4l; j++) {
+ TeVector2f32::deserialize(blockersfile, _rectBlockers[i]._pts[j]);
+ }
+ _rectBlockers[i]._x = 1;
+ }
}
}
@@ -218,7 +494,16 @@ void InGameScene::loadBackground(const Common::Path &path) {
}
void InGameScene::loadInteractions(const Common::Path &path) {
- error("TODO: Implement InGameScene::loadInteractions");
+ _gui3.load(path);
+ TeLayout *bgbackground = _bgGui.layoutChecked("background");
+ Game *game = g_engine->getGame();
+ TeSpriteLayout *root = game->findSpriteLayoutByName(bgbackground, "root");
+ TeLayout *background = _gui3.layoutChecked("background");
+ // TODO: For all TeButtonLayout childen of background, call
+ // setDoubleValidationProtectionEnabled(false)
+ // For now our button doesn't implement that.
+ background->setRatioMode(TeILayout::RATIO_MODE_NONE);
+ root->addChild(background);
}
void InGameScene::setStep(const Common::String &scene, const Common::String &step1, const Common::String &step2) {
diff --git a/engines/tetraedge/game/in_game_scene.h b/engines/tetraedge/game/in_game_scene.h
index d0e73c94eeb..ec557257632 100644
--- a/engines/tetraedge/game/in_game_scene.h
+++ b/engines/tetraedge/game/in_game_scene.h
@@ -28,12 +28,19 @@
#include "tetraedge/game/object3d.h"
#include "tetraedge/game/billboard.h"
+
+#include "tetraedge/te/te_act_zone.h"
+#include "tetraedge/te/te_bezier_curve.h"
+#include "tetraedge/te/te_free_move_zone.h"
#include "tetraedge/te/te_scene.h"
+#include "tetraedge/te/te_light.h"
#include "tetraedge/te/te_lua_gui.h"
+#include "tetraedge/te/te_pick_mesh2.h"
namespace Tetraedge {
class Character;
+class CharactersShadow;
class TeLayout;
class InGameScene : public TeScene {
@@ -52,13 +59,27 @@ public:
Common::String _stepSound2;
};
- class AnchorZone {
+ struct AnchorZone {
+ Common::String _name;
+ bool _activated;
+ };
+
+ struct Object {
+ TeIntrusivePtr<TeModel> _model;
+ Common::String _name;
};
class TeMarker {
};
- void activateAnchorZone(const Common::String &name, bool param_2);
+ struct Dummy {
+ Common::String _name;
+ TeVector3f32 _position;
+ TeQuaternion _rotation;
+ TeVector3f32 _scale;
+ };
+
+ void activateAnchorZone(const Common::String &name, bool val);
void addAnchorZone(const Common::String ¶m_1, const Common::String ¶m_2, float param_3);
void addBlockingObject(const Common::String &obj) {
_blockingObjects.push_back(obj);
@@ -68,18 +89,30 @@ public:
static float angularDistance(float a1, float a2);
bool aroundAnchorZone(const AnchorZone *zone);
TeLayout *background();
+ virtual bool load(const Common::Path &path) override;
void loadBackground(const Common::Path &path);
void loadInteractions(const Common::Path &path);
void initScroll();
void draw();
+ void drawPath();
Character *character(const Common::String &name);
bool loadCharacter(const Common::String &name);
+ void loadBlockers();
bool loadPlayerCharacter(const Common::String &name);
+ bool loadLights(const Common::Path &path);
bool changeBackground(const Common::String &name);
- void unloadPlayerCharacter(const Common::String &character);
void unloadCharacter(const Common::String &name);
+ // Original has a typo, "converPathToMesh", corrected.
+ void convertPathToMesh(TeFreeMoveZone *zone);
+ void onMainWindowSizeChanged();
+
+ // Original just calls these "deserialize" but that's a fairly vague name
+ // so renamed to be more meaningful.
+ void deserializeCam(Common::ReadStream &stream, TeIntrusivePtr<TeCamera> &cam);
+ void deserializeModel(Common::ReadStream &stream, TeIntrusivePtr<TeModel> &model, TePickMesh2 *pickmesh);
+
void close();
void reset();
void freeSceneObjects();
@@ -88,8 +121,9 @@ public:
void setStep(const Common::String &scene, const Common::String &step1, const Common::String &step2);
- void loadBlockers();
- Common::Path getBlockersFileName();
+ Common::Path getActZoneFileName() const;
+ Common::Path getBlockersFileName() const;
+ Common::Path getLightsFileName() const;
// Does nothing, but to keep calls from original..
static void updateScroll() {};
@@ -101,12 +135,19 @@ public:
TeLuaGUI &bgGui() { return _bgGui; }
+ int _shadowLightNo;
+ CharactersShadow *_charactersShadow;
+
private:
- struct TeBlocker {};
- struct TeRectBlocker {};
+ TeColor _shadowColor;
+ float _shadowFarPlane;
+ float _shadowNearPlane;
+ float _shadowFov;
Common::Array<TeBlocker> _blockers;
Common::Array<TeRectBlocker> _rectBlockers;
+ Common::Array<TeActZone> _actZones;
+ Common::Array<TeFreeMoveZone*> _freeMoveZones;
Common::Array<TeMarker *> _markers;
Common::Array<AnchorZone *> _anchorZones;
Common::Array<AnimObject *> _animObjects;
@@ -116,14 +157,23 @@ private:
Common::HashMap<Common::String, SoundStep> _soundSteps;
+ Common::Array<TeIntrusivePtr<TeModel>> _hitObjects;
+ Common::Array<Object> _objects;
+ Common::Array<TeIntrusivePtr<TeBezierCurve>> _bezierCurves;
+ Common::Array<Dummy> _dummies;
+
TeIntrusivePtr<TeModel> _playerCharacterModel;
Common::Array<Common::String> _blockingObjects;
TeLuaGUI _bgGui;
TeLuaGUI _gui2; // TODO: find a better name.
TeLuaGUI _gui3; // TODO: find a better name.
- // TODO add private members
+
+ Common::Array<TeLight> _lights;
TeVector2f32 _someScrollVector;
+ TeVector2f32 _viewportSize;
+
+ Common::Path _loadedPath;
};
} // end namespace Tetraedge
diff --git a/engines/tetraedge/game/inventory_menu.cpp b/engines/tetraedge/game/inventory_menu.cpp
index 31f0294eb29..a98c855c2da 100644
--- a/engines/tetraedge/game/inventory_menu.cpp
+++ b/engines/tetraedge/game/inventory_menu.cpp
@@ -117,7 +117,7 @@ bool InventoryMenu::onQuitButton() {
}
bool InventoryMenu::onSaveButton(){
- return false;
+ return false;
}
} // end namespace Tetraedge
diff --git a/engines/tetraedge/game/lua_binds.cpp b/engines/tetraedge/game/lua_binds.cpp
index a3f95d08d18..4a38a714a58 100644
--- a/engines/tetraedge/game/lua_binds.cpp
+++ b/engines/tetraedge/game/lua_binds.cpp
@@ -52,7 +52,7 @@ tolua_Error err;
static void AddRandomSound(const Common::String &s1, const Common::String &s2, float f1, float f2){
Game *game = g_engine->getGame();
- game->addRandomSound(s1, s2, f1, f2);
+ game->addRandomSound(s1, s2, f1, f2);
}
static int tolua_ExportedFunctions_AddRandomSound00(lua_State *L) {
@@ -89,9 +89,9 @@ static int tolua_ExportedFunctions_SetSoundStep00(lua_State *L) {
}
static void AddNumber(const Common::String &number) {
- Game *game = g_engine->getGame();
- if (!game->inventory().cellphone()->addNumber(number))
- warning("[AddNumber] Number \"%s\" already exist.", number.c_str());
+ Game *game = g_engine->getGame();
+ if (!game->inventory().cellphone()->addNumber(number))
+ warning("[AddNumber] Number \"%s\" already exist.", number.c_str());
}
static int tolua_ExportedFunctions_AddNumber00(lua_State *L) {
@@ -141,15 +141,21 @@ static int tolua_ExportedFunctions_UnlockArtwork00(lua_State *L) {
error("#ferror in function 'UnlockArtwork': %d %d %s", err.index, err.array, err.type);
}
-static void ChangeWarp(const Common::String &scene, const Common::String &zone) {
+static void ChangeWarp(const Common::String &zone, const Common::String &scene, bool flag) {
+ Game *game = g_engine->getGame();
+ if (game->changeWarp(zone, scene, flag))
+ return;
+ warning("[ChangeWarp] Zone \"%s\" with number Scene \"%s\" don't exist. Please reload and change with correct name.",
+ zone.c_str(), scene.c_str());
}
static int tolua_ExportedFunctions_ChangeWarp00(lua_State *L) {
tolua_Error err;
- if (tolua_isstring(L, 1, 0, &err) && tolua_isstring(L, 2, 0, &err) && tolua_isnoobj(L, 3, &err)) {
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isstring(L, 2, 0, &err) && tolua_isboolean(L, 3, 1, &err) && tolua_isnoobj(L, 4, &err)) {
Common::String s1(tolua_tostring(L, 1, nullptr));
Common::String s2(tolua_tostring(L, 2, nullptr));
- ChangeWarp(s1, s2);
+ bool flag = tolua_toboolean(L, 3, 0);
+ ChangeWarp(s1, s2, flag);
return 0;
}
error("#ferror in function 'ChangeWarp': %d %d %s", err.index, err.array, err.type);
@@ -157,153 +163,153 @@ static int tolua_ExportedFunctions_ChangeWarp00(lua_State *L) {
void LuaOpenBinds(lua_State *L) {
- tolua_open(L);
- tolua_module(L, 0, 0);
- tolua_beginmodule(L, 0);
- /*
- tolua_function(L, "LoadObjectMaterials", tolua_ExportedFunctions_LoadObjectMaterials00);
- tolua_function(L, "LoadObjectMaterials", tolua_ExportedFunctions_LoadObjectMaterials01);
- tolua_function(L, "HideObject", tolua_ExportedFunctions_HideObject00);
- tolua_function(L, "ShowObject", tolua_ExportedFunctions_ShowObject00);
- tolua_function(L, "ShowAllObjects", tolua_ExportedFunctions_ShowAllObjects00);
- tolua_function(L, "SetBackground", tolua_ExportedFunctions_SetBackground00);
- tolua_function(L, "AddBlockingObject", tolua_ExportedFunctions_AddBlockingObject00);
- tolua_function(L, "RemoveBlockingObject", tolua_ExportedFunctions_RemoveBlockingObject00);*/
- tolua_function(L, "ChangeWarp", tolua_ExportedFunctions_ChangeWarp00);
- tolua_function(L, "PlayMovie", tolua_ExportedFunctions_PlayMovie00);
- /*tolua_function(L, "PlayMovieAndWaitForEnd", tolua_ExportedFunctions_PlayMovieAndWaitForEnd00);
- tolua_function(L, "StartAnimationPart", tolua_ExportedFunctions_StartAnimationPart00);
- tolua_function(L, "StartAnimation", tolua_ExportedFunctions_StartAnimation00);
- tolua_function(L, "StartAnimationAndWaitForEnd",
- tolua_ExportedFunctions_StartAnimationAndWaitForEnd00);
- tolua_function(L, "AddAnimToSet", tolua_ExportedFunctions_AddAnimToSet00);
- tolua_function(L, "RequestAutoSave", tolua_ExportedFunctions_RequestAutoSave00);
- tolua_function(L, "SetVisibleButtonZoomed", tolua_ExportedFunctions_SetVisibleButtonZoomed00);
- tolua_function(L, "AddMarker", tolua_ExportedFunctions_AddMarker00);
- tolua_function(L, "SetVisibleMarker", tolua_ExportedFunctions_SetVisibleMarker00);
- tolua_function(L, "DeleteMarker", tolua_ExportedFunctions_DeleteMarker00);
- tolua_function(L, "SetVisibleCellphone", tolua_ExportedFunctions_SetVisibleCellphone00);
- tolua_function(L, "DisabledZone", tolua_ExportedFunctions_DisabledZone00);
- tolua_function(L, "DisabledInt", tolua_ExportedFunctions_DisabledInt00);
- tolua_function(L, "LockCursor", tolua_ExportedFunctions_LockCursor00);
- tolua_function(L, "SetCondition", tolua_ExportedFunctions_SetCondition00);
- tolua_function(L, "UnsetCondition", tolua_ExportedFunctions_UnsetCondition00);
- tolua_function(L, "TutoActive", tolua_ExportedFunctions_TutoActive00);
- tolua_function(L, "LaunchDialog", tolua_ExportedFunctions_LaunchDialog00);
- tolua_function(L, "LaunchDialogAndWaitForEnd", tolua_ExportedFunctions_LaunchDialogAndWaitForEnd00);
- tolua_function(L, "PushAnswer", tolua_ExportedFunctions_PushAnswer00);
- tolua_function(L, "HideAnswers", tolua_ExportedFunctions_HideAnswers00);
- tolua_function(L, "PushTask", tolua_ExportedFunctions_PushTask00);
- tolua_function(L, "DeleteTask", tolua_ExportedFunctions_DeleteTask00);
- tolua_function(L, "SetVisibleButtonHelp", tolua_ExportedFunctions_SetVisibleButtonHelp00);
- tolua_function(L, "HideTasks", tolua_ExportedFunctions_HideTasks00);
- tolua_function(L, "PlaySound", tolua_ExportedFunctions_PlaySound00);
- tolua_function(L, "PlaySoundAndWaitForEnd", tolua_ExportedFunctions_PlaySoundAndWaitForEnd00);
- tolua_function(L, "StopSound", tolua_ExportedFunctions_StopSound00);*/
- tolua_function(L, "AddRandomSound", tolua_ExportedFunctions_AddRandomSound00);
- /*tolua_function(L, "PlayRandomSound", tolua_ExportedFunctions_PlayRandomSound00);
- tolua_function(L, "PlayMusic", tolua_ExportedFunctions_PlayMusic00);*/
- tolua_function(L, "SetSoundStep", tolua_ExportedFunctions_SetSoundStep00);
- /*tolua_function(L, "Selected", tolua_ExportedFunctions_Selected00);
- tolua_function(L, "TakeObject", tolua_ExportedFunctions_TakeObject00);
- tolua_function(L, "TakeObjectInHand", tolua_ExportedFunctions_TakeObjectInHand00);
- tolua_function(L, "RemoveObject", tolua_ExportedFunctions_RemoveObject00);
- tolua_function(L, "RemoveObject", tolua_ExportedFunctions_RemoveObject01);*/
- tolua_function(L, "AddNumber", tolua_ExportedFunctions_AddNumber00);
- /*tolua_function(L, "ShowDocument", tolua_ExportedFunctions_ShowDocument00);
- tolua_function(L, "ShowDocumentAndWaitForEnd", tolua_ExportedFunctions_ShowDocumentAndWaitForEnd00);
- tolua_function(L, "HideDocument", tolua_ExportedFunctions_HideDocument00);
- tolua_function(L, "AddDocument", tolua_ExportedFunctions_AddDocument00);
- tolua_function(L, "LoadCharacter", tolua_ExportedFunctions_LoadCharacter00);
- tolua_function(L, "UnloadCharacter", tolua_ExportedFunctions_UnloadCharacter00);
- tolua_function(L, "GetRotationCharacter", tolua_ExportedFunctions_GetRotationCharacter00);
- tolua_function(L, "GetXPositionCharacter", tolua_ExportedFunctions_GetXPositionCharacter00);
- tolua_function(L, "GetYPositionCharacter", tolua_ExportedFunctions_GetYPositionCharacter00);
- tolua_function(L, "GetZPositionCharacter", tolua_ExportedFunctions_GetZPositionCharacter00);
- tolua_function(L, "MoveCharacterTo", tolua_ExportedFunctions_MoveCharacterTo00);
- tolua_function(L, "MoveCharacterToAndWaitForEnd",
- tolua_ExportedFunctions_MoveCharacterToAndWaitForEnd00);
- tolua_function(L, "MoveCharacterPlayerTo", tolua_ExportedFunctions_MoveCharacterPlayerTo00);
- tolua_function(L, "MoveCharacterPlayerToAndWaitForEnd",
- tolua_ExportedFunctions_MoveCharacterPlayerToAndWaitForEnd00);
- tolua_function(L, "MoveCharacterPlayerAtTo", tolua_ExportedFunctions_MoveCharacterPlayerAtTo00);
- tolua_function(L, "SetCharacterPosition", tolua_ExportedFunctions_SetCharacterPosition00);
- tolua_function(L, "PlaceCharacterOnDummy", tolua_ExportedFunctions_PlaceCharacterOnDummy00);
- tolua_function(L, "SetCharacterRotation", tolua_ExportedFunctions_SetCharacterRotation00);
- tolua_function(L, "SetCharacterOrientation", tolua_ExportedFunctions_SetCharacterOrientation00);
- tolua_function(L, "SetCharacterAnimation", tolua_ExportedFunctions_SetCharacterAnimation00);
- tolua_function(L, "SetCharacterAnimationAndWaitForEnd",
- tolua_ExportedFunctions_SetCharacterAnimationAndWaitForEnd00);
- tolua_function(L, "BlendCharacterAnimation", tolua_ExportedFunctions_BlendCharacterAnimation00);
- tolua_function(L, "BlendCharacterAnimationAndWaitForEnd",
- tolua_ExportedFunctions_BlendCharacterAnimationAndWaitForEnd00);
- tolua_function(L, "CurrentCharacterAnimation", tolua_ExportedFunctions_CurrentCharacterAnimation00);
- tolua_function(L, "SetCharacterPlayerVisible", tolua_ExportedFunctions_SetCharacterPlayerVisible00);
- tolua_function(L, "MoveCharacterPlayerDisabled",
- tolua_ExportedFunctions_MoveCharacterPlayerDisabled00);
- tolua_function(L, "SetRunMode", tolua_ExportedFunctions_SetRunMode00);
- tolua_function(L, "SetRunMode2", tolua_ExportedFunctions_SetRunMode200);
- tolua_function(L, "SetCharacterColor", tolua_ExportedFunctions_SetCharacterColor00);
- tolua_function(L, "SetCharacterSound", tolua_ExportedFunctions_SetCharacterSound00);
- tolua_function(L, "SetCharacterShadow", tolua_ExportedFunctions_SetCharacterShadow00);
- tolua_function(L, "AddCallback", tolua_ExportedFunctions_AddCallback00);
- tolua_function(L, "AddCallbackPlayer", tolua_ExportedFunctions_AddCallbackPlayer00);
- tolua_function(L, "AddCallbackAnimation2D", tolua_ExportedFunctions_AddCallbackAnimation2D00);
- tolua_function(L, "DeleteCallback", tolua_ExportedFunctions_DeleteCallback00);
- tolua_function(L, "DeleteCallbackPlayer", tolua_ExportedFunctions_DeleteCallbackPlayer00);
- tolua_function(L, "DeleteCallbackAnimation2D", tolua_ExportedFunctions_DeleteCallbackAnimation2D00);
- tolua_function(L, "SetObjectOnCharacter", tolua_ExportedFunctions_SetObjectOnCharacter00);
- tolua_function(L, "SetObjectRotation", tolua_ExportedFunctions_SetObjectRotation00);
- tolua_function(L, "SetObjectTranslation", tolua_ExportedFunctions_SetObjectTranslation00);
- tolua_function(L, "SetObjectScale", tolua_ExportedFunctions_SetObjectScale00);
- tolua_function(L, "SetObjectFrames", tolua_ExportedFunctions_SetObjectFrames00);
- tolua_function(L, "LoadObject", tolua_ExportedFunctions_LoadObject00);
- tolua_function(L, "UnloadObject", tolua_ExportedFunctions_UnloadObject00);
- tolua_function(L, "SetGroundObjectPosition", tolua_ExportedFunctions_SetGroundObjectPosition00);
- tolua_function(L, "SetGroundObjectRotation", tolua_ExportedFunctions_SetGroundObjectRotation00);
- tolua_function(L, "TranslateGroundObject", tolua_ExportedFunctions_TranslateGroundObject00);
- tolua_function(L, "RotateGroundObject", tolua_ExportedFunctions_RotateGroundObject00);
- tolua_function(L, "SetLightPlayerCharacter", tolua_ExportedFunctions_SetLightPlayerCharacter00);
- tolua_function(L, "SetLightPos", tolua_ExportedFunctions_SetLightPos00);
- tolua_function(L, "EnableLight", tolua_ExportedFunctions_EnableLight00);
- tolua_function(L, "SetLightDiffuse", tolua_ExportedFunctions_SetLightDiffuse00);
- tolua_function(L, "SetLightAmbient", tolua_ExportedFunctions_SetLightAmbient00);
- tolua_function(L, "SetLightSpecular", tolua_ExportedFunctions_SetLightSpecular00);
- tolua_function(L, "LoadBillBoard", tolua_ExportedFunctions_LoadBillBoard00);
- tolua_function(L, "SetBillboardPosition", tolua_ExportedFunctions_SetBillboardPosition00);
- tolua_function(L, "SetBillboardPosition2", tolua_ExportedFunctions_SetBillboardPosition200);
- tolua_function(L, "SetBillboardSize", tolua_ExportedFunctions_SetBillboardSize00);
- tolua_function(L, "ShowBillboard", tolua_ExportedFunctions_ShowBillboard00);
- tolua_function(L, "HideBillboard", tolua_ExportedFunctions_HideBillboard00);
- tolua_function(L, "UnlockAchievement", tolua_ExportedFunctions_UnlockAchievement00);
- tolua_function(L, "Save", tolua_ExportedFunctions_Save00);
- tolua_function(L, "Wait", tolua_ExportedFunctions_Wait00);
- tolua_function(L, "WaitAndWaitForEnd", tolua_ExportedFunctions_WaitAndWaitForEnd00);
- tolua_function(L, "OpenFinalURL", tolua_ExportedFunctions_OpenFinalURL00);
- tolua_function(L, "FinishGame", tolua_ExportedFunctions_FinishGame00);
- tolua_function(L, "RequestMainMenu", tolua_ExportedFunctions_RequestMainMenu00);
- tolua_function(L, "BFGRateImmediately", tolua_ExportedFunctions_BFGRateImmediately00);
- tolua_function(L, "BFGReportEvent", tolua_ExportedFunctions_BFGReportEvent00);
- tolua_function(L, "BFGReportEventWithValue", tolua_ExportedFunctions_BFGReportEventWithValue00);
- tolua_function(L, "BFGReachedFreemiumLimit", tolua_ExportedFunctions_BFGReachedFreemiumLimit00);
- tolua_function(L, "TestFileFlagSystemFlag", tolua_ExportedFunctions_TestFileFlagSystemFlag00);
- tolua_function(L, "PrintDebugMessage", tolua_ExportedFunctions_PrintDebugMessage00);
- tolua_function(L, "ExitZone", tolua_ExportedFunctions_ExitZone00);
- tolua_function(L, "EnableRectBlocker", tolua_ExportedFunctions_EnableRectBlocker00);
- tolua_function(L, "EnableBlocker", tolua_ExportedFunctions_EnableBlocker00);
- tolua_function(L, "AddAnchorZone", tolua_ExportedFunctions_AddAnchorZone00);
- tolua_function(L, "ActivateAnchorZone", tolua_ExportedFunctions_ActivateAnchorZone00);
- tolua_function(L, "SetCharacterAnchor", tolua_ExportedFunctions_SetCharacterAnchor00);
- tolua_function(L, "SetCharacterLookChar", tolua_ExportedFunctions_SetCharacterLookChar00);
- tolua_function(L, "Random", tolua_ExportedFunctions_Random00);
- tolua_function(L, "SetCharacterMeshVisible", tolua_ExportedFunctions_SetCharacterMeshVisible00);
- tolua_function(L, "SetRecallageY", tolua_ExportedFunctions_SetRecallageY00);
- tolua_function(L, "IsFreemiumUnlocked", tolua_ExportedFunctions_IsFreemiumUnlocked00);
- tolua_function(L, "ReachedFreemiumLimit", tolua_ExportedFunctions_ReachedFreemiumLimit00);*/
- tolua_function(L, "AddUnrecalAnim", tolua_ExportedFunctions_AddUnrecalAnim00);
- tolua_function(L, "UnlockArtwork", tolua_ExportedFunctions_UnlockArtwork00);
+ tolua_open(L);
+ tolua_module(L, 0, 0);
+ tolua_beginmodule(L, 0);
+ /*
+ tolua_function(L, "LoadObjectMaterials", tolua_ExportedFunctions_LoadObjectMaterials00);
+ tolua_function(L, "LoadObjectMaterials", tolua_ExportedFunctions_LoadObjectMaterials01);
+ tolua_function(L, "HideObject", tolua_ExportedFunctions_HideObject00);
+ tolua_function(L, "ShowObject", tolua_ExportedFunctions_ShowObject00);
+ tolua_function(L, "ShowAllObjects", tolua_ExportedFunctions_ShowAllObjects00);
+ tolua_function(L, "SetBackground", tolua_ExportedFunctions_SetBackground00);
+ tolua_function(L, "AddBlockingObject", tolua_ExportedFunctions_AddBlockingObject00);
+ tolua_function(L, "RemoveBlockingObject", tolua_ExportedFunctions_RemoveBlockingObject00);*/
+ tolua_function(L, "ChangeWarp", tolua_ExportedFunctions_ChangeWarp00);
+ tolua_function(L, "PlayMovie", tolua_ExportedFunctions_PlayMovie00);
+ /*tolua_function(L, "PlayMovieAndWaitForEnd", tolua_ExportedFunctions_PlayMovieAndWaitForEnd00);
+ tolua_function(L, "StartAnimationPart", tolua_ExportedFunctions_StartAnimationPart00);
+ tolua_function(L, "StartAnimation", tolua_ExportedFunctions_StartAnimation00);
+ tolua_function(L, "StartAnimationAndWaitForEnd",
+ tolua_ExportedFunctions_StartAnimationAndWaitForEnd00);
+ tolua_function(L, "AddAnimToSet", tolua_ExportedFunctions_AddAnimToSet00);
+ tolua_function(L, "RequestAutoSave", tolua_ExportedFunctions_RequestAutoSave00);
+ tolua_function(L, "SetVisibleButtonZoomed", tolua_ExportedFunctions_SetVisibleButtonZoomed00);
+ tolua_function(L, "AddMarker", tolua_ExportedFunctions_AddMarker00);
+ tolua_function(L, "SetVisibleMarker", tolua_ExportedFunctions_SetVisibleMarker00);
+ tolua_function(L, "DeleteMarker", tolua_ExportedFunctions_DeleteMarker00);
+ tolua_function(L, "SetVisibleCellphone", tolua_ExportedFunctions_SetVisibleCellphone00);
+ tolua_function(L, "DisabledZone", tolua_ExportedFunctions_DisabledZone00);
+ tolua_function(L, "DisabledInt", tolua_ExportedFunctions_DisabledInt00);
+ tolua_function(L, "LockCursor", tolua_ExportedFunctions_LockCursor00);
+ tolua_function(L, "SetCondition", tolua_ExportedFunctions_SetCondition00);
+ tolua_function(L, "UnsetCondition", tolua_ExportedFunctions_UnsetCondition00);
+ tolua_function(L, "TutoActive", tolua_ExportedFunctions_TutoActive00);
+ tolua_function(L, "LaunchDialog", tolua_ExportedFunctions_LaunchDialog00);
+ tolua_function(L, "LaunchDialogAndWaitForEnd", tolua_ExportedFunctions_LaunchDialogAndWaitForEnd00);
+ tolua_function(L, "PushAnswer", tolua_ExportedFunctions_PushAnswer00);
+ tolua_function(L, "HideAnswers", tolua_ExportedFunctions_HideAnswers00);
+ tolua_function(L, "PushTask", tolua_ExportedFunctions_PushTask00);
+ tolua_function(L, "DeleteTask", tolua_ExportedFunctions_DeleteTask00);
+ tolua_function(L, "SetVisibleButtonHelp", tolua_ExportedFunctions_SetVisibleButtonHelp00);
+ tolua_function(L, "HideTasks", tolua_ExportedFunctions_HideTasks00);
+ tolua_function(L, "PlaySound", tolua_ExportedFunctions_PlaySound00);
+ tolua_function(L, "PlaySoundAndWaitForEnd", tolua_ExportedFunctions_PlaySoundAndWaitForEnd00);
+ tolua_function(L, "StopSound", tolua_ExportedFunctions_StopSound00);*/
+ tolua_function(L, "AddRandomSound", tolua_ExportedFunctions_AddRandomSound00);
+ /*tolua_function(L, "PlayRandomSound", tolua_ExportedFunctions_PlayRandomSound00);
+ tolua_function(L, "PlayMusic", tolua_ExportedFunctions_PlayMusic00);*/
+ tolua_function(L, "SetSoundStep", tolua_ExportedFunctions_SetSoundStep00);
+ /*tolua_function(L, "Selected", tolua_ExportedFunctions_Selected00);
+ tolua_function(L, "TakeObject", tolua_ExportedFunctions_TakeObject00);
+ tolua_function(L, "TakeObjectInHand", tolua_ExportedFunctions_TakeObjectInHand00);
+ tolua_function(L, "RemoveObject", tolua_ExportedFunctions_RemoveObject00);
+ tolua_function(L, "RemoveObject", tolua_ExportedFunctions_RemoveObject01);*/
+ tolua_function(L, "AddNumber", tolua_ExportedFunctions_AddNumber00);
+ /*tolua_function(L, "ShowDocument", tolua_ExportedFunctions_ShowDocument00);
+ tolua_function(L, "ShowDocumentAndWaitForEnd", tolua_ExportedFunctions_ShowDocumentAndWaitForEnd00);
+ tolua_function(L, "HideDocument", tolua_ExportedFunctions_HideDocument00);
+ tolua_function(L, "AddDocument", tolua_ExportedFunctions_AddDocument00);
+ tolua_function(L, "LoadCharacter", tolua_ExportedFunctions_LoadCharacter00);
+ tolua_function(L, "UnloadCharacter", tolua_ExportedFunctions_UnloadCharacter00);
+ tolua_function(L, "GetRotationCharacter", tolua_ExportedFunctions_GetRotationCharacter00);
+ tolua_function(L, "GetXPositionCharacter", tolua_ExportedFunctions_GetXPositionCharacter00);
+ tolua_function(L, "GetYPositionCharacter", tolua_ExportedFunctions_GetYPositionCharacter00);
+ tolua_function(L, "GetZPositionCharacter", tolua_ExportedFunctions_GetZPositionCharacter00);
+ tolua_function(L, "MoveCharacterTo", tolua_ExportedFunctions_MoveCharacterTo00);
+ tolua_function(L, "MoveCharacterToAndWaitForEnd",
+ tolua_ExportedFunctions_MoveCharacterToAndWaitForEnd00);
+ tolua_function(L, "MoveCharacterPlayerTo", tolua_ExportedFunctions_MoveCharacterPlayerTo00);
+ tolua_function(L, "MoveCharacterPlayerToAndWaitForEnd",
+ tolua_ExportedFunctions_MoveCharacterPlayerToAndWaitForEnd00);
+ tolua_function(L, "MoveCharacterPlayerAtTo", tolua_ExportedFunctions_MoveCharacterPlayerAtTo00);
+ tolua_function(L, "SetCharacterPosition", tolua_ExportedFunctions_SetCharacterPosition00);
+ tolua_function(L, "PlaceCharacterOnDummy", tolua_ExportedFunctions_PlaceCharacterOnDummy00);
+ tolua_function(L, "SetCharacterRotation", tolua_ExportedFunctions_SetCharacterRotation00);
+ tolua_function(L, "SetCharacterOrientation", tolua_ExportedFunctions_SetCharacterOrientation00);
+ tolua_function(L, "SetCharacterAnimation", tolua_ExportedFunctions_SetCharacterAnimation00);
+ tolua_function(L, "SetCharacterAnimationAndWaitForEnd",
+ tolua_ExportedFunctions_SetCharacterAnimationAndWaitForEnd00);
+ tolua_function(L, "BlendCharacterAnimation", tolua_ExportedFunctions_BlendCharacterAnimation00);
+ tolua_function(L, "BlendCharacterAnimationAndWaitForEnd",
+ tolua_ExportedFunctions_BlendCharacterAnimationAndWaitForEnd00);
+ tolua_function(L, "CurrentCharacterAnimation", tolua_ExportedFunctions_CurrentCharacterAnimation00);
+ tolua_function(L, "SetCharacterPlayerVisible", tolua_ExportedFunctions_SetCharacterPlayerVisible00);
+ tolua_function(L, "MoveCharacterPlayerDisabled",
+ tolua_ExportedFunctions_MoveCharacterPlayerDisabled00);
+ tolua_function(L, "SetRunMode", tolua_ExportedFunctions_SetRunMode00);
+ tolua_function(L, "SetRunMode2", tolua_ExportedFunctions_SetRunMode200);
+ tolua_function(L, "SetCharacterColor", tolua_ExportedFunctions_SetCharacterColor00);
+ tolua_function(L, "SetCharacterSound", tolua_ExportedFunctions_SetCharacterSound00);
+ tolua_function(L, "SetCharacterShadow", tolua_ExportedFunctions_SetCharacterShadow00);
+ tolua_function(L, "AddCallback", tolua_ExportedFunctions_AddCallback00);
+ tolua_function(L, "AddCallbackPlayer", tolua_ExportedFunctions_AddCallbackPlayer00);
+ tolua_function(L, "AddCallbackAnimation2D", tolua_ExportedFunctions_AddCallbackAnimation2D00);
+ tolua_function(L, "DeleteCallback", tolua_ExportedFunctions_DeleteCallback00);
+ tolua_function(L, "DeleteCallbackPlayer", tolua_ExportedFunctions_DeleteCallbackPlayer00);
+ tolua_function(L, "DeleteCallbackAnimation2D", tolua_ExportedFunctions_DeleteCallbackAnimation2D00);
+ tolua_function(L, "SetObjectOnCharacter", tolua_ExportedFunctions_SetObjectOnCharacter00);
+ tolua_function(L, "SetObjectRotation", tolua_ExportedFunctions_SetObjectRotation00);
+ tolua_function(L, "SetObjectTranslation", tolua_ExportedFunctions_SetObjectTranslation00);
+ tolua_function(L, "SetObjectScale", tolua_ExportedFunctions_SetObjectScale00);
+ tolua_function(L, "SetObjectFrames", tolua_ExportedFunctions_SetObjectFrames00);
+ tolua_function(L, "LoadObject", tolua_ExportedFunctions_LoadObject00);
+ tolua_function(L, "UnloadObject", tolua_ExportedFunctions_UnloadObject00);
+ tolua_function(L, "SetGroundObjectPosition", tolua_ExportedFunctions_SetGroundObjectPosition00);
+ tolua_function(L, "SetGroundObjectRotation", tolua_ExportedFunctions_SetGroundObjectRotation00);
+ tolua_function(L, "TranslateGroundObject", tolua_ExportedFunctions_TranslateGroundObject00);
+ tolua_function(L, "RotateGroundObject", tolua_ExportedFunctions_RotateGroundObject00);
+ tolua_function(L, "SetLightPlayerCharacter", tolua_ExportedFunctions_SetLightPlayerCharacter00);
+ tolua_function(L, "SetLightPos", tolua_ExportedFunctions_SetLightPos00);
+ tolua_function(L, "EnableLight", tolua_ExportedFunctions_EnableLight00);
+ tolua_function(L, "SetLightDiffuse", tolua_ExportedFunctions_SetLightDiffuse00);
+ tolua_function(L, "SetLightAmbient", tolua_ExportedFunctions_SetLightAmbient00);
+ tolua_function(L, "SetLightSpecular", tolua_ExportedFunctions_SetLightSpecular00);
+ tolua_function(L, "LoadBillBoard", tolua_ExportedFunctions_LoadBillBoard00);
+ tolua_function(L, "SetBillboardPosition", tolua_ExportedFunctions_SetBillboardPosition00);
+ tolua_function(L, "SetBillboardPosition2", tolua_ExportedFunctions_SetBillboardPosition200);
+ tolua_function(L, "SetBillboardSize", tolua_ExportedFunctions_SetBillboardSize00);
+ tolua_function(L, "ShowBillboard", tolua_ExportedFunctions_ShowBillboard00);
+ tolua_function(L, "HideBillboard", tolua_ExportedFunctions_HideBillboard00);
+ tolua_function(L, "UnlockAchievement", tolua_ExportedFunctions_UnlockAchievement00);
+ tolua_function(L, "Save", tolua_ExportedFunctions_Save00);
+ tolua_function(L, "Wait", tolua_ExportedFunctions_Wait00);
+ tolua_function(L, "WaitAndWaitForEnd", tolua_ExportedFunctions_WaitAndWaitForEnd00);
+ tolua_function(L, "OpenFinalURL", tolua_ExportedFunctions_OpenFinalURL00);
+ tolua_function(L, "FinishGame", tolua_ExportedFunctions_FinishGame00);
+ tolua_function(L, "RequestMainMenu", tolua_ExportedFunctions_RequestMainMenu00);
+ tolua_function(L, "BFGRateImmediately", tolua_ExportedFunctions_BFGRateImmediately00);
+ tolua_function(L, "BFGReportEvent", tolua_ExportedFunctions_BFGReportEvent00);
+ tolua_function(L, "BFGReportEventWithValue", tolua_ExportedFunctions_BFGReportEventWithValue00);
+ tolua_function(L, "BFGReachedFreemiumLimit", tolua_ExportedFunctions_BFGReachedFreemiumLimit00);
+ tolua_function(L, "TestFileFlagSystemFlag", tolua_ExportedFunctions_TestFileFlagSystemFlag00);
+ tolua_function(L, "PrintDebugMessage", tolua_ExportedFunctions_PrintDebugMessage00);
+ tolua_function(L, "ExitZone", tolua_ExportedFunctions_ExitZone00);
+ tolua_function(L, "EnableRectBlocker", tolua_ExportedFunctions_EnableRectBlocker00);
+ tolua_function(L, "EnableBlocker", tolua_ExportedFunctions_EnableBlocker00);
+ tolua_function(L, "AddAnchorZone", tolua_ExportedFunctions_AddAnchorZone00);
+ tolua_function(L, "ActivateAnchorZone", tolua_ExportedFunctions_ActivateAnchorZone00);
+ tolua_function(L, "SetCharacterAnchor", tolua_ExportedFunctions_SetCharacterAnchor00);
+ tolua_function(L, "SetCharacterLookChar", tolua_ExportedFunctions_SetCharacterLookChar00);
+ tolua_function(L, "Random", tolua_ExportedFunctions_Random00);
+ tolua_function(L, "SetCharacterMeshVisible", tolua_ExportedFunctions_SetCharacterMeshVisible00);
+ tolua_function(L, "SetRecallageY", tolua_ExportedFunctions_SetRecallageY00);
+ tolua_function(L, "IsFreemiumUnlocked", tolua_ExportedFunctions_IsFreemiumUnlocked00);
+ tolua_function(L, "ReachedFreemiumLimit", tolua_ExportedFunctions_ReachedFreemiumLimit00);*/
+ tolua_function(L, "AddUnrecalAnim", tolua_ExportedFunctions_AddUnrecalAnim00);
+ tolua_function(L, "UnlockArtwork", tolua_ExportedFunctions_UnlockArtwork00);
- tolua_endmodule(L);
+ tolua_endmodule(L);
}
diff --git a/engines/tetraedge/game/main_menu.h b/engines/tetraedge/game/main_menu.h
index 4d256465c89..aefc03d2b83 100644
--- a/engines/tetraedge/game/main_menu.h
+++ b/engines/tetraedge/game/main_menu.h
@@ -42,14 +42,14 @@ public:
bool onBFGRateItButtonValidated();
bool onBFGRateItQuitButtonValidated();
bool onBFGSplashButtonUpdated() { return false; }
- bool onBFGSplashButtonValidated() { return false; }
- bool onBFGTellAFriendButtonValidated() { return false; }
+ bool onBFGSplashButtonValidated() { return false; }
+ bool onBFGTellAFriendButtonValidated() { return false; }
bool onBFGUnlockGameButtonValidated();
bool onContinueGameButtonValidated();
bool onDisabledTuto();
bool onEnterGameRotateAnimFinished();
- bool onFacebookButtonValidated() { return false; }
- bool onFacebookLogged() { return false; }
+ bool onFacebookButtonValidated() { return false; }
+ bool onFacebookLogged() { return false; }
bool onGalleryButtonValidated();
bool onHowToButtonValidated();
bool onLoadGameButtonValidated();
diff --git a/engines/tetraedge/game/notifier.cpp b/engines/tetraedge/game/notifier.cpp
index 9e1533b5b17..e24ee2a2c09 100644
--- a/engines/tetraedge/game/notifier.cpp
+++ b/engines/tetraedge/game/notifier.cpp
@@ -30,10 +30,49 @@ Notifier::Notifier() {
}
void Notifier::launchNextnotifier() {
- TeCurveAnim2<Te3DObject2, TeColor> *fadeInAnim = _gui.colorLinearAnimation("fadeIn");
- if (fadeInAnim->_runTimer._stopped) {
- warning("TODO: Implement Notifier::launchNextnotifier");
+ TeCurveAnim2<Te3DObject2, TeColor> *colorAnim = _gui.colorLinearAnimation("fadeIn");
+ assert(colorAnim);
+ if (!colorAnim->_runTimer._stopped)
+ return;
+
+ colorAnim = _gui.colorLinearAnimation("fadeOut");
+ if (!colorAnim->_runTimer._stopped) {
+ colorAnim = _gui.colorLinearAnimation("visible");
+ bool abort = true;
+ if (!colorAnim->_runTimer._stopped) {
+ abort = _notifierDataArray.empty();
+ }
+ if (abort)
+ return;
}
+
+ unload();
+ load();
+
+ if (_notifierDataArray.empty())
+ return;
+
+ TeVariant textformat = _gui.value("textFormat");
+ Common::String formattedName = Common::String::format(textformat.toString().c_str(), _notifierDataArray[0]._name.c_str());
+
+ TeTextLayout *text = _gui.textLayout("text");
+ text->setText(formattedName);
+
+ if (!_notifierDataArray[0]._imgpath.empty()) {
+ _gui.spriteLayoutChecked("image")->load(_notifierDataArray[0]._imgpath);
+ }
+
+ _gui.layoutChecked("notifier")->setVisible(true);
+
+ colorAnim = _gui.colorLinearAnimation("fadeIn");
+ colorAnim->_callbackObj = _gui.layoutChecked("sprite");
+ colorAnim->play();
+
+ colorAnim = _gui.colorLinearAnimation("fadeInImage");
+ colorAnim->_callbackObj = _gui.layoutChecked("image");
+ colorAnim->play();
+
+ _notifierDataArray.remove_at(0);
}
void Notifier::load() {
@@ -54,8 +93,15 @@ void Notifier::load() {
}
bool Notifier::onFadeInFinished() {
- //TeCurveAnim2<Te3DObject2, TeColor> *visible = _gui.colorLinearAnimation("visible");
- error("TODO: Implement me.");
+ TeCurveAnim2<Te3DObject2, TeColor> *colorAnim = _gui.colorLinearAnimation("visible");
+ colorAnim->_callbackObj = _gui.layout("sprite");
+ colorAnim->play();
+
+ colorAnim = _gui.colorLinearAnimation("visibleImage");
+ colorAnim->_callbackObj = _gui.layout("image");
+ colorAnim->play();
+
+ return false;
}
bool Notifier::onFadeOutFinished() {
@@ -66,7 +112,14 @@ bool Notifier::onFadeOutFinished() {
}
bool Notifier::onVisibleFinished() {
- error("TODO: Implement me.");
+ TeCurveAnim2<Te3DObject2, TeColor> *colorAnim = _gui.colorLinearAnimation("fadeOut");
+ colorAnim->_callbackObj = _gui.layout("sprite");
+ colorAnim->play();
+
+ colorAnim = _gui.colorLinearAnimation("fadeOutImage");
+ colorAnim->_callbackObj = _gui.layout("image");
+ colorAnim->play();
+ return false;
}
void Notifier::push(const Common::String &name, const Common::String &imgpath) {
diff --git a/engines/tetraedge/game/notifier.h b/engines/tetraedge/game/notifier.h
index b277f907ead..dcd1d70bc8f 100644
--- a/engines/tetraedge/game/notifier.h
+++ b/engines/tetraedge/game/notifier.h
@@ -43,8 +43,8 @@ public:
private:
struct notifierData {
- Common::String name;
- Common::String imgpath;
+ Common::String _name;
+ Common::String _imgpath;
};
Common::Array<notifierData> _notifierDataArray;
TeLuaGUI _gui;
diff --git a/engines/tetraedge/game/object_settings_xml_parser.h b/engines/tetraedge/game/object_settings_xml_parser.h
index c759156018b..6328f814041 100644
--- a/engines/tetraedge/game/object_settings_xml_parser.h
+++ b/engines/tetraedge/game/object_settings_xml_parser.h
@@ -47,6 +47,7 @@ public:
KEY_END()
} PARSER_END()
+private:
// Parser callback methods
bool parserCallback_ObjectsSettings(ParserNode *node);
bool parserCallback_Object(ParserNode *node);
@@ -54,7 +55,6 @@ public:
bool parserCallback_defaultScale(ParserNode *node);
bool textCallback(const Common::String &val) override;
-private:
enum TextTagType {
TagModelFileName,
TagDefaultScale
diff --git a/engines/tetraedge/game/objectif.cpp b/engines/tetraedge/game/objectif.cpp
index 825042955f1..44c99aba5dc 100644
--- a/engines/tetraedge/game/objectif.cpp
+++ b/engines/tetraedge/game/objectif.cpp
@@ -26,6 +26,7 @@
#include "tetraedge/game/game.h"
#include "tetraedge/game/objectif.h"
#include "tetraedge/te/te_vector2f32.h"
+#include "tetraedge/te/te_text_layout.h"
namespace Tetraedge {
@@ -157,7 +158,16 @@ void Objectif::update() {
}
}
- warning("TODO: Finish main part of Objectif::update");
+ float z = 0.1;
+ for (Te3DObject2 *child : tasks->childList()) {
+ TeTextLayout *text = dynamic_cast<TeTextLayout *>(child);
+ /*TeVector3f32 size =*/
+ text->size();
+ TeVector3f32 userPos = text->userPosition();
+ userPos.z() = z;
+ text->setPosition(userPos);
+ z += text->userSize().y();
+ }
}
_layoutsDirty = false;
}
diff --git a/engines/tetraedge/game/question2.h b/engines/tetraedge/game/question2.h
index 6bf9f408560..ca5ddd7ee6f 100644
--- a/engines/tetraedge/game/question2.h
+++ b/engines/tetraedge/game/question2.h
@@ -51,6 +51,7 @@ public:
bool onAnswerValidated(Answer &answer);
void pushAnswer(const Common::String &name, const Common::String &unk, const Common::String &path);
void unload();
+ TeLuaGUI &gui() { return _gui; }
private:
TeLuaGUI _gui;
diff --git a/engines/tetraedge/game/scene_lights_xml_parser.cpp b/engines/tetraedge/game/scene_lights_xml_parser.cpp
new file mode 100644
index 00000000000..2d2da20620b
--- /dev/null
+++ b/engines/tetraedge/game/scene_lights_xml_parser.cpp
@@ -0,0 +1,169 @@
+/* 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 "tetraedge/game/scene_lights_xml_parser.h"
+#include "tetraedge/te/te_light.h"
+
+namespace Tetraedge {
+
+bool SceneLightsXmlParser::parserCallback_Global(ParserNode *node) {
+ _parent = Parent_Global;
+ return true;
+}
+
+bool SceneLightsXmlParser::parseCol(ParserNode *node, TeColor &colout) {
+ uint r = node->values["r"].asUint64();
+ uint g = node->values["g"].asUint64();
+ uint b = node->values["b"].asUint64();
+ uint a;
+ if (node->values.contains("a"))
+ a = node->values["a"].asUint64();
+ else
+ a = 0xff;
+
+ if (r > 255 || g > 255 || b > 255 | a > 255) {
+ parserError("Invalid color values");
+ return false;
+ }
+ colout = TeColor(r, g, b, a);
+ return true;
+}
+
+
+bool SceneLightsXmlParser::parserCallback_Ambient(ParserNode *node) {
+ // can appear under either global or light
+ TeColor col;
+ if (!parseCol(node, col))
+ return false;
+
+ if (_parent == Parent_Global) {
+ TeLight::setGlobalAmbient(col);
+ } else {
+ _lights->back().setAmbient(col);
+ }
+ return true;
+}
+
+bool SceneLightsXmlParser::parserCallback_Lights(ParserNode *node) {
+ // Nothing to do, data handled in the child keys.
+ return true;
+}
+
+bool SceneLightsXmlParser::parserCallback_Light(ParserNode *node) {
+ _parent = Parent_Light;
+ _lights->push_back(TeLight());
+ return true;
+}
+
+bool SceneLightsXmlParser::parserCallback_Position(ParserNode *node) {
+ float x = atof(node->values["x"].c_str());
+ float y = atof(node->values["y"].c_str());
+ float z = atof(node->values["z"].c_str());
+ _lights->back().setPosition3d(TeVector3f32(x, y, z));
+ return true;
+}
+
+bool SceneLightsXmlParser::parserCallback_Direction(ParserNode *node) {
+ float h = (atof(node->values["h"].c_str()) * 3.141593) / 180.0;
+ float v = (atof(node->values["v"].c_str()) * 3.141593) / 180.0;
+ _lights->back().setPositionRadial(TeVector2f32(h, v));
+ return true;
+}
+
+bool SceneLightsXmlParser::parserCallback_Diffuse(ParserNode *node) {
+ TeColor col;
+ if (!parseCol(node, col))
+ return false;
+
+ _lights->back().setDiffuse(col);
+ return true;
+}
+
+bool SceneLightsXmlParser::parserCallback_Specular(ParserNode *node) {
+ TeColor col;
+ if (!parseCol(node, col))
+ return false;
+
+ _lights->back().setSpecular(col);
+ return true;
+}
+
+bool SceneLightsXmlParser::parserCallback_Attenuation(ParserNode *node) {
+ _lights->back().setConstAtten(atof(node->values["constant"].c_str()));
+ _lights->back().setLinearAtten(atof(node->values["linear"].c_str()));
+ _lights->back().setQuadraticAtten(atof(node->values["quadratic"].c_str()));
+ return true;
+}
+
+bool SceneLightsXmlParser::parserCallback_Cutoff(ParserNode *node) {
+ float f = atof(node->values["value"].c_str());
+ _lights->back().setCutoff((f * 3.141593) / 180.0);
+ return true;
+}
+
+bool SceneLightsXmlParser::parserCallback_Exponent(ParserNode *node) {
+ _lights->back().setExponent(atof(node->values["value"].c_str()));
+ return true;
+}
+
+bool SceneLightsXmlParser::parserCallback_DisplaySize(ParserNode *node) {
+ _lights->back().setDisplaySize(atof(node->values["value"].c_str()));
+ return true;
+}
+
+bool SceneLightsXmlParser::parserCallback_Shadow(ParserNode *node) {
+ _parent = Parent_Shadow;
+ return true;
+}
+
+bool SceneLightsXmlParser::parserCallback_SourceLight(ParserNode *node) {
+ _shadowLightNo = atof(node->values["number"].c_str());
+ return true;
+}
+
+bool SceneLightsXmlParser::parserCallback_Fov(ParserNode *node) {
+ _shadowFov = atof(node->values["value"].c_str());
+ return true;
+}
+
+bool SceneLightsXmlParser::parserCallback_NearPlane(ParserNode *node) {
+ _shadowNearPlane = atof(node->values["value"].c_str());
+ return true;
+}
+
+bool SceneLightsXmlParser::parserCallback_FarPlane(ParserNode *node) {
+ _shadowFarPlane = atof(node->values["value"].c_str());
+ return true;
+}
+
+bool SceneLightsXmlParser::parserCallback_Color(ParserNode *node) {
+ TeColor col;
+ if (parseCol(node, col)) {
+ _shadowColor = col;
+ return true;
+ }
+ return false;
+}
+
+
+
+}
+ // end namespace Tetraedge
diff --git a/engines/tetraedge/game/scene_lights_xml_parser.h b/engines/tetraedge/game/scene_lights_xml_parser.h
new file mode 100644
index 00000000000..0b85362ec5f
--- /dev/null
+++ b/engines/tetraedge/game/scene_lights_xml_parser.h
@@ -0,0 +1,162 @@
+/* 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 TETRAEDGE_GAME_SCENE_LIGHTS_XML_PARSER_H
+#define TETRAEDGE_GAME_SCENE_LIGHTS_XML_PARSER_H
+
+#include "common/xmlparser.h"
+#include "tetraedge/te/te_light.h"
+#include "tetraedge/te/te_vector3f32.h"
+
+
+namespace Tetraedge {
+
+class SceneLightsXmlParser : public Common::XMLParser {
+public:
+ void setLightArray(Common::Array<TeLight> *lights) {
+ _lights = lights;
+ }
+ TeColor getShadowColor() { return _shadowColor; }
+ int getShadowLightNo() { return _shadowLightNo; }
+ float getShadowFarPlane() { return _shadowFarPlane; }
+ float getShadowNearPlane() { return _shadowNearPlane; }
+ float getShadowFov() { return _shadowFov; }
+
+ // Parser
+ CUSTOM_XML_PARSER(SceneLightsXmlParser) {
+ XML_KEY(Global)
+ XML_KEY(Ambient)
+ XML_PROP(r, true)
+ XML_PROP(g, true)
+ XML_PROP(b, true)
+ KEY_END()
+ KEY_END()
+ XML_KEY(Lights)
+ XML_KEY(Light)
+ XML_PROP(Type, true)
+ XML_KEY(Position)
+ XML_PROP(x, true)
+ XML_PROP(y, true)
+ XML_PROP(z, true)
+ KEY_END()
+ XML_KEY(Direction)
+ XML_PROP(h, true)
+ XML_PROP(v, true)
+ KEY_END()
+ XML_KEY(Ambient)
+ XML_PROP(r, true)
+ XML_PROP(g, true)
+ XML_PROP(b, true)
+ KEY_END()
+ XML_KEY(Diffuse)
+ XML_PROP(r, true)
+ XML_PROP(g, true)
+ XML_PROP(b, true)
+ KEY_END()
+ XML_KEY(Specular)
+ XML_PROP(r, true)
+ XML_PROP(g, true)
+ XML_PROP(b, true)
+ KEY_END()
+ XML_KEY(Attenuation)
+ XML_PROP(constant, true)
+ XML_PROP(linear, true)
+ XML_PROP(quadratic, true)
+ KEY_END()
+ XML_KEY(Cutoff)
+ XML_PROP(value, true)
+ KEY_END()
+ XML_KEY(Exponent)
+ XML_PROP(value, true)
+ KEY_END()
+ XML_KEY(DisplaySize)
+ XML_PROP(value, true)
+ KEY_END()
+ KEY_END()
+ KEY_END()
+ XML_KEY(Shadow)
+ XML_KEY(SourceLight)
+ XML_PROP(number, true)
+ KEY_END()
+ XML_KEY(Fov)
+ XML_PROP(value, true)
+ KEY_END()
+ XML_KEY(NearPlane)
+ XML_PROP(value, true)
+ KEY_END()
+ XML_KEY(FarPlane)
+ XML_PROP(value, true)
+ KEY_END()
+ XML_KEY(Color)
+ XML_PROP(r, true)
+ XML_PROP(g, true)
+ XML_PROP(b, true)
+ XML_PROP(a, true)
+ KEY_END()
+ KEY_END()
+ } PARSER_END()
+
+private:
+ Common::Array<TeLight> *_lights;
+
+ enum ParentNodeType {
+ Parent_Global,
+ Parent_Light,
+ Parent_Shadow
+ };
+
+ TeColor _shadowColor;
+ int _shadowLightNo;
+ float _shadowFarPlane;
+ float _shadowNearPlane;
+ float _shadowFov;
+ ParentNodeType _parent;
+
+ // Parser callback methods
+ bool parserCallback_Global(ParserNode *node);
+ bool parserCallback_Ambient(ParserNode *node);
+
+ bool parserCallback_Lights(ParserNode *node);
+ bool parserCallback_Light(ParserNode *node);
+ bool parserCallback_Position(ParserNode *node);
+ bool parserCallback_Direction(ParserNode *node);
+ //bool parserCallback_Ambient(ParserNode *node);
+ bool parserCallback_Diffuse(ParserNode *node);
+ bool parserCallback_Specular(ParserNode *node);
+ bool parserCallback_Attenuation(ParserNode *node);
+ bool parserCallback_Cutoff(ParserNode *node);
+ bool parserCallback_Exponent(ParserNode *node);
+ bool parserCallback_DisplaySize(ParserNode *node);
+
+ bool parserCallback_Shadow(ParserNode *node);
+ bool parserCallback_SourceLight(ParserNode *node);
+ bool parserCallback_Fov(ParserNode *node);
+ bool parserCallback_NearPlane(ParserNode *node);
+ bool parserCallback_FarPlane(ParserNode *node);
+ bool parserCallback_Color(ParserNode *node);
+
+ bool parseCol(ParserNode *node, TeColor &colout);
+
+};
+
+} // end namespace Tetraedge
+
+#endif // TETRAEDGE_GAME_SCENE_LIGHTS_XML_PARSER_H
diff --git a/engines/tetraedge/module.mk b/engines/tetraedge/module.mk
index 9873d9ceabf..2908af876e3 100644
--- a/engines/tetraedge/module.mk
+++ b/engines/tetraedge/module.mk
@@ -38,10 +38,12 @@ MODULE_OBJS := \
game/options_menu.o \
game/owner_error_menu.o \
game/question2.o \
+ game/scene_lights_xml_parser.o \
game/splash_screens.o \
te/micropather.o \
te/te_3d_object2.o \
te/te_3d_texture.o \
+ te/te_act_zone.o \
te/te_animation.o \
te/te_bezier_curve.o \
te/te_button_layout.o \
diff --git a/engines/tetraedge/te/micropather.h b/engines/tetraedge/te/micropather.h
index 5e0b7461f00..493c035b583 100644
--- a/engines/tetraedge/te/micropather.h
+++ b/engines/tetraedge/te/micropather.h
@@ -58,6 +58,7 @@ distribution.
#include "common/array.h"
#include "common/util.h"
+#include "common/math.h"
#include "common/types.h"
diff --git a/engines/tetraedge/te/te_3d_object2.cpp b/engines/tetraedge/te/te_3d_object2.cpp
index 73fb4e2e3bc..f1830449f1a 100644
--- a/engines/tetraedge/te/te_3d_object2.cpp
+++ b/engines/tetraedge/te/te_3d_object2.cpp
@@ -42,13 +42,25 @@ Te3DObject2::~Te3DObject2() {
setParent(nullptr);
}
-void Te3DObject2::addChild(Te3DObject2 *child) {
- _children.push_back(child);
- child->setParent(this);
+void Te3DObject2::addChild(Te3DObject2 *newChild) {
+ assert(newChild != this && newChild != _parent);
+ for (auto *c : _children) {
+ if (c == newChild)
+ error("Trying to re-add child %s to object %s", newChild->name().c_str(), _name.c_str());
+ }
+
+ _children.push_back(newChild);
+ newChild->setParent(this);
_childListChangedSignal.call();
}
void Te3DObject2::addChildBefore(Te3DObject2 *newChild, const Te3DObject2 *ref) {
+ assert(newChild != this && newChild != _parent);
+ for (auto *c : _children) {
+ if (c == newChild)
+ error("Trying to re-add child %s to object %s", newChild->name().c_str(), _name.c_str());
+ }
+
Common::Array<Te3DObject2 *>::iterator iter;
for (iter = _children.begin(); iter != _children.end(); iter++) {
if (*iter == ref) {
@@ -67,15 +79,16 @@ Te3DObject2 *Te3DObject2::child(long offset) {
return _children[offset];
}
-long Te3DObject2::childIndex(Te3DObject2 *child) {
+long Te3DObject2::childIndex(Te3DObject2 *c) const {
for (uint i = 0; i < _children.size(); i++) {
- if (_children[i] == child)
+ if (_children[i] == c)
return i;
}
return -1;
}
-/*static*/ Common::String Te3DObject2::deserializeString(Common::ReadStream &stream) {
+/*static*/
+Common::String Te3DObject2::deserializeString(Common::ReadStream &stream) {
uint slen = stream.readUint32LE();
if (slen > 1024 * 1024)
error("Improbable string size %d", slen);
@@ -91,7 +104,8 @@ long Te3DObject2::childIndex(Te3DObject2 *child) {
return Common::String();
}
-/*static*/ void Te3DObject2::deserialize(Common::ReadStream &stream, Te3DObject2 &dest) {
+/*static*/
+void Te3DObject2::deserialize(Common::ReadStream &stream, Te3DObject2 &dest) {
Common::String str = deserializeString(stream);
dest.setName(str);
@@ -107,7 +121,8 @@ long Te3DObject2::childIndex(Te3DObject2 *child) {
dest.setScale(vect);
}
-/*static*/ void Te3DObject2::serialize(Common::WriteStream &stream, Te3DObject2 &src) {
+/*static*/
+void Te3DObject2::serialize(Common::WriteStream &stream, Te3DObject2 &src) {
const Common::String &name = src.name();
stream.writeUint32LE(name.size());
stream.write(name.c_str(), name.size());
@@ -171,6 +186,7 @@ void Te3DObject2::setColor(const TeColor &col) {
}
void Te3DObject2::setParent(Te3DObject2 *newparent) {
+ assert(newparent != this);
if (_parent) {
if (_onWorldVisibleChangedParentCallback)
_parent->onWorldVisibleChanged().remove(_onWorldVisibleChangedParentCallback);
@@ -305,4 +321,12 @@ bool Te3DObject2::worldVisible() {
}
}
+/*static*/
+bool Te3DObject2::loadAndCheckFourCC(Common::ReadStream &stream, const char *str) {
+ char buf[5];
+ buf[4] = '\0';
+ stream.read(buf, 4);
+ return !strncmp(buf, str, 4);
+}
+
} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_3d_object2.h b/engines/tetraedge/te/te_3d_object2.h
index c39a69fe48b..54fd905d8eb 100644
--- a/engines/tetraedge/te/te_3d_object2.h
+++ b/engines/tetraedge/te/te_3d_object2.h
@@ -46,9 +46,9 @@ public:
return _children.size();
}
- long childIndex(Te3DObject2 *childToFind);
+ long childIndex(Te3DObject2 *childToFind) const;
- Common::Array<Te3DObject2 *> &childList() {
+ const Common::Array<Te3DObject2 *> &childList() const {
return _children;
}
@@ -68,7 +68,7 @@ public:
static void serialize(Common::WriteStream &stream, Te3DObject2 &src);
static Common::String deserializeString(Common::ReadStream &stream);
- virtual void draw() = 0;
+ virtual void draw() {}
const Common::String &name() const {
return _name;
}
@@ -142,6 +142,8 @@ public:
virtual float ySize() { return _size.y(); };
virtual float zSize() { return _size.z(); };
+ static bool loadAndCheckFourCC(Common::ReadStream &stream, const char *str);
+
protected:
TeVector3f32 _size;
TeVector3f32 _position;
diff --git a/engines/tetraedge/te/te_3d_texture.cpp b/engines/tetraedge/te/te_3d_texture.cpp
index 408d87d57a9..6680bf37559 100644
--- a/engines/tetraedge/te/te_3d_texture.cpp
+++ b/engines/tetraedge/te/te_3d_texture.cpp
@@ -95,8 +95,18 @@ void Te3DTexture::destroy() {
_glTexture = NO_TEXTURE;
}
-void Te3DTexture::ForceTexData(uint gltextures, uint xsize, uint ysize) {
- error("TODO: Implement me");
+void Te3DTexture::forceTexData(uint gltextures, uint xsize, uint ysize) {
+ if (_glTexture != 0xffffffff) {
+ if (_createdTexture)
+ glDeleteTextures(1, &_glTexture);
+ _createdTexture = false;
+ _loaded = false;
+ }
+ _glTexture = gltextures;
+ _width = xsize;
+ _height = ysize;
+ _texWidth = xsize;
+ _texHeight = ysize;
}
bool Te3DTexture::hasAlpha() const {
@@ -217,6 +227,7 @@ TeVector2s32 Te3DTexture::optimisedSize(const TeVector2s32 &size) {
return TeVector2s32(v1, v2);
}
+/*static*/
void Te3DTexture::unbind() {
TeRenderer *renderer = g_engine->getRenderer();
renderer->setMatrixMode(TeRenderer::MM_GL_TEXTURE);
diff --git a/engines/tetraedge/te/te_3d_texture.h b/engines/tetraedge/te/te_3d_texture.h
index 039dc42efa6..cbf228836fe 100644
--- a/engines/tetraedge/te/te_3d_texture.h
+++ b/engines/tetraedge/te/te_3d_texture.h
@@ -44,7 +44,7 @@ public:
void create();
void destroy();
- void ForceTexData(uint gltextures, uint xsize, uint ysize);
+ void forceTexData(uint gltextures, uint xsize, uint ysize);
TeImage::Format getFormat() const { return _format; }
bool hasAlpha() const;
@@ -55,7 +55,7 @@ public:
static TeVector2s32 optimisedSize(const TeVector2s32 &size);
- void unbind();
+ static void unbind();
bool unload();
void update(const TeImage &img, uint xoff, uint yoff);
diff --git a/engines/tetraedge/te/te_act_zone.cpp b/engines/tetraedge/te/te_act_zone.cpp
new file mode 100644
index 00000000000..e6ec2ca3b09
--- /dev/null
+++ b/engines/tetraedge/te/te_act_zone.cpp
@@ -0,0 +1,31 @@
+/* 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 "tetraedge/te/te_act_zone.h"
+
+namespace Tetraedge {
+
+TeActZone::TeActZone() {
+}
+
+// TODO: Add more functions here.
+
+} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_act_zone.h b/engines/tetraedge/te/te_act_zone.h
new file mode 100644
index 00000000000..ef4ecc34911
--- /dev/null
+++ b/engines/tetraedge/te/te_act_zone.h
@@ -0,0 +1,47 @@
+/* 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 TETRAEDGE_TE_TE_ACT_ZONE_H
+#define TETRAEDGE_TE_TE_ACT_ZONE_H
+
+#include "common/str.h"
+#include "tetraedge/te/te_vector2f32.h"
+
+namespace Tetraedge {
+
+class TeActZone {
+public:
+ TeActZone();
+
+ Common::String s1;
+ Common::String s2;
+ TeVector2f32 points[4];
+ bool flag1;
+ bool flag2;
+
+private:
+ // TODO add private members
+
+};
+
+} // end namespace Tetraedge
+
+#endif // TETRAEDGE_TE_TE_ACT_ZONE_H
diff --git a/engines/tetraedge/te/te_animation.cpp b/engines/tetraedge/te/te_animation.cpp
index f2c7cd71b34..7c5a8c2defe 100644
--- a/engines/tetraedge/te/te_animation.cpp
+++ b/engines/tetraedge/te/te_animation.cpp
@@ -35,6 +35,9 @@ Common::Array<TeAnimation *> *TeAnimation::_animations = nullptr;
TeAnimation::TeAnimation() : _repeatCount(1), _dontRepeat(false) {
}
+TeAnimation::~TeAnimation() {
+ stop();
+}
void TeAnimation::cont() {
if (_runTimer._stopped) {
@@ -98,10 +101,13 @@ void TeAnimation::seekToStart() {
}
/*static*/ void TeAnimation::updateAll() {
- for (auto &anim : *animations()) {
- if (!anim->_runTimer._stopped) {
- float msFromStart = anim->_runTimer.getTimeFromStart() / 1000.0;
- anim->update(msFromStart);
+ Common::Array<TeAnimation *> &anims = *animations();
+ // Note: update can cause events which cascade into animtaions
+ // getting deleted, so be careful about the numbers.
+ for (unsigned int i = 0; i < anims.size(); i++) {
+ if (!anims[i]->_runTimer._stopped) {
+ float msFromStart = anims[i]->_runTimer.getTimeFromStart() / 1000.0;
+ anims[i]->update(msFromStart);
}
}
diff --git a/engines/tetraedge/te/te_animation.h b/engines/tetraedge/te/te_animation.h
index 3f71c68b692..ed1da6436cb 100644
--- a/engines/tetraedge/te/te_animation.h
+++ b/engines/tetraedge/te/te_animation.h
@@ -31,7 +31,7 @@ namespace Tetraedge {
class TeAnimation {
public:
TeAnimation();
- virtual ~TeAnimation() {};
+ virtual ~TeAnimation();
virtual void cont();
virtual void pause();
diff --git a/engines/tetraedge/te/te_bezier_curve.cpp b/engines/tetraedge/te/te_bezier_curve.cpp
index 2d9ff8b79d1..d30beb5191c 100644
--- a/engines/tetraedge/te/te_bezier_curve.cpp
+++ b/engines/tetraedge/te/te_bezier_curve.cpp
@@ -42,7 +42,19 @@ void TeBezierCurve::draw() {
float TeBezierCurve::length() {
if (_lengthNeedsUpdate) {
- error("TODO: Implement TeBezierCurve::length");
+ _length = 0.0;
+ _lengthNeedsUpdate = false;
+ _lengths.clear();
+
+ TeVector3f32 lastpt = _controlPoints[0];
+ for (unsigned int i = 0; i < _numiterations; i++) {
+ float amount = (float)i / _numiterations;
+ const TeVector3f32 pt = retrievePoint(amount);
+ float len = (lastpt - pt).length();
+ _length += len;
+ _lengths.push_back(_length);
+ lastpt = pt;
+ }
}
return _length;
}
@@ -81,5 +93,24 @@ void TeBezierCurve::setNbIterations(unsigned long iterations) {
_numiterations = iterations;
}
+/*static*/
+void TeBezierCurve::serialize(Common::WriteStream &stream, const TeBezierCurve &curve) {
+ error("TODO: Implement TeBezierCurve::serialize");
+}
+
+/*static*/
+void TeBezierCurve::deserialize(Common::ReadStream &stream, TeBezierCurve &curve) {
+ Te3DObject2::deserialize(stream, curve);
+
+ curve._lengthNeedsUpdate = false;
+ curve._length = stream.readFloatLE();
+ uint32 npoints = stream.readUint32LE();
+
+ for (unsigned int i = 0; i < npoints; i++) {
+ TeVector3f32 vec;
+ TeVector3f32::deserialize(stream, vec);
+ curve._controlPoints.push_back(vec);
+ }
+}
} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_bezier_curve.h b/engines/tetraedge/te/te_bezier_curve.h
index 858616e498a..ace2c2ceea5 100644
--- a/engines/tetraedge/te/te_bezier_curve.h
+++ b/engines/tetraedge/te/te_bezier_curve.h
@@ -44,19 +44,18 @@ public:
void setControlPoints(const Common::Array<TeVector3f32> &points);
void setNbIterations(unsigned long iterations);
- static void serialize(Common::WriteStream &stream, const TeBezierCurve &mesh);
- static void deserialize(Common::ReadStream &stream, TeBezierCurve &mesh);
+ static void serialize(Common::WriteStream &stream, const TeBezierCurve &curve);
+ static void deserialize(Common::ReadStream &stream, TeBezierCurve &curve);
private:
- int _numiterations;
+ unsigned int _numiterations;
float _length;
float _rawLength;
bool _lengthNeedsUpdate;
bool _rawLengthNeedsUpdate;
Common::Array<TeVector3f32> _controlPoints;
Common::Array<float> _rawLengths;
- // TODO add private members
-
+ Common::Array<float> _lengths;
};
} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_button_layout.cpp b/engines/tetraedge/te/te_button_layout.cpp
index 97aff6289ee..31bb77bb74e 100644
--- a/engines/tetraedge/te/te_button_layout.cpp
+++ b/engines/tetraedge/te/te_button_layout.cpp
@@ -209,6 +209,7 @@ void TeButtonLayout::resetTimeFromLastValidation() {
}
long TeButtonLayout::timeFromLastValidation() {
+ // probably not needed because we reimplemented how this works.
error("TODO: Implement TeButtonLayout::timeFromLastValidation.");
}
@@ -305,9 +306,11 @@ void TeButtonLayout::setEnable(bool enable) {
void TeButtonLayout::setPosition(const TeVector3f32 &pos) {
TeLayout::setPosition(pos);
+
if (_currentState != BUTTON_STATE_DISABLED) {
int somethingCount = 0;
if (!_intArr.empty()) {
+ // probably not needed as we reimplememted how this works.
error("TODO: Implement setPosition logic for up/down state");
}
if (_someClickFlag) {
diff --git a/engines/tetraedge/te/te_callback.h b/engines/tetraedge/te/te_callback.h
index 3530a46b276..2db003d15dc 100644
--- a/engines/tetraedge/te/te_callback.h
+++ b/engines/tetraedge/te/te_callback.h
@@ -66,7 +66,7 @@ public:
virtual ~TeICallback1Param() {}
virtual bool operator()(T data) = 0;
virtual bool call(T data) = 0;
- virtual float priority() const = 0;
+ virtual float &priority() = 0;
virtual bool equals(const TeICallback1Param *other) const = 0;
};
@@ -84,7 +84,7 @@ public:
bool operator()(S data) override { return (_object->*_method)(data); }
bool call(S data) override { return (_object->*_method)(data); }
- virtual float priority() const override { return _priority; }
+ virtual float &priority() override { return _priority; }
bool equals(const TeICallback1Param<S> *other) const override {
const TeCallback1Param<T, S> *o = dynamic_cast<const TeCallback1Param<T, S> *>(other);
@@ -99,7 +99,7 @@ public:
virtual ~TeICallback2Param() {}
virtual bool operator()(S data1, T data2) = 0;
virtual bool call(S data1, T data2) = 0;
- virtual float priority() const = 0;
+ virtual float &priority() = 0;
virtual bool equals(const TeICallback2Param *other) const = 0;
};
@@ -117,7 +117,7 @@ public:
bool operator()(S data1, T data2) override { return (_object->*_method)(data1, data2); }
bool call(S data1, T data2) override { return (_object->*_method)(data1, data2); }
- virtual float priority() const override { return _priority; }
+ virtual float &priority() override { return _priority; }
bool equals(const TeICallback2Param<S, T> *other) const override {
const TeCallback2Param<C, S, T> *o = dynamic_cast<const TeCallback2Param<C, S, T> *>(other);
diff --git a/engines/tetraedge/te/te_camera.cpp b/engines/tetraedge/te/te_camera.cpp
index e11b857287c..07ae8dd4501 100644
--- a/engines/tetraedge/te/te_camera.cpp
+++ b/engines/tetraedge/te/te_camera.cpp
@@ -30,7 +30,8 @@ namespace Tetraedge {
TeCamera::TeCamera() : _projectionMatrixType(0), _orthogonalParamL(1.0f),
_orthogonalParamR(0.0f), _orthogonalParamT(1.0f), _orthogonalParamB(0.0f),
- _orthNearVal(10.0), _orthFarVal(4000.0), _transformA(0), _transformB(0)
+ _orthNearVal(10.0f), _orthFarVal(4000.0f), _transformA(0), _transformB(0),
+ _focalLenMaybe(40.0f), _somePerspectiveVal(1.0f)
{
}
diff --git a/engines/tetraedge/te/te_camera.h b/engines/tetraedge/te/te_camera.h
index a6de84f02bc..1f02ccf0154 100644
--- a/engines/tetraedge/te/te_camera.h
+++ b/engines/tetraedge/te/te_camera.h
@@ -73,6 +73,8 @@ public:
int _projectionMatrixType;
float _orthNearVal;
float _orthFarVal;
+ float _focalLenMaybe;
+ float _somePerspectiveVal;
private:
int _viewportX;
diff --git a/engines/tetraedge/te/te_checkbox_layout.cpp b/engines/tetraedge/te/te_checkbox_layout.cpp
index 075fcf7acb8..05ad75eec21 100644
--- a/engines/tetraedge/te/te_checkbox_layout.cpp
+++ b/engines/tetraedge/te/te_checkbox_layout.cpp
@@ -45,6 +45,14 @@ _clickPassThrough(false), _state(CheckboxState6)
inputmgr->_mouseLUpSignal.insert(_onMouseLeftUpMaxPriorityCallback);
}
+TeCheckboxLayout::~TeCheckboxLayout() {
+ TeInputMgr *inputmgr = g_engine->getInputMgr();
+ inputmgr->_mouseMoveSignal.remove(_onMousePositionChangedCallback);
+ inputmgr->_mouseLDownSignal.remove(_onMouseLeftDownCallback);
+ inputmgr->_mouseLUpSignal.remove(_onMouseLeftUpCallback);
+ inputmgr->_mouseLUpSignal.remove(_onMouseLeftUpMaxPriorityCallback);
+}
+
void TeCheckboxLayout::setActiveLayout(TeLayout *layout) {
if (_activeLayout)
removeChild(_activeLayout);
diff --git a/engines/tetraedge/te/te_checkbox_layout.h b/engines/tetraedge/te/te_checkbox_layout.h
index 915b68836a3..11cb9def573 100644
--- a/engines/tetraedge/te/te_checkbox_layout.h
+++ b/engines/tetraedge/te/te_checkbox_layout.h
@@ -30,6 +30,7 @@ namespace Tetraedge {
class TeCheckboxLayout : public TeLayout {
public:
TeCheckboxLayout();
+ virtual ~TeCheckboxLayout();
enum State {
CheckboxStateActive,
diff --git a/engines/tetraedge/te/te_free_move_zone.cpp b/engines/tetraedge/te/te_free_move_zone.cpp
index 15c516515fd..6f072e56676 100644
--- a/engines/tetraedge/te/te_free_move_zone.cpp
+++ b/engines/tetraedge/te/te_free_move_zone.cpp
@@ -23,9 +23,41 @@
namespace Tetraedge {
-TeFreeMoveZone::TeFreeMoveZone() {
+TeFreeMoveZone::TeFreeMoveZone() : _actzones(nullptr), _blockers(nullptr), _rectBlockers(nullptr),
+_transformedVerticiesDirty(true), _bordersDirty(true), _pickMeshDirty(true), _projectedPointsDirty(true)
+{
}
-// TODO: Add more functions here.
+void TeFreeMoveZone::buildAStar() {
+ error("TODO: Implement TeFreeMoveZone::buildAStar");
+}
+
+void TeFreeMoveZone::calcGridMatrix() {
+ error("TODO: Implement TeFreeMoveZone::calcGridMatrix");
+}
+
+void TeFreeMoveZone::clear() {
+ error("TODO: Implement TeFreeMoveZone::clear");
+}
+
+Common::Array<TeVector3f32> TeFreeMoveZone::collisions(const TeVector3f32 &v1, const TeVector3f32 &v2) {
+ error("TODO: Implement TeFreeMoveZone::collisions");
+}
+
+TeVector3f32 TeFreeMoveZone::correctCharacterPosition(const TeVector3f32 &pos, bool *flagout, bool f) {
+ error("TODO: Implement TeFreeMoveZone::correctCharacterPosition");
+}
+
+/*static*/
+void TeFreeMoveZone::deserialize(Common::ReadStream &stream, TeFreeMoveZone &dest, Common::Array<TeBlocker> *blockers,
+ Common::Array<TeRectBlocker> *rectblockers, Common::Array<TeActZone> *actzones) {
+ dest.clear();
+ TePickMesh2::deserialize(stream, dest);
+
+ error("TODO: Implement TeFreeMoveZone::deserialize");
+ dest._blockers = blockers;
+ dest._rectBlockers = rectblockers;
+ dest._actzones = actzones;
+}
} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_free_move_zone.h b/engines/tetraedge/te/te_free_move_zone.h
index 48c61612198..d1ddb9a3f97 100644
--- a/engines/tetraedge/te/te_free_move_zone.h
+++ b/engines/tetraedge/te/te_free_move_zone.h
@@ -26,6 +26,7 @@
#include "tetraedge/te/te_pick_mesh2.h"
#include "tetraedge/te/te_vector3f32.h"
+#include "tetraedge/te/te_act_zone.h"
#include "tetraedge/te/te_timer.h"
namespace Tetraedge {
@@ -34,6 +35,20 @@ namespace micropather {
class MicroPather;
}
+// TODO: should these structs be moved to their own headers?
+struct TeBlocker {
+ Common::String _s;
+ TeVector2f32 _pts[2];
+ long _x;
+};
+
+struct TeRectBlocker {
+ Common::String _s;
+ TeVector2f32 _pts[4];
+ long _x;
+};
+
+
class TeFreeMoveZone : public TePickMesh2 {
public:
struct CollidePoint {
@@ -55,12 +70,17 @@ public:
void buildAStar();
void calcGridMatrix();
void clear();
- Common::Array<TeVector3f32> collisions(TeVector3f32 const&, TeVector2f32 const&);
- TeVector3f32 correctCharacterPosition(TeVector3f32 const&, bool*, bool);
+ Common::Array<TeVector3f32> collisions(const TeVector3f32 &v1, const TeVector3f32 &v2);
+ TeVector3f32 correctCharacterPosition(const TeVector3f32 &pos, bool *flagout, bool f);
- // TODO add public members
+ static void deserialize(Common::ReadStream &stream, TeFreeMoveZone &dest, Common::Array<TeBlocker> *blockers,
+ Common::Array<TeRectBlocker> *rectblockers, Common::Array<TeActZone> *actzones);
private:
+ Common::Array<TeActZone> *_actzones;
+ Common::Array<TeBlocker> *_blockers;
+ Common::Array<TeRectBlocker> *_rectBlockers;
+
TeFreeMoveZoneGraph *_graph;
bool _transformedVerticiesDirty;
bool _bordersDirty;
diff --git a/engines/tetraedge/te/te_i_3d_object2.h b/engines/tetraedge/te/te_i_3d_object2.h
index 9313c2535a9..de922feb320 100644
--- a/engines/tetraedge/te/te_i_3d_object2.h
+++ b/engines/tetraedge/te/te_i_3d_object2.h
@@ -28,6 +28,8 @@ class TeI3DObject2 {
public:
TeI3DObject2();
+ virtual ~TeI3DObject2() {}
+
// TODO add public members
private:
diff --git a/engines/tetraedge/te/te_image.cpp b/engines/tetraedge/te/te_image.cpp
index 8092ab1ef79..b59155364c8 100644
--- a/engines/tetraedge/te/te_image.cpp
+++ b/engines/tetraedge/te/te_image.cpp
@@ -58,7 +58,7 @@ void TeImage::create(uint xsize, uint ysize, Common::SharedPtr<TePalette> &pal,
Graphics::Surface::fillRect(Common::Rect(0, 0, xsize, ysize), 0xff883311);
}
-void TeImage::deSerialize(Common::ReadStream &stream) {
+void TeImage::deserialize(Common::ReadStream &stream) {
error("TODO: TeImage: Implement me.");
}
@@ -71,21 +71,21 @@ void TeImage::drawPlot(void *outbuf, int x, int y, const TeVector2s32 &bufsize,
error("TODO: TeImage: Implement me.");
}
-void TeImage::fill(byte val) {
+void TeImage::fill(byte val) {
error("TODO: TeImage: Implement me.");
}
-void TeImage::fill(byte r, byte g, byte b, byte a) {
+void TeImage::fill(byte r, byte g, byte b, byte a) {
Common::Rect wholeSurf(0, 0, w, h);
uint32 col = (r << 24) | (g << 16) | (b << 8) | a;
Graphics::Surface::fillRect(wholeSurf, col);
}
-void TeImage::getBuff(uint x, uint y, byte *pout, uint w_, uint h_) {
+void TeImage::getBuff(uint x, uint y, byte *pout, uint w_, uint h_) {
error("TODO: TeImage: Implement me.");
}
-bool TeImage::isExtensionSupported(const Common::Path &path) {
+bool TeImage::isExtensionSupported(const Common::Path &path) {
error("TODO: TeImage: Implement me.");
}
@@ -105,15 +105,15 @@ bool TeImage::load(const Common::Path &path) {
return true;
}
-bool TeImage::load(Common::ReadStream &stream, const Common::Path &path) {
+bool TeImage::load(Common::ReadStream &stream, const Common::Path &path) {
error("TODO: TeImage::load Implement me.");
}
-bool TeImage::save(const Common::Path &path, enum Type type) {
+bool TeImage::save(const Common::Path &path, enum Type type) {
error("TODO: TeImage::save Implement me.");
}
-int TeImage::serialize(Common::WriteStream &stream) {
+int TeImage::serialize(Common::WriteStream &stream) {
error("TODO: TeImage::serialize Implement me.");
}
diff --git a/engines/tetraedge/te/te_image.h b/engines/tetraedge/te/te_image.h
index 4dced597c29..995e8be2f91 100644
--- a/engines/tetraedge/te/te_image.h
+++ b/engines/tetraedge/te/te_image.h
@@ -61,7 +61,7 @@ public:
}
void create(uint xsize, uint ysize, Common::SharedPtr<TePalette> &pal,
Format format, uint bufxsize, uint bufysize);
- void deSerialize(Common::ReadStream &stream);
+ void deserialize(Common::ReadStream &stream);
void destroy();
void drawPlot(int x, int y, const TeColor &col) {
drawPlot(getPixels(), x, y, bufSize(), col);
diff --git a/engines/tetraedge/te/te_intrusive_ptr.h b/engines/tetraedge/te/te_intrusive_ptr.h
index a3eb1b28759..dd9224ae3ba 100644
--- a/engines/tetraedge/te/te_intrusive_ptr.h
+++ b/engines/tetraedge/te/te_intrusive_ptr.h
@@ -30,20 +30,20 @@ namespace Tetraedge {
*/
template<class T> class TeIntrusivePtr {
public:
- TeIntrusivePtr() : _p(nullptr) {}
+ typedef void(T::*Tdestructor)();
- TeIntrusivePtr(const TeIntrusivePtr<T> &other) {
+ TeIntrusivePtr() : _p(nullptr), _deleteFn(nullptr) {}
+
+ TeIntrusivePtr(const TeIntrusivePtr<T> &other) : _deleteFn(nullptr) {
_p = other._p;
if (_p)
_p->incrementCounter();
-
}
- TeIntrusivePtr(T *obj) {
+ TeIntrusivePtr(T *obj) : _deleteFn(nullptr) {
_p = obj;
if (_p)
_p->incrementCounter();
-
}
virtual ~TeIntrusivePtr() {
@@ -64,6 +64,7 @@ public:
if (this != &other) {
release();
_p = other._p;
+ _deleteFn = other._deleteFn;
if (_p)
_p->incrementCounter();
}
@@ -72,8 +73,12 @@ public:
void release() {
if (_p) {
- if (_p->decrementCounter())
- delete _p;
+ if (_p->decrementCounter()) {
+ if (_deleteFn)
+ (_p->*_deleteFn)();
+ else
+ delete _p;
+ }
}
_p = nullptr;
}
@@ -110,8 +115,13 @@ public:
return _p;
}
+ void setDeleteFn(Tdestructor destructor) {
+ _deleteFn = destructor;
+ }
+
private:
T *_p;
+ Tdestructor _deleteFn;
};
} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_layout.cpp b/engines/tetraedge/te/te_layout.cpp
index e3aa96f95c2..02072ef0511 100644
--- a/engines/tetraedge/te/te_layout.cpp
+++ b/engines/tetraedge/te/te_layout.cpp
@@ -36,7 +36,7 @@ TeLayout::TeLayout() : Te3DObject2(), _updatingZ(false), _updatingZSize(false),
_safeAreaRatio(1.3333334f), _ratioMode(RATIO_MODE_NONE),
_positionType(CoordinatesType::RELATIVE_TO_PARENT)
{
- _userPosition = _position = TeVector3f32(0.5f, 0.5f, 0.5f);
+ _userPosition = _position = TeVector3f32(0.5f, 0.5f, 0.0f);
_size = TeVector3f32(1.0f, 1.0f, 1.0f);
_onChildSizeChangedCallback.reset(
new TeCallback0Param<TeLayout>(this, &TeLayout::onChildSizeChanged));
@@ -50,8 +50,10 @@ TeLayout::TeLayout() : Te3DObject2(), _updatingZ(false), _updatingZSize(false),
}
TeLayout::~TeLayout() {
- if (parent() && _onParentSizeChangedCallback)
+ if (parent() && _onParentSizeChangedCallback) {
parent()->onSizeChanged().remove(_onParentSizeChangedCallback);
+ parent()->onWorldTransformationMatrixChanged().remove(_onParentWorldTransformationMatrixChangedCallback);
+ }
if (_onChildSizeChangedCallback) {
for (auto &child : childList()) {
@@ -111,7 +113,6 @@ bool TeLayout::isAutoZEnabled() {
void TeLayout::draw() {
if (visible() && worldVisible()) {
- //debug("Draw TeLayout %p (%s)", this, name().empty() ? "no name" : name().c_str());
// Ensure world transform is up-to-date.
worldTransformationMatrix();
for (auto &child : childList()) {
@@ -195,6 +196,7 @@ void TeLayout::setMode(DrawMode mode) {
}
void TeLayout::setParent(Te3DObject2 *parent) {
+ assert(parent != this);
Te3DObject2 *oldParent = Te3DObject2::parent();
if (oldParent) {
if (_onParentSizeChangedCallback)
@@ -253,7 +255,7 @@ void TeLayout::setRatioMode(RatioMode mode) {
_ratioMode = mode;
_sizeChanged = true;
_worldMatrixChanged = true;
- }
+ }
}
void TeLayout::setRotation(const TeQuaternion &rot) {
@@ -342,7 +344,8 @@ void TeLayout::updatePosition() {
const TeVector3f32 parentSize(parentObj->xSize(), parentObj->ySize(), 0.0);
const TeVector3f32 offsetAnchor = midPoint - _anchor;
const TeVector3f32 thisSize(xSize(), ySize(), 0.0);
- _position = (offsetUserPos * parentSize) + (offsetAnchor * thisSize);
+ const TeVector3f32 newpos = (offsetUserPos * parentSize) + (offsetAnchor * thisSize);
+ _position = newpos;
} else if (_positionType == RELATIVE_TO_PARENT && !parentObj) {
// Not in original, but no parent -> set midpoint.
const TeVector3f32 offsetAnchor = midPoint - _anchor;
@@ -351,6 +354,7 @@ void TeLayout::updatePosition() {
} else if (_positionType == ABSOLUTE) {
_position = _userPosition;
}
+ _position.z() = _userPosition.z();
_worldMatrixChanged = true;
_updatingPosition = false;
diff --git a/engines/tetraedge/te/te_light.cpp b/engines/tetraedge/te/te_light.cpp
index e5faa68d5cd..f02c6990e8b 100644
--- a/engines/tetraedge/te/te_light.cpp
+++ b/engines/tetraedge/te/te_light.cpp
@@ -19,24 +19,159 @@
*
*/
+#include "common/math.h"
+
#include "tetraedge/te/te_light.h"
+#include "tetraedge/te/te_color.h"
+#include "tetraedge/te/te_quaternion.h"
+#include "tetraedge/te/te_vector3f32.h"
#include "graphics/opengl/system_headers.h"
namespace Tetraedge {
-TeLight::TeLight() {
+static inline uint _toGlLight(uint lightno) {
+ return GL_LIGHT0 + lightno;
}
-/*static*/ void TeLight::enableAll() {
- glEnable(GL_LIGHTING);
+/*static*/
+TeColor TeLight::_globalAmbientColor;
+
+TeLight::TeLight() : _colAmbient(0, 0, 0, 0xff), _colDiffuse(0, 0, 0, 0xff), _colSpecular(0xff, 0xff, 0xff, 0xff),
+_constAtten(0.0f), _linearAtten(1.0f), _quadraticAtten(0.0f), _cutoff(0.0f), _exponent(0.0f), _type(LightTypePoint),
+_displaySize(3.0)
+{
+}
+
+TeVector3f32 TeLight::directionVector() const {
+ float cosx = cosf(_positionRadial.getX());
+ float cosy = cosf(_positionRadial.getY());
+ float sinx = sinf(_positionRadial.getX());
+ float siny = sinf(_positionRadial.getY());
+ return TeVector3f32(cosx * cosy, siny, sinx * cosy);
+}
+
+void TeLight::disable(uint lightno) {
+ glDisable(_toGlLight(lightno));
}
-/*static*/ void TeLight::disableAll() {
+void TeLight::enable(uint lightno) {
+ if (_colDiffuse.r() == 0 && _colDiffuse.g() == 0 && _colDiffuse.b() == 0)
+ glDisable(_toGlLight(lightno));
+ else
+ glEnable(_toGlLight(lightno));
+}
+
+/*static*/
+void TeLight::disableAll() {
glDisable(GL_LIGHTING);
}
+/*static*/
+void TeLight::enableAll() {
+ glEnable(GL_LIGHTING);
+}
+
+void TeLight::draw(TeCamera &camera) {
+ error("TODO: Finish TeLight::draw");
+}
+
+void TeLight::transformDirPoint(const TeVector3f32 &pt1,TeVector3f32 &pt2) {
+ const TeQuaternion q1 = TeQuaternion::fromAxisAndAngle(TeVector3f32(0, 1, 0), _positionRadial.getX() + M_PI);
+ const TeQuaternion q2 = TeQuaternion::fromAxisAndAngle(TeVector3f32(0, 0, -1), -_positionRadial.getY());
+ pt2.rotate(q2);
+ pt2.rotate(q1);
+ pt2 += pt1;
+}
+
+void TeLight::transformSpotPoint(TeVector3f32 &pt) {
+ const TeQuaternion q1 = TeQuaternion::fromAxisAndAngle(TeVector3f32(0, 1, 0), _positionRadial.getX());
+ const TeQuaternion q2 = TeQuaternion::fromAxisAndAngle(TeVector3f32(0, 0, -1), _positionRadial.getY());
+ pt.rotate(q2);
+ pt.rotate(q1);
+ pt += _position3d;
+}
+
+void TeLight::update(uint lightno) {
+ float col[4];
+ const uint glLight = _toGlLight(lightno);
+ col[0] = _colAmbient.r() / 255.0f;
+ col[1] = _colAmbient.g() / 255.0f;
+ col[2] = _colAmbient.b() / 255.0f;
+ col[3] = 1.0;
+ glLightfv(glLight, GL_AMBIENT, col);
+
+ col[0] = _colDiffuse.r() / 255.0f;
+ col[1] = _colDiffuse.g() / 255.0f;
+ col[2] = _colDiffuse.b() / 255.0f;
+ col[3] = 1.0;
+ glLightfv(glLight, GL_DIFFUSE, col);
+ if (col[0] < 0.01f && col[1] < 0.01f && col[2] < 0.01f)
+ glDisable(glLight);
+
+ col[0] = _colSpecular.r() / 255.0f;
+ col[1] = _colSpecular.g() / 255.0f;
+ col[2] = _colSpecular.b() / 255.0f;
+ col[3] = 1.0;
+ glLightfv(glLight, GL_SPECULAR, col);
+
+ if (_type == LightTypeSpot || _type == LightTypePoint) {
+ float pos[4];
+ pos[0] = _position3d.x();
+ pos[1] = _position3d.y();
+ pos[2] = _position3d.z();
+ pos[3] = 1.0f;
+ glLightfv(glLight, GL_POSITION, pos);
+ glLightfv(glLight, GL_CONSTANT_ATTENUATION, &_constAtten);
+ glLightfv(glLight, GL_LINEAR_ATTENUATION, &_linearAtten);
+ glLightfv(glLight, GL_QUADRATIC_ATTENUATION, &_quadraticAtten);
+ }
+
+ if (_type == LightTypeDirectional) {
+ float pos[4];
+ float cosx = cosf(_positionRadial.getX());
+ float cosy = cosf(_positionRadial.getY());
+ float sinx = sinf(_positionRadial.getX());
+ float siny = sinf(_positionRadial.getY());
+ pos[0] = cosx * cosy;
+ pos[1] = siny;
+ pos[2] = sinx * cosy;
+ pos[3] = 0.0;
+ glLightfv(glLight, GL_POSITION, pos);
+ }
+
+ float atten;
+ uint atype;
+ if (_type == LightTypeSpot) {
+ float pos[4];
+ float cosx = cosf(_positionRadial.getX());
+ float cosy = cosf(_positionRadial.getY());
+ float sinx = sinf(_positionRadial.getX());
+ float siny = sinf(_positionRadial.getY());
+ pos[0] = cosx * cosy;
+ pos[1] = siny;
+ pos[2] = sinx * cosy;
+ pos[3] = 0.0;
+ glLightfv(glLight, GL_SPOT_DIRECTION, pos);
+ glLightf(glLight, GL_SPOT_CUTOFF, (_cutoff * 180.0) / M_PI);
+ atten = _exponent;
+ atype = GL_SPOT_EXPONENT;
+ } else {
+ atten = 180.0;
+ atype = GL_SPOT_CUTOFF;
+ }
+ glLightf(glLight, atype, atten);
+}
+
+/*static*/
+void TeLight::updateGlobal() {
+ float col[4];
+ col[0] = _globalAmbientColor.r() / 255.0f;
+ col[1] = _globalAmbientColor.g() / 255.0f;
+ col[2] = _globalAmbientColor.b() / 255.0f;
+ col[3] = 1.0;
+ glLightModelfv(GL_LIGHT_MODEL_AMBIENT, col);
+}
-// TODO: Add more functions here.
} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_light.h b/engines/tetraedge/te/te_light.h
index 547b2896631..633a5c125c2 100644
--- a/engines/tetraedge/te/te_light.h
+++ b/engines/tetraedge/te/te_light.h
@@ -29,9 +29,9 @@
namespace Tetraedge {
enum TeLightType {
- Type0 = 0,
- Type1 = 1,
- Type2 = 2 // uses quadratic attenuation?
+ LightTypePoint = 0,
+ LightTypeDirectional = 1,
+ LightTypeSpot = 2
};
class TeCamera;
@@ -43,29 +43,49 @@ public:
TeVector3f32 directionVector() const;
void disable(uint lightno);
void enable(uint lightno);
- static void enableAll();
static void disableAll();
+ static void enableAll();
void draw(TeCamera &camera);
- void transformDirPoint(TeVector3f32 &pt1,TeVector3f32 &pt2);
+ void transformDirPoint(const TeVector3f32 &pt1, TeVector3f32 &pt2);
void transformSpotPoint(TeVector3f32 &pt1);
void update(uint lightno);
- void updateGlobal();
+ static void updateGlobal();
+ static void setGlobalAmbient(const TeColor &col) { _globalAmbientColor = col; }
+
+ void setSpecular(const TeColor &col) { _colSpecular = col; }
+ void setDiffuse(const TeColor &col) { _colDiffuse = col; }
+ void setAmbient(const TeColor &col) { _colAmbient = col; }
+
+ void setConstAtten(float val) { _constAtten = val; }
+ void setLinearAtten(float val) { _linearAtten = val; }
+ void setQuadraticAtten(float val) { _quadraticAtten = val; }
+ void setCutoff(float val) { _cutoff = val; }
+ void setExponent(float val) { _exponent = val; }
+ void setDisplaySize(float val) { _displaySize = val; }
+ void setPosition3d(const TeVector3f32 &pos) { _position3d = pos; }
+ void setPositionRadial(const TeVector2f32 &pos) { _positionRadial = pos; }
private:
TeVector3f32 _position3d;
TeVector2f32 _positionRadial;
- TeColor col1;
- TeColor col2;
- TeColor col3;
- // TODO add private members
+ TeColor _colAmbient;
+ TeColor _colDiffuse;
+ TeColor _colSpecular;
enum TeLightType _type;
static TeColor _globalAmbientColor;
+
+ float _constAtten;
+ float _linearAtten;
+ float _quadraticAtten;
+ float _cutoff;
+ float _exponent;
+ float _displaySize;
};
} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_lua_gui.cpp b/engines/tetraedge/te/te_lua_gui.cpp
index a70c2268f09..e6d55d14ed5 100644
--- a/engines/tetraedge/te/te_lua_gui.cpp
+++ b/engines/tetraedge/te/te_lua_gui.cpp
@@ -269,6 +269,24 @@ void TeLuaGUI::unload() {
iter._value->deleteLater();
}
_extendedTextLayouts.clear();
+
+ for (auto &iter : _layoutAnchorLinearAnimations) {
+ iter._value->stop();
+ delete iter._value;
+ }
+ _layoutAnchorLinearAnimations.clear();
+
+ for (auto &iter : _layoutPositionLinearAnimations) {
+ iter._value->stop();
+ delete iter._value;
+ }
+ _layoutPositionLinearAnimations.clear();
+
+ for (auto &iter : _colorLinearAnimations) {
+ iter._value->stop();
+ delete iter._value;
+ }
+ _colorLinearAnimations.clear();
}
TeVariant TeLuaGUI::value(const Common::String &globalName) {
diff --git a/engines/tetraedge/te/te_lua_gui_lua_callbacks.cpp b/engines/tetraedge/te/te_lua_gui_lua_callbacks.cpp
index 85f125033bd..b8a04c324c1 100644
--- a/engines/tetraedge/te/te_lua_gui_lua_callbacks.cpp
+++ b/engines/tetraedge/te/te_lua_gui_lua_callbacks.cpp
@@ -75,12 +75,12 @@ static float TeLuaToF32(lua_State *L, int index) {
}
static bool TeLuaToBool(lua_State *L,int index) {
- if (lua_type(L, index) != LUA_TBOOLEAN) {
- warning("TeLuaToBool:: not a bool");
- return false;
- } else {
- return lua_toboolean(L, index);
- }
+ if (lua_type(L, index) != LUA_TBOOLEAN) {
+ warning("TeLuaToBool:: not a bool");
+ return false;
+ } else {
+ return lua_toboolean(L, index);
+ }
}
@@ -245,7 +245,7 @@ int layoutBindings(lua_State *L) {
layout->setName(Common::String::format("%p", (void *)layout));
}
lua_pushstring(L, "__TeLuaGUIThis");
- lua_gettable(L, LUA_REGISTRYINDEX);
+ lua_gettable(L, LUA_REGISTRYINDEX);
TeLuaGUI *gui = TeLuaTo<TeLuaGUI*>(L,-1);
TeLuaGUI::StringMap<TeLayout *> &layouts = gui->layouts();
if (!layouts.contains(layout->name())) {
@@ -384,7 +384,7 @@ int spriteLayoutBindings(lua_State *L) {
}
lua_settop(L, -2);
}
- if (!imgFullPath.empty())
+ if (!imgFullPath.empty()) {}
layout->load(imgFullPath);
lua_pushnil(L);
diff --git a/engines/tetraedge/te/te_matrix4x4.cpp b/engines/tetraedge/te/te_matrix4x4.cpp
index 2c53fdfb996..1f54fbec634 100644
--- a/engines/tetraedge/te/te_matrix4x4.cpp
+++ b/engines/tetraedge/te/te_matrix4x4.cpp
@@ -20,6 +20,7 @@
*/
#include "tetraedge/te/te_matrix4x4.h"
+#include "tetraedge/te/te_trs.h"
namespace Tetraedge {
@@ -65,10 +66,12 @@ TeMatrix4x4 operator*(const TeMatrix4x4 &left, const TeMatrix4x4 &right) {
return retval;
}
+/*
TeMatrix4x4 &TeMatrix4x4::operator*=(const TeMatrix4x4 &mul) {
- error("TODO: Opeartor *=");
+ TeMatrix4x4 result = operator*(*this, mul);
+ *this = result;
return *this;
-}
+}*/
bool TeMatrix4x4::operator==(const TeMatrix4x4 &other) const {
for (int i = 0; i < 16; i++) {
@@ -316,5 +319,30 @@ void TeMatrix4x4::serialize(Common::WriteStream &stream) const {
}
}
+/*static*/
+TeMatrix4x4 TeMatrix4x4::fromTRS(const TeTRS &trs) {
+ TeMatrix4x4 result;
+ const TeVector3f32 trans = trs.getTranslation();
+ TeMatrix4x4 transm;
+ float *tm = transm.getData();
+ tm[12] = trans.x();
+ tm[13] = trans.y();
+ tm[14] = trans.z();
+ result = result * transm;
+
+ const TeMatrix4x4 rotm = trs.getRotation().toMatrix();
+ result = result * rotm;
+
+ const TeVector3f32 scle = trs.getScale();
+ TeMatrix4x4 scalem;
+ float *sm = scalem.getData();
+ sm[0] = scle.x();
+ sm[5] = scle.y();
+ sm[10] = scle.z();
+ result = result * scalem;
+
+ return result;
+}
+
} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_matrix4x4.h b/engines/tetraedge/te/te_matrix4x4.h
index 73c93c3eae2..36aac4935cd 100644
--- a/engines/tetraedge/te/te_matrix4x4.h
+++ b/engines/tetraedge/te/te_matrix4x4.h
@@ -28,6 +28,8 @@
namespace Tetraedge {
+class TeTRS;
+
/* A 4x4 matrix, but stored in *column-major* order to match
* OpenGL (and the original engine)
*/
@@ -51,7 +53,7 @@ public:
return !operator==(other);
}
- TeMatrix4x4 &operator*=(const TeMatrix4x4 &mul);
+ //TeMatrix4x4 &operator*=(const TeMatrix4x4 &mul);
TeVector3f32 operator*(const TeVector3f32 &mul) const;
@@ -73,6 +75,8 @@ public:
bool inverse();
+ static TeMatrix4x4 fromTRS(const TeTRS &trs);
+
const float *getData() const { return _data; }
float *getData() { return _data; }
diff --git a/engines/tetraedge/te/te_mesh.cpp b/engines/tetraedge/te/te_mesh.cpp
index de83f7f15dd..bdf7075fda5 100644
--- a/engines/tetraedge/te/te_mesh.cpp
+++ b/engines/tetraedge/te/te_mesh.cpp
@@ -361,7 +361,17 @@ void TeMesh::update(const Common::Array<TeMatrix4x4> *matricies1, const Common::
}
void TeMesh::update(TeIntrusivePtr<TeModelVertexAnimation> vertexanim) {
+ _updatedVerticies.resize(_verticies.size());
+ _updatedNormals.resize(_normals.size());
+ const Common::Array<TeVector3f32> &animverts = vertexanim->getVertices();
+ assert(animverts.size() >= _verticies.size());
+ for (unsigned int i = 0; i < _verticies.size(); i++) {
+ _updatedVerticies[i] = animverts[i];
+ }
+ for (unsigned int i = 0; i < _normals.size(); i++) {
+ _updatedNormals[i] = _normals[i];
+ }
}
void TeMesh::updateTo(const Common::Array<TeMatrix4x4> *matricies1, const Common::Array<TeMatrix4x4> *matricies2,
diff --git a/engines/tetraedge/te/te_mesh.h b/engines/tetraedge/te/te_mesh.h
index 9012f087cb4..9e3fa5612b9 100644
--- a/engines/tetraedge/te/te_mesh.h
+++ b/engines/tetraedge/te/te_mesh.h
@@ -37,6 +37,8 @@
namespace Tetraedge {
+class TeModel;
+class TeModelVertexAnimation;
class TeMesh : public Te3DObject2 {
public:
diff --git a/engines/tetraedge/te/te_model.cpp b/engines/tetraedge/te/te_model.cpp
index fa3446b8cdb..b1ca1f1f3d5 100644
--- a/engines/tetraedge/te/te_model.cpp
+++ b/engines/tetraedge/te/te_model.cpp
@@ -33,7 +33,39 @@
namespace Tetraedge {
-TeModel::TeModel() : _enableLights(false), _skipBoneMatricies(false) {
+TeModel::TeModel() : _enableLights(false), _skipBoneMatricies(false), _matrixForced(false) {
+ // TODO: set 0x17c to 1.0
+ // TODO: set 0x178, 0x170 to 0
+ _modelAnim.setDeleteFn(&TeModelAnimation::deleteLater);
+ _modelVertexAnim.setDeleteFn(&TeModelVertexAnimation::deleteLater);
+ create();
+}
+
+TeModel::~TeModel() {
+ destroy();
+}
+
+void TeModel::create() {
+ // TODO: set field_0x158 to 0
+ _modelAnim.release();
+ _modelVertexAnim.release();
+ _matrixForced = false;
+ _skipBoneMatricies = false;
+}
+
+void TeModel::destroy() {
+ _weightElements.clear();
+ // TODO: clear matrix array 0x148
+ _meshes.clear();
+ _bones.clear();
+ // TODO: clear matrix array 0x190
+ _boneMatrices.clear();
+ for (MeshBlender *blender : _meshBlenders)
+ delete blender;
+ _meshBlenders.clear();
+ for (BonesBlender *blender : _boneBlenders)
+ delete blender;
+ _boneBlenders.clear();
}
int TeModel::checkFileType(Common::SeekableReadStream &instream) {
@@ -49,11 +81,11 @@ int TeModel::checkFileType(Common::SeekableReadStream &instream) {
return 0;
}
-void TeModel::blendAnim(TeIntrusivePtr<TeModelAnimation>& anim, float amount, bool repeat) {
+void TeModel::blendAnim(TeIntrusivePtr<TeModelAnimation>& anim, float seconds, bool repeat) {
if (!_modelAnim) {
setAnim(anim, repeat);
} else {
- BonesBlender *blender = new BonesBlender(anim, amount);
+ BonesBlender *blender = new BonesBlender(anim, seconds);
anim->_repeatCount = (repeat ? -1 : 1);
anim->play();
_boneBlenders.push_back(blender);
@@ -73,7 +105,7 @@ void TeModel::draw() {
renderer->pushMatrix();
renderer->multiplyMatrix(transform);
for (TeMesh &mesh : _meshes) {
- // TODO: Set some value in the mesh here to this->field_0x158??
+ // TODO: Set some flag in the mesh here to this->field_0x158??
mesh.draw();
}
renderer->popMatrix();
@@ -81,6 +113,20 @@ void TeModel::draw() {
}
}
+void TeModel::forceMatrix(const TeMatrix4x4 &matrix) {
+ _matrixForced = true;
+ _forcedMatrix = matrix;
+}
+
+TeTRS TeModel::getBone(TeIntrusivePtr<TeModelAnimation> anim, unsigned long num) {
+ if (anim) {
+ int bone = anim->findBone(_bones[num]._name);
+ if (bone != -1)
+ return anim->getTRS(bone, anim->curFrame2(), false);
+ }
+ return _bones[num]._trs;
+}
+
void TeModel::setColor(const TeColor &col) {
Te3DObject2::setColor(col);
for (TeMesh &mesh : _meshes) {
@@ -99,9 +145,17 @@ void TeModel::removeAnim() {
void TeModel::update() {
Common::Array<TeMatrix4x4> matricies;
matricies.resize(_bones.size());
- for (const bone &b : _bones) {
- //TeMatrix4x4 matrix = TeMatrix4x4::fomTRS(b._trs);
- warning("TODO: Finish TeModel::update.");
+ for (unsigned int i = 0; i < _bones.size(); i++) {
+ const bone &b = _bones[i];
+ TeMatrix4x4 matrix = TeMatrix4x4::fromTRS(b._trs);
+ if (b._x == -1 || _bones.size() < 2) {
+ matricies[0] = matrix;
+ } else {
+ matricies[i] = matricies[b._x] * matrix;
+ }
+ }
+ if (_bones.size()) {
+ //warning("TODO: Finish TeModel::update. (disasm 190 ~ 697)");
}
for (TeMesh &mesh : _meshes) {
if (!_modelVertexAnim) {
@@ -128,14 +182,16 @@ _name(name), _amount(amount) {
_timer.start();
}
-/*static*/ void TeModel::loadAlign(Common::SeekableReadStream &stream) {
+/*static*/
+void TeModel::loadAlign(Common::SeekableReadStream &stream) {
int64 pos = stream.pos();
if (pos % 4) {
stream.seek(4 - (pos % 4), SEEK_CUR);
}
}
-/*static*/ void TeModel::saveAlign(Common::SeekableWriteStream &stream) {
+/*static*/
+void TeModel::saveAlign(Common::SeekableWriteStream &stream) {
int64 pos = stream.pos();
if (pos % 4) {
stream.seek(4 - (pos % 4), SEEK_CUR);
@@ -143,7 +199,10 @@ _name(name), _amount(amount) {
}
bool TeModel::load(Common::SeekableReadStream &stream) {
- if (!loadAndCheckString(stream, "TEMD")) {
+ destroy();
+ create();
+
+ if (!loadAndCheckFourCC(stream, "TEMD")) {
error("[TeModel::load] Unknown format.");
}
@@ -162,7 +221,7 @@ bool TeModel::load(Common::SeekableReadStream &stream) {
_skipBoneMatricies = stream.readUint32LE();
}
- if (!loadAndCheckString(stream, "SKEL")) {
+ if (!loadAndCheckFourCC(stream, "SKEL")) {
error("[TeModel::load] Unable to find skeleton.");
}
@@ -182,7 +241,7 @@ bool TeModel::load(Common::SeekableReadStream &stream) {
}
}
- if (!loadAndCheckString(stream, "WEIG")) {
+ if (!loadAndCheckFourCC(stream, "WEIG")) {
error("[TeModel::load] Unable to load weight.");
}
for (unsigned int i = 0; i < _weightElements.size(); i++) {
@@ -204,7 +263,7 @@ bool TeModel::load(const Common::Path &path) {
}
bool retval;
- if (loadAndCheckString(modelFile, "TEZ0")) {
+ if (loadAndCheckFourCC(modelFile, "TEZ0")) {
Common::SeekableReadStream *zlibStream = tryLoadZlibStream(modelFile);
if (!zlibStream)
return false;
@@ -233,7 +292,7 @@ Common::SeekableReadStream *TeModel::tryLoadZlibStream(Common::SeekableReadStrea
return Common::wrapCompressedReadStream(&substream, uncompressedSize);
}
-bool TeModel::loadWeights(Common::ReadStream &stream, Common::Array<weightElement> weights) {
+bool TeModel::loadWeights(Common::ReadStream &stream, Common::Array<weightElement> &weights) {
uint32 nweights = stream.readUint32LE();
if (nweights > 100000)
error("Improbable number of weights %d", (int)nweights);
@@ -247,7 +306,7 @@ bool TeModel::loadWeights(Common::ReadStream &stream, Common::Array<weightElemen
}
bool TeModel::loadMesh(Common::SeekableReadStream &stream, TeMesh &mesh) {
- if (!loadAndCheckString(stream, "MESH"))
+ if (!loadAndCheckFourCC(stream, "MESH"))
return false;
uint32 vertcount = stream.readUint32LE();
@@ -265,7 +324,7 @@ bool TeModel::loadMesh(Common::SeekableReadStream &stream, TeMesh &mesh) {
mesh.setName(Te3DObject2::deserializeString(stream));
loadAlign(stream);
- if (!loadAndCheckString(stream, "MTRL"))
+ if (!loadAndCheckFourCC(stream, "MTRL"))
return false;
for (unsigned int i = 0; i < mesh.materials().size(); i++) {
@@ -276,7 +335,7 @@ bool TeModel::loadMesh(Common::SeekableReadStream &stream, TeMesh &mesh) {
mesh.attachMaterial(i, mat);
}
- if (!loadAndCheckString(stream, "VERT"))
+ if (!loadAndCheckFourCC(stream, "VERT"))
return false;
for (unsigned int i = 0; i < mesh.numVerticies(); i++) {
@@ -285,7 +344,7 @@ bool TeModel::loadMesh(Common::SeekableReadStream &stream, TeMesh &mesh) {
mesh.setVertex(i, v);
}
if (mesh.hasUvs()) {
- if (!loadAndCheckString(stream, "TUVS"))
+ if (!loadAndCheckFourCC(stream, "TUVS"))
return false;
for (unsigned int i = 0; i < mesh.numVerticies(); i++) {
TeVector2f32 v;
@@ -294,7 +353,7 @@ bool TeModel::loadMesh(Common::SeekableReadStream &stream, TeMesh &mesh) {
}
}
- if (!loadAndCheckString(stream, "NORM"))
+ if (!loadAndCheckFourCC(stream, "NORM"))
return false;
for (unsigned int i = 0; i < mesh.numVerticies(); i++) {
@@ -304,7 +363,7 @@ bool TeModel::loadMesh(Common::SeekableReadStream &stream, TeMesh &mesh) {
}
if (mesh.hasColor()) {
- if (!loadAndCheckString(stream, "COLS"))
+ if (!loadAndCheckFourCC(stream, "COLS"))
return false;
for (unsigned int i = 0; i < mesh.numVerticies(); i++) {
@@ -314,7 +373,7 @@ bool TeModel::loadMesh(Common::SeekableReadStream &stream, TeMesh &mesh) {
}
}
- if (!loadAndCheckString(stream, "FCPM"))
+ if (!loadAndCheckFourCC(stream, "FCPM"))
return false;
for (unsigned int i = 0; i < mesh.materials().size(); i++) {
@@ -322,7 +381,7 @@ bool TeModel::loadMesh(Common::SeekableReadStream &stream, TeMesh &mesh) {
}
loadAlign(stream);
- if (!loadAndCheckString(stream, "MTXI"))
+ if (!loadAndCheckFourCC(stream, "MTXI"))
return false;
for (unsigned int i = 0; i < mesh.numVerticies(); i++) {
@@ -330,7 +389,7 @@ bool TeModel::loadMesh(Common::SeekableReadStream &stream, TeMesh &mesh) {
}
loadAlign(stream);
- if (!loadAndCheckString(stream, "IDXS"))
+ if (!loadAndCheckFourCC(stream, "IDXS"))
return false;
for (unsigned int i = 0; i < mesh.numIndexes(); i++) {
@@ -377,6 +436,11 @@ void TeModel::setAnim(TeIntrusivePtr<TeModelAnimation> &anim, bool repeat) {
_modelAnim = anim;
}
+void TeModel::setVertexAnim(TeIntrusivePtr<TeModelVertexAnimation> &anim, bool repeat) {
+ anim->_repeatCount = (repeat ? -1 : 1);
+ _modelVertexAnim = anim;
+}
+
void TeModel::setVisibleByName(const Common::String &name, bool vis) {
for (TeMesh &mesh : _meshes) {
if (mesh.name().contains(name)) {
@@ -385,14 +449,14 @@ void TeModel::setVisibleByName(const Common::String &name, bool vis) {
}
}
-bool TeModel::loadAndCheckString(Common::ReadStream &stream, const char *str) {
- char buf[5];
- buf[4] = '\0';
- stream.read(buf, 4);
- return !strncmp(buf, str, 4);
+TeMatrix4x4 TeModel::skinOffset(unsigned long boneno) const {
+ if (boneno >= _boneMatrices.size())
+ return TeMatrix4x4();
+ return _boneMatrices[boneno];
}
TeModel::BonesBlender::BonesBlender(TeIntrusivePtr<TeModelAnimation> anim, float seconds) : _anim(anim), _seconds(seconds) {
+ _anim.setDeleteFn(&TeModelAnimation::deleteLater);
_timer.stop();
_timer.start();
}
diff --git a/engines/tetraedge/te/te_model.h b/engines/tetraedge/te/te_model.h
index 74f17a3be64..532916e9c04 100644
--- a/engines/tetraedge/te/te_model.h
+++ b/engines/tetraedge/te/te_model.h
@@ -29,17 +29,18 @@
#include "tetraedge/te/te_trs.h"
#include "tetraedge/te/te_mesh.h"
#include "tetraedge/te/te_model_animation.h"
+#include "tetraedge/te/te_model_vertex_animation.h"
#include "tetraedge/te/te_tiled_texture.h"
#include "tetraedge/te/te_intrusive_ptr.h"
namespace Tetraedge {
+class TeModelVertexAnimation;
class TeModelAnimation;
+class TeMesh;
class TeModel : public Te3DObject2, public TeResource {
public:
- TeModel();
-
class BonesBlender {
public:
// Note: original takes a TeModel & but ignores it.
@@ -63,14 +64,18 @@ public:
struct bone {
Common::String _name;
- unsigned short _x;
+ short _x;
TeTRS _trs;
};
+
struct weightElement {
float _w;
unsigned short _x;
};
+ TeModel();
+ virtual ~TeModel();
+
void addMesh(const TeMesh &mesh) {
_meshes.push_back(mesh);
}
@@ -83,8 +88,16 @@ public:
int checkFileType(Common::SeekableReadStream &instream);
+ void create();
+ void destroy();
+
void draw() override;
- virtual void setColor(const TeColor &col) override;
+
+ int findModelBone(const Common::String &name);
+ int findOrAddWeights(const Common::Array<weightElement> &weights);
+ void forceMatrix(const TeMatrix4x4 &matrix);
+ TeTRS getBone(TeIntrusivePtr<TeModelAnimation> anim, unsigned long num);
+ TeMatrix4x4 lerpElementsMatrix(unsigned long num, Common::Array<TeMatrix4x4> &matricies);
/* Align the stream to the nearest 4 byte boudary*/
static void loadAlign(Common::SeekableReadStream &stream);
@@ -93,17 +106,26 @@ public:
bool load(const Common::Path &path);
bool load(Common::SeekableReadStream &stream);
- bool loadWeights(Common::ReadStream &stream, Common::Array<weightElement> weights);
+ bool loadWeights(Common::ReadStream &stream, Common::Array<weightElement> &weights);
bool loadMesh(Common::SeekableReadStream &stream, TeMesh &mesh);
+ void optimize();
void update();
void removeAnim();
- void setVisibleByName(const Common::String &name, bool vis);
- void setQuad(const TeIntrusivePtr<Te3DTexture> &tex, const Common::Array<TeVector3f32> &verts, const TeColor &col);
+
+ void saveBone(Common::SeekableWriteStream &stream, unsigned long boneno);
+ void saveMesh(Common::SeekableWriteStream &stream, const TeMesh &mesh);
+ void saveModel(Common::SeekableWriteStream &stream, unsigned int num);
+ void saveWeights(Common::SeekableWriteStream &stream, const Common::Array<weightElement> weights);
void setAnim(TeIntrusivePtr<TeModelAnimation> &anim, bool repeat);
+ virtual void setColor(const TeColor &col) override;
+ void setQuad(const TeIntrusivePtr<Te3DTexture> &tex, const Common::Array<TeVector3f32> &verts, const TeColor &col);
+ void setVertexAnim(TeIntrusivePtr<TeModelVertexAnimation> &anim, bool repeat);
+ void setVisibleByName(const Common::String &name, bool vis);
+
+ TeMatrix4x4 skinOffset(unsigned long boneno) const;
- static bool loadAndCheckString(Common::ReadStream &stream, const char *str);
static Common::SeekableReadStream *tryLoadZlibStream(Common::SeekableReadStream &instr);
TeIntrusivePtr<TeTiledTexture> _tiledTexture;
@@ -114,6 +136,8 @@ public:
Common::Array<TeMesh> _meshes;
protected:
+ bool _matrixForced;
+ TeMatrix4x4 _forcedMatrix;
Common::Array<MeshBlender *> _meshBlenders;
Common::Array<bone> _bones;
Common::Array<TeMatrix4x4> _boneMatrices;
diff --git a/engines/tetraedge/te/te_model_animation.cpp b/engines/tetraedge/te/te_model_animation.cpp
index f0565646660..8fad3f12fda 100644
--- a/engines/tetraedge/te/te_model_animation.cpp
+++ b/engines/tetraedge/te/te_model_animation.cpp
@@ -34,12 +34,12 @@ _curFrame(0), _curFrameValFresh(false), _repeatNum(0), _finishedSignalPending(fa
_curFrame2(0), _useNMOArrays(0), _speed(0.0f) {
}
-int TeModelAnimation::calcCurrentFrame(double proportion) {
+int TeModelAnimation::calcCurrentFrame(double millis) {
if (!_curFrameValFresh) {
int lastf = lastFrame();
int firstf = _firstFrame < 0 ? 0 : _firstFrame;
- int curf = (proportion / 1000.0) * _speed;
+ int curf = (millis / 1000.0) * _speed;
curf = curf % ((lastf + 1) - firstf) + firstf;
if (!_dontRepeat && curf < _curFrame) {
@@ -175,7 +175,7 @@ bool TeModelAnimation::load(const Common::Path &path) {
return false;
}
bool retval;
- if (TeModel::loadAndCheckString(modelFile, "TEZ0")) {
+ if (Te3DObject2::loadAndCheckFourCC(modelFile, "TEZ0")) {
Common::SeekableReadStream *zlibStream = TeModel::tryLoadZlibStream(modelFile);
if (!zlibStream)
return false;
@@ -190,7 +190,7 @@ bool TeModelAnimation::load(const Common::Path &path) {
}
bool TeModelAnimation::load(Common::SeekableReadStream &stream) {
- if (!TeModel::loadAndCheckString(stream, "TEAN")) {
+ if (!Te3DObject2::loadAndCheckFourCC(stream, "TEAN")) {
warning("[TeModelAnimation::load] Unknown format.");
return false;
}
@@ -214,11 +214,11 @@ bool TeModelAnimation::load(Common::SeekableReadStream &stream) {
_speed = stream.readFloatLE();
for (unsigned int i = 0; i < numBones; i++) {
- if (!TeModel::loadAndCheckString(stream, "BONE"))
+ if (!Te3DObject2::loadAndCheckFourCC(stream, "BONE"))
return false;
const Common::String boneName = Te3DObject2::deserializeString(stream);
setBoneName(i, boneName);
- if (!TeModel::loadAndCheckString(stream, "BTRA"))
+ if (!Te3DObject2::loadAndCheckFourCC(stream, "BTRA"))
return false;
uint32 numTrans = stream.readUint32LE();
for (unsigned int j = 0; j < numTrans; j++) {
@@ -227,7 +227,7 @@ bool TeModelAnimation::load(Common::SeekableReadStream &stream) {
TeVector3f32::deserialize(stream, trans);
setTranslation(j, f, trans);
}
- if (!TeModel::loadAndCheckString(stream, "BROT"))
+ if (!Te3DObject2::loadAndCheckFourCC(stream, "BROT"))
return false;
uint32 numRots = stream.readUint32LE();
for (unsigned int j = 0; j < numRots; j++) {
diff --git a/engines/tetraedge/te/te_model_animation.h b/engines/tetraedge/te/te_model_animation.h
index dff1540e2c4..b06a5c9b150 100644
--- a/engines/tetraedge/te/te_model_animation.h
+++ b/engines/tetraedge/te/te_model_animation.h
@@ -57,7 +57,7 @@ public:
void bind(const TeIntrusivePtr<TeModel> &ptr) {
_model = ptr;
};
- int calcCurrentFrame(double proportion);
+ int calcCurrentFrame(double millis);
void cont() override;
void destroy();
int findBone(const Common::String &name);
@@ -87,6 +87,8 @@ public:
void unbind();
void update(double proportion) override;
+ int curFrame2() const { return _curFrame2; }
+
TeIntrusivePtr<TeModel> _model;
int _firstFrame;
int _lastFrame;
diff --git a/engines/tetraedge/te/te_model_vertex_animation.cpp b/engines/tetraedge/te/te_model_vertex_animation.cpp
index 305765ed6bd..cef7f635c47 100644
--- a/engines/tetraedge/te/te_model_vertex_animation.cpp
+++ b/engines/tetraedge/te/te_model_vertex_animation.cpp
@@ -23,9 +23,84 @@
namespace Tetraedge {
-TeModelVertexAnimation::TeModelVertexAnimation() {
+TeModelVertexAnimation::TeModelVertexAnimation() : _rot(1.0f, 0.0f, 0.0f, 0.0f),
+_lastMillis(0.0f), _modelAnim(nullptr) {
+ // TODO: set some other things up here.
+ _rot.fromAxisAndAngle(TeVector3f32(0.0f, 1.0f, 0.0f), -1.570796);
}
-// TODO: Add more functions here.
+void TeModelVertexAnimation::bind(TeIntrusivePtr<TeModel> &model) {
+ _model = model;
+ _lastMillis = 0.0f;
+}
+
+void TeModelVertexAnimation::destroy() {
+ _keydata.clear();
+}
+
+TeVector3f32 TeModelVertexAnimation::getKeyVertex(unsigned long keyno, unsigned int vertexno) {
+ assert(keyno < _keydata.size());
+ const KeyData &data = _keydata[keyno];
+ assert(vertexno < data._vectors.size());
+ TeVector3f32 retval = data._vectors[vertexno];
+ if (!data._matricies.empty()) {
+ retval = data._matricies[vertexno] * retval;
+ retval.rotate(_rot);
+ }
+ return retval;
+}
+
+const Common::Array<TeVector3f32> &TeModelVertexAnimation::getVertices() {
+ static Common::Array<TeVector3f32> lerpVtx;
+
+ lerpVtx.clear();
+ if (_keydata.size() < 2)
+ return lerpVtx;
+
+ float frame = fmod((_lastMillis / 1000.0) * 30, _keydata[_keydata.size() - 1]._frame);
+ unsigned int keyno = 0;
+ while (keyno < _keydata.size() - 1 && _keydata[keyno]._frame < frame)
+ keyno++;
+
+ lerpVtx.resize(_keydata[0]._vectors.size());
+ float prevFrame = _keydata[keyno]._frame;
+ float nextFrame = _keydata[keyno + 1]._frame;
+ float interp = (frame - nextFrame) / (nextFrame - prevFrame);
+
+ for (unsigned int i = 0; i < _keydata[0]._vectors.size(); i++) {
+ const TeVector3f32 prevVector = getKeyVertex(keyno, i);
+ const TeVector3f32 nextVector = getKeyVertex(keyno + 1, i);
+ lerpVtx.push_back(prevVector * (1.0 - interp) + nextVector * interp);
+ }
+
+ return lerpVtx;
+}
+
+bool TeModelVertexAnimation::load(Common::ReadStream &stream) {
+ error("TODO: implement TeModelVertexAnimation::load");
+}
+
+void TeModelVertexAnimation::save(Common::WriteStream &stream) const {
+ error("TODO: implement TeModelVertexAnimation::save");
+}
+
+void TeModelVertexAnimation::update(double millis) {
+ if (_keydata.empty())
+ return;
+
+ double lastMillis = _lastMillis;
+ double lastFrame = fmod((lastMillis / 1000.0) * 30.0, _keydata.back()._frame);
+
+ if (_modelAnim) {
+ int frame = _modelAnim->calcCurrentFrame(millis);
+ millis = (frame * 1000.0) / 30.0;
+ }
+ _lastMillis = millis;
+ double thisFrame = fmod((millis / 1000.0) * 30.0, _keydata.back()._frame);
+ if (lastFrame > thisFrame)
+ _onFinishedSignal.call();
+}
+
+
} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_model_vertex_animation.h b/engines/tetraedge/te/te_model_vertex_animation.h
index 6f0a5a809ec..9e3e7ce9e76 100644
--- a/engines/tetraedge/te/te_model_vertex_animation.h
+++ b/engines/tetraedge/te/te_model_vertex_animation.h
@@ -19,37 +19,56 @@
*
*/
+#ifndef TETRAEDGE_TE_TE_MODEL_VERTEX_ANIMATION_H
+#define TETRAEDGE_TE_TE_MODEL_VERTEX_ANIMATION_H
+
#include "common/str.h"
#include "common/array.h"
+#include "common/stream.h"
#include "tetraedge/te/te_animation.h"
#include "tetraedge/te/te_matrix4x4.h"
+#include "tetraedge/te/te_model.h"
+#include "tetraedge/te/te_intrusive_ptr.h"
#include "tetraedge/te/te_resource.h"
#include "tetraedge/te/te_vector3f32.h"
-#ifndef TETRAEDGE_TE_TE_MODEL_VERTEX_ANIMATION_H
-#define TETRAEDGE_TE_TE_MODEL_VERTEX_ANIMATION_H
-
namespace Tetraedge {
+class TeModel;
+class TeModelAnimation;
+
class TeModelVertexAnimation : public TeAnimation, public TeResource {
public:
struct KeyData {
- float _f;
+ float _frame;
Common::Array<TeVector3f32> _vectors;
Common::Array<TeMatrix4x4> _matricies;
};
TeModelVertexAnimation();
+ void bind(TeIntrusivePtr<TeModel> &model);
+ // void deleteLater() // original overrides this, but just calls the super.
+ void destroy();
+
const Common::String &head() const { return _head; }
+ TeVector3f32 getKeyVertex(unsigned long keyno, unsigned int vertexno);
+ const Common::Array<TeVector3f32> &getVertices();
+
+ bool load(Common::ReadStream &stream);
+ void save(Common::WriteStream &stream) const;
+
+ void update(double amount) override;
private:
+ float _lastMillis;
+ TeIntrusivePtr<TeModel> _model;
+ TeModelAnimation *_modelAnim;
+ TeQuaternion _rot;
Common::String _head;
Common::Array<KeyData> _keydata;
- // TODO add private members
-
};
} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_obp.cpp b/engines/tetraedge/te/te_obp.cpp
index e86d4cdc667..613ec30323e 100644
--- a/engines/tetraedge/te/te_obp.cpp
+++ b/engines/tetraedge/te/te_obp.cpp
@@ -81,7 +81,7 @@ void TeOBP::setScale(const TeVector3f32 &scale) {
_boundsNeedUpdate = true;
}
-void TeOBP::translate(const TeVector3f32 &offset) {
+void TeOBP::translate(const TeVector3f32 &offset) {
Te3DObject2::translate(offset);
_boundsNeedUpdate = true;
}
diff --git a/engines/tetraedge/te/te_pick_mesh2.cpp b/engines/tetraedge/te/te_pick_mesh2.cpp
index 1621a035992..4b279900895 100644
--- a/engines/tetraedge/te/te_pick_mesh2.cpp
+++ b/engines/tetraedge/te/te_pick_mesh2.cpp
@@ -97,5 +97,24 @@ void TePickMesh2::setTriangle(unsigned long num, const TeVector3f32 &v1, const T
_verticies[num * 3 + 2] = v3;
}
+/*static*/
+void TePickMesh2::serialize(Common::WriteStream &stream, const TePickMesh2 &mesh) {
+ error("TODO: Implement TePickMesh2::serialize");
+}
+
+/*static*/
+void TePickMesh2::deserialize(Common::ReadStream &stream, TePickMesh2 &mesh) {
+ Te3DObject2::deserialize(stream, mesh);
+ uint32 ntriangles = stream.readUint32LE();
+ mesh._verticies.resize(ntriangles * 3);
+ mesh._lastTriangleHit = 0;
+
+ for (unsigned int i = 0; i < ntriangles * 3; i++) {
+ TeVector3f32 vec;
+ TeVector3f32::deserialize(stream, vec);
+ mesh._verticies.push_back(vec);
+ }
+}
+
} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_pick_mesh2.h b/engines/tetraedge/te/te_pick_mesh2.h
index 5d04d10aac2..1e7c07e8bb5 100644
--- a/engines/tetraedge/te/te_pick_mesh2.h
+++ b/engines/tetraedge/te/te_pick_mesh2.h
@@ -50,6 +50,7 @@ public:
static void serialize(Common::WriteStream &stream, const TePickMesh2 &mesh);
static void deserialize(Common::ReadStream &stream, TePickMesh2 &mesh);
+ Common::Array<TeVector3f32> &verticies() { return _verticies; }
private:
Common::Array<TeVector3f32> _verticies;
unsigned long _lastTriangleHit;
diff --git a/engines/tetraedge/te/te_scene.cpp b/engines/tetraedge/te/te_scene.cpp
index 3610bb6ce10..bfe9396c04d 100644
--- a/engines/tetraedge/te/te_scene.cpp
+++ b/engines/tetraedge/te/te_scene.cpp
@@ -23,7 +23,7 @@
namespace Tetraedge {
-TeScene::TeScene() {
+TeScene::TeScene() : _currentCameraIndex(0) {
}
void TeScene::close() {
@@ -90,7 +90,7 @@ void TeScene::setCurrentCamera(const Common::String &name) {
}
}
if (i == n) {
- warning("setCurrentCamera: Couldn't find camera %s", name.c_str());
+ //warning("TeScene::setCurrentCamera: Couldn't find camera %s", name.c_str());
return;
}
_currentCameraIndex = i;
diff --git a/engines/tetraedge/te/te_scene.h b/engines/tetraedge/te/te_scene.h
index 1a66565e33e..f01e5bace6e 100644
--- a/engines/tetraedge/te/te_scene.h
+++ b/engines/tetraedge/te/te_scene.h
@@ -47,7 +47,7 @@ public:
Common::String currentCameraName() const;
void draw();
- virtual void load(Common::Path &path) {};
+ virtual bool load(const Common::Path &path) { return false; };
void removeModel(const Common::String &name);
void setCurrentCamera(const Common::String &name);
diff --git a/engines/tetraedge/te/te_text_base2.cpp b/engines/tetraedge/te/te_text_base2.cpp
index 816454c83e1..8de44498a49 100644
--- a/engines/tetraedge/te/te_text_base2.cpp
+++ b/engines/tetraedge/te/te_text_base2.cpp
@@ -139,6 +139,7 @@ void TeTextBase2::clearText() {
}
void TeTextBase2::computeNbSpaces(Line &line, unsigned int startOffset, unsigned int endOffset) {
+ // only needed if we implement Justify
error("TODO: Implement TeTextBase2::computeNbSpaces");
}
@@ -292,8 +293,9 @@ void TeTextBase2::strikethrough(bool val) {
_strikethrough = val;
_valueWasSet = true;
}
- if (val)
+ if (val) {
warning("TODO: Implement TeTextBase2::draw strikethrough support");
+ }
}
diff --git a/engines/tetraedge/te/te_vector3f32.cpp b/engines/tetraedge/te/te_vector3f32.cpp
index 9acbf3366d4..ee7b2f62bf7 100644
--- a/engines/tetraedge/te/te_vector3f32.cpp
+++ b/engines/tetraedge/te/te_vector3f32.cpp
@@ -21,7 +21,9 @@
#include "tetraedge/tetraedge.h"
#include "common/str-array.h"
+#include "math/matrix4.h"
#include "tetraedge/te/te_vector3f32.h"
+#include "tetraedge/te/te_quaternion.h"
namespace Tetraedge {
@@ -35,5 +37,10 @@ bool TeVector3f32::parse(const Common::String &val) {
return true;
}
+void TeVector3f32::rotate(const TeQuaternion &rot) {
+ Math::Matrix4 matrix = rot.toMatrix();
+ matrix.transform(this, false);
+}
+
} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_vector3f32.h b/engines/tetraedge/te/te_vector3f32.h
index fa5fbce8aae..e6070b91310 100644
--- a/engines/tetraedge/te/te_vector3f32.h
+++ b/engines/tetraedge/te/te_vector3f32.h
@@ -28,6 +28,8 @@
namespace Tetraedge {
+class TeQuaternion;
+
class TeVector3f32 : public Math::Vector3d {
public:
@@ -42,6 +44,10 @@ public:
return *this;
}
+ //TeVector3f32 operator*(const TeVector3f32 &other) const {
+ // return TeVector3f32(x() * other.x(), y() * other.y(), z() * other.z());
+ //}
+
explicit TeVector3f32(const TeVector2s32 &vec2d) {
set(vec2d._x, vec2d._y, 0.0);
}
@@ -68,16 +74,8 @@ public:
Common::String dump() const {
return Common::String::format("TeVector3f32(%.02f %.02f %.02f)", x(), y(), z());
}
- /*
- TODO: do we need anything not already provided by Vector3d?
-public:
- TeVector3f32();
-public:
- float x;
- float y;
- float z;
- */
+ void rotate(const TeQuaternion &rot);
};
} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_visual_fade.cpp b/engines/tetraedge/te/te_visual_fade.cpp
index dcfcd49adf8..3c085d84001 100644
--- a/engines/tetraedge/te/te_visual_fade.cpp
+++ b/engines/tetraedge/te/te_visual_fade.cpp
@@ -30,7 +30,7 @@ TeVisualFade::TeVisualFade() {
}
void TeVisualFade::animateBlackFade() {
- error("TODO: Implement me.");
+ error("TODO: Implement TeVisualFade::animateBlackFade.");
}
void TeVisualFade::animateFade() {
diff --git a/engines/tetraedge/to_lua.cpp b/engines/tetraedge/to_lua.cpp
index 39eba13663a..a9ddd9c486c 100644
--- a/engines/tetraedge/to_lua.cpp
+++ b/engines/tetraedge/to_lua.cpp
@@ -163,13 +163,13 @@ static int tolua_bnd_type(lua_State *L) {
}
static void *tolua_clone(lua_State *L, void *dest, lua_CFunction fn) {
- lua_pushstring(L, "tolua_gc");
- lua_rawget(L, LUA_REGISTRYINDEX);
- lua_pushlightuserdata(L, dest);
- lua_pushcclosure(L, fn, 0);
- lua_rawset(L,-3);
- lua_settop(L,-2);
- return dest;
+ lua_pushstring(L, "tolua_gc");
+ lua_rawget(L, LUA_REGISTRYINDEX);
+ lua_pushlightuserdata(L, dest);
+ lua_pushcclosure(L, fn, 0);
+ lua_rawset(L,-3);
+ lua_settop(L,-2);
+ return dest;
}
@@ -182,13 +182,13 @@ static int tolua_bnd_takeownership(lua_State *L) {
if (lua_iscfunction(L,-1)) {
fn = lua_tocfunction(L, -1);
}
- lua_settop(L,-3);
- void *data = lua_touserdata(L, 1);
- tolua_clone(L, data, fn);
+ lua_settop(L,-3);
+ void *data = lua_touserdata(L, 1);
+ tolua_clone(L, data, fn);
+ }
}
- }
- lua_pushboolean(L, (uint)(fn != nullptr));
- return 1;
+ lua_pushboolean(L, (uint)(fn != nullptr));
+ return 1;
}
static int tolua_bnd_releaseownership(lua_State *L) {
@@ -309,12 +309,12 @@ static int module_newindex_event(lua_State *L) {
}
static void tolua_moduleevents(lua_State *L) {
- lua_pushstring(L, "__index");
- lua_pushcclosure(L, module_index_event, 0);
- lua_rawset(L, -3);
- lua_pushstring(L, "__newindex");
- lua_pushcclosure(L, module_newindex_event, 0);
- lua_rawset(L, -3);
+ lua_pushstring(L, "__index");
+ lua_pushcclosure(L, module_index_event, 0);
+ lua_rawset(L, -3);
+ lua_pushstring(L, "__newindex");
+ lua_pushcclosure(L, module_newindex_event, 0);
+ lua_rawset(L, -3);
}
static bool tolua_ismodulemetatable(lua_State *L) {
@@ -388,11 +388,11 @@ int tolua_isboolean(lua_State *L, int lo, int def, tolua_Error *err) {
int tolua_isnoobj(lua_State *L, int lo, tolua_Error *err) {
if (lua_gettop(L) < abs(lo))
- return 1;
+ return 1;
err->index = lo;
err->array = false;
err->type = "[no object]";
- return 0;
+ return 0;
}
int tolua_isnumber(lua_State *L, int lo, int def, tolua_Error *err) {
@@ -423,7 +423,7 @@ double tolua_tonumber(lua_State *L, int narg, double def) {
}
const char *tolua_tostring(lua_State *L, int narg, const char *def) {
- return lua_gettop(L) < abs(narg) ? def : lua_tostring(L, narg);
+ return lua_gettop(L) < abs(narg) ? def : lua_tostring(L, narg);
}
void *tolua_tousertype(lua_State *L, int narg, void* def) {
Commit: 681b4f8c555fd9ceae00beb7efb46aaad82bb4a3
https://github.com/scummvm/scummvm/commit/681b4f8c555fd9ceae00beb7efb46aaad82bb4a3
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2023-01-16T17:36:43+01:00
Commit Message:
TETRAEDGE: More WIP. First scene now loads, yay.
Changed paths:
A engines/tetraedge/te/te_ray_intersection.cpp
A engines/tetraedge/te/te_ray_intersection.h
R engines/tetraedge/te/te_fee_move_zone.cpp
R engines/tetraedge/te/te_fee_move_zone.h
engines/tetraedge/game/application.cpp
engines/tetraedge/game/application.h
engines/tetraedge/game/character.h
engines/tetraedge/game/character_settings_xml_parser.h
engines/tetraedge/game/characters_shadow.cpp
engines/tetraedge/game/dialog2.cpp
engines/tetraedge/game/documents_browser.cpp
engines/tetraedge/game/documents_browser.h
engines/tetraedge/game/game.cpp
engines/tetraedge/game/game.h
engines/tetraedge/game/help_option_menu.cpp
engines/tetraedge/game/in_game_scene.cpp
engines/tetraedge/game/in_game_scene.h
engines/tetraedge/game/inventory.cpp
engines/tetraedge/game/lua_binds.cpp
engines/tetraedge/game/main_menu.cpp
engines/tetraedge/game/main_menu.h
engines/tetraedge/game/notifier.cpp
engines/tetraedge/game/notifier.h
engines/tetraedge/game/objectif.h
engines/tetraedge/module.mk
engines/tetraedge/te/te_3d_object2.cpp
engines/tetraedge/te/te_3d_object2.h
engines/tetraedge/te/te_3d_texture.cpp
engines/tetraedge/te/te_animation.cpp
engines/tetraedge/te/te_bezier_curve.h
engines/tetraedge/te/te_button_layout.cpp
engines/tetraedge/te/te_button_layout.h
engines/tetraedge/te/te_camera.cpp
engines/tetraedge/te/te_camera.h
engines/tetraedge/te/te_free_move_zone.cpp
engines/tetraedge/te/te_free_move_zone.h
engines/tetraedge/te/te_light.h
engines/tetraedge/te/te_lua_gui_lua_callbacks.cpp
engines/tetraedge/te/te_lua_thread.cpp
engines/tetraedge/te/te_lua_thread.h
engines/tetraedge/te/te_matrix4x4.h
engines/tetraedge/te/te_model.cpp
engines/tetraedge/te/te_model.h
engines/tetraedge/te/te_model_animation.cpp
engines/tetraedge/te/te_model_animation.h
engines/tetraedge/te/te_obp.cpp
engines/tetraedge/te/te_pick_mesh2.h
engines/tetraedge/te/te_renderer.cpp
engines/tetraedge/te/te_scene.cpp
engines/tetraedge/te/te_scene.h
engines/tetraedge/te/te_scrolling_layout.cpp
engines/tetraedge/te/te_sprite_layout.h
engines/tetraedge/te/te_text_layout.h
engines/tetraedge/te/te_tiled_surface.h
engines/tetraedge/te/te_timer.h
engines/tetraedge/te/te_vector2s32.cpp
engines/tetraedge/te/te_vector2s32.h
engines/tetraedge/te/te_vector3f32.cpp
engines/tetraedge/te/te_vector3f32.h
engines/tetraedge/te/te_visual_fade.cpp
engines/tetraedge/te/te_visual_fade.h
engines/tetraedge/te/te_xml_gui.h
diff --git a/engines/tetraedge/game/application.cpp b/engines/tetraedge/game/application.cpp
index 9345f2d11af..b985b63e921 100644
--- a/engines/tetraedge/game/application.cpp
+++ b/engines/tetraedge/game/application.cpp
@@ -60,7 +60,8 @@ _captureFade(false), _difficulty(1), _created(false), _tutoActivated(false) {
// TODO: Configure sound manager here?
// TODO: Configure freemium things here?
- // TODO: Start some timer here?
+
+ // Note: original has an app run timer, but it's never used?
loadOptions("options.xml");
}
@@ -72,6 +73,7 @@ void Application::create() {
const int winHeight = g_engine->getDefaultScreenHeight();
// See TeMainWindowBase::initCamera
_mainWindowCamera.reset(new TeCamera());
+ _mainWindowCamera->setName("_mainWinCam");
_mainWindowCamera->_projectionMatrixType = 4;
_mainWindowCamera->viewport(0, 0, winWidth, winHeight);
_mainWindowCamera->orthogonalParams(winWidth * -0.5f, winWidth * 0.5f, winHeight * 0.5f, winHeight * -0.5f);
@@ -234,6 +236,7 @@ void Application::create() {
_autoSaveIconAnim1.pause();
_autoSaveIconAnim1._startVal = TeColor(255, 255, 255, 0);
_autoSaveIconAnim1._endVal = TeColor(255, 255, 255, 255);
+ _autoSaveIconAnim1._repeatCount = -1;
Common::Array<float> curve;
curve.push_back(0.0f);
curve.push_back(1.0f);
@@ -256,12 +259,13 @@ void Application::create() {
_autoSaveIconAnim2.pause();
_autoSaveIconAnim2._startVal = TeColor(255, 255, 255, 0);
_autoSaveIconAnim2._endVal = TeColor(255, 255, 255, 255);
+ _autoSaveIconAnim2._repeatCount = 1;
_autoSaveIconAnim2.setCurve(curve);
_autoSaveIconAnim2._duration = 4000.0f;
_autoSaveIconAnim2._callbackObj = &_autoSaveIcon2;
_autoSaveIconAnim2._callbackMethod = &Te3DObject2::setColor;
- _blackFadeAnimationFinishedSignal.add<Application>(this, &Application::onBlackFadeAnimationFinished);
+ _visFade.blackFadeCurveAnim().onFinished().add(this, &Application::onBlackFadeAnimationFinished);
g_engine->getInputMgr()->_mouseMoveSignal.add(this, &Application::onMousePositionChanged);
@@ -394,7 +398,6 @@ void Application::performRender() {
renderer->renderTransparentMeshes();
renderer->clearBuffer(GL_ACCUM);
-
if (game->running()) {
if (game->scene()._character
&& game->scene()._shadowLightNo != -1
@@ -403,7 +406,7 @@ void Application::performRender() {
if (currentCamera) {
currentCamera->apply();
renderer->shadowMode(TeRenderer::ShadowMode2);
- game->scene()._charactersShadow->createTexture(&game->scene());
+ game->scene()._charactersShadow->draw(&game->scene());
renderer->shadowMode(TeRenderer::ShadowMode0);
}
}
@@ -438,10 +441,7 @@ void Application::captureFade() {
}
bool Application::isFading() {
- warning("Application::isFading: Check field here.");
- if (true /* field_0xb1e1? */)
- return _visFade.fading();
- return false;
+ return _visFade.blackFading() || _visFade.fading();
}
bool Application::onBlackFadeAnimationFinished() {
diff --git a/engines/tetraedge/game/application.h b/engines/tetraedge/game/application.h
index 7ffb34901eb..707642cba43 100644
--- a/engines/tetraedge/game/application.h
+++ b/engines/tetraedge/game/application.h
@@ -107,6 +107,7 @@ public:
TeLayout _frontOrientationLayout;
TeLayout _backLayout;
TeButtonLayout _lockCursorButton;
+ TeButtonLayout _lockCursorFromActionButton;
LocFile _loc;
Common::String _firstWarpPath;
Common::String _firstZone;
@@ -117,7 +118,6 @@ private:
TeMusic _music;
TeSpriteLayout _appSpriteLayout;
TeSpriteLayout _mouseCursorLayout;
- TeButtonLayout _lockCursorFromActionButton;
TeSpriteLayout _autoSaveIcon1;
TeSpriteLayout _autoSaveIcon2;
@@ -129,8 +129,6 @@ private:
TeCurveAnim2<Te3DObject2, TeColor> _autoSaveIconAnim1;
TeCurveAnim2<Te3DObject2, TeColor> _autoSaveIconAnim2;
- TeSignal0Param _blackFadeAnimationFinishedSignal;
-
Common::SharedPtr<TeCamera> _mainWindowCamera; // TODO: should be part of TeMainWindow.
TeLayout _mainWindow; // TODO: should be a specialised class.
diff --git a/engines/tetraedge/game/character.h b/engines/tetraedge/game/character.h
index dd0d9b13329..d71aa86c60a 100644
--- a/engines/tetraedge/game/character.h
+++ b/engines/tetraedge/game/character.h
@@ -67,8 +67,8 @@ public:
TeVector3f32 _cutSceneCurveDemiPosition;
Common::String _defaultEyes; // Note: Engine supports more, but in practice only one ever used.
- Common::String _defaultMouth; // Note: Engine supports more, but in practice only one ever used.
- Common::String _defaultBody; // Note: Engine supports more, but in practice only one ever used.
+ Common::String _defaultMouth; // Note: Engine supports more, but in practice only one ever used.
+ Common::String _defaultBody; // Note: Engine supports more, but in practice only one ever used.
void clear();
};
@@ -150,15 +150,19 @@ public:
TeSignal1Param<const Common::String &> _onCharacterAnimFinishedSignal;
const CharacterSettings &characterSettings() const { return _characterSettings; }
- const Common::String walkModeStr() const { return _walkModeStr; }
- const Common::String curAnimName() const { return _curAnimName; }
+ const Common::String &walkModeStr() const { return _walkModeStr; }
+ const Common::String &curAnimName() const { return _curAnimName; }
+ TeFreeMoveZone *freeMoveZone() { return _freeMoveZone; }
+ const Common::String &freeMoveZoneName() const { return _freeMoveZoneName; }
bool needsSomeUpdate() const { return _needsSomeUpdate; }
+ void setNeedsSomeUpdate(bool val) { _needsSomeUpdate = val; }
void setCharLookingAt(Character *other) { _charLookingAt = other; }
private:
float _curveOffset;
TeIntrusivePtr<TeBezierCurve> _curve;
TeFreeMoveZone *_freeMoveZone;
+ Common::String _freeMoveZoneName;
Common::String _stepSound1;
Common::String _stepSound2;
Common::String _walkModeStr; // Walk or Jog
diff --git a/engines/tetraedge/game/character_settings_xml_parser.h b/engines/tetraedge/game/character_settings_xml_parser.h
index 3d6ae90b288..1c15e95e0f9 100644
--- a/engines/tetraedge/game/character_settings_xml_parser.h
+++ b/engines/tetraedge/game/character_settings_xml_parser.h
@@ -94,8 +94,8 @@ public:
bool parserCallback_walk(ParserNode *node);
bool parserCallback_animationFileName(ParserNode *node);
bool parserCallback_walkType(ParserNode *node);
- bool parserCallback_start(ParserNode *node); // walk anim
- bool parserCallback_loop(ParserNode *node); // walk anim
+ bool parserCallback_start(ParserNode *node); // walk anim
+ bool parserCallback_loop(ParserNode *node); // walk anim
bool parserCallback_endD(ParserNode *node); // for walk anim
bool parserCallback_endG(ParserNode *node); // for walk anim
bool parserCallback_speed(ParserNode *node); // walk speed
@@ -122,7 +122,6 @@ private:
};
TextTagType _curTextTag;
- // TODO add private members
Character::CharacterSettings *_curCharacter;
Character::WalkSettings *_curWalkSettings;
Common::HashMap<Common::String, Character::CharacterSettings> *_characterSettings;
diff --git a/engines/tetraedge/game/characters_shadow.cpp b/engines/tetraedge/game/characters_shadow.cpp
index 2ed2fba9c5b..92951817947 100644
--- a/engines/tetraedge/game/characters_shadow.cpp
+++ b/engines/tetraedge/game/characters_shadow.cpp
@@ -22,6 +22,7 @@
#include "graphics/opengl/system_headers.h"
#include "tetraedge/tetraedge.h"
+#include "tetraedge/game/character.h"
#include "tetraedge/game/characters_shadow.h"
#include "tetraedge/te/te_light.h"
#include "tetraedge/te/te_renderer.h"
@@ -42,7 +43,8 @@ void CharactersShadow::create(InGameScene *scene) {
renderer->enableTexture();
_camera = new TeCamera();
_camera->_projectionMatrixType = 2;
- // TODO: set camera field 0x130 to 1.0?
+ _camera->_somePerspectiveVal = 1.0;
+ _camera->setName("_shadowCam");
_camera->viewport(0, 0, _texSize, _texSize);
Te3DTexture::unbind();
glGenTextures(1, &_glTex);
@@ -58,8 +60,33 @@ void CharactersShadow::create(InGameScene *scene) {
void CharactersShadow::createTexture(InGameScene *scene) {
TeRenderer *renderer = g_engine->getRenderer();
renderer->enableTexture();
- //TeLight *light = scene->shadowLight();
- error("TODO: Implement CharactersShadow::createTexture");
+ TeLight *light = scene->shadowLight();
+ if (light) {
+ TeQuaternion q1 = TeQuaternion::fromAxisAndAngle(TeVector3f32(0, 1, 0), light->positionRadial().getX() - M_PI_2);
+ TeQuaternion q2 = TeQuaternion::fromAxisAndAngle(TeVector3f32(1, 0, 0), light->positionRadial().getY());
+ _camera->rotate(q2 * q1);
+ _camera->setPosition(light->position3d());
+ }
+ _camera->_fov = scene->shadowFov() * M_PI / 180.0;
+ _camera->_orthNearVal = scene->shadowNearPlane();
+ _camera->_orthFarVal = scene->shadowFarPlane();
+ _camera->apply();
+
+ glClearColor(0.0, 0.0, 0.0, 0.0);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+
+ for (Character *character : scene->_characters) {
+ character->_model->draw();
+ }
+ scene->_character->_model->draw();
+ Te3DTexture::unbind();
+ glBindTexture(GL_TEXTURE_2D, _glTex);
+ glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, _texSize, _texSize);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ TeCamera::restore();
+ TeCamera::restore();
}
void CharactersShadow::destroy() {
@@ -76,7 +103,69 @@ void CharactersShadow::destroy() {
}
void CharactersShadow::draw(InGameScene *scene) {
- error("TODO: Implement CharactersShadow::draw");
+ TeRenderer *renderer = g_engine->getRenderer();
+ glDepthMask(false);
+ renderer->disableZBuffer();
+ renderer->enableTexture();
+ glBindTexture(GL_TEXTURE_2D, _glTex);
+ Te3DTexture::unbind();
+ glBindTexture(GL_TEXTURE_2D, _glTex);
+ glEnable(GL_BLEND);
+ renderer->setCurrentColor(scene->shadowColor());
+
+ TeMatrix4x4 matrix;
+ matrix.translate(TeVector3f32(0.5f, 0.5f, 0.5f));
+ matrix.scale(TeVector3f32(0.5f, 0.5f, 0.5f));
+ matrix = matrix * _camera->projectionMatrix();
+
+ TeMatrix4x4 cammatrix = _camera->worldTransformationMatrix();
+ cammatrix.inverse();
+
+ matrix = matrix * cammatrix;
+
+ glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
+
+ float f[4];
+ for (unsigned int i = 0; i < 4; i++)
+ f[i] = matrix(i, 0);
+
+ glTexGenfv(GL_S, GL_EYE_PLANE, f);
+ glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
+
+ for (unsigned int i = 0; i < 4; i++)
+ f[i] = matrix(i, 1);
+
+ glTexGenfv(GL_T, GL_EYE_PLANE, f);
+ glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
+
+ for (unsigned int i = 0; i < 4; i++)
+ f[i] = matrix(i, 2);
+
+ glTexGenfv(GL_R, GL_EYE_PLANE, f);
+ glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
+
+ for (unsigned int i = 0; i < 4; i++)
+ f[i] = matrix(i, 3);
+
+ glTexGenfv(GL_Q, GL_EYE_PLANE, f);
+
+ Te3DTexture::unbind();
+ glBindTexture(GL_TEXTURE_2D, _glTex);
+ glEnable(GL_BLEND);
+ renderer->setCurrentColor(scene->shadowColor());
+
+ for (TeIntrusivePtr<TeModel> model : scene->models()) {
+ if (model->_meshes.size() > 0 && model->_meshes[0].materials().empty()) {
+ model->_meshes[0].defaultMaterial(TeIntrusivePtr<Te3DTexture>());
+ model->_meshes[0].materials()[0]._enableSomethingDefault0 = true;
+ model->_meshes[0].materials()[0]._diffuseColor = scene->shadowColor();
+ }
+ model->draw();
+ }
+
+ renderer->disableTexture();
+ glDepthMask(true);
+ renderer->enableZBuffer();
}
} // end namespace Tetraedge
diff --git a/engines/tetraedge/game/dialog2.cpp b/engines/tetraedge/game/dialog2.cpp
index 1d46d18f5b0..07847b0845d 100644
--- a/engines/tetraedge/game/dialog2.cpp
+++ b/engines/tetraedge/game/dialog2.cpp
@@ -99,9 +99,9 @@ bool Dialog2::onMinimumTimeTimer() {
bool Dialog2::onSkipButton() {
const TeCurveAnim2<TeLayout,TeVector3f32> *dialogAnimUp = _gui.layoutAnchorLinearAnimation("dialogAnimationUp");
- if (!dialogAnimUp->_runTimer._stopped) {
+ if (dialogAnimUp->_runTimer.running()) {
const TeCurveAnim2<TeLayout,TeVector3f32> *dialogAnimDown = _gui.layoutAnchorLinearAnimation("dialogAnimationDown");
- if (dialogAnimDown->_runTimer._stopped) {
+ if (!dialogAnimDown->_runTimer.running()) {
startDownAnimation();
_music.stop();
}
@@ -110,7 +110,7 @@ bool Dialog2::onSkipButton() {
}
bool Dialog2::onSoundFinished() {
- if (_minimumTimeTimer._stopped)
+ if (!_minimumTimeTimer.running())
startDownAnimation();
return false;
}
diff --git a/engines/tetraedge/game/documents_browser.cpp b/engines/tetraedge/game/documents_browser.cpp
index 5762275900f..e9f29b577a2 100644
--- a/engines/tetraedge/game/documents_browser.cpp
+++ b/engines/tetraedge/game/documents_browser.cpp
@@ -32,6 +32,10 @@ void DocumentsBrowser::enter() {
currentPage(_curPage);
}
+void DocumentsBrowser::hideDocument() {
+ error("TODO: Implement DocumentsBrowser::hideDocument");
+}
+
void DocumentsBrowser::leave() {
_timer.stop();
setVisible(false);
@@ -106,7 +110,9 @@ void DocumentsBrowser::showDocument(const Common::String &str, long n) {
error("TODO: Implement DocumentsBrowser::showDocument");
}
-
-// TODO: Add more functions here.
+void DocumentsBrowser::unload() {
+ hideDocument();
+ error("TODO: Implement DocumentsBrowser::unload");
+}
} // end namespace Tetraedge
diff --git a/engines/tetraedge/game/documents_browser.h b/engines/tetraedge/game/documents_browser.h
index 0331cb2cb28..f1d4818cb2d 100644
--- a/engines/tetraedge/game/documents_browser.h
+++ b/engines/tetraedge/game/documents_browser.h
@@ -88,7 +88,6 @@ private:
TeTimer _timer;
TeLayout _zoomedLayout;
unsigned long _curPage;
- // TODO add private members
// TiXmlDocument _xmldoc;
};
diff --git a/engines/tetraedge/game/game.cpp b/engines/tetraedge/game/game.cpp
index 427a56abbf4..69a40880ee9 100644
--- a/engines/tetraedge/game/game.cpp
+++ b/engines/tetraedge/game/game.cpp
@@ -32,15 +32,19 @@
#include "tetraedge/game/game_achievements.h"
#include "tetraedge/game/lua_binds.h"
#include "tetraedge/game/object3d.h"
+
+#include "tetraedge/te/te_camera.h"
#include "tetraedge/te/te_core.h"
#include "tetraedge/te/te_input_mgr.h"
+#include "tetraedge/te/te_ray_intersection.h"
#include "tetraedge/te/te_variant.h"
namespace Tetraedge {
Game::Game() : _objectsTakenVal(0), _score(0), _entered(false), _gameLoadState(0),
_noScaleLayout(nullptr), _noScaleLayout2(nullptr), _warped(false), _saveRequested(false),
-_firstInventory(true), _movePlayerCharacterDisabled(false) {
+_firstInventory(true), _movePlayerCharacterDisabled(false), _enteredFlag2(false),
+_luaShowOwnerError(false), _markersVisible(true), _running(false), _loadName("save.xml") {
for (int i = 0; i < NUM_OBJECTS_TAKEN_IDS; i++) {
_objectsTakenBits[i] = false;
}
@@ -135,8 +139,16 @@ void Game::addNoScaleChildren() {
_noScaleLayout->addChild(&_documentsBrowser.zoomedLayout());
}
-void Game::addRandomSound(const Common::String &s1, const Common::String &s2, float f1, float f2) {
- warning("TODO: Implemet Game::addRandomSound %s %s %f %f", s1.c_str(), s1.c_str(), f1, f2);
+void Game::addRandomSound(const Common::String &name, const Common::String &path, float f1, float f2) {
+ if (!_randomSounds.contains(name)) {
+ _randomSounds[name] = Common::Array<RandomSound*>();
+ }
+ RandomSound *randsound = new RandomSound();
+ randsound->_path = path;
+ randsound->_f1 = f1;
+ randsound->_f2 = f2;
+ randsound->_name = name;
+ _randomSounds[name].push_back(randsound);
}
void Game::addToBag(const Common::String &objname) {
@@ -169,6 +181,7 @@ void Game::addToScore(int score) {
}
bool Game::changeWarp(const Common::String &zone, const Common::String &scene, bool fadeFlag) {
+ debug("Game::changeWarp(%s, %s, %s)", zone.c_str(), scene.c_str(), fadeFlag ? "true" : "false");
Application *app = g_engine->getApplication();
if (fadeFlag) {
app->blackFade();
@@ -183,6 +196,7 @@ bool Game::changeWarp(const Common::String &zone, const Common::String &scene, b
}
bool Game::changeWarp2(const Common::String &zone, const Common::String &scene, bool fadeFlag) {
+ debug("Game::changeWarp2(%s, %s, %s)", zone.c_str(), scene.c_str(), fadeFlag ? "true" : "false");
_warped = false;
_movePlayerCharacterDisabled = false;
_sceneCharacterVisibleFromLoad = false;
@@ -191,7 +205,7 @@ bool Game::changeWarp2(const Common::String &zone, const Common::String &scene,
luapath.joinInPlace(zone);
luapath.joinInPlace(scene);
luapath.joinInPlace("Logic");
- luapath.appendInPlace(zone);
+ luapath.appendInPlace(scene);
luapath.appendInPlace(".lua");
if (Common::File::exists(luapath)) {
@@ -243,7 +257,7 @@ void Game::draw() {
}
void Game::enter(bool newgame) {
- warning("TODO: Game::enter set field_0x42f0 true here");
+ _enteredFlag2 = true;
_entered = true;
_luaShowOwnerError = false;
_score = 0;
@@ -322,7 +336,7 @@ void Game::enter(bool newgame) {
}
/*static*/ TeI3DObject2 *Game::findLayoutByName(TeLayout *parent, const Common::String &name) {
- error("TODO: Implement me - although maybe this is never used?");
+ error("TODO: Implement Game::findLayoutByName - although maybe never used?");
}
/*static*/ TeSpriteLayout *Game::findSpriteLayoutByName(TeLayout *parent, const Common::String &name) {
@@ -407,6 +421,7 @@ void Game::initScene(bool fade, const Common::String &scenePath) {
}
bool Game::initWarp(const Common::String &zone, const Common::String &scene, bool fadeFlag) {
+ debug("Game::initWarp(%s, %s, %s)", zone.c_str(), scene.c_str(), fadeFlag ? "true" : "false");
_inventoryMenu.unload();
_gui4.unload();
_movePlayerCharacterDisabled = false;
@@ -465,8 +480,9 @@ bool Game::initWarp(const Common::String &zone, const Common::String &scene, boo
_scene.reset();
_scene.bgGui().unload();
- _gui2.unload();
- Common::Path geomPath(Common::String::format("scenes/%s/Geometry/%s.bin",
+ _scene.markerGui().unload();
+ _scene.hitObjectGui().unload();
+ Common::Path geomPath(Common::String::format("scenes/%s/Geometry%s.bin",
zone.c_str(), zone.c_str()));
_scene.load(geomPath);
_scene.loadBackground(setLuaPath);
@@ -485,7 +501,18 @@ bool Game::initWarp(const Common::String &zone, const Common::String &scene, boo
if (intLuaExists) {
_scene.loadInteractions(intLuaPath);
- warning("TODO: Game::initWarp: Finish interactions.");
+ TeLuaGUI::StringMap<TeButtonLayout *> &blayouts = _scene.hitObjectGui().buttonLayouts();
+ for (auto &entry : blayouts) {
+ HitObject *hobj = new HitObject();
+ TeButtonLayout *btn = entry._value;
+ hobj->_game = this;
+ hobj->_button = btn;
+ hobj->_name = btn->name();
+ btn->onMouseClickValidated().add(hobj, &HitObject::onValidated);
+ btn->onButtonChangedToStateDownSignal().add(hobj, &HitObject::onDown);
+ btn->onButtonChangedToStateUpSignal().add(hobj, &HitObject::onUp);
+ _gameHitObjects.push_back(hobj);
+ }
}
_inventoryMenu.load();
@@ -541,7 +568,7 @@ bool Game::initWarp(const Common::String &zone, const Common::String &scene, boo
if (_inventory.selectedObject().size()) {
_inventory.selectedObject(*_inventory.selectedInventoryObject());
}
- _inventory.setVisible(true);
+ _inventory.setVisible(false);
_objectif.setVisibleObjectif(false);
_objectif.setVisibleButtonHelp(true);
_running = true;
@@ -561,13 +588,13 @@ bool Game::initWarp(const Common::String &zone, const Common::String &scene, boo
// Special hacks for certain scenes (don't blame me, original does this..)
if (scene == "14050") {
TeIntrusivePtr<TeCamera> curcamera = _scene.currentCamera();
- const TeVector3f32 coords(1200.6f,-1937.5f,1544.1f);
+ const TeVector3f32 coords(1200.6f, -1937.5f, 1544.1f);
curcamera->setPosition(coords);
} else if (scene == "34610") {
TeIntrusivePtr<TeCamera> curcamera = _scene.currentCamera();
- const TeVector3f32 coords(-328.243f,340.303f,-1342.84f);
+ const TeVector3f32 coords(-328.243f, 340.303f, -1342.84f);
curcamera->setPosition(coords);
- const TeQuaternion rot(0.003194, 0.910923, -0.009496, -0.412389);
+ const TeQuaternion rot(0.003194f, 0.910923f, -0.009496f, -0.412389f);
curcamera->setRotation(rot);
}
@@ -582,15 +609,21 @@ bool Game::initWarp(const Common::String &zone, const Common::String &scene, boo
//for (auto & sound : _gameSounds) {
warning("TODO: Game::initWarp: Do game sound stuff here");
}
- // TODO: Also do random sound stuff here.
+
+ for (auto &randsoundlist : _randomSounds) {
+ for (auto *randsound : randsoundlist._value) {
+ delete randsound;
+ }
+ randsoundlist._value.clear();
+ }
+ _randomSounds.clear();
_scene.initScroll();
return true;
}
bool Game::isDocumentOpened() {
- TeLayout *layout = _documentsBrowser.layout("zoomed");
- return layout->visible();
+ return _documentsBrowser.layoutChecked("zoomed")->visible();
}
bool Game::isMoviePlaying() {
@@ -600,17 +633,62 @@ bool Game::isMoviePlaying() {
return false;
}
-bool Game::launchDialog(const Common::String ¶m_1, uint param_2, const Common::String ¶m_3,
- const Common::String ¶m_4, float param_5) {
- error("TODO: Implemet Game::launchDialog");
+bool Game::launchDialog(const Common::String ¶m_1, uint param_2, const Common::String &charname,
+ const Common::String &animfile, float param_5) {
+ error("TODO: Implemet Game::launchDialog %s %d %s %s %f", param_1.c_str(),
+ param_2, charname.c_str(), animfile.c_str(), param_5);
}
void Game::leave(bool flag) {
- error("TODO: Implemet Game::leave");
+ if (!_enteredFlag2)
+ return;
+
+ deleteNoScale();
+ _entered = false;
+ _running = false;
+ _notifier.unload();
+ g_engine->getInputMgr()->_mouseLUpSignal.remove(this, &Game::onMouseClick);
+ _question2.unload();
+ _inventory.cellphone()->unload();
+ _dialog2.unload();
+ _inventory.unload();
+ _documentsBrowser.unload();
+ _inventoryMenu.unload();
+ _gui1.unload();
+ _scene.close();
+ _gui3.unload();
+ if (_scene._character) {
+ _scene._character->deleteAllCallback();
+ _scene._character->stop();
+ _scene.unloadCharacter(_scene._character->_model->name());
+ }
+ warning("TODO: Game::leave: clear game sounds");
+
+ for (auto *hitobj : _gameHitObjects) {
+ delete hitobj;
+ }
+ _gameHitObjects.clear();
+
+ // TODO: clear Game::HitObject tree here?
+
+ _luaContext.destroy();
+ _running = false;
+ _gui4.buttonLayoutChecked("skipVideoButton")->onMouseClickValidated().remove(this, &Game::onSkipVideoButtonValidated);
+ _gui4.buttonLayoutChecked("videoBackgroundButton")->onMouseClickValidated().remove(this, &Game::onLockVideoButtonValidated);
+ _gui4.spriteLayoutChecked("video")->_tiledSurfacePtr->_frameAnim.onFinished().remove(this, &Game::onSkipVideoButtonValidated);
+ _gui4.buttonLayoutChecked("inventoryButton")->onMouseClickValidated().remove(this, &Game::onInventoryButtonValidated);
+ _gui4.unload();
+ _playedTimer.stop();
+
+ Application *app = g_engine->getApplication();
+ app->_lockCursorButton.setVisible(false);
+ app->_lockCursorFromActionButton.setVisible(false);
+ // TODO: Set some inputmgr flag here?
+ Character::animCacheFreeAll();
}
bool Game::loadBackup(const Common::String &path) {
- error("TODO: Implemet Game::loadBackup");
+ error("TODO: Implemet Game::loadBackup %s", path.c_str());
}
bool Game::loadCharacter(const Common::String &name) {
@@ -661,19 +739,19 @@ bool Game::onCallNumber(Common::String val) {
}
bool Game::onCharacterAnimationFinished(const Common::String &val) {
- error("TODO: Implemet me");
+ error("TODO: Implemet Game::onCharacterAnimationFinished %s", val.c_str());
}
bool Game::onCharacterAnimationPlayerFinished(const Common::String &val) {
- error("TODO: Implemet me");
+ error("TODO: Implemet Game::onCharacterAnimationPlayerFinished %s", val.c_str());
}
bool Game::onDialogFinished(const Common::String &val) {
- error("TODO: Implemet me");
+ error("TODO: Implemet Game::onDialogFinished %s", val.c_str());
}
bool Game::onDisplacementFinished() {
- error("TODO: Implemet me");
+ error("TODO: Implemet Game::onDisplacementFinished");
}
bool Game::onFinishedCheckBackup(bool result) {
@@ -718,6 +796,57 @@ bool Game::onMarkersVisible(TeCheckboxLayout::State state) {
return false;
}
+static
+TePickMesh2 *findNearestMesh(TeIntrusivePtr<TeCamera> &camera, const TeVector2s32 &frompt,
+ Common::Array<TePickMesh2*> &pickMeshes, TeVector3f32 *outloc, bool lastHitFirst) {
+ TeVector3f32 locresult;
+ TePickMesh2 *nearest = nullptr;
+ float furthest = camera->_orthFarVal;
+ if (!pickMeshes.empty()) {
+ TeVector3f32 v1;
+ TeVector3f32 v2;
+ for (unsigned int i = 0; i < pickMeshes.size(); i++) {
+ TePickMesh2 *mesh = pickMeshes[i];
+ const TeMatrix4x4 transform = mesh->worldTransformationMatrix();
+ if (lastHitFirst) {
+ unsigned int tricount = mesh->verticies().size() / 3;
+ unsigned int vert = mesh->lastTriangleHit() * 3;
+ if (mesh->lastTriangleHit() >= tricount)
+ vert = 0;
+ const TeVector3f32 v3 = transform * mesh->verticies()[vert];
+ const TeVector3f32 v4 = transform * mesh->verticies()[vert + 1];
+ const TeVector3f32 v5 = transform * mesh->verticies()[vert + 2];
+ TeVector3f32 result;
+ float fresult;
+ int intresult = TeRayIntersection::intersect(v1, v2, v3, v4, v5, result, fresult);
+ if (intresult == 1 && fresult < furthest && fresult >= camera->_orthNearVal)
+ return mesh;
+ }
+ for (unsigned int tri = 0; tri < mesh->verticies().size() / 3; tri++) {
+ const TeVector3f32 v3 = transform * mesh->verticies()[tri * 3];
+ const TeVector3f32 v4 = transform * mesh->verticies()[tri * 3 + 1];
+ const TeVector3f32 v5 = transform * mesh->verticies()[tri * 3 + 1];
+ camera->getRay(frompt, v1, v2);
+ TeVector3f32 result;
+ float fresult;
+ int intresult = TeRayIntersection::intersect(v1, v2, v3, v4, v5, result, fresult);
+ if (intresult == 1 && fresult < furthest && fresult >= camera->_orthNearVal) {
+ mesh->setLastTriangleHit(tri);
+ locresult = result;
+ furthest = fresult;
+ nearest = mesh;
+ if (lastHitFirst)
+ break;
+ }
+ }
+ }
+ }
+ if (outloc) {
+ *outloc = locresult;
+ }
+ return nearest;
+}
+
bool Game::onMouseClick(const Common::Point &pt) {
Application *app = g_engine->getApplication();
@@ -734,7 +863,7 @@ bool Game::onMouseClick(const Common::Point &pt) {
float xdist = pt.x / winSize.x() - lastMousePos._x / winSize.x();
float ydist = pt.y / winSize.y() - lastMousePos._y / winSize.y();
float sqrdist = xdist * xdist + ydist * ydist;
- if (sqrdist > 0.0001 && (_walkTimer._stopped || _walkTimer.timeElapsed() > 300000.0
+ if (sqrdist > 0.0001 && (!_walkTimer.running() || _walkTimer.timeElapsed() > 300000.0
|| (_scene._character && _scene._character->walkModeStr() != "Walk"))) {
return false;
// Double-click, but already jogging
@@ -744,10 +873,79 @@ bool Game::onMouseClick(const Common::Point &pt) {
if (!app->_frontLayout.isMouseIn(pt))
return false;
+ Common::String nearestMeshName = "None";
TeIntrusivePtr<TeCamera> curCamera = _scene.currentCamera();
- //TePickMesh2 *nearestMesh = findNearestMesh(curCamera, _scene._pickMeshes, nullptr, false);
+ Common::Array<TePickMesh2*> pickMeshes = _scene.pickMeshes();
+ TePickMesh2 *nearestMesh = findNearestMesh(curCamera, pt, pickMeshes, nullptr, false);
+ if (nearestMesh) {
+ nearestMeshName = nearestMesh->name();
+ _lastCharMoveMousePos = TeVector2s32(0, 0);
+ }
+
+ if (app->isLockCursor() || _movePlayerCharacterDisabled)
+ return false;
+
+ Character *character = _scene._character;
+ const Common::String &charAnim = character->curAnimName();
+
+ if (charAnim == character->characterSettings()._walkFileName
+ || charAnim == character->walkAnim(Character::WalkPart_Start)
+ || charAnim == character->walkAnim(Character::WalkPart_Loop)
+ || charAnim == character->walkAnim(Character::WalkPart_EndD)
+ || charAnim == character->walkAnim(Character::WalkPart_EndG)) {
+ _luaScript.execute("On");
+ if (!_scene.isObjectBlocking(nearestMeshName)) {
+ if (character->freeMoveZone()) {
+ TeVector3f32 charPos = character->_model->position();
+ TeIntrusivePtr<TeBezierCurve> curve = character->freeMoveZone()->curve(charPos, TeVector2s32(pt), 8.0, true);
+ if (curve) {
+ _scene.setCurve(curve);
+ // TODO: set character field_0x214 to TeVector3f32(0,0,0)
+ if (curve->controlPoints().size() == 1) {
+ character->endMove();
+ } else {
+ if (!_walkTimer.running() || _walkTimer.timeElapsed() > 300000) {
+ _walkTimer.stop();
+ _walkTimer.start();
+ character->walkMode("Walk");
+ } else {
+ // Note: original checks the timer elapsed again here.. why?
+ _walkTimer.stop();
+ character->walkMode("Jog");
+ }
+ character->placeOnCurve(curve);
+ character->setCurveOffset(0.0);
+ if (charAnim != character->walkAnim(Character::WalkPart_Start)) {
+ character->setAnimation(character->walkAnim(Character::WalkPart_Start), false, false, false, -1, 9999);
+ }
+ character->walkTo(1.0, false);
+ _sceneCharacterVisibleFromLoad = false;
+ _lastCharMoveMousePos = pt;
+ }
+ } else {
+ return false;
+ }
+ }
+ // TOOD: Finis this (line ~180 onward)
+ warning("TODO: Finish Game::onMouseClick");
+ }
+ TeVector3f32 lastPoint = _scene.curve()->controlPoints().back();
+ character->setAnimation(character->walkAnim(Character::WalkPart_Loop), true, false, false, -1, 9999);
+ character->walkTo(1.0, false);
+ // TODO: Set app field field_0x910b
+ _posPlayer = lastPoint;
+ }
+
+ if (!_sceneCharacterVisibleFromLoad || (character->curAnimName() == character->characterSettings()._walkFileName)) {
+ _lastCharMoveMousePos = TeVector2s32(0, 0);
+ _movePlayerCharacterDisabled = true;
+ // TODO: Set field 0x4249 to false
+ if (nearestMesh) {
+ character->stop();
+ _luaScript.execute("OnWarpObjectHit", nearestMeshName);
+ }
+ }
- warning("TODO: Finish Game::onMouseClick");
return false;
}
@@ -786,6 +984,16 @@ bool Game::onMouseMove() {
return false;
}
+ // TODO: All the logic below is a bit suspicious and unfinished.
+ //
+ // The original game goes through a series of checks of mouseIn and
+ // visible before deciding whether to do a full search for a mouse
+ // cursor to apply. But after all that, in practice, none of the
+ // mouse cursors above actually exist in the game data.
+ //
+ // So maybe all this is useless?
+
+#if ENABLE_CUSTOM_CURSOR_CHECKS
TeVector2s32 mouseLoc = g_engine->getInputMgr()->lastMousePos();
bool skipFullSearch = false;
@@ -798,29 +1006,37 @@ bool Game::onMouseMove() {
return false;
}
}
- if (_dialog2.gui().layout("imgDialog")) {
- warning("TODO: Finish Game::onMouseMove");
+ TeLayout *imgDialog = _dialog2.gui().layoutChecked("imgDialog");
+ bool mouseInImgDialog = imgDialog->isMouseIn(mouseLoc);
+ if (mouseInImgDialog || !imgDialog->visible()) {
+ if (!mouseInImgDialog)
+ skipFullSearch = true;
+ //warning("TODO: Finish Game::onMouseMove");
}
bool checkedCursor = false;
- for (unsigned int i = 0; i < cellbg->childCount(); i++) {
- TeLayout *childlayout = dynamic_cast<TeLayout *>(cellbg->child(i));
- if (childlayout && childlayout->isMouseIn(mouseLoc) && childlayout->visible()) {
- for (int i = 0; i < ARRAYSIZE(cursorsTable); i++) {
- if (childlayout->name().contains(cursorsTable[i][0])) {
- app->mouseCursorLayout().load(cursorsTable[i][1]);
- if (Common::String(cursorsTable[i][0]).contains(".anim")) {
- app->mouseCursorLayout()._tiledSurfacePtr->_frameAnim._loopCount = -1;
- app->mouseCursorLayout()._tiledSurfacePtr->_frameAnim.play();
+ if (!skipFullSearch && _scene.gui2().loaded()) {
+ TeLayout *bglayout = _scene.gui2().layoutChecked("background");
+ for (unsigned int i = 0; i < bglayout->childCount(); i++) {
+ TeLayout *childlayout = dynamic_cast<TeLayout *>(bglayout->child(i));
+ if (childlayout && childlayout->isMouseIn(mouseLoc) && childlayout->visible()) {
+ for (int i = 0; i < ARRAYSIZE(cursorsTable); i++) {
+ if (childlayout->name().contains(cursorsTable[i][0])) {
+ app->mouseCursorLayout().load(cursorsTable[i][1]);
+ if (Common::String(cursorsTable[i][0]).contains(".anim")) {
+ app->mouseCursorLayout()._tiledSurfacePtr->_frameAnim._loopCount = -1;
+ app->mouseCursorLayout()._tiledSurfacePtr->_frameAnim.play();
+ }
}
}
+ checkedCursor = true;
}
- checkedCursor = true;
}
}
if (!checkedCursor)
app->mouseCursorLayout().load(DEFAULT_CURSOR);
+#endif // ENABLE_CUSTOM_CURSOR_CHECKS
return false;
}
@@ -848,7 +1064,7 @@ bool Game::onVideoFinished() {
video->setVisible(false);
_music.stop();
_running = true;
- warning("TODO: Game::onVideoFinished: update yieldedCallbacks");
+ warning("TODO: Game::onVideoFinished: update yieldedCallbacks %s", video->_tiledSurfacePtr->path().toString().c_str());
_luaScript.execute("OnMovieFinished", video->_tiledSurfacePtr->path().toString());
app->fade();
return false;
@@ -892,7 +1108,11 @@ void Game::playMovie(const Common::String &vidPath, const Common::String &musicP
}
void Game::playRandomSound(const Common::String &name) {
- error("TODO: Implemet Game::playRandomSound");
+ if (!_randomSounds.contains(name)) {
+ warning("Game::playRandomSound: can't find sound list %s", name.c_str());
+ return;
+ }
+ error("TODO: Implemet Game::playRandomSound");
}
void Game::playSound(const Common::String &name, int param_2, float param_3) {
@@ -1049,7 +1269,17 @@ void Game::update() {
if (_scene._character->needsSomeUpdate()) {
Game *game = g_engine->getGame();
game->_sceneCharacterVisibleFromLoad = false;
- error("TODO: Game::update: Finish bit after permanentUpdate");
+ TeVector3f32 charPos = _scene._character->_model->position();
+ const Common::String charName = _scene._character->_model->name();
+ TeFreeMoveZone *zone = _scene.pathZone(_scene._character->freeMoveZoneName());
+ if (zone) {
+ TeIntrusivePtr<TeCamera> cam = _scene.currentCamera();
+ zone->setCamera(cam, false);
+ _scene._character->setFreeMoveZone(zone);
+ _scene.setPositionCharacter(charName, _scene._character->freeMoveZoneName(), charPos);
+ error("TODO: Game::update: Finish bit after permanentUpdate");
+ }
+ _scene._character->setNeedsSomeUpdate(false);
}
const Common::String &charAnim = _scene._character->curAnimName();
@@ -1087,4 +1317,31 @@ void Game::update() {
}
}
+
+bool Game::HitObject::onChangeWarp() {
+ // Seems like this function is never used?
+ error("TODO: Implement Game::HitObject::onChangeWarp");
+ return false;
+}
+
+bool Game::HitObject::onDown() {
+ _game->luaScript().execute("OnButtonDown", _name);
+ // TODO: set this field _game->field_0x4249 = 1;
+ return false;
+}
+
+bool Game::HitObject::onUp() {
+ _game->luaScript().execute("OnButtonUp", _name);
+ // TODO: set this field _game->field_0x4249 = 1;
+ return false;
+}
+
+bool Game::HitObject::onValidated() {
+ if (!g_engine->getApplication()->isLockCursor()) {
+ _game->luaScript().execute("OnWarpObjectHit", _name);
+ // TODO: set this field _game->field_0x4249 = 1;
+ }
+ return false;
+}
+
} // end namespace Tetraedge
diff --git a/engines/tetraedge/game/game.h b/engines/tetraedge/game/game.h
index d65a9fc7d36..c7bf5dca547 100644
--- a/engines/tetraedge/game/game.h
+++ b/engines/tetraedge/game/game.h
@@ -46,12 +46,12 @@ public:
Game();
struct HitObject {
- byte OnChangeWarp();
- byte OnDown();
- byte OnUp();
- byte OnValidated();
+ bool onChangeWarp();
+ bool onDown();
+ bool onUp();
+ bool onValidated();
//byte OnVisible(); empty never used?
-
+
Common::String _name;
Game *_game;
TeButtonLayout *_button;
@@ -60,10 +60,10 @@ public:
class RandomSound {
public:
Common::Path _path;
- Common::String _str;
+ Common::String _name;
TeMusic _music;
- float f1;
- float f2;
+ float _f1;
+ float _f2;
byte onSoundFinished();
};
@@ -158,6 +158,7 @@ public:
bool _returnToMainMenu;
bool _firstInventory;
+ bool _movePlayerCharacterDisabled;
const Common::String ¤tZone() { return _currentZone; }
const Common::String ¤tScene() { return _currentScene; }
@@ -171,6 +172,7 @@ private:
bool _luaShowOwnerError;
bool _running;
bool _entered;
+ bool _enteredFlag2;
TeLuaGUI _gui1;
TeLuaGUI _gui2;
@@ -188,6 +190,7 @@ private:
static char **_objectsTakenIDs;
TeVector2s32 _previousMousePos;
+ TeVector2s32 _lastCharMoveMousePos;
Common::String _warpZone;
Common::String _warpScene;
@@ -203,8 +206,10 @@ private:
Common::String _loadName;
Common::Array<GameSound *> _gameSounds;
+ Common::Array<HitObject *> _gameHitObjects;
Common::HashMap<Common::String, bool> _unlockedArtwork;
+ Common::HashMap<Common::String, Common::Array<RandomSound*>> _randomSounds;
int _gameLoadState;
@@ -229,7 +234,6 @@ private:
bool _sceneCharacterVisibleFromLoad;
bool _markersVisible;
bool _saveRequested;
- bool _movePlayerCharacterDisabled;
TeLayout *_noScaleLayout;
TeLayout *_noScaleLayout2;
diff --git a/engines/tetraedge/game/help_option_menu.cpp b/engines/tetraedge/game/help_option_menu.cpp
index 1c3cd972e1e..b1f890774c1 100644
--- a/engines/tetraedge/game/help_option_menu.cpp
+++ b/engines/tetraedge/game/help_option_menu.cpp
@@ -48,6 +48,4 @@ void HelpOptionMenu::leave() {
_entered = false;
}
-// TODO: Add more functions here.
-
} // end namespace Tetraedge
diff --git a/engines/tetraedge/game/in_game_scene.cpp b/engines/tetraedge/game/in_game_scene.cpp
index 9c88e98f9dc..2a89abd7afa 100644
--- a/engines/tetraedge/game/in_game_scene.cpp
+++ b/engines/tetraedge/game/in_game_scene.cpp
@@ -62,7 +62,7 @@ void InGameScene::draw() {
for (unsigned int i = 0; i < _lights.size(); i++)
_lights[i].update(i);
- currentCamera()->restore();
+ TeCamera::restore();
}
void InGameScene::drawPath() {
@@ -72,9 +72,8 @@ void InGameScene::drawPath() {
currentCamera()->apply();
g_engine->getRenderer()->disableZBuffer();
- warning("TODO: Do free move zones in InGameScene::drawPath");
- //for (unsigned int i = 0; i < _freeMoveZones.size(); i++)
- // _freeMoveZones[i]->
+ for (unsigned int i = 0; i < _freeMoveZones.size(); i++)
+ _freeMoveZones[i]->draw();
g_engine->getRenderer()->enableZBuffer();
}
@@ -116,8 +115,8 @@ void InGameScene::reset() {
freeSceneObjects();
_bgGui.unload();
unloadSpriteLayouts();
- _gui2.unload();
- _gui3.unload();
+ _markerGui.unload();
+ _hitObjectGui.unload();
}
void InGameScene::deleteAllCallback() {
@@ -215,6 +214,8 @@ bool InGameScene::load(const Common::Path &path) {
return false;
uint32 ncameras = scenefile.readUint32LE();
+ if (ncameras > 1024)
+ error("Improbable number of cameras %d", ncameras);
for (unsigned int i = 0; i < ncameras; i++) {
TeIntrusivePtr<TeCamera> cam = new TeCamera();
deserializeCam(scenefile, cam);
@@ -222,6 +223,8 @@ bool InGameScene::load(const Common::Path &path) {
}
uint32 nobjects = scenefile.readUint32LE();
+ if (nobjects > 1024)
+ error("Improbable number of objects %d", nobjects);
for (unsigned int i = 0; i < nobjects; i++) {
TeIntrusivePtr<TeModel> model = new TeModel();
const Common::String modelname = Te3DObject2::deserializeString(scenefile);
@@ -254,6 +257,8 @@ bool InGameScene::load(const Common::Path &path) {
}
uint32 nfreemovezones = scenefile.readUint32LE();
+ if (nfreemovezones > 1024)
+ error("Improbable number of free move zones %d", nfreemovezones);
for (unsigned int i = 0; i < nfreemovezones; i++) {
TeFreeMoveZone *zone = new TeFreeMoveZone();
TeFreeMoveZone::deserialize(scenefile, *zone, &_blockers, &_rectBlockers, &_actZones);
@@ -261,6 +266,8 @@ bool InGameScene::load(const Common::Path &path) {
}
uint32 ncurves = scenefile.readUint32LE();
+ if (ncurves > 1024)
+ error("Improbable number of curves %d", ncurves);
for (unsigned int i = 0; i < ncurves; i++) {
TeIntrusivePtr<TeBezierCurve> curve = new TeBezierCurve();
TeBezierCurve::deserialize(scenefile, *curve);
@@ -269,6 +276,8 @@ bool InGameScene::load(const Common::Path &path) {
}
uint32 ndummies = scenefile.readUint32LE();
+ if (ndummies > 1024)
+ error("Improbable number of dummies %d", ndummies);
for (unsigned int i = 0; i < ndummies; i++) {
InGameScene::Dummy dummy;
TeVector3f32 vec;
@@ -297,7 +306,12 @@ void InGameScene::convertPathToMesh(TeFreeMoveZone *zone) {
}
void InGameScene::onMainWindowSizeChanged() {
- error("TODO: Implement InGameScene::onMainWindowSizeChanged");
+ TeCamera *mainWinCam = g_engine->getApplication()->mainWindowCamera();
+ _viewportSize = mainWinCam->viewportSize();
+ Common::Array<TeIntrusivePtr<TeCamera>> &cams = cameras();
+ for (unsigned int i = 0; i < cams.size(); i++) {
+ cams[i]->viewport(0, 0, _viewportSize.getX(), _viewportSize.getY());
+ }
}
bool InGameScene::loadLights(const Common::Path &path) {
@@ -326,10 +340,13 @@ bool InGameScene::loadCharacter(const Common::String &name) {
void InGameScene::deserializeCam(Common::ReadStream &stream, TeIntrusivePtr<TeCamera> &cam) {
cam->_projectionMatrixType = 2;
cam->viewport(0, 0, _viewportSize.getX(), _viewportSize.getY());
+ // load name/position/rotation/scale
Te3DObject2::deserialize(stream, *cam);
- cam->_focalLenMaybe = stream.readFloatLE();
+ cam->_fov = stream.readFloatLE();
cam->_somePerspectiveVal = stream.readFloatLE();
cam->_orthNearVal = stream.readFloatLE();
+ // Original loads the val then ignores it and sets 3000.
+ stream.readFloatLE();
cam->_orthFarVal = 3000.0;
}
@@ -413,6 +430,13 @@ bool InGameScene::findKate() {
return false;
}
+TeLight *InGameScene::shadowLight() {
+ if (_shadowLightNo == -1) {
+ return nullptr;
+ }
+ return &_lights[_shadowLightNo];
+}
+
static Common::Path _sceneFileNameBase() {
Game *game = g_engine->getGame();
Common::Path retval("scenes");
@@ -494,11 +518,11 @@ void InGameScene::loadBackground(const Common::Path &path) {
}
void InGameScene::loadInteractions(const Common::Path &path) {
- _gui3.load(path);
+ _hitObjectGui.load(path);
TeLayout *bgbackground = _bgGui.layoutChecked("background");
Game *game = g_engine->getGame();
TeSpriteLayout *root = game->findSpriteLayoutByName(bgbackground, "root");
- TeLayout *background = _gui3.layoutChecked("background");
+ TeLayout *background = _hitObjectGui.layoutChecked("background");
// TODO: For all TeButtonLayout childen of background, call
// setDoubleValidationProtectionEnabled(false)
// For now our button doesn't implement that.
@@ -517,6 +541,84 @@ void InGameScene::initScroll() {
_someScrollVector = TeVector2f32(0.5f, 0.0f);
}
+bool InGameScene::isObjectBlocking(const Common::String &name) {
+ for (const Common::String &b: _blockingObjects) {
+ if (name == b)
+ return true;
+ }
+ return false;
+}
+
+void InGameScene::addMarker(const Common::String &name, const Common::String &imgPath, float x, float y, const Common::String &locType, const Common::String &markerVal) {
+ error("TODO: Implement InGameScene::addMarker");
+}
+
+void InGameScene::setVisibleMarker(const Common::String &markerName, bool val) {
+ if (!isMarker(markerName))
+ return;
+
+ error("TODO: Implement InGameScene::setVisibleMarker");
+}
+
+
+void InGameScene::deleteMarker(const Common::String &markerName) {
+ if (!isMarker(markerName))
+ return;
+
+ error("TODO: Implement InGameScene::deleteMarker");
+}
+
+
+bool InGameScene::isMarker(const Common::String &name) {
+ for (const TeMarker *marker : _markers) {
+ if (marker->_name == name)
+ return true;
+ }
+ return false;
+}
+
+TeFreeMoveZone *InGameScene::pathZone(const Common::String &name) {
+ for (TeFreeMoveZone *zone: _freeMoveZones) {
+ if (zone->name() == name)
+ return zone;
+ }
+ return nullptr;
+}
+
+void InGameScene::moveCharacterTo(const Common::String &charName, const Common::String &curveName, float curveOffset, float curveEnd) {
+ Character *c = character(charName);
+ if (c != nullptr && c != _character) {
+ Game *game = g_engine->getGame();
+ if (!game->_movePlayerCharacterDisabled) {
+ // TODO: c->field_0x214 = c->characterSettings()._cutSceneCurveDemiPosition;
+ TeIntrusivePtr<TeBezierCurve> crve = curve(curveName);
+ c->placeOnCurve(crve);
+ c->setCurveOffset(curveOffset);
+ const Common::String walkStartAnim = c->walkAnim(Character::WalkPart_Start);
+ if (walkStartAnim.empty()) {
+ c->setAnimation(c->walkAnim(Character::WalkPart_Loop), true, false, false, -1, 9999);
+ } else {
+ c->setAnimation(c->walkAnim(Character::WalkPart_Start), false, false, false, -1, 9999);
+ }
+ c->walkTo(curveEnd, false);
+ error("TODO: Finish InGameScene::moveCharacterTo");
+ }
+ }
+}
+
+TeIntrusivePtr<TeBezierCurve> InGameScene::curve(const Common::String &curveName) {
+ for (TeIntrusivePtr<TeBezierCurve> &c : _bezierCurves) {
+ if (c->name() == curveName)
+ return c;
+ }
+ return TeIntrusivePtr<TeBezierCurve>();
+}
+
+void InGameScene::setPositionCharacter(const Common::String &charName, const Common::String &freeMoveZoneName, const TeVector3f32 &position) {
+ error("TODO: Implement InGameScene::setPositionCharacter");
+}
+
+
bool InGameScene::AnimObject::onFinished() {
error("TODO: Implement InGameScene::AnimObject::onFinished");
}
diff --git a/engines/tetraedge/game/in_game_scene.h b/engines/tetraedge/game/in_game_scene.h
index ec557257632..e18559207c8 100644
--- a/engines/tetraedge/game/in_game_scene.h
+++ b/engines/tetraedge/game/in_game_scene.h
@@ -69,7 +69,9 @@ public:
Common::String _name;
};
- class TeMarker {
+ struct TeMarker {
+ Common::String _name;
+ Common::String _val;
};
struct Dummy {
@@ -85,7 +87,7 @@ public:
_blockingObjects.push_back(obj);
}
void addCallbackAnimation2D(const Common::String ¶m_1, const Common::String ¶m_2, float param_3);
- void addMarker(const Common::String &name, const Common::String ¶m_2, float param_3, float param_4, const Common::String ¶m_5, const Common::String ¶m_6);
+ void addMarker(const Common::String &name, const Common::String &imgPath, float x, float y, const Common::String &locType, const Common::String &markerVal);
static float angularDistance(float a1, float a2);
bool aroundAnchorZone(const AnchorZone *zone);
TeLayout *background();
@@ -93,6 +95,14 @@ public:
void loadBackground(const Common::Path &path);
void loadInteractions(const Common::Path &path);
void initScroll();
+ bool isObjectBlocking(const Common::String &name);
+ bool isMarker(const Common::String &name);
+ TeFreeMoveZone *pathZone(const Common::String &name);
+ void moveCharacterTo(const Common::String &charName, const Common::String &curveName, float curveOffset, float curveEnd);
+ TeIntrusivePtr<TeBezierCurve> curve(const Common::String &curveName);
+ void setPositionCharacter(const Common::String &charName, const Common::String &freeMoveZoneName, const TeVector3f32 &position);
+ void setVisibleMarker(const Common::String &markerName, bool val);
+ void deleteMarker(const Common::String &markerName);
void draw();
void drawPath();
@@ -120,6 +130,7 @@ public:
void deleteAllCallback();
void setStep(const Common::String &scene, const Common::String &step1, const Common::String &step2);
+ TeLight *shadowLight();
Common::Path getActZoneFileName() const;
Common::Path getBlockersFileName() const;
@@ -134,9 +145,20 @@ public:
Common::Array<Character *> _characters;
TeLuaGUI &bgGui() { return _bgGui; }
+ TeLuaGUI &hitObjectGui() { return _hitObjectGui; }
+ TeLuaGUI &markerGui() { return _markerGui; }
+
+ Common::Array<TePickMesh2 *> &pickMeshes() { return _pickMeshes; }
+
+ float shadowFarPlane() const { return _shadowFarPlane; }
+ float shadowNearPlane() const { return _shadowNearPlane; }
+ float shadowFov() const { return _shadowFov; }
+ const TeColor &shadowColor() const { return _shadowColor; }
int _shadowLightNo;
CharactersShadow *_charactersShadow;
+ TeIntrusivePtr<TeBezierCurve> curve() { return _curve; }
+ void setCurve(TeIntrusivePtr<TeBezierCurve> &c) { c = _curve; }
private:
TeColor _shadowColor;
@@ -154,6 +176,7 @@ private:
Common::Array<Object3D *> _object3Ds;
Common::Array<Billboard *> _billboards;
Common::Array<TeSpriteLayout *> _sprites;
+ Common::Array<TePickMesh2 *> _pickMeshes;
Common::HashMap<Common::String, SoundStep> _soundSteps;
@@ -163,10 +186,11 @@ private:
Common::Array<Dummy> _dummies;
TeIntrusivePtr<TeModel> _playerCharacterModel;
+ TeIntrusivePtr<TeBezierCurve> _curve;
Common::Array<Common::String> _blockingObjects;
TeLuaGUI _bgGui;
- TeLuaGUI _gui2; // TODO: find a better name.
- TeLuaGUI _gui3; // TODO: find a better name.
+ TeLuaGUI _markerGui;
+ TeLuaGUI _hitObjectGui;
Common::Array<TeLight> _lights;
diff --git a/engines/tetraedge/game/inventory.cpp b/engines/tetraedge/game/inventory.cpp
index ee1be431277..79fcacffb71 100644
--- a/engines/tetraedge/game/inventory.cpp
+++ b/engines/tetraedge/game/inventory.cpp
@@ -227,7 +227,7 @@ bool Inventory::onMainMenuButton() {
bool Inventory::onObjectSelected(InventoryObject &obj) {
selectedObject(obj);
- if (!_selectedTimer._stopped) {
+ if (_selectedTimer.running()) {
if (_selectedTimer.timeElapsed() < 300000)
g_engine->getGame()->inventoryMenu().leave();
} else {
diff --git a/engines/tetraedge/game/lua_binds.cpp b/engines/tetraedge/game/lua_binds.cpp
index 4a38a714a58..462411909e5 100644
--- a/engines/tetraedge/game/lua_binds.cpp
+++ b/engines/tetraedge/game/lua_binds.cpp
@@ -22,6 +22,7 @@
#include "tetraedge/tetraedge.h"
#include "tetraedge/game/application.h"
+#include "tetraedge/game/character.h"
#include "tetraedge/game/game.h"
#include "tetraedge/game/lua_binds.h"
#include "tetraedge/to_lua.h"
@@ -161,6 +162,105 @@ static int tolua_ExportedFunctions_ChangeWarp00(lua_State *L) {
error("#ferror in function 'ChangeWarp': %d %d %s", err.index, err.array, err.type);
}
+static void SetCharacterPlayerVisible(bool val) {
+ Game *game = g_engine->getGame();
+ game->scene()._character->_model->setVisible(val);
+}
+
+static int tolua_ExportedFunctions_SetCharacterPlayerVisible00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isboolean(L, 1, 0, &err) && tolua_isnoobj(L, 2, &err)) {
+ SetCharacterPlayerVisible(tolua_toboolean(L, 1, 0));
+ return 0;
+ }
+ error("#ferror in function 'SetCharacterPlayerVisible': %d %d %s", err.index, err.array, err.type);
+}
+
+static void MoveCharacterPlayerDisabled(bool val) {
+ Game *game = g_engine->getGame();
+ game->_movePlayerCharacterDisabled = val;
+}
+
+static int tolua_ExportedFunctions_MoveCharacterPlayerDisabled00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isboolean(L, 1, 0, &err) && tolua_isnoobj(L, 2, &err)) {
+ MoveCharacterPlayerDisabled(tolua_toboolean(L, 1, 0));
+ return 0;
+ }
+ error("#ferror in function 'MoveCharacterPlayerDisabled': %d %d %s", err.index, err.array, err.type);
+}
+
+static void AddMarker(const Common::String &markerName, const Common::String &imgPath, float x, float y,
+ const Common::String &loctype, const Common::String &markerVal) {
+ Game *game = g_engine->getGame();
+ game->scene().addMarker(markerName, imgPath, x, y, loctype, markerVal);
+}
+
+static int tolua_ExportedFunctions_AddMarker00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isstring(L, 2, 0, &err)
+ && tolua_isnumber(L, 3, 0, &err) && tolua_isnumber(L, 4, 0, &err)
+ && tolua_isstring(L, 5, 1, &err) && tolua_isstring(L, 6, 1, &err)
+ && tolua_isnoobj(L, 7, &err)) {
+ Common::String s1(tolua_tostring(L, 1, nullptr));
+ Common::String s2(tolua_tostring(L, 2, nullptr));
+ double n1 = tolua_tonumber(L, 3, 0.0);
+ double n2 = tolua_tonumber(L, 4, 0.0);
+ Common::String s3(tolua_tostring(L, 5, ""));
+ Common::String s4(tolua_tostring(L, 6, ""));
+ AddMarker(s1, s2, n1, n2, s3, s4);
+ return 0;
+ }
+ error("#ferror in function 'AddMarker': %d %d %s", err.index, err.array, err.type);
+}
+
+static void SetVisibleMarker(const Common::String &markerName, bool val) {
+ Game *game = g_engine->getGame();
+ game->scene().setVisibleMarker(markerName, val);
+}
+
+static int tolua_ExportedFunctions_SetVisibleMarker00(lua_State *L) {
+tolua_Error err;
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isboolean(L, 2, 0, &err) && tolua_isnoobj(L, 3, &err)) {
+ Common::String s(tolua_tostring(L, 1, nullptr));
+ bool b = tolua_toboolean(L, 1, 0);
+ SetVisibleMarker(s, b);
+ return 0;
+ }
+ error("#ferror in function 'SetVisibleMarker': %d %d %s", err.index, err.array, err.type);
+}
+
+static void DeleteMarker(const Common::String &markerName) {
+ Game *game = g_engine->getGame();
+ game->scene().deleteMarker(markerName);
+}
+
+static int tolua_ExportedFunctions_DeleteMarker00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isnoobj(L, 2, &err)) {
+ Common::String s1(tolua_tostring(L, 1, nullptr));
+ DeleteMarker(s1);
+ return 0;
+ }
+ error("#ferror in function 'DeleteMarker': %d %d %s", err.index, err.array, err.type);
+}
+
+static void SetVisibleCellphone(bool visible) {
+ Game *game = g_engine->getGame();
+ game->inventory().cellphone()->setVisible(visible);
+}
+
+static int tolua_ExportedFunctions_SetVisibleCellphone00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isboolean(L, 1, 0, &err) && tolua_isnoobj(L, 2, &err)) {
+ SetVisibleCellphone(tolua_toboolean(L, 1, 0));
+ return 0;
+ }
+ error("#ferror in function 'SetVisibleCellphone': %d %d %s", err.index, err.array, err.type);
+}
+
+
+// ////////////////////////////////////////////////////////////////////////
void LuaOpenBinds(lua_State *L) {
tolua_open(L);
@@ -184,12 +284,12 @@ void LuaOpenBinds(lua_State *L) {
tolua_ExportedFunctions_StartAnimationAndWaitForEnd00);
tolua_function(L, "AddAnimToSet", tolua_ExportedFunctions_AddAnimToSet00);
tolua_function(L, "RequestAutoSave", tolua_ExportedFunctions_RequestAutoSave00);
- tolua_function(L, "SetVisibleButtonZoomed", tolua_ExportedFunctions_SetVisibleButtonZoomed00);
+ tolua_function(L, "SetVisibleButtonZoomed", tolua_ExportedFunctions_SetVisibleButtonZoomed00);*/
tolua_function(L, "AddMarker", tolua_ExportedFunctions_AddMarker00);
tolua_function(L, "SetVisibleMarker", tolua_ExportedFunctions_SetVisibleMarker00);
tolua_function(L, "DeleteMarker", tolua_ExportedFunctions_DeleteMarker00);
tolua_function(L, "SetVisibleCellphone", tolua_ExportedFunctions_SetVisibleCellphone00);
- tolua_function(L, "DisabledZone", tolua_ExportedFunctions_DisabledZone00);
+ /*tolua_function(L, "DisabledZone", tolua_ExportedFunctions_DisabledZone00);
tolua_function(L, "DisabledInt", tolua_ExportedFunctions_DisabledInt00);
tolua_function(L, "LockCursor", tolua_ExportedFunctions_LockCursor00);
tolua_function(L, "SetCondition", tolua_ExportedFunctions_SetCondition00);
@@ -243,11 +343,11 @@ void LuaOpenBinds(lua_State *L) {
tolua_function(L, "BlendCharacterAnimation", tolua_ExportedFunctions_BlendCharacterAnimation00);
tolua_function(L, "BlendCharacterAnimationAndWaitForEnd",
tolua_ExportedFunctions_BlendCharacterAnimationAndWaitForEnd00);
- tolua_function(L, "CurrentCharacterAnimation", tolua_ExportedFunctions_CurrentCharacterAnimation00);
+ tolua_function(L, "CurrentCharacterAnimation", tolua_ExportedFunctions_CurrentCharacterAnimation00);*/
tolua_function(L, "SetCharacterPlayerVisible", tolua_ExportedFunctions_SetCharacterPlayerVisible00);
tolua_function(L, "MoveCharacterPlayerDisabled",
tolua_ExportedFunctions_MoveCharacterPlayerDisabled00);
- tolua_function(L, "SetRunMode", tolua_ExportedFunctions_SetRunMode00);
+ /*tolua_function(L, "SetRunMode", tolua_ExportedFunctions_SetRunMode00);
tolua_function(L, "SetRunMode2", tolua_ExportedFunctions_SetRunMode200);
tolua_function(L, "SetCharacterColor", tolua_ExportedFunctions_SetCharacterColor00);
tolua_function(L, "SetCharacterSound", tolua_ExportedFunctions_SetCharacterSound00);
diff --git a/engines/tetraedge/game/main_menu.cpp b/engines/tetraedge/game/main_menu.cpp
index 7fb93fbd6c1..e2adbfb54f8 100644
--- a/engines/tetraedge/game/main_menu.cpp
+++ b/engines/tetraedge/game/main_menu.cpp
@@ -52,7 +52,7 @@ void MainMenu::enter() {
Application *app = g_engine->getApplication();
TeSpriteLayout &appSpriteLayout = app->appSpriteLayout();
appSpriteLayout.setVisible(true);
- if (appSpriteLayout._tiledSurfacePtr->_frameAnim._runTimer._stopped) {
+ if (!appSpriteLayout._tiledSurfacePtr->_frameAnim._runTimer.running()) {
appSpriteLayout.load("menus/menu.ogv");
appSpriteLayout._tiledSurfacePtr->_frameAnim._loopCount = -1;
appSpriteLayout._tiledSurfacePtr->play();
diff --git a/engines/tetraedge/game/main_menu.h b/engines/tetraedge/game/main_menu.h
index aefc03d2b83..81708ecfe89 100644
--- a/engines/tetraedge/game/main_menu.h
+++ b/engines/tetraedge/game/main_menu.h
@@ -72,7 +72,6 @@ private:
Confirm _tutoConfirm;
Confirm _quitConfirm;
- // TODO add private members
TeSignal0Param onFacebookLoggedSignal;
bool _entered;
diff --git a/engines/tetraedge/game/notifier.cpp b/engines/tetraedge/game/notifier.cpp
index e24ee2a2c09..bd5085f2123 100644
--- a/engines/tetraedge/game/notifier.cpp
+++ b/engines/tetraedge/game/notifier.cpp
@@ -32,14 +32,14 @@ Notifier::Notifier() {
void Notifier::launchNextnotifier() {
TeCurveAnim2<Te3DObject2, TeColor> *colorAnim = _gui.colorLinearAnimation("fadeIn");
assert(colorAnim);
- if (!colorAnim->_runTimer._stopped)
+ if (colorAnim->_runTimer.running())
return;
colorAnim = _gui.colorLinearAnimation("fadeOut");
- if (!colorAnim->_runTimer._stopped) {
+ if (!colorAnim->_runTimer.running()) {
colorAnim = _gui.colorLinearAnimation("visible");
bool abort = true;
- if (!colorAnim->_runTimer._stopped) {
+ if (!colorAnim->_runTimer.running()) {
abort = _notifierDataArray.empty();
}
if (abort)
diff --git a/engines/tetraedge/game/notifier.h b/engines/tetraedge/game/notifier.h
index dcd1d70bc8f..afcea1aa2f2 100644
--- a/engines/tetraedge/game/notifier.h
+++ b/engines/tetraedge/game/notifier.h
@@ -48,7 +48,6 @@ private:
};
Common::Array<notifierData> _notifierDataArray;
TeLuaGUI _gui;
- // TODO add private members
};
diff --git a/engines/tetraedge/game/objectif.h b/engines/tetraedge/game/objectif.h
index 2584462d2fe..9e71169ef02 100644
--- a/engines/tetraedge/game/objectif.h
+++ b/engines/tetraedge/game/objectif.h
@@ -50,7 +50,6 @@ public:
// void save()
void setVisibleButtonHelp(bool visible);
void setVisibleObjectif(bool visible);
- // TODO add public members
void unload();
void update();
diff --git a/engines/tetraedge/module.mk b/engines/tetraedge/module.mk
index 2908af876e3..c276c075ceb 100644
--- a/engines/tetraedge/module.mk
+++ b/engines/tetraedge/module.mk
@@ -53,7 +53,6 @@ MODULE_OBJS := \
te/te_color.o \
te/te_core.o \
te/te_extended_text_layout.o \
- te/te_fee_move_zone.o \
te/te_font3.o \
te/te_frame_anim.o \
te/te_free_move_zone.o \
@@ -87,6 +86,7 @@ MODULE_OBJS := \
te/te_pick_mesh2.o \
te/te_png.o \
te/te_quaternion.o \
+ te/te_ray_intersection.o \
te/te_real_timer.o \
te/te_renderer.o \
te/te_resource.o \
diff --git a/engines/tetraedge/te/te_3d_object2.cpp b/engines/tetraedge/te/te_3d_object2.cpp
index f1830449f1a..8c1ecb8cad0 100644
--- a/engines/tetraedge/te/te_3d_object2.cpp
+++ b/engines/tetraedge/te/te_3d_object2.cpp
@@ -87,23 +87,6 @@ long Te3DObject2::childIndex(Te3DObject2 *c) const {
return -1;
}
-/*static*/
-Common::String Te3DObject2::deserializeString(Common::ReadStream &stream) {
- uint slen = stream.readUint32LE();
- if (slen > 1024 * 1024)
- error("Improbable string size %d", slen);
-
- if (slen) {
- char *buf = new char[slen + 1];
- buf[slen] = '\0';
- stream.read(buf, slen);
- Common::String str(buf);
- delete[] buf;
- return str;
- }
- return Common::String();
-}
-
/*static*/
void Te3DObject2::deserialize(Common::ReadStream &stream, Te3DObject2 &dest) {
Common::String str = deserializeString(stream);
@@ -329,4 +312,42 @@ bool Te3DObject2::loadAndCheckFourCC(Common::ReadStream &stream, const char *str
return !strncmp(buf, str, 4);
}
+/*static*/
+Common::String Te3DObject2::deserializeString(Common::ReadStream &stream) {
+ uint slen = stream.readUint32LE();
+ if (slen > 1024 * 1024)
+ error("Improbable string size %d", slen);
+
+ if (slen) {
+ char *buf = new char[slen + 1];
+ buf[slen] = '\0';
+ stream.read(buf, slen);
+ Common::String str(buf);
+ delete[] buf;
+ return str;
+ }
+ return Common::String();
+}
+
+/*static*/
+void Te3DObject2::deserializeVectorArray(Common::ReadStream &stream, Common::Array<TeVector3f32> &dest) {
+ uint32 nentries = stream.readUint32LE();
+ if (nentries > 1000000)
+ error("TeFreeMoveZone improbable number of vectors %d", nentries);
+ dest.resize(nentries);
+ for (unsigned int i = 0; i < nentries; i++)
+ TeVector3f32::deserialize(stream, dest[i]);
+}
+
+/*static*/
+void Te3DObject2::deserializeUintArray(Common::ReadStream &stream, Common::Array<unsigned int> &dest) {
+ uint32 nentries = stream.readUint32LE();
+ if (nentries > 1000000)
+ error("TeFreeMoveZone improbable number of ints %d", nentries);
+ dest.resize(nentries);
+ for (unsigned int i = 0; i < nentries; i++)
+ dest[i] = stream.readUint32LE();
+}
+
+
} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_3d_object2.h b/engines/tetraedge/te/te_3d_object2.h
index 54fd905d8eb..3c5e090888a 100644
--- a/engines/tetraedge/te/te_3d_object2.h
+++ b/engines/tetraedge/te/te_3d_object2.h
@@ -66,7 +66,6 @@ public:
static void deserialize(Common::ReadStream &stream, Te3DObject2 &dest);
static void serialize(Common::WriteStream &stream, Te3DObject2 &src);
- static Common::String deserializeString(Common::ReadStream &stream);
virtual void draw() {}
const Common::String &name() const {
@@ -143,6 +142,9 @@ public:
virtual float zSize() { return _size.z(); };
static bool loadAndCheckFourCC(Common::ReadStream &stream, const char *str);
+ static Common::String deserializeString(Common::ReadStream &stream);
+ static void deserializeVectorArray(Common::ReadStream &stream, Common::Array<TeVector3f32> &dest);
+ static void deserializeUintArray(Common::ReadStream &stream, Common::Array<unsigned int> &dest);
protected:
TeVector3f32 _size;
diff --git a/engines/tetraedge/te/te_3d_texture.cpp b/engines/tetraedge/te/te_3d_texture.cpp
index 6680bf37559..ca8f6ae00f3 100644
--- a/engines/tetraedge/te/te_3d_texture.cpp
+++ b/engines/tetraedge/te/te_3d_texture.cpp
@@ -268,6 +268,4 @@ void Te3DTexture::update(const TeImage &img, uint xoff, uint yoff) {
return;
}
-// TODO: Add more functions here.
-
} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_animation.cpp b/engines/tetraedge/te/te_animation.cpp
index 7c5a8c2defe..08b9cc9bf3d 100644
--- a/engines/tetraedge/te/te_animation.cpp
+++ b/engines/tetraedge/te/te_animation.cpp
@@ -40,7 +40,7 @@ TeAnimation::~TeAnimation() {
}
void TeAnimation::cont() {
- if (_runTimer._stopped) {
+ if (!_runTimer.running()) {
_runTimer.start();
animations()->push_back(this);
update(_runTimer.getTimeFromStart() / 1000.0);
@@ -60,14 +60,14 @@ void TeAnimation::removeThisFromAnimations() {
}
void TeAnimation::pause() {
- if (!_runTimer._stopped) {
+ if (_runTimer.running()) {
removeThisFromAnimations();
_runTimer.pause();
}
}
void TeAnimation::stop() {
- if (!_runTimer._stopped) {
+ if (_runTimer.running()) {
removeThisFromAnimations();
_runTimer.stop();
_onStopSignal.call();
@@ -75,7 +75,7 @@ void TeAnimation::stop() {
}
void TeAnimation::reset() {
- if (!_runTimer._stopped) {
+ if (_runTimer.running()) {
removeThisFromAnimations();
stop();
}
@@ -87,30 +87,32 @@ void TeAnimation::seekToStart() {
update(_runTimer.getTimeFromStart() / 1000.0);
}
-/*static*/ void TeAnimation::pauseAll() {
+/*static*/
+void TeAnimation::pauseAll() {
for (auto &anim : *animations()) {
- if (!anim->_runTimer._stopped)
+ if (anim->_runTimer.running())
anim->pause();
}
}
-/*static*/ void TeAnimation::resumeAll() {
+/*static*/
+void TeAnimation::resumeAll() {
for (auto &anim : *animations()) {
anim->cont();
}
}
-/*static*/ void TeAnimation::updateAll() {
+/*static*/
+void TeAnimation::updateAll() {
Common::Array<TeAnimation *> &anims = *animations();
// Note: update can cause events which cascade into animtaions
// getting deleted, so be careful about the numbers.
for (unsigned int i = 0; i < anims.size(); i++) {
- if (!anims[i]->_runTimer._stopped) {
+ if (anims[i]->_runTimer.running()) {
float msFromStart = anims[i]->_runTimer.getTimeFromStart() / 1000.0;
anims[i]->update(msFromStart);
}
}
-
}
} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_bezier_curve.h b/engines/tetraedge/te/te_bezier_curve.h
index ace2c2ceea5..9b201c13f50 100644
--- a/engines/tetraedge/te/te_bezier_curve.h
+++ b/engines/tetraedge/te/te_bezier_curve.h
@@ -47,6 +47,8 @@ public:
static void serialize(Common::WriteStream &stream, const TeBezierCurve &curve);
static void deserialize(Common::ReadStream &stream, TeBezierCurve &curve);
+ const Common::Array<TeVector3f32> &controlPoints() { return _controlPoints; }
+
private:
unsigned int _numiterations;
float _length;
diff --git a/engines/tetraedge/te/te_button_layout.cpp b/engines/tetraedge/te/te_button_layout.cpp
index 31bb77bb74e..f0235e3492c 100644
--- a/engines/tetraedge/te/te_button_layout.cpp
+++ b/engines/tetraedge/te/te_button_layout.cpp
@@ -60,7 +60,7 @@ _hitZoneLayout(nullptr)
inputmgr->_mouseLUpSignal.insert(_onMouseLeftUpMaxPriorityCallback);
setEditionColor(TeColor(128, 128, 128, 255));
- if (getDoubleValidationProtectionTimer()->_stopped)
+ if (!getDoubleValidationProtectionTimer()->running())
getDoubleValidationProtectionTimer()->start();
}
@@ -202,7 +202,7 @@ void TeButtonLayout::reset() {
void TeButtonLayout::resetTimeFromLastValidation() {
TeTimer *timer = getDoubleValidationProtectionTimer();
- if (timer->_stopped) {
+ if (!timer->running()) {
timer->start();
}
timer->timeElapsed();
diff --git a/engines/tetraedge/te/te_button_layout.h b/engines/tetraedge/te/te_button_layout.h
index a8a7b7068b3..ebeaab28ae0 100644
--- a/engines/tetraedge/te/te_button_layout.h
+++ b/engines/tetraedge/te/te_button_layout.h
@@ -88,6 +88,9 @@ public:
void setState(State newState);
TeSignal0Param &onMouseClickValidated() { return _onMouseClickValidatedSignal; };
+ TeSignal0Param &onButtonChangedToStateUpSignal() { return _onButtonChangedToStateUpSignal; };
+ TeSignal0Param &onButtonChangedToStateDownSignal() { return _onButtonChangedToStateDownSignal; };
+ TeSignal0Param &onButtonChangedToStateRolloverSignal() { return _onButtonChangedToStateRolloverSignal; };
bool _someClickFlag;
TeLayout *_upLayout;
diff --git a/engines/tetraedge/te/te_camera.cpp b/engines/tetraedge/te/te_camera.cpp
index 07ae8dd4501..f41baa6d4c4 100644
--- a/engines/tetraedge/te/te_camera.cpp
+++ b/engines/tetraedge/te/te_camera.cpp
@@ -31,10 +31,18 @@ namespace Tetraedge {
TeCamera::TeCamera() : _projectionMatrixType(0), _orthogonalParamL(1.0f),
_orthogonalParamR(0.0f), _orthogonalParamT(1.0f), _orthogonalParamB(0.0f),
_orthNearVal(10.0f), _orthFarVal(4000.0f), _transformA(0), _transformB(0),
- _focalLenMaybe(40.0f), _somePerspectiveVal(1.0f)
+ _fov(40.0f), _somePerspectiveVal(1.0f)
{
}
+void TeCamera::apply() {
+ /*debug("TeCamera::apply %13s mtype %d fov %.2f persp %.2f orth(%.2f %.2f) pos %s scale %s", name().c_str(),
+ _projectionMatrixType, _fov, _somePerspectiveVal, _orthNearVal, _orthFarVal,
+ position().dump().c_str(), scale().dump().c_str());*/
+ applyProjection();
+ applyTransformations();
+}
+
void TeCamera::applyProjection() {
TeRenderer *renderer = g_engine->getRenderer();
renderer->setCurrentCamera(this);
@@ -50,7 +58,7 @@ void TeCamera::applyProjection() {
void TeCamera::applyTransformations() {
TeRenderer *renderer = g_engine->getRenderer();
renderer->setMatrixMode(TeRenderer::MatrixMode::MM_GL_MODELVIEW);
- TeMatrix4x4 matrix = transformationMatrix();
+ TeMatrix4x4 matrix = worldTransformationMatrix();
matrix.inverse();
renderer->loadMatrix(matrix);
renderer->loadCurrentMatrixToGL();
@@ -92,23 +100,60 @@ void TeCamera::buildOrthoMatrix() {
}
void TeCamera::buildPerspectiveMatrix() {
- error("TODO: Implement TeCamera::buildPerspectiveMatrix");
+ _projectionMatrix = TeMatrix4x4();
+ float f = tanf(_fov * 0.5);
+ _projectionMatrix.setValue(0, 0, (1.0 / f) / ((float)_viewportW / _viewportH));
+ _projectionMatrix.setValue(1, 1, 1.0 / f);
+ _projectionMatrix.setValue(2, 2, (_orthNearVal + _orthFarVal) / (_orthNearVal - _orthFarVal));
+ _projectionMatrix.setValue(2, 2, (_orthNearVal * _orthFarVal) / (_orthNearVal - _orthFarVal));
+ _projectionMatrix.setValue(2, 3, -1);
+ _projectionMatrix.setValue(3, 3, 0.0);
}
void TeCamera::buildPerspectiveMatrix2() {
- error("TODO: Implement TeCamera::buildPerspectiveMatrix2");
+ _projectionMatrix = TeMatrix4x4();
+ float f = tanf(_fov * 0.5);
+ _projectionMatrix.setValue(0, 0, 1.0 / f);
+ _projectionMatrix.setValue(1, 1, _somePerspectiveVal / f);
+ _projectionMatrix.setValue(2, 2, -(_orthNearVal + _orthFarVal) / (_orthNearVal - _orthFarVal));
+ _projectionMatrix.setValue(3, 2, 1.0);
+ _projectionMatrix.setValue(2, 3, (_orthFarVal * 2) * _orthNearVal / (_orthNearVal - _orthFarVal));
+ _projectionMatrix.setValue(3, 3, 0.0);
}
void TeCamera::buildPerspectiveMatrix3() {
- error("TODO: Implement TeCamera::buildPerspectiveMatrix3");
+ _projectionMatrix = TeMatrix4x4();
+ float f = tanf(_fov * 0.5);
+ _projectionMatrix.setValue(0, 0, (1.0 / f) / _somePerspectiveVal);
+ _projectionMatrix.setValue(1, 1, 1.0 / f);
+ _projectionMatrix.setValue(2, 2, -(_orthNearVal + _orthFarVal) / (_orthNearVal - _orthFarVal));
+ _projectionMatrix.setValue(3, 2, 1.0);
+ _projectionMatrix.setValue(2, 3, (_orthFarVal * 2) * _orthNearVal / (_orthNearVal - _orthFarVal));
+ _projectionMatrix.setValue(3, 3, 0.0);
}
void TeCamera::draw() {
error("TODO: Implement TeCamera::draw");
}
-void TeCamera::getRay(const TeVector2s32 ¶m_1, TeVector3f32 &out1, TeVector3f32 &out2) {
- error("TODO: Implement TeCamera::getRay");
+void TeCamera::getRay(const TeVector2s32 &pxloc, TeVector3f32 &out1, TeVector3f32 &out2) {
+ float xval = (pxloc._x - _viewportX) / fabs(_viewportW);
+ out2.x() = xval * 2 - 1;
+ float yval = (pxloc._y - _viewportY) / fabs(_viewportH);
+ out2.y() = yval * 2 - 1;
+ out2.z() = 1.0;
+
+ TeMatrix4x4 inverse = projectionMatrix();
+ inverse.inverse();
+ out2 = inverse * out2;
+ out2.normalize();
+
+ TeVector3f32 pos = position();
+ TeQuaternion rot = rotation();
+ out1 = pos;
+ rot.normalize();
+ TeMatrix4x4 rotmatrix = rot.toMatrix();
+ out2 = rotmatrix * out2;
}
void TeCamera::loadBin(const Common::String &path) {
diff --git a/engines/tetraedge/te/te_camera.h b/engines/tetraedge/te/te_camera.h
index 1f02ccf0154..f6344d53a24 100644
--- a/engines/tetraedge/te/te_camera.h
+++ b/engines/tetraedge/te/te_camera.h
@@ -36,11 +36,7 @@ class TeCamera : public Te3DObject2, public TeReferencesCounter {
public:
TeCamera();
- void apply() {
- applyProjection();
- applyTransformations();
- }
-
+ void apply();
void applyProjection();
void applyTransformations();
void buildOrthoMatrix();
@@ -69,11 +65,12 @@ public:
void updateProjectionMatrix();
void viewport(int x, int y, uint width, uint height);
+ TeVector2f32 viewportSize() const { return TeVector2f32(_viewportW, _viewportH); }
int _projectionMatrixType;
float _orthNearVal;
float _orthFarVal;
- float _focalLenMaybe;
+ float _fov;
float _somePerspectiveVal;
private:
diff --git a/engines/tetraedge/te/te_fee_move_zone.cpp b/engines/tetraedge/te/te_fee_move_zone.cpp
deleted file mode 100644
index 414c9a0841b..00000000000
--- a/engines/tetraedge/te/te_fee_move_zone.cpp
+++ /dev/null
@@ -1,31 +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 "tetraedge/te/te_fee_move_zone.h"
-
-namespace Tetraedge {
-
-TeFeeMoveZone::TeFeeMoveZone() {
-}
-
-// TODO: Add more functions here.
-
-} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_free_move_zone.cpp b/engines/tetraedge/te/te_free_move_zone.cpp
index 6f072e56676..89999b5717e 100644
--- a/engines/tetraedge/te/te_free_move_zone.cpp
+++ b/engines/tetraedge/te/te_free_move_zone.cpp
@@ -19,13 +19,50 @@
*
*/
+#include "tetraedge/tetraedge.h"
+
#include "tetraedge/te/te_free_move_zone.h"
+#include "tetraedge/te/micropather.h"
+#include "tetraedge/te/te_renderer.h"
namespace Tetraedge {
+class TeFreeMoveZoneGraph : micropather::Graph {
+ friend class TeFreeMoveZone;
+ TeVector2s32 _size;
+ Common::Array<char> _flags;
+ float _bordersDistance;
+ TeFreeMoveZone *_owner;
+
+ // These don't match ScummVM naming convention but are needed to match MicroPather API.
+ virtual float LeastCostEstimate(void * stateStart, void *stateEnd);
+ virtual void AdjacentCost(void *state, Common::Array<micropather::StateCost> *adjacent);
+ virtual void PrintStateInfo(void *state);
+
+ int flag(const TeVector2s32 &loc);
+ void setSize(const TeVector2s32 &size);
+
+ void deserialize(Common::ReadStream &stream);
+ void serialize(Common::WriteStream &stream) const;
+};
+
+
TeFreeMoveZone::TeFreeMoveZone() : _actzones(nullptr), _blockers(nullptr), _rectBlockers(nullptr),
_transformedVerticiesDirty(true), _bordersDirty(true), _pickMeshDirty(true), _projectedPointsDirty(true)
{
+ _graph = new TeFreeMoveZoneGraph();
+ _graph->_bordersDistance = 2048.0f;
+ _graph->_owner = this;
+ _micropather = new micropather::MicroPather(_graph);
+}
+
+TeFreeMoveZone::~TeFreeMoveZone() {
+ // TODO: remove signal.
+ delete _micropather;
+}
+
+float TeFreeMoveZone::bordersDistance() const {
+ return _graph->_bordersDistance;
}
void TeFreeMoveZone::buildAStar() {
@@ -37,10 +74,19 @@ void TeFreeMoveZone::calcGridMatrix() {
}
void TeFreeMoveZone::clear() {
- error("TODO: Implement TeFreeMoveZone::clear");
+ setNbTriangles(0);
+ _pickMeshDirty = true;
+ _projectedPointsDirty = true;
+ // TODO: Clear 3 other point vectors here.
+ // TODO: _gridDirty = true;
+ _graph->_flags.clear();
+ _graph->_size = TeVector2s32(0, 0);
+ _micropather->Reset();
}
Common::Array<TeVector3f32> TeFreeMoveZone::collisions(const TeVector3f32 &v1, const TeVector3f32 &v2) {
+ updatePickMesh();
+ updateProjectedPoints();
error("TODO: Implement TeFreeMoveZone::collisions");
}
@@ -48,16 +94,215 @@ TeVector3f32 TeFreeMoveZone::correctCharacterPosition(const TeVector3f32 &pos, b
error("TODO: Implement TeFreeMoveZone::correctCharacterPosition");
}
+TeIntrusivePtr<TeBezierCurve> TeFreeMoveZone::curve(const TeVector3f32 ¶m_3, const TeVector2s32 ¶m_4, float param_5, bool findMeshFlag) {
+ error("TODO: Implement TeFreeMoveZone::curve");
+}
+
+TeIntrusivePtr<TeBezierCurve> TeFreeMoveZone::curve(const TeVector3f32 ¶m_3, const TeVector2s32 ¶m_4) {
+ error("TODO: Implement TeFreeMoveZone::curve");
+}
+
/*static*/
void TeFreeMoveZone::deserialize(Common::ReadStream &stream, TeFreeMoveZone &dest, Common::Array<TeBlocker> *blockers,
Common::Array<TeRectBlocker> *rectblockers, Common::Array<TeActZone> *actzones) {
dest.clear();
TePickMesh2::deserialize(stream, dest);
+ TeVector2f32::deserialize(stream, dest._gridOffsetSomething);
+ dest._transformedVerticiesDirty = (stream.readByte() != 0);
+ dest._bordersDirty = (stream.readByte() != 0);
+ dest._pickMeshDirty = (stream.readByte() != 0);
+ dest._projectedPointsDirty = (stream.readByte() != 0);
+ dest._gridDirty = (stream.readByte() != 0);
+
+ Te3DObject2::deserializeVectorArray(stream, dest._freeMoveZoneVerticies);
+ Te3DObject2::deserializeUintArray(stream, dest._uintArray1);
+ Te3DObject2::deserializeVectorArray(stream, dest._vectorArray);
+ Te3DObject2::deserializeUintArray(stream, dest._uintArray2);
+
+ TeOBP::deserialize(stream, dest._obp);
- error("TODO: Implement TeFreeMoveZone::deserialize");
+ TeVector2f32::deserialize(stream, dest._someGridVec1);
+ TeVector2f32::deserialize(stream, dest._someGridVec2);
+ dest._someGridFloat = stream.readFloatLE();
+
+ dest._graph->deserialize(stream);
+ if (dest.name().contains("19000")) {
+ dest._gridOffsetSomething = TeVector2f32(2.0, 2.0);
+ dest._gridDirty = true;
+ }
dest._blockers = blockers;
dest._rectBlockers = rectblockers;
dest._actzones = actzones;
}
+void TeFreeMoveZone::draw() {
+ if (!worldVisible())
+ return;
+
+ TeRenderer *renderer = g_engine->getRenderer();
+ renderer->enableWireFrame();
+ TePickMesh2::draw();
+ TeMesh mesh;
+ mesh.setConf(_uintArray2.size(), _uintArray2.size(), TeMesh::MeshMode_Lines, 0, 0);
+
+ error("TODO: Finish TeFreeMoveZone::draw");
+}
+
+TeVector3f32 TeFreeMoveZone::findNearestPointOnBorder(const TeVector2f32 &pt) {
+ error("TODO: Implement TeFreeMoveZone::findNearestPointOnBorder");
+}
+
+bool TeFreeMoveZone::hasBlockerIntersection(const TeVector2s32 &pt) {
+ error("TODO: Implement TeFreeMoveZone::hasBlockerIntersection");
+}
+
+bool TeFreeMoveZone::hasCellBorderIntersection(const TeVector2s32 &pt) {
+ error("TODO: Implement TeFreeMoveZone::hasCellBorderIntersection");
+}
+
+TeActZone *TeFreeMoveZone::isInZone(const TeVector3f32 &pt) {
+ error("TODO: Implement TeFreeMoveZone::isInZone");
+}
+
+bool TeFreeMoveZone::onViewportChanged() {
+ _projectedPointsDirty = true;
+ return false;
+}
+
+void TeFreeMoveZone::preUpdateGrid() {
+ error("TODO: Implement TeFreeMoveZone::preUpdateGrid");
+}
+
+TeVector3f32 TeFreeMoveZone::projectOnAStarGrid(const TeVector3f32 &pt) {
+ error("TODO: Implement TeFreeMoveZone::projectOnAStarGrid");
+}
+
+Common::Array<TeVector3f32> &TeFreeMoveZone::removeInsignificantPoints(const Common::Array<TeVector3f32> &points) {
+ error("TODO: Implement TeFreeMoveZone::removeInsignificantPoints");
+}
+
+void TeFreeMoveZone::setBordersDistance(float dist) {
+ _graph->_bordersDistance = dist;
+}
+
+void TeFreeMoveZone::setCamera(TeIntrusivePtr<TeCamera> &cam, bool recalcProjPoints) {
+ error("TODO: Implement TeFreeMoveZone::setCamera");
+}
+
+void TeFreeMoveZone::setNbTriangles(unsigned long len) {
+ _freeMoveZoneVerticies.resize(len * 3);
+
+ _gridDirty = true;
+ _transformedVerticiesDirty = true;
+ _bordersDirty = true;
+ _pickMeshDirty = true;
+ _projectedPointsDirty = true;
+}
+
+void TeFreeMoveZone::setPathFindingOccluder(const TeOBP &occluder) {
+ error("TODO: Implement TeFreeMoveZone::setPathFindingOccluder");
+}
+
+void TeFreeMoveZone::setVertex(unsigned long offset, const TeVector3f32 &vertex) {
+ _freeMoveZoneVerticies[offset] = vertex;
+
+ _gridDirty = true;
+ _transformedVerticiesDirty = true;
+ _bordersDirty = true;
+ _pickMeshDirty = true;
+ _projectedPointsDirty = true;
+}
+
+TeVector2s32 TeFreeMoveZone::transformAStarGridInWorldSpace(const TeVector2s32 &gridpt) {
+ error("TODO: Implement TeFreeMoveZone::transformAStarGridInWorldSpace");
+}
+
+float TeFreeMoveZone::transformHeightMin(float minval) {
+ error("TODO: Implement TeFreeMoveZone::transformHeightMin");
+}
+
+TeVector3f32 TeFreeMoveZone::transformVectorInWorldSpace(float param_3,float param_4) {
+ error("TODO: Implement TeFreeMoveZone::transformVectorInWorldSpace");
+}
+
+void TeFreeMoveZone::updateBorders() {
+ error("TODO: Implement TeFreeMoveZone::updateBorders");
+}
+
+void TeFreeMoveZone::updateGrid(bool force) {
+ if (!force && !_gridDirty)
+ return;
+ _gridDirty = true;
+ _updateTimer.stop();
+ _updateTimer.start();
+ buildAStar();
+ _micropather->Reset();
+ debug("[TeFreeMoveZone::updateGrid()] %s time : %.2f", name().c_str(), _updateTimer.getTimeFromStart() / 1000000.0);
+ _gridDirty = false;
+}
+
+void TeFreeMoveZone::updatePickMesh() {
+ if (!_pickMeshDirty)
+ return;
+
+ error("TODO: Implement TeFreeMoveZone::updatePickMesh");
+}
+
+void TeFreeMoveZone::updateProjectedPoints() {
+ if (!_projectedPointsDirty)
+ return;
+
+ error("TODO: Implement TeFreeMoveZone::updateProjectedPoints");
+}
+
+void TeFreeMoveZone::updateTransformedVertices() {
+ if (!_transformedVerticiesDirty)
+ return;
+
+ error("TODO: Implement TeFreeMoveZone::updateTransformedVertices");
+}
+
+/*========*/
+
+float TeFreeMoveZoneGraph::LeastCostEstimate(void * stateStart, void *stateEnd) {
+ error("TODO: Implement TeFreeMoveZone::TeFreeMoveZoneGraph::LeastCostEstimate");
+}
+
+void TeFreeMoveZoneGraph::AdjacentCost(void *state, Common::Array<micropather::StateCost> *adjacent) {
+ error("TODO: Implement TeFreeMoveZone::TeFreeMoveZoneGraph::AdjacentCost");
+}
+
+void TeFreeMoveZoneGraph::PrintStateInfo(void *state) {
+ error("TODO: Implement TeFreeMoveZone::TeFreeMoveZoneGraph::PrintStateInfo");
+}
+
+int TeFreeMoveZoneGraph::flag(const TeVector2s32 &loc) {
+ if (loc._x < 0 || loc._x >= _size._x || loc._y < 0 || loc._y >= _size._y)
+ return 1;
+ return _flags[loc._y * _size._x + loc._x];
+}
+
+void TeFreeMoveZoneGraph::setSize(const TeVector2s32 &size) {
+ _flags.clear();
+ _size = size;
+ _flags.resize(size._x * _size._y);
+}
+
+void TeFreeMoveZoneGraph::deserialize(Common::ReadStream &stream) {
+ TeVector2s32::deserialize(stream, _size);
+ uint32 flaglen = stream.readUint32LE();
+ if (flaglen > 1000000 || (int)flaglen != _size._x * _size._y)
+ error("Flags unexpected size, expect %d got %d", _size._x * _size._y, flaglen);
+ _flags.resize(flaglen);
+ for (unsigned int i = 0; i < flaglen; i++) {
+ _flags[i] = stream.readByte();
+ }
+ _bordersDistance = stream.readFloatLE();
+}
+
+void TeFreeMoveZoneGraph::serialize(Common::WriteStream &stream) const {
+ error("TODO: Implement TeFreeMoveZoneGraph::serialize");
+}
+
+
} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_free_move_zone.h b/engines/tetraedge/te/te_free_move_zone.h
index d1ddb9a3f97..13f0b9856ee 100644
--- a/engines/tetraedge/te/te_free_move_zone.h
+++ b/engines/tetraedge/te/te_free_move_zone.h
@@ -24,6 +24,10 @@
#include "common/array.h"
+#include "tetraedge/te/te_bezier_curve.h"
+#include "tetraedge/te/te_camera.h"
+#include "tetraedge/te/te_intrusive_ptr.h"
+#include "tetraedge/te/te_obp.h"
#include "tetraedge/te/te_pick_mesh2.h"
#include "tetraedge/te/te_vector3f32.h"
#include "tetraedge/te/te_act_zone.h"
@@ -48,6 +52,7 @@ struct TeRectBlocker {
long _x;
};
+class TeFreeMoveZoneGraph;
class TeFreeMoveZone : public TePickMesh2 {
public:
@@ -56,31 +61,76 @@ public:
float _distance;
};
- class TeFreeMoveZoneGraph {
- friend class TeFreeMoveZone;
- TeVector2s32 _size;
- Common::Array<char> _flags;
- float _f;
- TeFreeMoveZone *_owner;
- };
-
TeFreeMoveZone();
+ ~TeFreeMoveZone();
- float bordersDistance() const { return _graph->_f; }
+ float bordersDistance() const;
void buildAStar();
void calcGridMatrix();
void clear();
Common::Array<TeVector3f32> collisions(const TeVector3f32 &v1, const TeVector3f32 &v2);
TeVector3f32 correctCharacterPosition(const TeVector3f32 &pos, bool *flagout, bool f);
+ TeIntrusivePtr<TeBezierCurve> curve(const TeVector3f32 ¶m_3, const TeVector2s32 ¶m_4, float param_5, bool findMeshFlag);
+ TeIntrusivePtr<TeBezierCurve> curve(const TeVector3f32 ¶m_3, const TeVector2s32 ¶m_4);
+
+ void draw() override;
+ TeVector3f32 findNearestPointOnBorder(const TeVector2f32 &pt);
+ bool hasBlockerIntersection(const TeVector2s32 &pt);
+ bool hasCellBorderIntersection(const TeVector2s32 &pt);
+
+ TeActZone *isInZone(const TeVector3f32 &pt);
+
+ // loadBin() 2 versions, seem unused
+
+ // name(), onPositionChanged(), position(), rotate(), rotation(), scale(),
+ // setName(), setPosition(), setRotation(), setScale(), setVisible(),
+ // translate(), and visible() are all implemented in original, but all
+ // just do the same as super.
+
+ bool onViewportChanged();
+ void preUpdateGrid();
+ TeVector3f32 projectOnAStarGrid(const TeVector3f32 &pt);
+ Common::Array<TeVector3f32> &removeInsignificantPoints(const Common::Array<TeVector3f32> &points);
+ void setBordersDistance(float dist);
+ void setCamera(TeIntrusivePtr<TeCamera> &cam, bool recalcProjPoints);
+ void setNbTriangles(unsigned long len);
+ void setPathFindingOccluder(const TeOBP &occluder);
+ void setVertex(unsigned long offset, const TeVector3f32 &vertex);
+ TeVector2s32 transformAStarGridInWorldSpace(const TeVector2s32 &gridpt);
+ float transformHeightMin(float minval);
+ TeVector3f32 transformVectorInWorldSpace(float param_3,float param_4);
+ void updateBorders();
+ void updateGrid(bool force);
+ void updatePickMesh();
+ void updateProjectedPoints();
+ void updateTransformedVertices();
+
+ static float normalizeAngle(float angle);
static void deserialize(Common::ReadStream &stream, TeFreeMoveZone &dest, Common::Array<TeBlocker> *blockers,
Common::Array<TeRectBlocker> *rectblockers, Common::Array<TeActZone> *actzones);
+ static void serialize(Common::WriteStream &stream, const TeFreeMoveZone &src, bool updateFirst);
private:
Common::Array<TeActZone> *_actzones;
Common::Array<TeBlocker> *_blockers;
Common::Array<TeRectBlocker> *_rectBlockers;
+ Common::Array<TeVector3f32> _freeMoveZoneVerticies;
+ // TODO: Find better names..
+ Common::Array<unsigned int> _uintArray1;
+ Common::Array<TeVector3f32> _vectorArray;
+ Common::Array<unsigned int> _uintArray2;
+
+ TeVector2f32 _gridOffsetSomething;
+ TeVector2f32 _someGridVec1;
+ TeVector2f32 _someGridVec2;
+
+ float _someGridFloat;
+
+ TeOBP _obp;
+
+ bool _gridDirty;
TeFreeMoveZoneGraph *_graph;
bool _transformedVerticiesDirty;
bool _bordersDirty;
diff --git a/engines/tetraedge/te/te_light.h b/engines/tetraedge/te/te_light.h
index 633a5c125c2..72f2a05cd38 100644
--- a/engines/tetraedge/te/te_light.h
+++ b/engines/tetraedge/te/te_light.h
@@ -68,6 +68,9 @@ public:
void setPosition3d(const TeVector3f32 &pos) { _position3d = pos; }
void setPositionRadial(const TeVector2f32 &pos) { _positionRadial = pos; }
+ const TeVector2f32 &positionRadial() const { return _positionRadial; }
+ const TeVector3f32 &position3d() const { return _position3d; }
+
private:
TeVector3f32 _position3d;
TeVector2f32 _positionRadial;
diff --git a/engines/tetraedge/te/te_lua_gui_lua_callbacks.cpp b/engines/tetraedge/te/te_lua_gui_lua_callbacks.cpp
index b8a04c324c1..78850e02155 100644
--- a/engines/tetraedge/te/te_lua_gui_lua_callbacks.cpp
+++ b/engines/tetraedge/te/te_lua_gui_lua_callbacks.cpp
@@ -332,7 +332,7 @@ int spriteLayoutBindings(lua_State *L) {
TeSpriteLayout *layout = new TeSpriteLayout();
lua_pushnil(L);
- bool playNow = !layout->_tiledSurfacePtr->_frameAnim._runTimer._stopped;
+ bool playNow = layout->_tiledSurfacePtr->_frameAnim._runTimer.running();
int startingFrame = 0;
int endingFrame = -1;
Common::Path imgFullPath;
diff --git a/engines/tetraedge/te/te_lua_thread.cpp b/engines/tetraedge/te/te_lua_thread.cpp
index ad4653c05e7..baa7bbadb36 100644
--- a/engines/tetraedge/te/te_lua_thread.cpp
+++ b/engines/tetraedge/te/te_lua_thread.cpp
@@ -76,7 +76,7 @@ void TeLuaThread::execute(const Common::String &fname) {
_resume(0);
} else {
if (!fname.contains("Update"))
- warning("[TeLuaThread::Execute] La fonction : \"%s\" n'existe pas.", fname.c_str());
+ warning("[TeLuaThread::Execute0] La fonction : \"%s\" n'existe pas.", fname.c_str());
lua_settop(_luaThread, -2);
}
}
@@ -91,7 +91,7 @@ void TeLuaThread::execute(const Common::String &fname, const TeVariant &p1) {
_resume(1);
} else {
if (!fname.contains("Update"))
- warning("[TeLuaThread::Execute] La fonction : \"%s\" n'existe pas.", fname.c_str());
+ warning("[TeLuaThread::Execute1] La fonction : \"%s\" n'existe pas.", fname.c_str());
lua_settop(_luaThread, -2);
}
}
@@ -107,7 +107,7 @@ void TeLuaThread::execute(const Common::String &fname, const TeVariant &p1, cons
_resume(2);
} else {
if (!fname.contains("Update"))
- warning("[TeLuaThread::Execute] La fonction : \"%s\" n'existe pas.", fname.c_str());
+ warning("[TeLuaThread::Execute2] La fonction : \"%s\" n'existe pas.", fname.c_str());
lua_settop(_luaThread, -2);
}
}
@@ -124,7 +124,7 @@ void TeLuaThread::execute(const Common::String &fname, const TeVariant &p1, cons
_resume(3);
} else {
if (!fname.contains("Update"))
- warning("[TeLuaThread::Execute] La fonction : \"%s\" n'existe pas.", fname.c_str());
+ warning("[TeLuaThread::Execute3] La fonction : \"%s\" n'existe pas.", fname.c_str());
lua_settop(_luaThread, -2);
}
}
diff --git a/engines/tetraedge/te/te_lua_thread.h b/engines/tetraedge/te/te_lua_thread.h
index 5f8b0e77f4f..ac2be3cd209 100644
--- a/engines/tetraedge/te/te_lua_thread.h
+++ b/engines/tetraedge/te/te_lua_thread.h
@@ -69,7 +69,6 @@ private:
bool _released;
static Common::Array<TeLuaThread *> _threadList;
- // TODO add private members
};
diff --git a/engines/tetraedge/te/te_matrix4x4.h b/engines/tetraedge/te/te_matrix4x4.h
index 36aac4935cd..68159bac5bd 100644
--- a/engines/tetraedge/te/te_matrix4x4.h
+++ b/engines/tetraedge/te/te_matrix4x4.h
@@ -61,7 +61,6 @@ public:
void translate(const TeVector3f32 &vec);
TeVector3f32 mult3x3(const TeVector3f32 &vec) const;
TeVector3f32 mult4x3(const TeVector3f32 &vec) const;
- // TODO add public members
Common::String toString() const;
diff --git a/engines/tetraedge/te/te_model.cpp b/engines/tetraedge/te/te_model.cpp
index b1ca1f1f3d5..5b22b028a4d 100644
--- a/engines/tetraedge/te/te_model.cpp
+++ b/engines/tetraedge/te/te_model.cpp
@@ -214,6 +214,8 @@ bool TeModel::load(Common::SeekableReadStream &stream) {
_meshes.resize(stream.readUint32LE());
_weightElements.resize(stream.readUint32LE());
uint32 bonecount = stream.readUint32LE();
+ if (bonecount > 100000)
+ error("TeModel::load: Unexpected number of bones %d", bonecount);
_bones.resize(bonecount);
_boneMatrices.resize(bonecount);
@@ -248,10 +250,8 @@ bool TeModel::load(Common::SeekableReadStream &stream) {
loadWeights(stream, _weightElements[i]);
}
- //if (*(long *)(*(long *)&(_bones).field_0x8 + 0x68) != 0) {
- // return true;
- //}
- _bones.resize(1);
+ if (_bones.empty())
+ _bones.resize(1);
return true;
}
@@ -313,6 +313,10 @@ bool TeModel::loadMesh(Common::SeekableReadStream &stream, TeMesh &mesh) {
uint32 matcount = stream.readUint32LE();
uint32 matidxcount = stream.readUint32LE();
uint32 idxcount = stream.readUint32LE();
+
+ if (vertcount > 100000 || matcount > 100000 || matidxcount > 100000 || idxcount > 100000)
+ error("Improbable mesh sizes %d %d %d %d", vertcount, matcount, matidxcount, idxcount);
+
mesh.setConf(vertcount, idxcount, TeMesh::MeshMode_TriangleFan, matcount, matidxcount);
uint32 flags = stream.readUint32LE();
diff --git a/engines/tetraedge/te/te_model.h b/engines/tetraedge/te/te_model.h
index 532916e9c04..10166e37a2c 100644
--- a/engines/tetraedge/te/te_model.h
+++ b/engines/tetraedge/te/te_model.h
@@ -146,7 +146,6 @@ protected:
TeIntrusivePtr<TeModelAnimation> _modelAnim;
TeIntrusivePtr<TeModelVertexAnimation> _modelVertexAnim;
- // TODO add private members
};
diff --git a/engines/tetraedge/te/te_model_animation.cpp b/engines/tetraedge/te/te_model_animation.cpp
index 8fad3f12fda..98a0062be70 100644
--- a/engines/tetraedge/te/te_model_animation.cpp
+++ b/engines/tetraedge/te/te_model_animation.cpp
@@ -323,7 +323,7 @@ void TeModelAnimation::update(double proportion) {
}
if (frames) {
- _curFrameValFresh = false;
+ _curFrameValFresh = false;
_curFrame2 = calcCurrentFrame(proportion);
if (_finishedSignalPending) {
_finishedSignalPending = false;
diff --git a/engines/tetraedge/te/te_model_animation.h b/engines/tetraedge/te/te_model_animation.h
index b06a5c9b150..8765b7ab840 100644
--- a/engines/tetraedge/te/te_model_animation.h
+++ b/engines/tetraedge/te/te_model_animation.h
@@ -108,7 +108,6 @@ private:
int _useNMOArrays; // TODO: probably a bad name?
int _numNMOFrames;
float _speed;
- // TODO add private members
};
diff --git a/engines/tetraedge/te/te_obp.cpp b/engines/tetraedge/te/te_obp.cpp
index 613ec30323e..bb501152ad7 100644
--- a/engines/tetraedge/te/te_obp.cpp
+++ b/engines/tetraedge/te/te_obp.cpp
@@ -105,4 +105,14 @@ void TeOBP::updateTransformed() {
_boundsNeedUpdate = false;
}
+/*static*/
+void TeOBP::deserialize(Common::ReadStream &stream, TeOBP &dest) {
+ dest._boundsNeedUpdate = true;
+ Te3DObject2::deserialize(stream, dest);
+ TeVector3f32::deserialize(stream, dest._corner1);
+ TeVector3f32::deserialize(stream, dest._corner2);
+ TeVector3f32::deserialize(stream, dest._corner3);
+ TeVector3f32::deserialize(stream, dest._corner4);
+}
+
} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_pick_mesh2.h b/engines/tetraedge/te/te_pick_mesh2.h
index 1e7c07e8bb5..c43ee54f5ac 100644
--- a/engines/tetraedge/te/te_pick_mesh2.h
+++ b/engines/tetraedge/te/te_pick_mesh2.h
@@ -51,6 +51,7 @@ public:
static void deserialize(Common::ReadStream &stream, TePickMesh2 &mesh);
Common::Array<TeVector3f32> &verticies() { return _verticies; }
+ const Common::Array<TeVector3f32> &verticies() const { return _verticies; }
private:
Common::Array<TeVector3f32> _verticies;
unsigned long _lastTriangleHit;
diff --git a/engines/tetraedge/te/te_ray_intersection.cpp b/engines/tetraedge/te/te_ray_intersection.cpp
new file mode 100644
index 00000000000..fa1d6080a29
--- /dev/null
+++ b/engines/tetraedge/te/te_ray_intersection.cpp
@@ -0,0 +1,76 @@
+/* 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 "tetraedge/te/te_ray_intersection.h"
+
+namespace Tetraedge {
+
+namespace TeRayIntersection {
+
+TePickMesh *getMesh(const TeVector3f32 ¶m_1, const TeVector3f32 ¶m_2, const Common::Array<TePickMesh *> &pickMeshes,
+ float param_4, float param_5, TeVector3f32 *param_6) {
+ error("TODO: implement TeRayIntersection::getMesh");
+}
+
+int intersect(const TeVector3f32 &v1, const TeVector3f32 &v2, const TeVector3f32 &v3,
+ const TeVector3f32 &v4, const TeVector3f32 &v5, TeVector3f32 &vout, float &fout) {
+ const TeVector3f32 v4_v3 = (v4 - v3);
+ const TeVector3f32 v5_v3 = (v5 - v3);
+ TeVector3f32 v = v4_v3 ^ v5_v3;
+
+ if (v == TeVector3f32(0.0f, 0.0f, 0.0f))
+ return -1;
+
+ int result = -1;
+ float f1 = v.dotProduct(v1 - v3);
+ float f2 = v.dotProduct(v2);
+ if (fabs(f2) > 1e-9) {
+ f2 = -f1 / f2;
+ fout = f2;
+ if (f2 >= 0.0) {
+ vout = v1 + (v2 * f2);
+ float dot1 = v4_v3.dotProduct(v4_v3);
+ float dot2 = v4_v3.dotProduct(v5_v3);
+ float dot3 = v5_v3.dotProduct(v5_v3);
+ const TeVector3f32 vout_v3 = vout - v3;
+ float dots1 = (dot2 * dot2) - (dot1 * dot3);
+ float dot4 = vout_v3.dotProduct(v4_v3);
+ float dot5 = vout_v3.dotProduct(v5_v3);
+ float dots2 = ((dot2 * dot5) - (dot3 * dot4)) / dots1;
+ if (dots2 >= 0.0) {
+ result = 0;
+ if (dots2 <= 1.0) {
+ float dots3 = (dot2 * dot4 - dot1 * dot5) / dots1;
+ if (dots3 >= 0 && dots2 + dots3 <= 1.0)
+ result = 1;
+ }
+ }
+ }
+ }
+ return result;
+}
+
+
+}
+
+
+
+} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_fee_move_zone.h b/engines/tetraedge/te/te_ray_intersection.h
similarity index 59%
rename from engines/tetraedge/te/te_fee_move_zone.h
rename to engines/tetraedge/te/te_ray_intersection.h
index 30d0e642958..d4f4f19c329 100644
--- a/engines/tetraedge/te/te_fee_move_zone.h
+++ b/engines/tetraedge/te/te_ray_intersection.h
@@ -19,22 +19,26 @@
*
*/
-#ifndef TETRAEDGE_TE_TE_FEE_MOVE_ZONE_H
-#define TETRAEDGE_TE_TE_FEE_MOVE_ZONE_H
+#ifndef TETRAEDGE_TE_TE_RAY_INTERSECTION_H
+#define TETRAEDGE_TE_TE_RAY_INTERSECTION_H
+
+#include "common/array.h"
+#include "tetraedge/te/te_vector3f32.h"
namespace Tetraedge {
-class TeFeeMoveZone {
-public:
- TeFeeMoveZone();
+class TePickMesh;
+
+namespace TeRayIntersection {
- // TODO add public members
+TePickMesh *getMesh(const TeVector3f32 ¶m_1, const TeVector3f32 ¶m_2, const Common::Array<TePickMesh *> &pickMeshes,
+ float param_4, float param_5, TeVector3f32 *param_6);
-private:
- // TODO add private members
+int intersect(const TeVector3f32 &v1, const TeVector3f32 &v2, const TeVector3f32 &v3,
+ const TeVector3f32 &v4, const TeVector3f32 &v5, TeVector3f32 &vout, float &fout);
-};
+} // end namespace TeRayIntersection
} // end namespace Tetraedge
-#endif // TETRAEDGE_TE_TE_FEE_MOVE_ZONE_H
+#endif // TETRAEDGE_TE_TE_RAY_INTERSECTION_H
diff --git a/engines/tetraedge/te/te_renderer.cpp b/engines/tetraedge/te/te_renderer.cpp
index e49b9c6aebb..6250e74b634 100644
--- a/engines/tetraedge/te/te_renderer.cpp
+++ b/engines/tetraedge/te/te_renderer.cpp
@@ -455,10 +455,10 @@ void TeRenderer::renderTransparentMeshes() {
}
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
if (meshProperties._scissorEnabled) {
- glDisable(GL_SCISSOR_TEST);
+ glDisable(GL_SCISSOR_TEST);
}
if (texture) {
- glDisable(GL_TEXTURE_2D);
+ glDisable(GL_TEXTURE_2D);
_textureEnabled = false;
}
glPopMatrix();
diff --git a/engines/tetraedge/te/te_scene.cpp b/engines/tetraedge/te/te_scene.cpp
index bfe9396c04d..3df69b9b559 100644
--- a/engines/tetraedge/te/te_scene.cpp
+++ b/engines/tetraedge/te/te_scene.cpp
@@ -90,10 +90,13 @@ void TeScene::setCurrentCamera(const Common::String &name) {
}
}
if (i == n) {
- //warning("TeScene::setCurrentCamera: Couldn't find camera %s", name.c_str());
+ debug("TeScene::setCurrentCamera: Couldn't find camera %s", name.c_str());
return;
}
_currentCameraIndex = i;
+ TeCamera *c = _cameras[i].get();
+ assert(c);
+ debug("TeScene::setCurrentCamera: Set %s", c->name().c_str());
}
void TeScene::update() {
diff --git a/engines/tetraedge/te/te_scene.h b/engines/tetraedge/te/te_scene.h
index f01e5bace6e..4302a16c81f 100644
--- a/engines/tetraedge/te/te_scene.h
+++ b/engines/tetraedge/te/te_scene.h
@@ -57,9 +57,11 @@ public:
void update();
- Common::Array<TeIntrusivePtr<TeCamera>> &cameras() { return _cameras; }
Common::Array<TeIntrusivePtr<TeModel>> &models() { return _models; }
+protected:
+ Common::Array<TeIntrusivePtr<TeCamera>> &cameras() { return _cameras; }
+
private:
uint _currentCameraIndex;
Common::Array<TeIntrusivePtr<TeCamera>> _cameras;
diff --git a/engines/tetraedge/te/te_scrolling_layout.cpp b/engines/tetraedge/te/te_scrolling_layout.cpp
index 0e9317c4300..d4e3b334a22 100644
--- a/engines/tetraedge/te/te_scrolling_layout.cpp
+++ b/engines/tetraedge/te/te_scrolling_layout.cpp
@@ -33,7 +33,7 @@ void TeScrollingLayout::setContentLayout(TeLayout *layout) {
_contentLayout = layout;
if (layout) {
_contentLayoutUserPos = layout->userPosition();
- // TODO: original seems to call addChildBefore(layout this) which doesn't make sense?
+ // TODO: original seems to call addChildBefore(layout, this) which doesn't make sense?
addChild(_contentLayout);
}
}
diff --git a/engines/tetraedge/te/te_sprite_layout.h b/engines/tetraedge/te/te_sprite_layout.h
index ffac3e577b6..4784cabb8e2 100644
--- a/engines/tetraedge/te/te_sprite_layout.h
+++ b/engines/tetraedge/te/te_sprite_layout.h
@@ -66,8 +66,6 @@ private:
bool _sizeSet;
bool _allowFloatTranslate;
- // TODO add private members
-
};
} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_text_layout.h b/engines/tetraedge/te/te_text_layout.h
index 7aa5ddd2c55..d889f0d8d63 100644
--- a/engines/tetraedge/te/te_text_layout.h
+++ b/engines/tetraedge/te/te_text_layout.h
@@ -58,7 +58,6 @@ private:
int _baseFontSize;
TeTextBase2 _base;
- // TODO add private members
};
diff --git a/engines/tetraedge/te/te_tiled_surface.h b/engines/tetraedge/te/te_tiled_surface.h
index e7e9b8e4455..e081f5c1df9 100644
--- a/engines/tetraedge/te/te_tiled_surface.h
+++ b/engines/tetraedge/te/te_tiled_surface.h
@@ -103,8 +103,6 @@ private:
Common::Path _path;
- // TODO add private members
-
};
} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_timer.h b/engines/tetraedge/te/te_timer.h
index 6d1d972e999..fa7962516ee 100644
--- a/engines/tetraedge/te/te_timer.h
+++ b/engines/tetraedge/te/te_timer.h
@@ -50,7 +50,7 @@ public:
static void resumeAll();
static void updateAll();
- bool _stopped;
+ bool running() const { return !_stopped; }
private:
static TeRealTimer *realTimer();
@@ -62,6 +62,7 @@ private:
bool _pausable;
bool _alarmSet;
bool _updated;
+ bool _stopped;
TeSignal0Param _alarmSignal;
diff --git a/engines/tetraedge/te/te_vector2s32.cpp b/engines/tetraedge/te/te_vector2s32.cpp
index db80dae6bf6..2541e265f41 100644
--- a/engines/tetraedge/te/te_vector2s32.cpp
+++ b/engines/tetraedge/te/te_vector2s32.cpp
@@ -19,6 +19,8 @@
*
*/
+#include "common/stream.h"
+
#include "tetraedge/te/te_vector2s32.h"
namespace Tetraedge {
@@ -26,6 +28,10 @@ namespace Tetraedge {
TeVector2s32::TeVector2s32() : _x(0), _y(0) {
}
-// TODO: Add more functions here.
+/*static*/
+void TeVector2s32::deserialize(Common::ReadStream &stream, TeVector2s32 &dest) {
+ dest._x = stream.readSint32LE();
+ dest._y = stream.readSint32LE();
+}
} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_vector2s32.h b/engines/tetraedge/te/te_vector2s32.h
index db6fd56dc6f..ecaa6e05e08 100644
--- a/engines/tetraedge/te/te_vector2s32.h
+++ b/engines/tetraedge/te/te_vector2s32.h
@@ -23,6 +23,7 @@
#define TETRAEDGE_TE_TE_VECTOR2S32_H
#include "common/rect.h"
+#include "common/stream.h"
namespace Tetraedge {
@@ -45,6 +46,8 @@ public:
return *this;
}
+ static void deserialize(Common::ReadStream &stream, TeVector2s32 &dest);
+
public:
int _x;
int _y;
diff --git a/engines/tetraedge/te/te_vector3f32.cpp b/engines/tetraedge/te/te_vector3f32.cpp
index ee7b2f62bf7..07baa317294 100644
--- a/engines/tetraedge/te/te_vector3f32.cpp
+++ b/engines/tetraedge/te/te_vector3f32.cpp
@@ -42,5 +42,20 @@ void TeVector3f32::rotate(const TeQuaternion &rot) {
matrix.transform(this, false);
}
+TeVector3f32 operator^(const TeVector3f32 &left, const TeVector3f32 &right) {
+ TeVector3f32 retval;
+ float rx = right.x();
+ float ry = right.y();
+ float rz = right.z();
+ float lx = left.x();
+ float ly = left.y();
+ float lz = left.z();
+ retval.x() = ly * rz - lz * ry;
+ retval.y() = lz * rx - rz * lx;
+ retval.z() = ry * lx - ly * rx;
+ return retval;
+}
+
+
} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_vector3f32.h b/engines/tetraedge/te/te_vector3f32.h
index e6070b91310..668328aa7aa 100644
--- a/engines/tetraedge/te/te_vector3f32.h
+++ b/engines/tetraedge/te/te_vector3f32.h
@@ -72,12 +72,14 @@ public:
bool parse(const Common::String &val);
Common::String dump() const {
- return Common::String::format("TeVector3f32(%.02f %.02f %.02f)", x(), y(), z());
+ return Common::String::format("TeVec3f32(%.02f %.02f %.02f)", x(), y(), z());
}
void rotate(const TeQuaternion &rot);
};
+TeVector3f32 operator^(const TeVector3f32 &left, const TeVector3f32 &right);
+
} // end namespace Tetraedge
#endif // TETRAEDGE_TE_TE_VECTOR3F32_H
diff --git a/engines/tetraedge/te/te_visual_fade.cpp b/engines/tetraedge/te/te_visual_fade.cpp
index 3c085d84001..4773118de7f 100644
--- a/engines/tetraedge/te/te_visual_fade.cpp
+++ b/engines/tetraedge/te/te_visual_fade.cpp
@@ -30,24 +30,47 @@ TeVisualFade::TeVisualFade() {
}
void TeVisualFade::animateBlackFade() {
- error("TODO: Implement TeVisualFade::animateBlackFade.");
+ _fadeCaptureSprite.setVisible(false);
+ _fadeCurveAnim.stop();
+ _fadeCurveAnim._startVal = TeColor(255, 255, 255, 0);
+ _fadeCurveAnim._endVal = TeColor(255, 255, 255, 255);
+ Common::Array<float> curve;
+ curve.push_back(0.0);
+ curve.push_back(0.0);
+ curve.push_back(1.0);
+ curve.push_back(1.0);
+ curve.push_back(1.0);
+ _fadeCurveAnim.setCurve(curve);
+ _fadeCurveAnim._duration = 2000.0;
+ _fadeCurveAnim._callbackObj = &_fadeCaptureSprite;
+ _fadeCurveAnim._callbackMethod = &Te3DObject2::setColor;
+ _fadeCurveAnim.play();
+
+ _blackFadeSprite.setVisible(true);
+ _blackFadeCurveAnim.stop();
+ _blackFadeCurveAnim._startVal = TeColor(255, 255, 255, 255);
+ _blackFadeCurveAnim._endVal = TeColor(255, 255, 255, 0);
+ _blackFadeCurveAnim.setCurve(curve);
+ _blackFadeCurveAnim._duration = 2000.0;
+ _blackFadeCurveAnim._callbackObj = &_blackFadeSprite;
+ _blackFadeCurveAnim._callbackMethod = &Te3DObject2::setColor;
+ _blackFadeCurveAnim.play();
}
void TeVisualFade::animateFade() {
- //debug("visual fade %p animate", this);
- _animateFadeCurveAnim.stop();
- _animateFadeCurveAnim._runTimer.pausable(false);
+ _fadeCurveAnim.stop();
+ _fadeCurveAnim._runTimer.pausable(false);
_fadeCaptureSprite.setVisible(true);
- _animateFadeCurveAnim._startVal = TeColor(255, 255, 255, 255);
- _animateFadeCurveAnim._endVal = TeColor(255, 255, 255, 0);
+ _fadeCurveAnim._startVal = TeColor(255, 255, 255, 255);
+ _fadeCurveAnim._endVal = TeColor(255, 255, 255, 0);
Common::Array<float> curve;
curve.push_back(0.0);
curve.push_back(1.0);
- _animateFadeCurveAnim.setCurve(curve);
- _animateFadeCurveAnim._duration = 400.0;
- _animateFadeCurveAnim._callbackObj = &_fadeCaptureSprite;
- _animateFadeCurveAnim._callbackMethod = &Te3DObject2::setColor;
- _animateFadeCurveAnim.play();
+ _fadeCurveAnim.setCurve(curve);
+ _fadeCurveAnim._duration = 400.0;
+ _fadeCurveAnim._callbackObj = &_fadeCaptureSprite;
+ _fadeCurveAnim._callbackMethod = &Te3DObject2::setColor;
+ _fadeCurveAnim.play();
}
void TeVisualFade::captureFrame() {
diff --git a/engines/tetraedge/te/te_visual_fade.h b/engines/tetraedge/te/te_visual_fade.h
index 389cb7de304..307c2d95983 100644
--- a/engines/tetraedge/te/te_visual_fade.h
+++ b/engines/tetraedge/te/te_visual_fade.h
@@ -45,14 +45,17 @@ public:
TeSpriteLayout _blackFadeSprite;
TeButtonLayout _buttonLayout;
- bool fading() const { return !_animateFadeCurveAnim._runTimer._stopped; }
+ bool fading() const { return _fadeCurveAnim._runTimer.running(); }
+ bool blackFading() const { return _blackFadeCurveAnim._runTimer.running(); }
+
+ TeCurveAnim2<Te3DObject2, TeColor> blackFadeCurveAnim() { return _blackFadeCurveAnim; }
private:
TeIntrusivePtr<Te3DTexture> _texturePtr;
- TeCurveAnim2<Te3DObject2, TeColor> _animateFadeCurveAnim;
+ TeCurveAnim2<Te3DObject2, TeColor> _fadeCurveAnim;
+ TeCurveAnim2<Te3DObject2, TeColor> _blackFadeCurveAnim;
TeImage _image;
- // TODO add private members
};
diff --git a/engines/tetraedge/te/te_xml_gui.h b/engines/tetraedge/te/te_xml_gui.h
index 7e119f5bbd3..e187bab5fdc 100644
--- a/engines/tetraedge/te/te_xml_gui.h
+++ b/engines/tetraedge/te/te_xml_gui.h
@@ -37,11 +37,8 @@ public:
void load(const Common::Path &path);
- // TODO add public members
-
private:
Common::StringMap _map;
- // TODO add private members
};
Commit: 1d62d47edba2495673f3c79769635b1230fe35e6
https://github.com/scummvm/scummvm/commit/1d62d47edba2495673f3c79769635b1230fe35e6
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2023-01-16T17:36:43+01:00
Commit Message:
TETRAEDGE: More WIP. Can now see Kate in first scene.
Changed paths:
A engines/tetraedge/te/te_images_sequence.cpp
A engines/tetraedge/te/te_images_sequence.h
engines/tetraedge/game/application.cpp
engines/tetraedge/game/application.h
engines/tetraedge/game/billboard.h
engines/tetraedge/game/character.cpp
engines/tetraedge/game/character.h
engines/tetraedge/game/characters_shadow.cpp
engines/tetraedge/game/confirm.cpp
engines/tetraedge/game/game.cpp
engines/tetraedge/game/game.h
engines/tetraedge/game/in_game_scene.cpp
engines/tetraedge/game/in_game_scene.h
engines/tetraedge/game/inventory.cpp
engines/tetraedge/game/inventory_object.cpp
engines/tetraedge/game/inventory_object.h
engines/tetraedge/game/lua_binds.cpp
engines/tetraedge/game/main_menu.cpp
engines/tetraedge/game/object3d.cpp
engines/tetraedge/game/object3d.h
engines/tetraedge/game/objectif.cpp
engines/tetraedge/game/objectif.h
engines/tetraedge/game/owner_error_menu.cpp
engines/tetraedge/game/splash_screens.cpp
engines/tetraedge/module.mk
engines/tetraedge/te/te_camera.h
engines/tetraedge/te/te_core.cpp
engines/tetraedge/te/te_frame_anim.cpp
engines/tetraedge/te/te_frame_anim.h
engines/tetraedge/te/te_free_move_zone.cpp
engines/tetraedge/te/te_free_move_zone.h
engines/tetraedge/te/te_i_codec.h
engines/tetraedge/te/te_lua_script.cpp
engines/tetraedge/te/te_lua_thread.cpp
engines/tetraedge/te/te_mesh.cpp
engines/tetraedge/te/te_model.cpp
engines/tetraedge/te/te_model.h
engines/tetraedge/te/te_pick_mesh2.cpp
engines/tetraedge/te/te_pick_mesh2.h
engines/tetraedge/te/te_quaternion.cpp
engines/tetraedge/te/te_quaternion.h
engines/tetraedge/te/te_scene.cpp
engines/tetraedge/te/te_scene.h
engines/tetraedge/te/te_scummvm_codec.h
engines/tetraedge/te/te_sound_manager.cpp
engines/tetraedge/te/te_sound_manager.h
engines/tetraedge/te/te_theora.cpp
engines/tetraedge/te/te_theora.h
engines/tetraedge/te/te_tiled_surface.h
engines/tetraedge/te/te_timer.cpp
engines/tetraedge/te/te_timer.h
engines/tetraedge/te/te_xml_gui.cpp
diff --git a/engines/tetraedge/game/application.cpp b/engines/tetraedge/game/application.cpp
index b985b63e921..174870ef10f 100644
--- a/engines/tetraedge/game/application.cpp
+++ b/engines/tetraedge/game/application.cpp
@@ -19,6 +19,7 @@
*
*/
+#include "common/config-manager.h"
#include "common/textconsole.h"
#include "common/file.h"
#include "common/util.h"
@@ -43,7 +44,8 @@ namespace Tetraedge {
bool Application::_dontUpdateWhenApplicationPaused = false;
Application::Application() : _finishedGame(false), _finishedFremium(false),
-_captureFade(false), _difficulty(1), _created(false), _tutoActivated(false) {
+_captureFade(false), _difficulty(1), _created(false), _tutoActivated(false),
+_drawShadows(true) {
TeCore *core = g_engine->getCore();
core->_coreNotReady = true;
core->fileFlagSystemSetFlag("platform", "MacOSX");
@@ -271,6 +273,8 @@ void Application::create() {
onMainWindowSizeChanged();
_splashScreens.enter();
+
+ _drawShadows = (ConfMan.get("disable_shadows") != "true");
_created = true;
}
@@ -386,7 +390,7 @@ void Application::performRender() {
Game *game = g_engine->getGame();
TeRenderer *renderer = g_engine->getRenderer();
- if (game->running() && game->scene()._character
+ if (_drawShadows && game->running() && game->scene()._character
&& game->scene()._shadowLightNo != -1
&& game->scene()._charactersShadow != nullptr) {
renderer->shadowMode(TeRenderer::ShadowMode1);
@@ -399,7 +403,7 @@ void Application::performRender() {
renderer->renderTransparentMeshes();
renderer->clearBuffer(GL_ACCUM);
if (game->running()) {
- if (game->scene()._character
+ if (_drawShadows && game->scene()._character
&& game->scene()._shadowLightNo != -1
&& game->scene()._charactersShadow != nullptr) {
TeIntrusivePtr<TeCamera> currentCamera = game->scene().currentCamera();
@@ -417,7 +421,6 @@ void Application::performRender() {
renderer->clearBuffer(GL_ACCUM);
drawFront();
renderer->renderTransparentMeshes();
- // What gets called here??
game->scene().drawPath();
g_system->updateScreen();
}
diff --git a/engines/tetraedge/game/application.h b/engines/tetraedge/game/application.h
index 707642cba43..d5a43e8c21e 100644
--- a/engines/tetraedge/game/application.h
+++ b/engines/tetraedge/game/application.h
@@ -149,6 +149,7 @@ private:
bool _captureFade;
bool _created;
bool _tutoActivated;
+ bool _drawShadows;
int _difficulty;
diff --git a/engines/tetraedge/game/billboard.h b/engines/tetraedge/game/billboard.h
index 4fc376fac99..3860294c713 100644
--- a/engines/tetraedge/game/billboard.h
+++ b/engines/tetraedge/game/billboard.h
@@ -43,6 +43,8 @@ public:
void position2(const TeVector3f32 &pos);
void size(const TeVector2f32 &size);
+ TeIntrusivePtr<TeModel> &model() { return _model; }
+
private:
TeIntrusivePtr<TeModel> _model;
TeVector3f32 _pos;
diff --git a/engines/tetraedge/game/character.cpp b/engines/tetraedge/game/character.cpp
index 9aabbf0220c..e231c0c32f9 100644
--- a/engines/tetraedge/game/character.cpp
+++ b/engines/tetraedge/game/character.cpp
@@ -55,7 +55,8 @@ void Character::WalkSettings::clear() {
}
Character::Character() : _curveOffset(0), _lastFrame(-1), _callbacksChanged(false),
-_missingCurrentAnim(false), _someRepeatFlag(false), _walkModeStr("Walk"), _needsSomeUpdate(false),
+_missingCurrentAnim(false), _someRepeatFlag(false), _walkModeStr("Walk"),
+_needsSomeUpdate(false), _positionFlag(false),
_stepSound1("sounds/SFX/PAS_H_BOIS1.ogg"), _stepSound2("sounds/SFX/PAS_H_BOIS2.ogg"),
_freeMoveZone(nullptr), _animSoundOffset(0), _lastAnimFrame(0), _charLookingAt(nullptr) {
_curModelAnim.setDeleteFn(&TeModelAnimation::deleteLater);
@@ -235,9 +236,10 @@ int Character::rightStepFrame(enum Character::WalkPart walkpart) {
return -1;
}
-bool Character::loadModel(const Common::String &name, bool param_2) {
+bool Character::loadModel(const Common::String &name, bool unused) {
assert(_globalCharacterSettings);
if (_model) {
+ //TODO
//_model->bonesUpdateSignal().remove(this, &Character::onBonesUpdate);
}
_model = new TeModel();
@@ -257,14 +259,16 @@ bool Character::loadModel(const Common::String &name, bool param_2) {
_model->setName(name);
_model->setScale(_characterSettings._defaultScale);
- for (unsigned int i = 0; i < _model->_meshes.size(); i++)
- _model->_meshes[i].setVisible(true);
+ for (auto &mesh : _model->_meshes)
+ mesh.setVisible(true);
_model->setVisibleByName("_B_", false);
_model->setVisibleByName("_Y_", false);
+ // Note: game loops through "faces" here, but it only ever uses the default ones.
_model->setVisibleByName(_characterSettings._defaultEyes, true);
_model->setVisibleByName(_characterSettings._defaultMouth, true);
+ _model->setVisibleByName(_characterSettings._defaultBody, true);
setAnimation(_characterSettings._walkFileName, true, false, false, -1, 9999);
@@ -304,12 +308,12 @@ bool Character::loadModel(const Common::String &name, bool param_2) {
Common::File xmlFile;
if (!xmlFile.open(path))
error("Character::loadSettings: Can't open %s", path.c_str());
- const uint32 bufsize = xmlFile.size();
+ const int64 bufsize = xmlFile.size();
char *buf = new char[bufsize+1];
buf[bufsize] = '\0';
xmlFile.read(buf, bufsize);
Common::String fixedbuf(buf);
- uint32 offset = fixedbuf.find("------------");
+ size_t offset = fixedbuf.find("------------");
while (offset != Common::String::npos) {
fixedbuf.replace(offset, 12, "--");
offset = fixedbuf.find("------------");
@@ -318,9 +322,9 @@ bool Character::loadModel(const Common::String &name, bool param_2) {
// Big HACK: Remove the embedded comment in this config.
offset = fixedbuf.find("<!--<walk>");
if (offset != Common::String::npos) {
- uint32 endOffset = fixedbuf.find(" -->", offset);
+ size_t endOffset = fixedbuf.find(" -->", offset);
if (endOffset != Common::String::npos) {
- uint32 realEndOffset = fixedbuf.find("walk>-->", endOffset);
+ size_t realEndOffset = fixedbuf.find("walk>-->", endOffset);
if (realEndOffset != Common::String::npos && realEndOffset > endOffset) {
fixedbuf.replace(offset, endOffset - offset, "<!-- ");
}
@@ -455,11 +459,14 @@ void Character::updateAnimFrame() {
if (_model->anim()) {
_lastAnimFrame = _model->anim()->curFrame2();
}
- error("TODO: Implement Character::updateAnimFrame");
}
void Character::updatePosition(float curveOffset) {
- error("TODO: Implement Character::updatePosition");
+ if (!_curve->controlPoints().empty()) {
+ //TeVector3f32 pt = _curve->retrievePoint(curveOffset);
+ // add field 0x214
+ error("TODO: Implement Character::updatePosition");
+ }
}
Common::String Character::walkAnim(Character::WalkPart part) {
diff --git a/engines/tetraedge/game/character.h b/engines/tetraedge/game/character.h
index d71aa86c60a..9e13e8b89c7 100644
--- a/engines/tetraedge/game/character.h
+++ b/engines/tetraedge/game/character.h
@@ -154,9 +154,13 @@ public:
const Common::String &curAnimName() const { return _curAnimName; }
TeFreeMoveZone *freeMoveZone() { return _freeMoveZone; }
const Common::String &freeMoveZoneName() const { return _freeMoveZoneName; }
+ void setFreeMoveZoneName(const Common::String &val) { _freeMoveZoneName = val; }
bool needsSomeUpdate() const { return _needsSomeUpdate; }
void setNeedsSomeUpdate(bool val) { _needsSomeUpdate = val; }
void setCharLookingAt(Character *other) { _charLookingAt = other; }
+ void setPositionCharacter(const TeVector3f32 &val) { _positionCharacter = val; }
+ bool positionFlag() const { return _positionFlag; }
+ void setPositionFlag(bool val) { _positionFlag = val; }
private:
float _curveOffset;
@@ -190,6 +194,9 @@ private:
bool _someRepeatFlag; // TODO: what is this?
bool _callbacksChanged;
bool _needsSomeUpdate; // TODO: what is this? Field 0x85.
+ bool _positionFlag;
+
+ TeVector3f32 _positionCharacter;
// TODO: work out how these are different
Common::String _setAnimName;
diff --git a/engines/tetraedge/game/characters_shadow.cpp b/engines/tetraedge/game/characters_shadow.cpp
index 92951817947..19025678183 100644
--- a/engines/tetraedge/game/characters_shadow.cpp
+++ b/engines/tetraedge/game/characters_shadow.cpp
@@ -75,7 +75,6 @@ void CharactersShadow::createTexture(InGameScene *scene) {
glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
for (Character *character : scene->_characters) {
character->_model->draw();
}
@@ -154,7 +153,7 @@ void CharactersShadow::draw(InGameScene *scene) {
glEnable(GL_BLEND);
renderer->setCurrentColor(scene->shadowColor());
- for (TeIntrusivePtr<TeModel> model : scene->models()) {
+ for (TeIntrusivePtr<TeModel> model : scene->zoneModels()) {
if (model->_meshes.size() > 0 && model->_meshes[0].materials().empty()) {
model->_meshes[0].defaultMaterial(TeIntrusivePtr<Te3DTexture>());
model->_meshes[0].materials()[0]._enableSomethingDefault0 = true;
diff --git a/engines/tetraedge/game/confirm.cpp b/engines/tetraedge/game/confirm.cpp
index 5ba7cbeec5c..b27d994b0c3 100644
--- a/engines/tetraedge/game/confirm.cpp
+++ b/engines/tetraedge/game/confirm.cpp
@@ -19,6 +19,8 @@
*
*/
+#include "common/config-manager.h"
+
#include "tetraedge/game/confirm.h"
#include "tetraedge/game/application.h"
#include "tetraedge/tetraedge.h"
@@ -89,6 +91,10 @@ void Confirm::enter(const Common::String &guiPath, const Common::String &y) {
// Make sure the mouse cursor is back on top.
app->_frontOrientationLayout.removeChild(&app->mouseCursorLayout());
app->_frontOrientationLayout.addChild(&app->mouseCursorLayout());
+
+ if (ConfMan.get("skip_confirm") == "true") {
+ onButtonYes();
+ }
}
void Confirm::leave() {
diff --git a/engines/tetraedge/game/game.cpp b/engines/tetraedge/game/game.cpp
index 69a40880ee9..6bfc12cc8c4 100644
--- a/engines/tetraedge/game/game.cpp
+++ b/engines/tetraedge/game/game.cpp
@@ -23,6 +23,7 @@
#include "common/path.h"
#include "common/str-array.h"
#include "common/system.h"
+#include "common/config-manager.h"
#include "tetraedge/tetraedge.h"
#include "tetraedge/game/application.h"
@@ -37,7 +38,9 @@
#include "tetraedge/te/te_core.h"
#include "tetraedge/te/te_input_mgr.h"
#include "tetraedge/te/te_ray_intersection.h"
+#include "tetraedge/te/te_sound_manager.h"
#include "tetraedge/te/te_variant.h"
+#include "tetraedge/te/te_lua_thread.h"
namespace Tetraedge {
@@ -62,31 +65,26 @@ bool Game::addAnimToSet(const Common::String &anim) {
// Get path to lua script, eg scenes/ValVoralberg/14040/Set14040.lua
const Common::Path animPath(Common::String("scenes/") + anim + "/");
- bool retval = false;
if (Common::File::exists(animPath)) {
Common::StringArray parts = TetraedgeEngine::splitString(anim, '/');
assert(parts.size() >= 2);
- Common::String layoutName = parts[1];
- Common::String path = Common::String("scenes/") + parts[0] + "/" + parts[1] + "/Set" + parts[1];
+ const Common::String layoutName = parts[1];
+ const Common::String path = Common::String("scenes/") + parts[0] + "/" + parts[1] + "/Set" + parts[1];
_gui2.load(path + ".lua");
- /*
- TeILayout *layout = _gui2.layout("root");
- TeSpriteLayout *spriteLayout2 = findSpriteLayoutByName(layout, layoutName);
-
- TeLayout *layout2 = TeLuaGUI::layout(&(this->scene).field_0x170,"root");
- long lVar5 = 0;
- if (spriteLayout2) {
- lVar5 = (long)plVar3 + *(long *)(*plVar3 + -0x198);
- }
- (**(code **)(*(long *)((long)&pTVar2->vptr + (long)pTVar2->vptr[-0x33]) + 0x30))
- ((long)&pTVar2->vptr + (long)pTVar2->vptr[-0x33],lVar5);
- */
- retval = true;
+
+ // Note: game makes this here, but never uses it..
+ // it seems like a random memory leak??
+ // TeSpriteLayout *spritelayout = new TeSpriteLayout();
+
+ TeSpriteLayout *spritelayout = findSpriteLayoutByName(_gui2.layoutChecked("root"), layoutName);
+
+ _scene.bgGui().layoutChecked("root")->addChild(spritelayout);
+ return true;
}
- return retval;
+ return false;
}
void Game::addArtworkUnlocked(const Common::String &name, bool notify) {
@@ -108,7 +106,7 @@ void Game::addNoScale2Children() {
if (!_noScaleLayout2)
return;
- TeLayout *vidbtn = _gui4.layout("videoButtonLayout");
+ TeLayout *vidbtn = _inGameGui.layout("videoButtonLayout");
if (vidbtn)
_noScaleLayout2->addChild(vidbtn);
@@ -124,7 +122,7 @@ void Game::addNoScale2Children() {
void Game::addNoScaleChildren() {
if (!_noScaleLayout)
return;
- TeLayout *inGame = _gui4.layout("inGame");
+ TeLayout *inGame = _inGameGui.layout("inGame");
if (inGame)
_noScaleLayout->addChild(inGame);
@@ -309,7 +307,7 @@ void Game::enter(bool newgame) {
_luaContext.setGlobal("BUTTON_RS_LEFT", 0x800000);
_luaContext.setGlobal("BUTTON_RS_RIGHT", 0x1000000);
- _luaScript.attachToContext(&_luaContext);
+ _gameEnterScript.attachToContext(&_luaContext);
if (!_objectif.gui1().loaded()) {
_objectif.load();
@@ -373,7 +371,9 @@ void Game::finishGame() {
}
void Game::initLoadedBackupData() {
+ bool warpFlag = true;
if (!_loadName.empty()) {
+ warpFlag = false;
error("TODO: Implemet Game::initLoadedBackupData loading part");
}
Application *app = g_engine->getApplication();
@@ -391,7 +391,7 @@ void Game::initLoadedBackupData() {
_gameLoadState = 0;
app->showLoadingIcon(false);
_loadName.clear();
- initScene(true, firstWarpPath);
+ initScene(warpFlag, firstWarpPath);
}
void Game::initNoScale() {
@@ -423,12 +423,12 @@ void Game::initScene(bool fade, const Common::String &scenePath) {
bool Game::initWarp(const Common::String &zone, const Common::String &scene, bool fadeFlag) {
debug("Game::initWarp(%s, %s, %s)", zone.c_str(), scene.c_str(), fadeFlag ? "true" : "false");
_inventoryMenu.unload();
- _gui4.unload();
+ _inGameGui.unload();
_movePlayerCharacterDisabled = false;
_sceneCharacterVisibleFromLoad = true;
if (_scene._character) {
- _scene._character->_model->setVisible(false);
+ _scene._character->_model->setVisible(true);
_scene._character->deleteAllCallback();
_scene._character->stop();
_scene._character->setAnimation(_scene._character->characterSettings()._walkFileName, true, false, false, -1, 9999);
@@ -472,6 +472,7 @@ bool Game::initWarp(const Common::String &zone, const Common::String &scene, boo
_luaContext.addBindings(LuaBinds::LuaOpenBinds);
_luaScript.attachToContext(&_luaContext);
_luaScript.load("menus/help/help.lua");
+ _luaScript.execute();
_luaScript.load(logicLuaPath);
}
@@ -516,25 +517,25 @@ bool Game::initWarp(const Common::String &zone, const Common::String &scene, boo
}
_inventoryMenu.load();
- _gui4.load("InGame.lua");
+ _inGameGui.load("InGame.lua");
- TeButtonLayout *skipbtn = _gui4.buttonLayout("skipVideoButton");
+ TeButtonLayout *skipbtn = _inGameGui.buttonLayout("skipVideoButton");
skipbtn->setVisible(false);
skipbtn->onMouseClickValidated().remove(this, &Game::onSkipVideoButtonValidated);
skipbtn->onMouseClickValidated().add(this, &Game::onSkipVideoButtonValidated);
- TeButtonLayout *vidbgbtn = _gui4.buttonLayout("videoBackgroundButton");
+ TeButtonLayout *vidbgbtn = _inGameGui.buttonLayout("videoBackgroundButton");
vidbgbtn->setVisible(false);
/* TODO: Restore the original behavior here (onLockVideoButtonValidated) */
vidbgbtn->onMouseClickValidated().remove(this, &Game::onSkipVideoButtonValidated);
vidbgbtn->onMouseClickValidated().add(this, &Game::onSkipVideoButtonValidated);
- TeSpriteLayout *video = _gui4.spriteLayout("video");
+ TeSpriteLayout *video = _inGameGui.spriteLayout("video");
video->setVisible(false);
video->_tiledSurfacePtr->_frameAnim.onFinished().remove(this, &Game::onVideoFinished);
video->_tiledSurfacePtr->_frameAnim.onFinished().add(this, &Game::onVideoFinished);
- TeButtonLayout *invbtn = _gui4.buttonLayout("inventoryButton");
+ TeButtonLayout *invbtn = _inGameGui.buttonLayout("inventoryButton");
invbtn->setSizeType(TeILayout::RELATIVE_TO_PARENT); // TODO: Double-check if this is the right virt fn.
invbtn->onMouseClickValidated().remove(this, &Game::onInventoryButtonValidated);
invbtn->onMouseClickValidated().add(this, &Game::onInventoryButtonValidated);
@@ -546,7 +547,7 @@ bool Game::initWarp(const Common::String &zone, const Common::String &scene, boo
invbtn->setSize(TeVector3f32(0.08, (4.0 / ((winSize.y() / winSize.x()) * 4.0)) * 0.08, 0.0));
}
- TeCheckboxLayout *markersCheckbox = _gui4.checkboxLayout("markersVisibleButton");
+ TeCheckboxLayout *markersCheckbox = _inGameGui.checkboxLayout("markersVisibleButton");
markersCheckbox->setVisible(!_markersVisible);
markersCheckbox->onStateChangedSignal().add(this, &Game::onMarkersVisible);
@@ -554,7 +555,7 @@ bool Game::initWarp(const Common::String &zone, const Common::String &scene, boo
removeNoScale2Children();
app->_frontLayout.removeChild(_noScaleLayout2);
- TeLayout *vidLayout = _gui4.layout("videoLayout");
+ TeLayout *vidLayout = _inGameGui.layout("videoLayout");
app->_frontLayout.removeChild(vidLayout);
removeNoScaleChildren();
app->_frontLayout.removeChild(_noScaleLayout);
@@ -627,15 +628,15 @@ bool Game::isDocumentOpened() {
}
bool Game::isMoviePlaying() {
- TeButtonLayout *vidButton = _gui4.buttonLayout("videoBackgroundButton");
+ TeButtonLayout *vidButton = _inGameGui.buttonLayout("videoBackgroundButton");
if (vidButton)
return vidButton->visible();
return false;
}
-bool Game::launchDialog(const Common::String ¶m_1, uint param_2, const Common::String &charname,
+bool Game::launchDialog(const Common::String &dname, uint param_2, const Common::String &charname,
const Common::String &animfile, float param_5) {
- error("TODO: Implemet Game::launchDialog %s %d %s %s %f", param_1.c_str(),
+ error("TODO: Implemet Game::launchDialog %s %d %s %s %f", dname.c_str(),
param_2, charname.c_str(), animfile.c_str(), param_5);
}
@@ -673,11 +674,11 @@ void Game::leave(bool flag) {
_luaContext.destroy();
_running = false;
- _gui4.buttonLayoutChecked("skipVideoButton")->onMouseClickValidated().remove(this, &Game::onSkipVideoButtonValidated);
- _gui4.buttonLayoutChecked("videoBackgroundButton")->onMouseClickValidated().remove(this, &Game::onLockVideoButtonValidated);
- _gui4.spriteLayoutChecked("video")->_tiledSurfacePtr->_frameAnim.onFinished().remove(this, &Game::onSkipVideoButtonValidated);
- _gui4.buttonLayoutChecked("inventoryButton")->onMouseClickValidated().remove(this, &Game::onInventoryButtonValidated);
- _gui4.unload();
+ _inGameGui.buttonLayoutChecked("skipVideoButton")->onMouseClickValidated().remove(this, &Game::onSkipVideoButtonValidated);
+ _inGameGui.buttonLayoutChecked("videoBackgroundButton")->onMouseClickValidated().remove(this, &Game::onLockVideoButtonValidated);
+ _inGameGui.spriteLayoutChecked("video")->_tiledSurfacePtr->_frameAnim.onFinished().remove(this, &Game::onSkipVideoButtonValidated);
+ _inGameGui.buttonLayoutChecked("inventoryButton")->onMouseClickValidated().remove(this, &Game::onInventoryButtonValidated);
+ _inGameGui.unload();
_playedTimer.stop();
Application *app = g_engine->getApplication();
@@ -695,9 +696,8 @@ bool Game::loadCharacter(const Common::String &name) {
bool result = true;
Character *character = _scene.character(name);
if (!character) {
- result = false;
- bool loaded = _scene.loadCharacter(name);
- if (loaded) {
+ result = _scene.loadCharacter(name);
+ if (result) {
character = _scene.character(name);
character->_onCharacterAnimFinishedSignal.remove<Game>(this, &Game::onCharacterAnimationFinished);
character->_onCharacterAnimFinishedSignal.add<Game>(this, &Game::onCharacterAnimationFinished);
@@ -719,8 +719,8 @@ bool Game::loadPlayerCharacter(const Common::String &name) {
}
bool Game::loadScene(const Common::String &name) {
- _luaScript.load("scenes/OnGameEnter.lua");
- _luaScript.execute();
+ _gameEnterScript.load("scenes/OnGameEnter.lua");
+ _gameEnterScript.execute();
Character *character = _scene._character;
if (character && character->_model->visible()) {
_sceneCharacterVisibleFromLoad = true;
@@ -739,6 +739,9 @@ bool Game::onCallNumber(Common::String val) {
}
bool Game::onCharacterAnimationFinished(const Common::String &val) {
+ if (!_scene._character)
+ return false;
+
error("TODO: Implemet Game::onCharacterAnimationFinished %s", val.c_str());
}
@@ -747,11 +750,54 @@ bool Game::onCharacterAnimationPlayerFinished(const Common::String &val) {
}
bool Game::onDialogFinished(const Common::String &val) {
- error("TODO: Implemet Game::onDialogFinished %s", val.c_str());
+ for (unsigned int i = 0; i < _yieldedCallbacks.size(); i++) {
+ YieldedCallback &cb = _yieldedCallbacks[i];
+ if (cb._luaFnName == "OnDialogFinished" && cb._luaParam == val) {
+ TeLuaThread *lua = cb._luaThread;
+ _yieldedCallbacks.remove_at(i);
+ if (lua) {
+ lua->resume();
+ return false;
+ }
+ break;
+ }
+ }
+
+ _luaScript.execute("OnDialogFinished", val);
+ _luaScript.execute("OnCellDialogFinished", val);
+ return false;
}
bool Game::onDisplacementFinished() {
- error("TODO: Implemet Game::onDisplacementFinished");
+ _sceneCharacterVisibleFromLoad = true;
+ _scene._character->stop();
+ _scene._character->setAnimation(_scene._character->characterSettings()._walkFileName, true, false, false, -1, 9999);
+
+ // TODO: Twiddle flags 0x424b and 0x4249
+ /*
+ if (!_field_0x424b) {
+ _field_0x4249 = false;
+ } else {
+ _field_0x424b = false;
+ _field_0x4249 = true;
+ }*/
+
+ TeLuaThread *thread = nullptr;
+
+ for (unsigned int i = 0; i < _yieldedCallbacks.size(); i++) {
+ YieldedCallback &cb = _yieldedCallbacks[i];
+ if (cb._luaFnName == "OnDisplacementFinished") {
+ thread = cb._luaThread;
+ _yieldedCallbacks.remove_at(i);
+ break;
+ }
+ }
+ if (thread) {
+ thread->resume();
+ } else {
+ _luaScript.execute("OnDisplacementFinished");
+ }
+ return false;
}
bool Game::onFinishedCheckBackup(bool result) {
@@ -785,7 +831,7 @@ bool Game::onInventoryButtonValidated() {
}
bool Game::onLockVideoButtonValidated() {
- TeButtonLayout *btn = _gui4.buttonLayoutChecked("skipVideoButton");
+ TeButtonLayout *btn = _inGameGui.buttonLayoutChecked("skipVideoButton");
btn->setVisible(!btn->visible());
return true;
}
@@ -884,10 +930,10 @@ bool Game::onMouseClick(const Common::Point &pt) {
if (app->isLockCursor() || _movePlayerCharacterDisabled)
return false;
-
+
Character *character = _scene._character;
const Common::String &charAnim = character->curAnimName();
-
+
if (charAnim == character->characterSettings()._walkFileName
|| charAnim == character->walkAnim(Character::WalkPart_Start)
|| charAnim == character->walkAnim(Character::WalkPart_Loop)
@@ -935,7 +981,7 @@ bool Game::onMouseClick(const Common::Point &pt) {
// TODO: Set app field field_0x910b
_posPlayer = lastPoint;
}
-
+
if (!_sceneCharacterVisibleFromLoad || (character->curAnimName() == character->characterSettings()._walkFileName)) {
_lastCharMoveMousePos = TeVector2s32(0, 0);
_movePlayerCharacterDisabled = true;
@@ -1041,48 +1087,61 @@ bool Game::onMouseMove() {
}
bool Game::onSkipVideoButtonValidated() {
- TeSpriteLayout *sprite = _gui4.spriteLayoutChecked("video");
- TeButtonLayout *btn = _gui4.buttonLayoutChecked("videoBackgroundButton");
+ TeSpriteLayout *sprite = _inGameGui.spriteLayoutChecked("video");
+ TeButtonLayout *btn = _inGameGui.buttonLayoutChecked("videoBackgroundButton");
sprite->stop();
btn->setVisible(false);
return false;
}
bool Game::onVideoFinished() {
- if (!_gui4.loaded())
+ if (!_inGameGui.loaded())
return false;
Application *app = g_engine->getApplication();
app->captureFade();
- TeSpriteLayout *video = _gui4.spriteLayoutChecked("video");
- TeButtonLayout *btn = _gui4.buttonLayoutChecked("videoBackgroundButton");
+ TeSpriteLayout *video = _inGameGui.spriteLayoutChecked("video");
+ Common::String vidPath = video->_tiledSurfacePtr->path().toString();
+ TeButtonLayout *btn = _inGameGui.buttonLayoutChecked("videoBackgroundButton");
btn->setVisible(false);
- btn = _gui4.buttonLayoutChecked("skipVideoButton");
+ btn = _inGameGui.buttonLayoutChecked("skipVideoButton");
btn->setVisible(false);
video->setVisible(false);
_music.stop();
_running = true;
- warning("TODO: Game::onVideoFinished: update yieldedCallbacks %s", video->_tiledSurfacePtr->path().toString().c_str());
- _luaScript.execute("OnMovieFinished", video->_tiledSurfacePtr->path().toString());
+ bool resumed = false;
+ for (unsigned int i = 0; i < _yieldedCallbacks.size(); i++) {
+ YieldedCallback &cb = _yieldedCallbacks[i];
+ if (cb._luaFnName == "OnMovieFinished" && cb._luaParam == vidPath) {
+ TeLuaThread *lua = cb._luaThread;
+ _yieldedCallbacks.remove_at(i);
+ resumed = true;
+ if (lua)
+ lua->resume();
+ break;
+ }
+ }
+ if (!resumed)
+ _luaScript.execute("OnMovieFinished", vidPath);
app->fade();
return false;
}
void Game::pauseMovie() {
_music.pause();
- TeSpriteLayout *sprite = _gui4.spriteLayoutChecked("video");
+ TeSpriteLayout *sprite = _inGameGui.spriteLayoutChecked("video");
sprite->pause();
}
void Game::playMovie(const Common::String &vidPath, const Common::String &musicPath) {
Application *app = g_engine->getApplication();
app->captureFade();
- TeButtonLayout *videoBackgroundButton = _gui4.buttonLayoutChecked("videoBackgroundButton");
+ TeButtonLayout *videoBackgroundButton = _inGameGui.buttonLayoutChecked("videoBackgroundButton");
videoBackgroundButton->setVisible(true);
- TeButtonLayout *skipVideoButton = _gui4.buttonLayoutChecked("skipVideoButton");
+ TeButtonLayout *skipVideoButton = _inGameGui.buttonLayoutChecked("skipVideoButton");
skipVideoButton->setVisible(false);
TeMusic &music = app->music();
@@ -1094,15 +1153,17 @@ void Game::playMovie(const Common::String &vidPath, const Common::String &musicP
_running = false;
- TeSpriteLayout *videoSpriteLayout = _gui4.spriteLayoutChecked("video");
+ TeSpriteLayout *videoSpriteLayout = _inGameGui.spriteLayoutChecked("video");
videoSpriteLayout->load(vidPath);
videoSpriteLayout->setVisible(true);
music.play();
videoSpriteLayout->play();
// FIXME TODO!! Stop the movie and soundearly for testing.
- videoSpriteLayout->_tiledSurfacePtr->_frameAnim._nbFrames = 10;
- music.stop();
+ if (ConfMan.get("skip_videos") == "true") {
+ videoSpriteLayout->_tiledSurfacePtr->_frameAnim._nbFrames = 10;
+ music.stop();
+ }
app->fade();
}
@@ -1112,11 +1173,11 @@ void Game::playRandomSound(const Common::String &name) {
warning("Game::playRandomSound: can't find sound list %s", name.c_str());
return;
}
- error("TODO: Implemet Game::playRandomSound");
+ warning("TODO: Implemet Game::playRandomSound");
}
void Game::playSound(const Common::String &name, int param_2, float param_3) {
- error("TODO: Implemet Game::playSound");
+ warning("TODO: Implemet Game::playSound");
}
void Game::removeNoScale2Child(TeLayout *layout) {
@@ -1129,7 +1190,7 @@ void Game::removeNoScale2Children() {
if (!_noScaleLayout2)
return;
- TeLayout *vidbtn = _gui4.layout("videoButtonLayout");
+ TeLayout *vidbtn = _inGameGui.layout("videoButtonLayout");
if (vidbtn)
_noScaleLayout2->removeChild(vidbtn);
@@ -1164,19 +1225,19 @@ void Game::resetPreviousMousePos() {
void Game::resumeMovie() {
_music.play();
- _gui4.spriteLayout("video")->play();
+ _inGameGui.spriteLayout("video")->play();
}
void Game::saveBackup(const Common::String &saveName) {
- error("TODO: Implemet me");
+ warning("TODO: Implemet Game::saveBackup %s", saveName.c_str());
}
-void Game::setBackground(const Common::String &name) {
- _scene.changeBackground(name);
+bool Game::setBackground(const Common::String &name) {
+ return _scene.changeBackground(name);
}
void Game::setCurrentObjectSprite(const Common::String &spritePath) {
- TeSpriteLayout *currentSprite = _gui4.spriteLayout("currentObjectSprite");
+ TeSpriteLayout *currentSprite = _inGameGui.spriteLayout("currentObjectSprite");
if (currentSprite) {
if (!spritePath.empty()) {
currentSprite->unload();
@@ -1187,15 +1248,35 @@ void Game::setCurrentObjectSprite(const Common::String &spritePath) {
}
bool Game::showMarkers(bool val) {
- error("TODO: Implemet me");
+ TeLayout *bg = _gui3.layoutChecked("background");
+ for (unsigned int i = 0; i < bg->childCount(); i++) {
+ const InGameScene::TeMarker *marker = _scene.findMarker(bg->child(i)->name());
+ if (marker)
+ bg->child(i)->setVisible(!val);
+ }
+ return false;
}
-bool Game::startAnimation(const Common::String &animName, int param_2, bool param_3) {
- error("TODO: Implemet me");
+bool Game::startAnimation(const Common::String &animName, int loopcount, bool reversed) {
+ TeSpriteLayout *layout = _scene.bgGui().spriteLayout(animName);
+ if (layout) {
+ layout->_tiledSurfacePtr->_frameAnim._loopCount = loopcount;
+ layout->_tiledSurfacePtr->_frameAnim._reversed = reversed;
+ layout->_tiledSurfacePtr->play();
+ }
+ return layout != nullptr;
}
void Game::stopSound(const Common::String &name) {
- error("TODO: Implemet me");
+ for (unsigned int i = 0; i < _gameSounds.size(); i++) {
+ GameSound *sound = _gameSounds[i];
+ if (sound->getAccessName() == name) {
+ sound->stop();
+ sound->deleteLater();
+ }
+ _gameSounds.remove_at(i);
+ }
+ g_engine->getSoundManager()->stopFreeSound(name);
}
bool Game::unloadCharacter(const Common::String &charname) {
@@ -1234,7 +1315,7 @@ void Game::update() {
if (!_entered)
return;
- TeTextLayout *debugTimeTextLayout = _gui4.textLayout("debugTimeText1");
+ TeTextLayout *debugTimeTextLayout = _inGameGui.textLayout("debugTimeText1");
if (debugTimeTextLayout) {
warning("TODO: Game::update: Fill out debugTimeTextLayout");
}
@@ -1254,7 +1335,7 @@ void Game::update() {
app->_lockCursorButton.setVisible(false);
}
- TeButtonLayout *invbtn = _gui4.buttonLayout("inventoryButton");
+ TeButtonLayout *invbtn = _inGameGui.buttonLayout("inventoryButton");
if (invbtn)
invbtn->setVisible(!app->isLockCursor() && !_dialog2.isDialogPlaying());
else
@@ -1305,7 +1386,7 @@ void Game::update() {
}
if (_saveRequested) {
_saveRequested = false;
- error("TODO: Game::update: Save game");
+ saveBackup("save.xml");
}
_luaScript.execute("Update");
diff --git a/engines/tetraedge/game/game.h b/engines/tetraedge/game/game.h
index c7bf5dca547..f383f899f3a 100644
--- a/engines/tetraedge/game/game.h
+++ b/engines/tetraedge/game/game.h
@@ -41,6 +41,8 @@
namespace Tetraedge {
+class TeLuaThread;
+
class Game {
public:
Game();
@@ -67,6 +69,13 @@ public:
byte onSoundFinished();
};
+ struct YieldedCallback {
+ TeLuaThread *_luaThread;
+ Common::String _luaParam;
+ Common::String _luaFnName;
+ // Note: original game has more String, long, and int fields.. seem unused.
+ };
+
//enum EGameScoreID {}; // Not needed?
bool addAnimToSet(const Common::String &path);
@@ -89,8 +98,8 @@ public:
void draw();
void enter(bool newgame);
// Note: game uses ILayouts here..
- static TeI3DObject2 *findLayoutByName(TeLayout *layout, const Common::String &name);
- static TeSpriteLayout *findSpriteLayoutByName(TeLayout *layout, const Common::String &name);
+ static TeI3DObject2 *findLayoutByName(TeLayout *parent, const Common::String &name);
+ static TeSpriteLayout *findSpriteLayoutByName(TeLayout *parent, const Common::String &name);
void finishFreemium();
void finishGame();
@@ -138,10 +147,10 @@ public:
void resumeMovie();
void resumeSounds() {}; // does nothing?
void saveBackup(const Common::String &saveName);
- void setBackground(const Common::String &name);
+ bool setBackground(const Common::String &name);
void setCurrentObjectSprite(const Common::String &spritePath);
bool showMarkers(bool val);
- bool startAnimation(const Common::String &animName, int param_2, bool param_3);
+ bool startAnimation(const Common::String &animName, int loopcount, bool reversed);
void startAnimationPart(const Common::String ¶m_1, int param_2, int param_3, int param_4, bool param_5) {};
void stopSound(const Common::String &name);
bool unloadCharacter(const Common::String &character);
@@ -167,6 +176,11 @@ public:
InGameScene &scene() { return _scene; }
Dialog2 &dialog2() { return _dialog2; }
Question2 &question2() { return _question2; }
+ TeLuaGUI &gui3() { return _gui3; }
+ Objectif &objectif() { return _objectif; }
+ Common::Array<YieldedCallback> yieldedCallbacks() { return _yieldedCallbacks; }
+ void setSaveRequested() { _saveRequested = true; }
+ bool markersVisible() const { return _markersVisible; }
private:
bool _luaShowOwnerError;
@@ -174,10 +188,10 @@ private:
bool _entered;
bool _enteredFlag2;
- TeLuaGUI _gui1;
+ TeLuaGUI _gui1; // TODO: get better names for these.
TeLuaGUI _gui2;
TeLuaGUI _gui3;
- TeLuaGUI _gui4;
+ TeLuaGUI _inGameGui;
Inventory _inventory;
InventoryMenu _inventoryMenu;
@@ -207,6 +221,8 @@ private:
Common::Array<GameSound *> _gameSounds;
Common::Array<HitObject *> _gameHitObjects;
+ // These are static in original, but cleaner to keep here.
+ Common::Array<YieldedCallback> _yieldedCallbacks;
Common::HashMap<Common::String, bool> _unlockedArtwork;
Common::HashMap<Common::String, Common::Array<RandomSound*>> _randomSounds;
@@ -217,6 +233,7 @@ private:
TeTimer _walkTimer;
TeLuaScript _luaScript;
TeLuaContext _luaContext;
+ TeLuaScript _gameEnterScript;
TeMusic _music;
Notifier _notifier;
DocumentsBrowser _documentsBrowser;
diff --git a/engines/tetraedge/game/in_game_scene.cpp b/engines/tetraedge/game/in_game_scene.cpp
index 2a89abd7afa..157ef41ff73 100644
--- a/engines/tetraedge/game/in_game_scene.cpp
+++ b/engines/tetraedge/game/in_game_scene.cpp
@@ -35,13 +35,19 @@
#include "tetraedge/te/te_bezier_curve.h"
#include "tetraedge/te/te_camera.h"
+#include "tetraedge/te/te_core.h"
#include "tetraedge/te/te_free_move_zone.h"
#include "tetraedge/te/te_light.h"
#include "tetraedge/te/te_renderer.h"
+#include "tetraedge/te/te_lua_script.h"
+#include "tetraedge/te/te_lua_thread.h"
namespace Tetraedge {
-InGameScene::InGameScene() : _character(nullptr), _charactersShadow(nullptr), _shadowLightNo(-1) {
+InGameScene::InGameScene() : _character(nullptr), _charactersShadow(nullptr),
+_shadowLightNo(-1), _waitTime(-1.0f), _shadowColor(0, 0, 0, 0x80), _shadowFov(20.0f),
+_shadowFarPlane(1000), _shadowNearPlane(1)
+ {
}
void InGameScene::activateAnchorZone(const Common::String &name, bool val) {
@@ -51,6 +57,253 @@ void InGameScene::activateAnchorZone(const Common::String &name, bool val) {
}
}
+void InGameScene::addAnchorZone(const Common::String &s1, const Common::String &name, float radius) {
+ for (AnchorZone *zone : _anchorZones) {
+ if (zone->_name == name) {
+ zone->_radius = radius;
+ return;
+ }
+ }
+ warning("TODO: Finish InGameScene::addAnchorZone");
+}
+
+bool InGameScene::addMarker(const Common::String &markerName, const Common::String &imgPath, float x, float y, const Common::String &locType, const Common::String &markerVal) {
+ const TeMarker *marker = findMarker(markerName);
+ if (!marker) {
+ Game *game = g_engine->getGame();
+ TeSpriteLayout *markerSprite = new TeSpriteLayout();
+ // Note: game checks paths here but seems to just use the original?
+ markerSprite->setName(markerName);
+ markerSprite->setAnchor(TeVector3f32(0.0f, 0.0f, 0.0f));
+ markerSprite->load(imgPath);
+ markerSprite->setSizeType(TeILayout::RELATIVE_TO_PARENT);
+ markerSprite->setPositionType(TeILayout::RELATIVE_TO_PARENT);
+ TeVector3f32 newSize;
+ if (locType == "PERCENT") {
+ Application *app = g_engine->getApplication();
+ TeVector3f32 frontLayoutSize = app->_frontLayout.userSize();
+ newSize.x() = frontLayoutSize.x() * (x / 100.0);
+ newSize.y() = frontLayoutSize.y() * (y / 100.0);
+ } else {
+ newSize.x() = x / 800.0;
+ newSize.y() = y / 600.0;
+ }
+ markerSprite->setSize(newSize);
+
+ float screenWidth = (float)g_engine->getDefaultScreenWidth();
+ float screenHeight = (float)g_engine->getDefaultScreenHeight();
+ if (g_engine->getCore()->fileFlagSystemFlag("definition") == "SD") {
+ markerSprite->setPosition(TeVector3f32(0.07, (4.0 / ((screenWidth / screenHeight) * 4.0)) * 0.04, 0.0));
+ } else {
+ markerSprite->setPosition(TeVector3f32(0.04, (4.0 / ((screenWidth / screenHeight) * 4.0)) * 0.04, 0.0));
+ }
+ markerSprite->setVisible(game->markersVisible());
+ markerSprite->_tiledSurfacePtr->_frameAnim._loopCount = -1;
+ markerSprite->play();
+
+ TeMarker newMarker;
+ newMarker._name = markerName;
+ newMarker._val = markerVal;
+ _markers.push_back(newMarker);
+ TeLayout *bg = game->gui3().layout("background");
+ if (bg)
+ bg->addChild(markerSprite);
+ _sprites.push_back(markerSprite);
+ } else {
+ setImagePathMarker(markerName, imgPath);
+ }
+ return true;
+}
+
+/*static*/
+float InGameScene::angularDistance(float a1, float a2) {
+ float result;
+
+ result = a2 - a1;
+ if (result >= -3.141593 && result > 3.141593) {
+ result = result + -6.283185;
+ } else {
+ result = result + 6.283185;
+ }
+ return result;
+}
+
+bool InGameScene::aroundAnchorZone(const AnchorZone *zone) {
+ if (!zone->_activated)
+ return false;
+ const TeVector3f32 charpos = _character->_model->position();
+
+ float xoff = charpos.x() - zone->_loc.x();
+ float zoff = charpos.z() - zone->_loc.z();
+ return sqrt(xoff * xoff + zoff * zoff) <= zone->_radius;
+}
+
+TeLayout *InGameScene::background() {
+ return _bgGui.layout("background");
+}
+
+Billboard *InGameScene::billboard(const Common::String &name) {
+ for (Billboard *billboard : _billboards) {
+ if (billboard->model()->name() == name)
+ return billboard;
+ }
+ return nullptr;
+}
+
+bool InGameScene::changeBackground(const Common::String &name) {
+ if (Common::File::exists(name)) {
+ _bgGui.spriteLayoutChecked("root")->load(name);
+ return true;
+ }
+ return false;
+}
+
+Character *InGameScene::character(const Common::String &name) {
+ if (_character->_model->name() == name)
+ return _character;
+
+ for (Character *c : _characters) {
+ if (c->_model->name() == name)
+ return c;
+ }
+
+ return nullptr;
+}
+
+void InGameScene::close() {
+ reset();
+ _loadedPath = "";
+ TeScene::close();
+ freeGeometry();
+ if (_character && _character->_model && !findKate()) {
+ models().push_back(_character->_model);
+ models().push_back(_character->_shadowModel[0]);
+ models().push_back(_character->_shadowModel[1]);
+ }
+ _objects.clear();
+ for (TeFreeMoveZone *zone : _freeMoveZones)
+ delete zone;
+ _freeMoveZones.clear();
+ _hitObjects.clear();
+ for (TePickMesh2 *mesh : _pickMeshes)
+ delete mesh;
+ _pickMeshes.clear();
+ _bezierCurves.clear();
+ _dummies.clear();
+ freeSceneObjects();
+}
+
+void InGameScene::convertPathToMesh(TeFreeMoveZone *zone) {
+ TeIntrusivePtr<TeModel> model = new TeModel();
+ model->_meshes.resize(1);
+ model->setName("shadowReceiving");
+ model->setPosition(zone->position());
+ model->setRotation(zone->rotation());
+ model->setScale(zone->scale());
+ unsigned long nverticies = zone->verticies().size();
+ model->_meshes[0].setConf(nverticies, nverticies, TeMesh::MeshMode_Triangles, 0, 0);
+ for (unsigned int i = 0; i < nverticies; i++) {
+ model->_meshes[0].setIndex(i, i);
+ model->_meshes[0].setVertex(i, zone->verticies()[i]);
+ model->_meshes[0].setNormal(i, TeVector3f32(0, 0, 1));
+ }
+ _zoneModels.push_back(model);
+}
+
+TeIntrusivePtr<TeBezierCurve> InGameScene::curve(const Common::String &curveName) {
+ for (TeIntrusivePtr<TeBezierCurve> &c : _bezierCurves) {
+ if (c->name() == curveName)
+ return c;
+ }
+ return TeIntrusivePtr<TeBezierCurve>();
+}
+
+void InGameScene::deleteAllCallback() {
+ warning("TODO: implement InGameScene::deleteAllCallback");
+}
+
+void InGameScene::deleteMarker(const Common::String &markerName) {
+ if (!isMarker(markerName))
+ return;
+
+ for (unsigned int i = 0; i < _markers.size(); i++) {
+ if (_markers[i]._name == markerName) {
+ _markers.remove_at(i);
+ break;
+ }
+ }
+
+ Game *game = g_engine->getGame();
+ TeLayout *bg = game->gui3().layout("background");
+ if (!bg)
+ return;
+ for (Te3DObject2 *child : bg->childList()) {
+ if (child->name() == markerName) {
+ bg->removeChild(child);
+ break;
+ }
+ }
+}
+
+void InGameScene::deserializeCam(Common::ReadStream &stream, TeIntrusivePtr<TeCamera> &cam) {
+ cam->_projectionMatrixType = 2;
+ cam->viewport(0, 0, _viewportSize.getX(), _viewportSize.getY());
+ // load name/position/rotation/scale
+ Te3DObject2::deserialize(stream, *cam);
+ cam->_fov = stream.readFloatLE();
+ cam->_somePerspectiveVal = stream.readFloatLE();
+ cam->_orthNearVal = stream.readFloatLE();
+ // Original loads the val then ignores it and sets 3000.
+ stream.readFloatLE();
+ cam->_orthFarVal = 3000.0;
+}
+
+void InGameScene::deserializeModel(Common::ReadStream &stream, TeIntrusivePtr<TeModel> &model, TePickMesh2 *pickmesh) {
+ TeVector3f32 vec;
+ TeVector2f32 vec2;
+ TeQuaternion rot;
+ TeColor col;
+ TeMesh mesh;
+
+ TeVector3f32::deserialize(stream, vec);
+ model->setPosition(vec);
+ pickmesh->setPosition(vec);
+ TeQuaternion::deserialize(stream, rot);
+ model->setRotation(rot);
+ pickmesh->setRotation(rot);
+ TeVector3f32::deserialize(stream, vec);
+ model->setScale(vec);
+ pickmesh->setScale(vec);
+ uint32 indexcount = stream.readUint32LE();
+ uint32 vertexcount = stream.readUint32LE();
+
+ mesh.setConf(vertexcount, indexcount, TeMesh::MeshMode_Triangles, 0, 0);
+ for (unsigned int i = 0; i < indexcount; i++)
+ mesh.setIndex(i, stream.readUint32LE());
+ for (unsigned int i = 0; i < vertexcount; i++) {
+ TeVector3f32::deserialize(stream, vec);
+ mesh.setVertex(i, vec);
+ }
+ for (unsigned int i = 0; i < vertexcount; i++) {
+ TeVector3f32::deserialize(stream, vec);
+ mesh.setNormal(i, vec);
+ }
+ for (unsigned int i = 0; i < vertexcount; i++) {
+ TeVector2f32::deserialize(stream, vec2);
+ mesh.setTextureUV(i, vec2);
+ }
+ for (unsigned int i = 0; i < vertexcount; i++) {
+ col.deserialize(stream);
+ mesh.setColor(i, col);
+ }
+ pickmesh->setNbTriangles(indexcount / 3);
+ for (unsigned int i = 0; i < indexcount; i++) {
+ vec = mesh.vertex(mesh.index(i));
+ pickmesh->verticies().push_back(vec);
+ }
+ model->addMesh(mesh);
+}
+
void InGameScene::draw() {
TeScene::draw();
@@ -78,49 +331,59 @@ void InGameScene::drawPath() {
g_engine->getRenderer()->enableZBuffer();
}
-
-bool InGameScene::changeBackground(const Common::String &name) {
- if (Common::File::exists(name)) {
- _bgGui.spriteLayoutChecked("root")->load(name);
- return true;
+InGameScene::Dummy InGameScene::dummy(const Common::String &name) {
+ for (const Dummy &dummy : _dummies) {
+ if (dummy._name == name)
+ return dummy;
}
- return false;
+ return Dummy();
}
-/*static*/
-float InGameScene::angularDistance(float a1, float a2) {
- float result;
-
- result = a2 - a1;
- if (result >= -3.141593 && result > 3.141593) {
- result = result + -6.283185;
- } else {
- result = result + 6.283185;
+bool InGameScene::findKate() {
+ for (auto &m : models()) {
+ if (m->name() == "Kate")
+ return true;
}
- return result;
+ return false;
}
-TeLayout *InGameScene::background() {
- return _bgGui.layout("background");
+const InGameScene::TeMarker *InGameScene::findMarker(const Common::String &name) {
+ for (const TeMarker &marker : _markers) {
+ if (marker._name == name)
+ return ▮
+ }
+ return nullptr;
}
-void InGameScene::close() {
- reset();
- error("TODO: Implement InGameScene::close");
+const InGameScene::TeMarker *InGameScene::findMarkerByInt(const Common::String &val) {
+ for (const TeMarker &marker : _markers) {
+ if (marker._val == val)
+ return ▮
+ }
+ return nullptr;
}
-void InGameScene::reset() {
- if (_character)
- _character->setFreeMoveZone(nullptr);
- freeSceneObjects();
- _bgGui.unload();
- unloadSpriteLayouts();
- _markerGui.unload();
- _hitObjectGui.unload();
+InGameScene::SoundStep InGameScene::findSoundStep(const Common::String &name) {
+ for (const auto &step : _soundSteps) {
+ if (step._key == name)
+ return step._value;
+ }
+ return SoundStep();
}
-void InGameScene::deleteAllCallback() {
- warning("TODO: implement InGameScene::deleteAllCallback");
+void InGameScene::freeGeometry() {
+ _loadedPath.set("");
+ for (TeFreeMoveZone *zone : _freeMoveZones)
+ delete zone;
+ _freeMoveZones.clear();
+ _bezierCurves.clear();
+ _dummies.clear();
+ cameras().clear();
+ _zoneModels.clear();
+ if (_charactersShadow) {
+ delete _charactersShadow;
+ _charactersShadow = nullptr;
+ }
}
void InGameScene::freeSceneObjects() {
@@ -161,15 +424,48 @@ void InGameScene::freeSceneObjects() {
_anchorZones.clear();
}
-void InGameScene::unloadSpriteLayouts() {
- for (auto *animobj : _animObjects) {
- delete animobj;
+float InGameScene::getHeadHorizontalRotation(Character *cter, const TeVector3f32 &vec) {
+ //TeVector3f32 pos = cter->_model->position() - vec;
+ error("TODO: Implement InGameScene::getHeadHorizontalRotation");
+}
+
+float InGameScene::getHeadVerticalRotation(Character *cter, const TeVector3f32 &vec) {
+ //TeVector3f32 pos = cter->_model->position() - vec;
+ error("TODO: Implement InGameScene::getHeadVerticalRotation");
+}
+
+Common::String InGameScene::imagePathMarker(const Common::String &name) {
+ if (!isMarker(name))
+ return Common::String();
+ Game *game = g_engine->getGame();
+ TeLayout *bg = game->gui3().layoutChecked("background");
+ for (Te3DObject2 *child : bg->childList()) {
+ TeSpriteLayout *spritelayout = dynamic_cast<TeSpriteLayout *>(child);
+ if (spritelayout && spritelayout->name() == name) {
+ return spritelayout->_tiledSurfacePtr->path().toString();
+ }
}
- _animObjects.clear();
+ return Common::String();
}
-Character *InGameScene::character(const Common::String &name) {
- error("TODO: Implement InGameScene::character");
+void InGameScene::initScroll() {
+ _someScrollVector = TeVector2f32(0.5f, 0.0f);
+}
+
+bool InGameScene::isMarker(const Common::String &name) {
+ for (const TeMarker &marker : _markers) {
+ if (marker._name == name)
+ return true;
+ }
+ return false;
+}
+
+bool InGameScene::isObjectBlocking(const Common::String &name) {
+ for (const Common::String &b: _blockingObjects) {
+ if (name == b)
+ return true;
+ }
+ return false;
}
bool InGameScene::load(const Common::Path &path) {
@@ -262,7 +558,8 @@ bool InGameScene::load(const Common::Path &path) {
for (unsigned int i = 0; i < nfreemovezones; i++) {
TeFreeMoveZone *zone = new TeFreeMoveZone();
TeFreeMoveZone::deserialize(scenefile, *zone, &_blockers, &_rectBlockers, &_actZones);
-
+ _freeMoveZones.push_back(zone);
+ zone->setVisible(false);
}
uint32 ncurves = scenefile.readUint32LE();
@@ -298,20 +595,31 @@ bool InGameScene::load(const Common::Path &path) {
_charactersShadow = new CharactersShadow();
_charactersShadow->create(this);
onMainWindowSizeChanged();
- return true;
-}
-void InGameScene::convertPathToMesh(TeFreeMoveZone *zone) {
- error("TODO: Implement InGameScene::convertPathToMesh");
+ // FIXME: For some reason the game never re-adds kate's model to the list here..
+ // how does it ever get drawn???
+ if (!findKate()) {
+ models().push_back(_character->_model);
+ }
+
+ return true;
}
-void InGameScene::onMainWindowSizeChanged() {
- TeCamera *mainWinCam = g_engine->getApplication()->mainWindowCamera();
- _viewportSize = mainWinCam->viewportSize();
- Common::Array<TeIntrusivePtr<TeCamera>> &cams = cameras();
- for (unsigned int i = 0; i < cams.size(); i++) {
- cams[i]->viewport(0, 0, _viewportSize.getX(), _viewportSize.getY());
+bool InGameScene::loadCharacter(const Common::String &name) {
+ Character *c = character(name);
+ if (!c) {
+ c = new Character();
+ if (!c->loadModel(name, false)) {
+ delete c;
+ return false;
+ }
+ models().push_back(c->_model);
+ models().push_back(c->_shadowModel[0]);
+ models().push_back(c->_shadowModel[1]);
+ _characters.push_back(c);
}
+ c->_model->setVisible(true);
+ return true;
}
bool InGameScene::loadLights(const Common::Path &path) {
@@ -333,67 +641,35 @@ bool InGameScene::loadLights(const Common::Path &path) {
return true;
}
-bool InGameScene::loadCharacter(const Common::String &name) {
- error("TODO: Implement InGameScene::loadCharacter");
+void InGameScene::loadMarkers(const Common::Path &path) {
+ _markerGui.load(path);
+ TeLayout *bg = _bgGui.layoutChecked("background");
+ TeSpriteLayout *root = Game::findSpriteLayoutByName(bg, "root");
+ bg->setRatioMode(TeILayout::RATIO_MODE_NONE);
+ root->addChild(bg);
}
-void InGameScene::deserializeCam(Common::ReadStream &stream, TeIntrusivePtr<TeCamera> &cam) {
- cam->_projectionMatrixType = 2;
- cam->viewport(0, 0, _viewportSize.getX(), _viewportSize.getY());
- // load name/position/rotation/scale
- Te3DObject2::deserialize(stream, *cam);
- cam->_fov = stream.readFloatLE();
- cam->_somePerspectiveVal = stream.readFloatLE();
- cam->_orthNearVal = stream.readFloatLE();
- // Original loads the val then ignores it and sets 3000.
- stream.readFloatLE();
- cam->_orthFarVal = 3000.0;
+bool InGameScene::loadObject(const Common::String &name) {
+ Object3D *obj = object3D(name);
+ if (!obj) {
+ obj = new Object3D();
+ if (!obj->loadModel(name)) {
+ delete obj;
+ return false;
+ }
+ models().push_back(obj->model());
+ _object3Ds.push_back(obj);
+ }
+ obj->model()->setVisible(true);
+ return true;
}
-void InGameScene::deserializeModel(Common::ReadStream &stream, TeIntrusivePtr<TeModel> &model, TePickMesh2 *pickmesh) {
- TeVector3f32 vec;
- TeVector2f32 vec2;
- TeQuaternion rot;
- TeColor col;
- TeMesh mesh;
-
- TeVector3f32::deserialize(stream, vec);
- model->setPosition(vec);
- pickmesh->setPosition(vec);
- TeQuaternion::deserialize(stream, rot);
- model->setRotation(rot);
- pickmesh->setRotation(rot);
- TeVector3f32::deserialize(stream, vec);
- model->setScale(vec);
- pickmesh->setScale(vec);
- uint32 indexcount = stream.readUint32LE();
- uint32 vertexcount = stream.readUint32LE();
+void InGameScene::loadObjectMaterials(const Common::String &name) {
+ error("TODO: InGameScene::loadObjectMaterials");
+}
- mesh.setConf(vertexcount, indexcount, TeMesh::MeshMode_Triangles, 0, 0);
- for (unsigned int i = 0; i < indexcount; i++)
- mesh.setIndex(i, stream.readUint32LE());
- for (unsigned int i = 0; i < vertexcount; i++) {
- TeVector3f32::deserialize(stream, vec);
- mesh.setVertex(i, vec);
- }
- for (unsigned int i = 0; i < vertexcount; i++) {
- TeVector3f32::deserialize(stream, vec);
- mesh.setNormal(i, vec);
- }
- for (unsigned int i = 0; i < vertexcount; i++) {
- TeVector2f32::deserialize(stream, vec2);
- mesh.setTextureUV(i, vec2);
- }
- for (unsigned int i = 0; i < vertexcount; i++) {
- col.deserialize(stream);
- mesh.setColor(i, col);
- }
- pickmesh->setNbTriangles(indexcount / 3);
- for (unsigned int i = 0; i < indexcount; i++) {
- vec = mesh.vertex(mesh.index(i));
- pickmesh->verticies().push_back(vec);
- }
- model->addMesh(mesh);
+void InGameScene::loadObjectMaterials(const Common::String &path, const Common::String &name) {
+ error("TODO: InGameScene::loadObjectMaterials");
}
bool InGameScene::loadPlayerCharacter(const Common::String &name) {
@@ -407,10 +683,9 @@ bool InGameScene::loadPlayerCharacter(const Common::String &name) {
_playerCharacterModel = _character->_model;
if (!findKate()) {
- Common::Array<TeIntrusivePtr<TeModel>> &ms = models();
- ms.push_back(_character->_model);
- ms.push_back(_character->_shadowModel[0]);
- ms.push_back(_character->_shadowModel[1]);
+ models().push_back(_character->_model);
+ models().push_back(_character->_shadowModel[0]);
+ models().push_back(_character->_shadowModel[1]);
}
}
@@ -418,25 +693,6 @@ bool InGameScene::loadPlayerCharacter(const Common::String &name) {
return true;
}
-void InGameScene::unloadCharacter(const Common::String &name) {
- warning("TODO: Implement InGameScene::unloadCharacter %s", name.c_str());
-}
-
-bool InGameScene::findKate() {
- for (auto &m : models()) {
- if (m->name() == "Kate")
- return true;
- }
- return false;
-}
-
-TeLight *InGameScene::shadowLight() {
- if (_shadowLightNo == -1) {
- return nullptr;
- }
- return &_lights[_shadowLightNo];
-}
-
static Common::Path _sceneFileNameBase() {
Game *game = g_engine->getGame();
Common::Path retval("scenes");
@@ -517,6 +773,20 @@ void InGameScene::loadBackground(const Common::Path &path) {
}
}
+bool InGameScene::loadBillboard(const Common::String &name) {
+ Billboard *b = billboard(name);
+ if (b)
+ return true;
+ b = new Billboard();
+ if (b->load(name)) {
+ _billboards.push_back(b);
+ return true;
+ } else {
+ delete b;
+ return false;
+ }
+}
+
void InGameScene::loadInteractions(const Common::Path &path) {
_hitObjectGui.load(path);
TeLayout *bgbackground = _bgGui.layoutChecked("background");
@@ -530,92 +800,199 @@ void InGameScene::loadInteractions(const Common::Path &path) {
root->addChild(background);
}
-void InGameScene::setStep(const Common::String &scene, const Common::String &step1, const Common::String &step2) {
- SoundStep ss;
- ss._stepSound1 = step1;
- ss._stepSound2 = step2;
- _soundSteps[scene] = ss;
+void InGameScene::moveCharacterTo(const Common::String &charName, const Common::String &curveName, float curveOffset, float curveEnd) {
+ Character *c = character(charName);
+ if (c != nullptr && c != _character) {
+ Game *game = g_engine->getGame();
+ if (!game->_movePlayerCharacterDisabled) {
+ // TODO: c->field_0x214 = c->characterSettings()._cutSceneCurveDemiPosition;
+ TeIntrusivePtr<TeBezierCurve> crve = curve(curveName);
+ c->placeOnCurve(crve);
+ c->setCurveOffset(curveOffset);
+ const Common::String walkStartAnim = c->walkAnim(Character::WalkPart_Start);
+ if (walkStartAnim.empty()) {
+ c->setAnimation(c->walkAnim(Character::WalkPart_Loop), true, false, false, -1, 9999);
+ } else {
+ c->setAnimation(c->walkAnim(Character::WalkPart_Start), false, false, false, -1, 9999);
+ }
+ c->walkTo(curveEnd, false);
+ error("TODO: Finish InGameScene::moveCharacterTo");
+ }
+ }
}
-void InGameScene::initScroll() {
- _someScrollVector = TeVector2f32(0.5f, 0.0f);
+void InGameScene::onMainWindowSizeChanged() {
+ TeCamera *mainWinCam = g_engine->getApplication()->mainWindowCamera();
+ _viewportSize = mainWinCam->viewportSize();
+ Common::Array<TeIntrusivePtr<TeCamera>> &cams = cameras();
+ for (unsigned int i = 0; i < cams.size(); i++) {
+ cams[i]->viewport(0, 0, _viewportSize.getX(), _viewportSize.getY());
+ }
}
-bool InGameScene::isObjectBlocking(const Common::String &name) {
- for (const Common::String &b: _blockingObjects) {
- if (name == b)
- return true;
+Object3D *InGameScene::object3D(const Common::String &name) {
+ for (Object3D *obj : _object3Ds) {
+ if (obj->model()->name() == name)
+ return obj;
}
- return false;
+ return nullptr;
}
-void InGameScene::addMarker(const Common::String &name, const Common::String &imgPath, float x, float y, const Common::String &locType, const Common::String &markerVal) {
- error("TODO: Implement InGameScene::addMarker");
+TeFreeMoveZone *InGameScene::pathZone(const Common::String &name) {
+ for (TeFreeMoveZone *zone: _freeMoveZones) {
+ if (zone->name() == name)
+ return zone;
+ }
+ return nullptr;
}
-void InGameScene::setVisibleMarker(const Common::String &markerName, bool val) {
+void InGameScene::reset() {
+ if (_character)
+ _character->setFreeMoveZone(nullptr);
+ freeSceneObjects();
+ _bgGui.unload();
+ unloadSpriteLayouts();
+ _markerGui.unload();
+ _hitObjectGui.unload();
+}
+
+TeLight *InGameScene::shadowLight() {
+ if (_shadowLightNo == -1) {
+ return nullptr;
+ }
+ return &_lights[_shadowLightNo];
+}
+
+void InGameScene::setImagePathMarker(const Common::String &markerName, const Common::String &path) {
if (!isMarker(markerName))
return;
- error("TODO: Implement InGameScene::setVisibleMarker");
+ Game *game = g_engine->getGame();
+ TeLayout *bg = game->gui3().layoutChecked("background");
+
+ for (Te3DObject2 *child : bg->childList()) {
+ if (child->name() == markerName) {
+ TeSpriteLayout *sprite = dynamic_cast<TeSpriteLayout *>(child);
+ if (sprite) {
+ sprite->load(path);
+ sprite->_tiledSurfacePtr->_frameAnim._loopCount = -1;
+ sprite->play();
+ }
+ }
+ }
}
+void InGameScene::setPositionCharacter(const Common::String &charName, const Common::String &freeMoveZoneName, const TeVector3f32 &position) {
+ Character *c = character(charName);
+ if (!c) {
+ warning("[SetCharacterPosition] Character not found %s", charName.c_str());
+ } else if (c == _character && c->positionFlag()) {
+ c->setFreeMoveZoneName(freeMoveZoneName);
+ c->setPositionCharacter(position);
+ c->setPositionFlag(false);
+ c->setNeedsSomeUpdate(true);
+ } else {
+ c->stop();
+ TeFreeMoveZone *zone = pathZone(freeMoveZoneName);
+ if (!zone) {
+ warning("[SetCharacterPosition] PathZone not found %s", freeMoveZoneName.c_str());
+ for (TeFreeMoveZone *zone : _freeMoveZones)
+ warning("zone: %s", zone->name().c_str());
+ return;
+ }
+ TeIntrusivePtr<TeCamera> cam = currentCamera();
+ zone->setCamera(cam, false);
+ c->setFreeMoveZone(zone);
+ SoundStep step = findSoundStep(freeMoveZoneName);
+ c->setStepSound(step._stepSound1, step._stepSound2);
+ bool correctFlag = true;
+ const TeVector3f32 corrected = zone->correctCharacterPosition(position, &correctFlag, true);
+ c->_model->setPosition(corrected);
+ if (!correctFlag)
+ error("[SetCharacterPosition] Warning : The character is not above the ground %s", charName.c_str());
+ }
+}
-void InGameScene::deleteMarker(const Common::String &markerName) {
+void InGameScene::setStep(const Common::String &scene, const Common::String &step1, const Common::String &step2) {
+ SoundStep ss;
+ ss._stepSound1 = step1;
+ ss._stepSound2 = step2;
+ _soundSteps[scene] = ss;
+}
+
+void InGameScene::setVisibleMarker(const Common::String &markerName, bool val) {
if (!isMarker(markerName))
return;
- error("TODO: Implement InGameScene::deleteMarker");
+ error("TODO: Implement InGameScene::setVisibleMarker");
}
-
-bool InGameScene::isMarker(const Common::String &name) {
- for (const TeMarker *marker : _markers) {
- if (marker->_name == name)
- return true;
+void InGameScene::unloadCharacter(const Common::String &name) {
+ if (_character && _character->_model->name() == name) {
+ _character->removeAnim();
+ _character->deleteAnim();
+ _character->deleteAllCallback();
+ // TODO: deleteLater() something here..
+ _character = nullptr;
+ }
+ for (unsigned int i = 0; i < _characters.size(); i++) {
+ Character *c = _characters[i];
+ if (c && c->_model->name() == name) {
+ c->removeAnim();
+ c->deleteAnim();
+ c->deleteAllCallback();
+ // TODO: deleteLater() something here..
+ _characters.remove_at(i);
+ break;
+ }
}
- return false;
}
-TeFreeMoveZone *InGameScene::pathZone(const Common::String &name) {
- for (TeFreeMoveZone *zone: _freeMoveZones) {
- if (zone->name() == name)
- return zone;
+void InGameScene::unloadObject(const Common::String &name) {
+ error("TODO: InGameScene::unloadObject");
+}
+
+void InGameScene::unloadSpriteLayouts() {
+ for (auto *animobj : _animObjects) {
+ delete animobj;
}
- return nullptr;
+ _animObjects.clear();
}
-void InGameScene::moveCharacterTo(const Common::String &charName, const Common::String &curveName, float curveOffset, float curveEnd) {
- Character *c = character(charName);
- if (c != nullptr && c != _character) {
- Game *game = g_engine->getGame();
- if (!game->_movePlayerCharacterDisabled) {
- // TODO: c->field_0x214 = c->characterSettings()._cutSceneCurveDemiPosition;
- TeIntrusivePtr<TeBezierCurve> crve = curve(curveName);
- c->placeOnCurve(crve);
- c->setCurveOffset(curveOffset);
- const Common::String walkStartAnim = c->walkAnim(Character::WalkPart_Start);
- if (walkStartAnim.empty()) {
- c->setAnimation(c->walkAnim(Character::WalkPart_Loop), true, false, false, -1, 9999);
- } else {
- c->setAnimation(c->walkAnim(Character::WalkPart_Start), false, false, false, -1, 9999);
+void InGameScene::update() {
+ Game *game = g_engine->getGame();
+ if (_bgGui.loaded()) {
+ _bgGui.layoutChecked("background")->setZPosition(0.0f);
+ }
+ if (_character) {
+ // TODO: Do some stuff for character here.
+ }
+ for (Character *c : _characters) {
+ // TODO: Something with other characters.
+ }
+ // TODO: some other stuff with callbacks and spritelayouts here
+
+ TeScene::update();
+
+ float waitTime = _waitTimeTimer.timeFromLastTimeElapsed();
+ if (_waitTime != -1.0 && waitTime > _waitTime) {
+ bool resumed = false;
+ for (unsigned int i = 0; i < game->yieldedCallbacks().size(); i++) {
+ Game::YieldedCallback &yc = game->yieldedCallbacks()[i];
+ if (yc._luaFnName == "OnWaitFinished") {
+ TeLuaThread *thread = yc._luaThread;
+ game->yieldedCallbacks().remove_at(i);
+ thread->resume();
+ resumed = true;
}
- c->walkTo(curveEnd, false);
- error("TODO: Finish InGameScene::moveCharacterTo");
}
+ if (!resumed)
+ game->luaScript().execute("OnWaitFinished");
}
-}
-TeIntrusivePtr<TeBezierCurve> InGameScene::curve(const Common::String &curveName) {
- for (TeIntrusivePtr<TeBezierCurve> &c : _bezierCurves) {
- if (c->name() == curveName)
- return c;
+ for (Object3D *obj : _object3Ds) {
+ // TODO: something with object3ds
}
- return TeIntrusivePtr<TeBezierCurve>();
-}
-
-void InGameScene::setPositionCharacter(const Common::String &charName, const Common::String &freeMoveZoneName, const TeVector3f32 &position) {
- error("TODO: Implement InGameScene::setPositionCharacter");
}
diff --git a/engines/tetraedge/game/in_game_scene.h b/engines/tetraedge/game/in_game_scene.h
index e18559207c8..cc8dcf76f61 100644
--- a/engines/tetraedge/game/in_game_scene.h
+++ b/engines/tetraedge/game/in_game_scene.h
@@ -62,6 +62,8 @@ public:
struct AnchorZone {
Common::String _name;
bool _activated;
+ TeVector3f32 _loc;
+ float _radius;
};
struct Object {
@@ -82,64 +84,89 @@ public:
};
void activateAnchorZone(const Common::String &name, bool val);
- void addAnchorZone(const Common::String ¶m_1, const Common::String ¶m_2, float param_3);
+ void addAnchorZone(const Common::String &s1, const Common::String &name, float radius);
void addBlockingObject(const Common::String &obj) {
_blockingObjects.push_back(obj);
}
void addCallbackAnimation2D(const Common::String ¶m_1, const Common::String ¶m_2, float param_3);
- void addMarker(const Common::String &name, const Common::String &imgPath, float x, float y, const Common::String &locType, const Common::String &markerVal);
+ bool addMarker(const Common::String &name, const Common::String &imgPath, float x, float y, const Common::String &locType, const Common::String &markerVal);
static float angularDistance(float a1, float a2);
bool aroundAnchorZone(const AnchorZone *zone);
TeLayout *background();
- virtual bool load(const Common::Path &path) override;
- void loadBackground(const Common::Path &path);
- void loadInteractions(const Common::Path &path);
- void initScroll();
- bool isObjectBlocking(const Common::String &name);
- bool isMarker(const Common::String &name);
- TeFreeMoveZone *pathZone(const Common::String &name);
- void moveCharacterTo(const Common::String &charName, const Common::String &curveName, float curveOffset, float curveEnd);
- TeIntrusivePtr<TeBezierCurve> curve(const Common::String &curveName);
- void setPositionCharacter(const Common::String &charName, const Common::String &freeMoveZoneName, const TeVector3f32 &position);
- void setVisibleMarker(const Common::String &markerName, bool val);
- void deleteMarker(const Common::String &markerName);
-
- void draw();
- void drawPath();
- Character *character(const Common::String &name);
- bool loadCharacter(const Common::String &name);
- void loadBlockers();
- bool loadPlayerCharacter(const Common::String &name);
- bool loadLights(const Common::Path &path);
+ Billboard *billboard(const Common::String &name);
+ TeVector2f32 boundLayerSize();
bool changeBackground(const Common::String &name);
- void unloadCharacter(const Common::String &name);
-
+ Character *character(const Common::String &name);
+ virtual void close() override;
// Original has a typo, "converPathToMesh", corrected.
void convertPathToMesh(TeFreeMoveZone *zone);
- void onMainWindowSizeChanged();
-
+ TeIntrusivePtr<TeBezierCurve> curve(const Common::String &curveName);
+ void deleteAllCallback();
+ void deleteCallback(const Common::String &key, const Common::String &name, float f);
+ void deleteMarker(const Common::String &markerName);
// Original just calls these "deserialize" but that's a fairly vague name
// so renamed to be more meaningful.
void deserializeCam(Common::ReadStream &stream, TeIntrusivePtr<TeCamera> &cam);
void deserializeModel(Common::ReadStream &stream, TeIntrusivePtr<TeModel> &model, TePickMesh2 *pickmesh);
-
- void close();
- void reset();
+ virtual void draw() override;
+ void drawPath();
+ Dummy dummy(const Common::String &name);
+ bool findKate();
+ const TeMarker *findMarker(const Common::String &name);
+ const TeMarker *findMarkerByInt(const Common::String &name);
+ SoundStep findSoundStep(const Common::String &name);
+ void freeGeometry();
void freeSceneObjects();
- void unloadSpriteLayouts();
- void deleteAllCallback();
-
- void setStep(const Common::String &scene, const Common::String &step1, const Common::String &step2);
- TeLight *shadowLight();
-
Common::Path getActZoneFileName() const;
Common::Path getBlockersFileName() const;
Common::Path getLightsFileName() const;
+ float getHeadHorizontalRotation(Character *cter, const TeVector3f32 &vec);
+ float getHeadVerticalRotation(Character *cter, const TeVector3f32 &vec);
+ Common::String imagePathMarker(const Common::String &name);
+ void initScroll();
+ bool isMarker(const Common::String &name);
+ bool isObjectBlocking(const Common::String &name);
+ bool isVisibleMarker(const Common::String &name);
+ TeVector2f32 layerSize();
+
+ virtual bool load(const Common::Path &path) override;
+ void loadBackground(const Common::Path &path);
+ bool loadBillboard(const Common::String &name);
+ void loadBlockers();
+ bool loadCharacter(const Common::String &name);
+ void loadInteractions(const Common::Path &path);
+ bool loadLights(const Common::Path &path);
+ void loadMarkers(const Common::Path &path);
+ bool loadObject(const Common::String &name);
+ void loadObjectMaterials(const Common::String &name);
+ void loadObjectMaterials(const Common::String &path, const Common::String &name);
+ bool loadPlayerCharacter(const Common::String &name);
+
+ void moveCharacterTo(const Common::String &charName, const Common::String &curveName, float curveOffset, float curveEnd);
+ int object(const Common::String &name);
+ Object3D *object3D(const Common::String &name);
+ void onMainWindowSizeChanged();
+ TeFreeMoveZone *pathZone(const Common::String &name);
+ TeVector3f32 positionMarker(const Common::String &name);
+ void removeBlockingObject(const Common::String &name);
+
+ void reset();
+ void setImagePathMarker(const Common::String &markerName, const Common::String &path);
+ void setPositionCharacter(const Common::String &charName, const Common::String &freeMoveZoneName, const TeVector3f32 &position);
+ void setPositionMarker(const Common::String &name, const TeVector3f32 &vec);
+ void setStep(const Common::String &scene, const Common::String &step1, const Common::String &step2);
+ void setVisibleMarker(const Common::String &markerName, bool val);
+ TeLight *shadowLight();
+ bool showAllObjects(const Common::String &name);
+ void unloadAllObjects();
+ void unloadCharacter(const Common::String &name);
+ void unloadObject(const Common::String &name);
+ void unloadSpriteLayouts();
+ void update() override;
// Does nothing, but to keep calls from original..
static void updateScroll() {};
-
- bool findKate();
+ static void updateViewport() {};
Character *_character;
Common::Array<Character *> _characters;
@@ -159,6 +186,8 @@ public:
CharactersShadow *_charactersShadow;
TeIntrusivePtr<TeBezierCurve> curve() { return _curve; }
void setCurve(TeIntrusivePtr<TeBezierCurve> &c) { c = _curve; }
+ Common::Array<TeIntrusivePtr<TeModel>> &zoneModels() { return _zoneModels; }
+ Common::Array<TeRectBlocker> &rectBlockers() { return _rectBlockers; }
private:
TeColor _shadowColor;
@@ -166,11 +195,14 @@ private:
float _shadowNearPlane;
float _shadowFov;
+ float _waitTime;
+ TeTimer _waitTimeTimer;
+
Common::Array<TeBlocker> _blockers;
Common::Array<TeRectBlocker> _rectBlockers;
Common::Array<TeActZone> _actZones;
Common::Array<TeFreeMoveZone*> _freeMoveZones;
- Common::Array<TeMarker *> _markers;
+ Common::Array<TeMarker> _markers;
Common::Array<AnchorZone *> _anchorZones;
Common::Array<AnimObject *> _animObjects;
Common::Array<Object3D *> _object3Ds;
@@ -184,6 +216,7 @@ private:
Common::Array<Object> _objects;
Common::Array<TeIntrusivePtr<TeBezierCurve>> _bezierCurves;
Common::Array<Dummy> _dummies;
+ Common::Array<TeIntrusivePtr<TeModel>> _zoneModels;
TeIntrusivePtr<TeModel> _playerCharacterModel;
TeIntrusivePtr<TeBezierCurve> _curve;
diff --git a/engines/tetraedge/game/inventory.cpp b/engines/tetraedge/game/inventory.cpp
index 79fcacffb71..2ad6b17d88b 100644
--- a/engines/tetraedge/game/inventory.cpp
+++ b/engines/tetraedge/game/inventory.cpp
@@ -188,6 +188,8 @@ void Inventory::addObject(const Common::String &objId) {
}
bool Inventory::addObject(InventoryObject &obj) {
+ _invObjects.push_back(&obj);
+ obj.selectedSignal().add(this, &Inventory::onObjectSelected);
error("TODO: implement Inventory::addObject.");
}
@@ -266,10 +268,18 @@ bool Inventory::onZoomed() {
}
void Inventory::pauseAnims() {
+ Game *game = g_engine->getGame();
+ if (game->scene()._character) {
+
+ }
error("TODO: implement Inventory::pauseAnims");
}
void Inventory::unPauseAnims() {
+ Game *game = g_engine->getGame();
+ if (game->scene()._character) {
+
+ }
error("TODO: implement Inventory::unPauseAnims");
}
diff --git a/engines/tetraedge/game/inventory_object.cpp b/engines/tetraedge/game/inventory_object.cpp
index af214d5969c..f12e169b6fb 100644
--- a/engines/tetraedge/game/inventory_object.cpp
+++ b/engines/tetraedge/game/inventory_object.cpp
@@ -27,9 +27,25 @@ InventoryObject::InventoryObject() {
}
void InventoryObject::load(const Common::String &name) {
- error("TODO: Implement InventoryObject::load");
+ setSizeType(RELATIVE_TO_PARENT);
+ setSize(TeVector3f32(1.0f, 1.0f, 1.0f));
+ _gui.load("Inventory/InventoryObject.lua");
+ addChild(_gui.layoutChecked("object"));
+ setName(name);
+ _gui.spriteLayoutChecked("upLayout")->load(spritePath());
+ TeButtonLayout *btn = _gui.buttonLayoutChecked("object");
+ btn->onMouseClickValidated().add(this, &InventoryObject::onButtonDown);
+ // TODO: btn->setDoubleValidationProtectionEnabled(false)
+}
+
+Common::Path InventoryObject::spritePath() {
+ return Common::Path("Inventory/Objects").join(name()).append(".png");
+}
+
+bool InventoryObject::onButtonDown() {
+ _selectedSignal.call(*this);
+ return false;
}
-// TODO: Add more functions here.
} // end namespace Tetraedge
diff --git a/engines/tetraedge/game/inventory_object.h b/engines/tetraedge/game/inventory_object.h
index 8a9ae452f7b..5464f813811 100644
--- a/engines/tetraedge/game/inventory_object.h
+++ b/engines/tetraedge/game/inventory_object.h
@@ -28,15 +28,20 @@
namespace Tetraedge {
-class InventoryObject : TeLuaGUI {
+class InventoryObject : TeLayout {
public:
InventoryObject();
void load(const Common::String &name);
+ Common::Path spritePath();
+ bool onButtonDown();
+ TeSignal1Param<InventoryObject&> &selectedSignal() { return _selectedSignal; };
+
const Common::String &name() const { return _name; }
private:
Common::String _name;
-
+ TeLuaGUI _gui;
+ TeSignal1Param<InventoryObject&> _selectedSignal;
};
} // end namespace Tetraedge
diff --git a/engines/tetraedge/game/lua_binds.cpp b/engines/tetraedge/game/lua_binds.cpp
index 462411909e5..88745e3c0e3 100644
--- a/engines/tetraedge/game/lua_binds.cpp
+++ b/engines/tetraedge/game/lua_binds.cpp
@@ -59,7 +59,7 @@ static void AddRandomSound(const Common::String &s1, const Common::String &s2, f
static int tolua_ExportedFunctions_AddRandomSound00(lua_State *L) {
tolua_Error err;
if (tolua_isstring(L, 1, 0, &err) && tolua_isstring(L, 2, 0, &err)
- && tolua_isnumber(L, 3, 0, &err) && tolua_isnumber(L, 4, 0, &err)
+ && tolua_isnumber(L, 3, 0, &err) && tolua_isnumber(L, 4, 1, &err)
&& tolua_isnoobj(L, 5, &err)) {
Common::String s1(tolua_tostring(L, 1, nullptr));
Common::String s2(tolua_tostring(L, 2, nullptr));
@@ -223,7 +223,7 @@ static int tolua_ExportedFunctions_SetVisibleMarker00(lua_State *L) {
tolua_Error err;
if (tolua_isstring(L, 1, 0, &err) && tolua_isboolean(L, 2, 0, &err) && tolua_isnoobj(L, 3, &err)) {
Common::String s(tolua_tostring(L, 1, nullptr));
- bool b = tolua_toboolean(L, 1, 0);
+ bool b = tolua_toboolean(L, 2, 0);
SetVisibleMarker(s, b);
return 0;
}
@@ -259,20 +259,380 @@ static int tolua_ExportedFunctions_SetVisibleCellphone00(lua_State *L) {
error("#ferror in function 'SetVisibleCellphone': %d %d %s", err.index, err.array, err.type);
}
+static void RequestAutoSave() {
+ Game *game = g_engine->getGame();
+ game->setSaveRequested();
+}
+
+static int tolua_ExportedFunctions_RequestAutoSave00(lua_State *L) {
+ RequestAutoSave();
+ return 0;
+}
+
+static void HideObject(const Common::String &objName) {
+ warning("TODO: HideObject");
+}
+
+static int tolua_ExportedFunctions_HideObject00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isnoobj(L, 2, &err)) {
+ Common::String s1(tolua_tostring(L, 1, nullptr));
+ HideObject(s1);
+ return 0;
+ }
+ error("#ferror in function 'HideObject': %d %d %s", err.index, err.array, err.type);
+}
+
+static void ShowObject(const Common::String &objName) {
+ warning("TODO: ShowObject");
+}
+
+static int tolua_ExportedFunctions_ShowObject00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isnoobj(L, 2, &err)) {
+ Common::String s1(tolua_tostring(L, 1, nullptr));
+ ShowObject(s1);
+ return 0;
+ }
+ error("#ferror in function 'ShowObject': %d %d %s", err.index, err.array, err.type);
+}
+
+static void LoadObject(const Common::String &objName) {
+ Game *game = g_engine->getGame();
+ game->scene().loadObject(objName);
+}
+
+static int tolua_ExportedFunctions_LoadObject00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isnoobj(L, 2, &err)) {
+ Common::String s1(tolua_tostring(L, 1, nullptr));
+ LoadObject(s1);
+ return 0;
+ }
+ error("#ferror in function 'LoadObject': %d %d %s", err.index, err.array, err.type);
+}
+
+static void UnloadObject(const Common::String &objName) {
+ Game *game = g_engine->getGame();
+ game->scene().unloadObject(objName);
+}
+
+static int tolua_ExportedFunctions_UnloadObject00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isnoobj(L, 2, &err)) {
+ Common::String s1(tolua_tostring(L, 1, nullptr));
+ UnloadObject(s1);
+ return 0;
+ }
+ error("#ferror in function 'UnloadObject': %d %d %s", err.index, err.array, err.type);
+}
+
+static void SetCharacterRotation(const Common::String &charname, float f1, float f2, float f3) {
+ // TODO: check if this is good.
+ TeQuaternion quat = TeQuaternion::fromEuler(TeVector3f32(f1 * M_PI / 180.0, f2 * M_PI / 180.0, f3 * M_PI / 180.0));
+ Game *game = g_engine->getGame();
+ Character *c = game->scene().character(charname);
+ if (c) {
+ c->_model->setRotation(quat);
+ } else {
+ warning("[SetCharacterRotation] Character not found %s", charname.c_str());
+ }
+}
+
+static int tolua_ExportedFunctions_SetCharacterRotation00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isnumber(L, 2, 0, &err)
+ && tolua_isnumber(L, 3, 0, &err) && tolua_isnumber(L, 4, 0, &err)
+ && tolua_isnoobj(L, 5, &err)) {
+ Common::String s1(tolua_tostring(L, 1, nullptr));
+ float f1 = tolua_tonumber(L, 2, 0.0);
+ float f2 = tolua_tonumber(L, 3, 0.0);
+ float f3 = tolua_tonumber(L, 4, 1.0);
+ SetCharacterRotation(s1, f1, f2, f3);
+ return 0;
+ }
+ error("#ferror in function 'SetCharacterRotation': %d %d %s", err.index, err.array, err.type);
+}
+
+static void SetCharacterPosition(const Common::String &charname, const Common::String &zonename, float f1, float f2, float f3) {
+ Game *game = g_engine->getGame();
+ game->scene().setPositionCharacter(charname, zonename, TeVector3f32(f1, f2, f3));
+}
+
+static int tolua_ExportedFunctions_SetCharacterPosition00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isstring(L, 2, 0, &err)
+ && tolua_isnumber(L, 3, 0, &err) && tolua_isnumber(L, 4, 0, &err)
+ && tolua_isnumber(L, 5, 0, &err) && tolua_isnoobj(L, 6, &err)) {
+ Common::String s1(tolua_tostring(L, 1, nullptr));
+ Common::String s2(tolua_tostring(L, 2, nullptr));
+ float f1 = tolua_tonumber(L, 3, 0.0);
+ float f2 = tolua_tonumber(L, 4, 1.0);
+ float f3 = tolua_tonumber(L, 5, 0.0);
+ SetCharacterPosition(s1, s2, f1, f2, f3);
+ return 0;
+ }
+ error("#ferror in function 'SetCharacterPosition': %d %d %s", err.index, err.array, err.type);
+}
+
+static void SetGroundObjectPosition(const Common::String &objname, float f1, float f2, float f3) {
+ warning("TODO: Implement SetGroundObjectPosition");
+}
+
+static int tolua_ExportedFunctions_SetGroundObjectPosition00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isnumber(L, 2, 0, &err)
+ && tolua_isnumber(L, 3, 0, &err) && tolua_isnumber(L, 4, 0, &err)
+ && tolua_isnoobj(L, 5, &err)) {
+ Common::String s1(tolua_tostring(L, 1, nullptr));
+ float f1 = tolua_tonumber(L, 2, 0.0);
+ float f2 = tolua_tonumber(L, 3, 0.0);
+ float f3 = tolua_tonumber(L, 4, 1.0);
+ SetGroundObjectPosition(s1, f1, f2, f3);
+ return 0;
+ }
+ error("#ferror in function 'SetGroundObjectPosition': %d %d %s", err.index, err.array, err.type);
+}
+
+static void SetGroundObjectRotation(const Common::String &objname, float f1, float f2, float f3) {
+ warning("TODO: Implement SetGroundObjectRotation");
+}
+
+static int tolua_ExportedFunctions_SetGroundObjectRotation00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isnumber(L, 2, 0, &err)
+ && tolua_isnumber(L, 3, 0, &err) && tolua_isnumber(L, 4, 0, &err)
+ && tolua_isnoobj(L, 5, &err)) {
+ Common::String s1(tolua_tostring(L, 1, nullptr));
+ float f1 = tolua_tonumber(L, 2, 0.0);
+ float f2 = tolua_tonumber(L, 3, 0.0);
+ float f3 = tolua_tonumber(L, 4, 1.0);
+ SetGroundObjectRotation(s1, f1, f2, f3);
+ return 0;
+ }
+ error("#ferror in function 'SetGroundObjectRotation': %d %d %s", err.index, err.array, err.type);
+}
+
+static void SetBackground(const Common::String &name) {
+ Game *game = g_engine->getGame();
+ if (!game->setBackground(name))
+ warning("[SetBackground] Background \"%s\" doesn't exist.", name.c_str());
+}
+
+static int tolua_ExportedFunctions_SetBackground00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isnoobj(L, 2, &err)) {
+ Common::String s1(tolua_tostring(L, 1, nullptr));
+ SetBackground(s1);
+ return 0;
+ }
+ error("#ferror in function 'SetBackground': %d %d %s", err.index, err.array, err.type);
+}
+
+static void PushTask(const Common::String &s1, const Common::String &s2) {
+ Game *game = g_engine->getGame();
+ game->objectif().pushObjectif(s1, s2);
+}
+
+static int tolua_ExportedFunctions_PushTask00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isstring(L, 2, 0, &err) && tolua_isnoobj(L, 3, &err)) {
+ Common::String s1(tolua_tostring(L, 1, nullptr));
+ Common::String s2(tolua_tostring(L, 2, nullptr));
+ PushTask(s1, s2);
+ return 0;
+ }
+ error("#ferror in function 'PushTask': %d %d %s", err.index, err.array, err.type);
+}
+
+static void EnableRectBlocker(uint offset, bool enabled) {
+ Game *game = g_engine->getGame();
+ if (game->scene().rectBlockers().size() < offset)
+ error("invalid rectblocker offset %d", offset);
+
+ game->scene().rectBlockers()[offset]._x = enabled;
+}
+
+static int tolua_ExportedFunctions_EnableRectBlocker00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isnumber(L, 1, 0, &err) && tolua_isboolean(L, 2, 0, &err) && tolua_isnoobj(L, 3, &err)) {
+ double d1 = tolua_tonumber(L, 1, 0.0f);
+ bool b1 = tolua_toboolean(L, 2, 0);
+ EnableRectBlocker((uint)d1, b1);
+ return 0;
+ }
+ error("#ferror in function 'EnableRectBlocker': %d %d %s", err.index, err.array, err.type);
+}
+
+static void AddAnchorZone(const Common::String &s1, const Common::String &s2, float f1) {
+ if (s1.empty())
+ return;
+
+ Game *game = g_engine->getGame();
+
+ if (s1.contains("Dummy")) {
+ game->scene().addAnchorZone(s1, s2, f1);
+ } else if (s1.contains("Int")) {
+ if (game->scene().hitObjectGui().loaded()) {
+ TeButtonLayout *layout = game->scene().hitObjectGui().buttonLayout(s2);
+ if (!layout) {
+ warning("[AddAnchorZone] Zone \"%s\" doesn't exist.", s2.c_str());
+ } else {
+ game->scene().addAnchorZone(s1, s2, f1);
+ }
+ }
+ }
+}
+
+static int tolua_ExportedFunctions_AddAnchorZone00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isstring(L, 2, 0, &err) && tolua_isnumber(L, 3, 1, &err) && tolua_isnoobj(L, 4, &err)) {
+ Common::String s1(tolua_tostring(L, 1, nullptr));
+ Common::String s2(tolua_tostring(L, 2, nullptr));
+ double d1 = tolua_tonumber(L, 3, 1.0);
+ AddAnchorZone(s1, s2, d1);
+ return 0;
+ }
+ error("#ferror in function 'AddAnchorZone': %d %d %s", err.index, err.array, err.type);
+}
+
+static void DisabledZone(const Common::String &s1, bool b) {
+ Game *game = g_engine->getGame();
+ if (!game->scene().markerGui().loaded())
+ return;
+
+ warning("TODO: Implement DisabledZone");
+}
+
+static int tolua_ExportedFunctions_DisabledZone00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isboolean(L, 2, 1, &err) && tolua_isnoobj(L, 3, &err)) {
+ Common::String s(tolua_tostring(L, 1, nullptr));
+ bool b = tolua_toboolean(L, 2, 1);
+ DisabledZone(s, b);
+ return 0;
+ }
+ error("#ferror in function 'DisabledZone': %d %d %s", err.index, err.array, err.type);
+}
+
+static void DisabledInt(const Common::String &name, bool b) {
+ Game *game = g_engine->getGame();
+ if (!game->scene().hitObjectGui().loaded())
+ return;
+
+ TeButtonLayout *layout = game->scene().hitObjectGui().buttonLayout(name);
+ if (layout) {
+ layout->setVisible(!b);
+ }
+}
+
+static int tolua_ExportedFunctions_DisabledInt00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isboolean(L, 2, 1, &err) && tolua_isnoobj(L, 3, &err)) {
+ Common::String s(tolua_tostring(L, 1, nullptr));
+ bool b = tolua_toboolean(L, 2, 1);
+ DisabledInt(s, b);
+ return 0;
+ }
+ error("#ferror in function 'DisabledInt': %d %d %s", err.index, err.array, err.type);
+}
+
+static void LockCursor(bool b) {
+ Application *app = g_engine->getApplication();
+ app->lockCursorFromAction(b);
+}
+
+static int tolua_ExportedFunctions_LockCursor00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isboolean(L, 1, 0, &err) && tolua_isnoobj(L, 2, &err)) {
+ bool b = tolua_toboolean(L, 1, 0);
+ LockCursor(b);
+ return 0;
+ }
+ error("#ferror in function 'LockCursor': %d %d %s", err.index, err.array, err.type);
+}
+
+static void PlaySound(const Common::String &name, int i1, float f2) {
+ Game *game = g_engine->getGame();
+ game->playSound(name, i1, f2);
+}
+
+static int tolua_ExportedFunctions_PlaySound00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isnumber(L, 2, 1, &err) && tolua_isnumber(L, 3, 1, &err) && tolua_isnoobj(L, 4, &err)) {
+ Common::String s1(tolua_tostring(L, 1, nullptr));
+ double d1 = tolua_tonumber(L, 2, -1.0);
+ double d2 = tolua_tonumber(L, 3, 1.0);
+ PlaySound(s1, d1, d2);
+ return 0;
+ }
+ error("#ferror in function 'PlaySound': %d %d %s", err.index, err.array, err.type);
+}
+
+static void StopSound(const Common::String &name) {
+ Game *game = g_engine->getGame();
+ game->stopSound(name);
+}
+
+static int tolua_ExportedFunctions_StopSound00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isnoobj(L, 2, &err)) {
+ Common::String s1(tolua_tostring(L, 1, nullptr));
+ StopSound(s1);
+ return 0;
+ }
+ error("#ferror in function 'StopSound': %d %d %s", err.index, err.array, err.type);
+}
+
+static void PlayRandomSound(const Common::String &name) {
+ Game *game = g_engine->getGame();
+ game->playRandomSound(name);
+}
+
+static int tolua_ExportedFunctions_PlayRandomSound00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isnoobj(L, 2, &err)) {
+ Common::String s1(tolua_tostring(L, 1, nullptr));
+ PlayRandomSound(s1);
+ return 0;
+ }
+ error("#ferror in function 'PlayRandomSound': %d %d %s", err.index, err.array, err.type);
+}
+
+static void PlayMusic(const Common::String &path) {
+ TeMusic &music = g_engine->getApplication()->music();
+ music.load(path);
+ music.play();
+ music.repeat(false);
+ music.volume(1.0);
+}
+
+static int tolua_ExportedFunctions_PlayMusic00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isnoobj(L, 2, &err)) {
+ Common::String s1(tolua_tostring(L, 1, nullptr));
+ PlayMusic(s1);
+ return 0;
+ }
+ error("#ferror in function 'PlayMusic': %d %d %s", err.index, err.array, err.type);
+}
+
// ////////////////////////////////////////////////////////////////////////
+
+
void LuaOpenBinds(lua_State *L) {
tolua_open(L);
tolua_module(L, 0, 0);
tolua_beginmodule(L, 0);
/*
tolua_function(L, "LoadObjectMaterials", tolua_ExportedFunctions_LoadObjectMaterials00);
- tolua_function(L, "LoadObjectMaterials", tolua_ExportedFunctions_LoadObjectMaterials01);
+ tolua_function(L, "LoadObjectMaterials", tolua_ExportedFunctions_LoadObjectMaterials01);*/
tolua_function(L, "HideObject", tolua_ExportedFunctions_HideObject00);
tolua_function(L, "ShowObject", tolua_ExportedFunctions_ShowObject00);
- tolua_function(L, "ShowAllObjects", tolua_ExportedFunctions_ShowAllObjects00);
- tolua_function(L, "SetBackground", tolua_ExportedFunctions_SetBackground00);
+ /*tolua_function(L, "ShowAllObjects", tolua_ExportedFunctions_ShowAllObjects00);*/
+ tolua_function(L, "SetBackground", tolua_ExportedFunctions_SetBackground00);/*
tolua_function(L, "AddBlockingObject", tolua_ExportedFunctions_AddBlockingObject00);
tolua_function(L, "RemoveBlockingObject", tolua_ExportedFunctions_RemoveBlockingObject00);*/
tolua_function(L, "ChangeWarp", tolua_ExportedFunctions_ChangeWarp00);
@@ -282,33 +642,33 @@ void LuaOpenBinds(lua_State *L) {
tolua_function(L, "StartAnimation", tolua_ExportedFunctions_StartAnimation00);
tolua_function(L, "StartAnimationAndWaitForEnd",
tolua_ExportedFunctions_StartAnimationAndWaitForEnd00);
- tolua_function(L, "AddAnimToSet", tolua_ExportedFunctions_AddAnimToSet00);
+ tolua_function(L, "AddAnimToSet", tolua_ExportedFunctions_AddAnimToSet00); */
tolua_function(L, "RequestAutoSave", tolua_ExportedFunctions_RequestAutoSave00);
- tolua_function(L, "SetVisibleButtonZoomed", tolua_ExportedFunctions_SetVisibleButtonZoomed00);*/
+ /*tolua_function(L, "SetVisibleButtonZoomed", tolua_ExportedFunctions_SetVisibleButtonZoomed00);*/
tolua_function(L, "AddMarker", tolua_ExportedFunctions_AddMarker00);
tolua_function(L, "SetVisibleMarker", tolua_ExportedFunctions_SetVisibleMarker00);
tolua_function(L, "DeleteMarker", tolua_ExportedFunctions_DeleteMarker00);
tolua_function(L, "SetVisibleCellphone", tolua_ExportedFunctions_SetVisibleCellphone00);
- /*tolua_function(L, "DisabledZone", tolua_ExportedFunctions_DisabledZone00);
+ tolua_function(L, "DisabledZone", tolua_ExportedFunctions_DisabledZone00);
tolua_function(L, "DisabledInt", tolua_ExportedFunctions_DisabledInt00);
tolua_function(L, "LockCursor", tolua_ExportedFunctions_LockCursor00);
- tolua_function(L, "SetCondition", tolua_ExportedFunctions_SetCondition00);
+ /*tolua_function(L, "SetCondition", tolua_ExportedFunctions_SetCondition00);
tolua_function(L, "UnsetCondition", tolua_ExportedFunctions_UnsetCondition00);
tolua_function(L, "TutoActive", tolua_ExportedFunctions_TutoActive00);
tolua_function(L, "LaunchDialog", tolua_ExportedFunctions_LaunchDialog00);
tolua_function(L, "LaunchDialogAndWaitForEnd", tolua_ExportedFunctions_LaunchDialogAndWaitForEnd00);
tolua_function(L, "PushAnswer", tolua_ExportedFunctions_PushAnswer00);
- tolua_function(L, "HideAnswers", tolua_ExportedFunctions_HideAnswers00);
+ tolua_function(L, "HideAnswers", tolua_ExportedFunctions_HideAnswers00);*/
tolua_function(L, "PushTask", tolua_ExportedFunctions_PushTask00);
- tolua_function(L, "DeleteTask", tolua_ExportedFunctions_DeleteTask00);
+ /*tolua_function(L, "DeleteTask", tolua_ExportedFunctions_DeleteTask00);
tolua_function(L, "SetVisibleButtonHelp", tolua_ExportedFunctions_SetVisibleButtonHelp00);
- tolua_function(L, "HideTasks", tolua_ExportedFunctions_HideTasks00);
+ tolua_function(L, "HideTasks", tolua_ExportedFunctions_HideTasks00);*/
tolua_function(L, "PlaySound", tolua_ExportedFunctions_PlaySound00);
- tolua_function(L, "PlaySoundAndWaitForEnd", tolua_ExportedFunctions_PlaySoundAndWaitForEnd00);
- tolua_function(L, "StopSound", tolua_ExportedFunctions_StopSound00);*/
+ /*tolua_function(L, "PlaySoundAndWaitForEnd", tolua_ExportedFunctions_PlaySoundAndWaitForEnd00);*/
+ tolua_function(L, "StopSound", tolua_ExportedFunctions_StopSound00);
tolua_function(L, "AddRandomSound", tolua_ExportedFunctions_AddRandomSound00);
- /*tolua_function(L, "PlayRandomSound", tolua_ExportedFunctions_PlayRandomSound00);
- tolua_function(L, "PlayMusic", tolua_ExportedFunctions_PlayMusic00);*/
+ tolua_function(L, "PlayRandomSound", tolua_ExportedFunctions_PlayRandomSound00);
+ tolua_function(L, "PlayMusic", tolua_ExportedFunctions_PlayMusic00);
tolua_function(L, "SetSoundStep", tolua_ExportedFunctions_SetSoundStep00);
/*tolua_function(L, "Selected", tolua_ExportedFunctions_Selected00);
tolua_function(L, "TakeObject", tolua_ExportedFunctions_TakeObject00);
@@ -332,11 +692,11 @@ void LuaOpenBinds(lua_State *L) {
tolua_function(L, "MoveCharacterPlayerTo", tolua_ExportedFunctions_MoveCharacterPlayerTo00);
tolua_function(L, "MoveCharacterPlayerToAndWaitForEnd",
tolua_ExportedFunctions_MoveCharacterPlayerToAndWaitForEnd00);
- tolua_function(L, "MoveCharacterPlayerAtTo", tolua_ExportedFunctions_MoveCharacterPlayerAtTo00);
+ tolua_function(L, "MoveCharacterPlayerAtTo", tolua_ExportedFunctions_MoveCharacterPlayerAtTo00);*/
tolua_function(L, "SetCharacterPosition", tolua_ExportedFunctions_SetCharacterPosition00);
- tolua_function(L, "PlaceCharacterOnDummy", tolua_ExportedFunctions_PlaceCharacterOnDummy00);
+ /*tolua_function(L, "PlaceCharacterOnDummy", tolua_ExportedFunctions_PlaceCharacterOnDummy00);*/
tolua_function(L, "SetCharacterRotation", tolua_ExportedFunctions_SetCharacterRotation00);
- tolua_function(L, "SetCharacterOrientation", tolua_ExportedFunctions_SetCharacterOrientation00);
+ /*tolua_function(L, "SetCharacterOrientation", tolua_ExportedFunctions_SetCharacterOrientation00);
tolua_function(L, "SetCharacterAnimation", tolua_ExportedFunctions_SetCharacterAnimation00);
tolua_function(L, "SetCharacterAnimationAndWaitForEnd",
tolua_ExportedFunctions_SetCharacterAnimationAndWaitForEnd00);
@@ -362,12 +722,12 @@ void LuaOpenBinds(lua_State *L) {
tolua_function(L, "SetObjectRotation", tolua_ExportedFunctions_SetObjectRotation00);
tolua_function(L, "SetObjectTranslation", tolua_ExportedFunctions_SetObjectTranslation00);
tolua_function(L, "SetObjectScale", tolua_ExportedFunctions_SetObjectScale00);
- tolua_function(L, "SetObjectFrames", tolua_ExportedFunctions_SetObjectFrames00);
+ tolua_function(L, "SetObjectFrames", tolua_ExportedFunctions_SetObjectFrames00);*/
tolua_function(L, "LoadObject", tolua_ExportedFunctions_LoadObject00);
tolua_function(L, "UnloadObject", tolua_ExportedFunctions_UnloadObject00);
tolua_function(L, "SetGroundObjectPosition", tolua_ExportedFunctions_SetGroundObjectPosition00);
tolua_function(L, "SetGroundObjectRotation", tolua_ExportedFunctions_SetGroundObjectRotation00);
- tolua_function(L, "TranslateGroundObject", tolua_ExportedFunctions_TranslateGroundObject00);
+ /*tolua_function(L, "TranslateGroundObject", tolua_ExportedFunctions_TranslateGroundObject00);
tolua_function(L, "RotateGroundObject", tolua_ExportedFunctions_RotateGroundObject00);
tolua_function(L, "SetLightPlayerCharacter", tolua_ExportedFunctions_SetLightPlayerCharacter00);
tolua_function(L, "SetLightPos", tolua_ExportedFunctions_SetLightPos00);
@@ -394,10 +754,10 @@ void LuaOpenBinds(lua_State *L) {
tolua_function(L, "BFGReachedFreemiumLimit", tolua_ExportedFunctions_BFGReachedFreemiumLimit00);
tolua_function(L, "TestFileFlagSystemFlag", tolua_ExportedFunctions_TestFileFlagSystemFlag00);
tolua_function(L, "PrintDebugMessage", tolua_ExportedFunctions_PrintDebugMessage00);
- tolua_function(L, "ExitZone", tolua_ExportedFunctions_ExitZone00);
+ tolua_function(L, "ExitZone", tolua_ExportedFunctions_ExitZone00);*/
tolua_function(L, "EnableRectBlocker", tolua_ExportedFunctions_EnableRectBlocker00);
- tolua_function(L, "EnableBlocker", tolua_ExportedFunctions_EnableBlocker00);
- tolua_function(L, "AddAnchorZone", tolua_ExportedFunctions_AddAnchorZone00);
+ /*tolua_function(L, "EnableBlocker", tolua_ExportedFunctions_EnableBlocker00);*/
+ tolua_function(L, "AddAnchorZone", tolua_ExportedFunctions_AddAnchorZone00);/*
tolua_function(L, "ActivateAnchorZone", tolua_ExportedFunctions_ActivateAnchorZone00);
tolua_function(L, "SetCharacterAnchor", tolua_ExportedFunctions_SetCharacterAnchor00);
tolua_function(L, "SetCharacterLookChar", tolua_ExportedFunctions_SetCharacterLookChar00);
diff --git a/engines/tetraedge/game/main_menu.cpp b/engines/tetraedge/game/main_menu.cpp
index e2adbfb54f8..7c56dccb83d 100644
--- a/engines/tetraedge/game/main_menu.cpp
+++ b/engines/tetraedge/game/main_menu.cpp
@@ -123,6 +123,10 @@ void MainMenu::enter() {
const Common::String versionSectionStr("<section style=\"left\" /><color r=\"255\" g=\"255\" b=\"255\"/><font file=\"Common/Fonts/arial.ttf\" size=\"12\" />");
versionNum->setText(versionSectionStr + app->getVersionString());
}
+
+ if (ConfMan.get("skip_mainmenu") == "true") {
+ onNewGameConfirmed();
+ }
}
void MainMenu::leave() {
@@ -131,10 +135,9 @@ void MainMenu::leave() {
Application *app = g_engine->getApplication();
app->captureFade();
- warning("TODO: MainMenu::leave Stop some game sounds here.");
- //Game *game = g_engine->getGame();
- //game->stopSound("sounds/Ambiances/b_automatebike.ogg");
- //game->stopSound("sounds/Ambiances/b_engrenagebg.ogg");
+ Game *game = g_engine->getGame();
+ game->stopSound("sounds/Ambiances/b_automatebike.ogg");
+ game->stopSound("sounds/Ambiances/b_engrenagebg.ogg");
TeLuaGUI::unload();
app->fade();
_entered= false;
@@ -164,11 +167,11 @@ bool MainMenu::onBFGRateItButtonValidated() {
}
bool MainMenu::onBFGRateItQuitButtonValidated() {
- error("TODO: Implement MainMenu function");
+ error("TODO: Implement MainMenu::onBFGRateItQuitButtonValidated");
}
bool MainMenu::onBFGUnlockGameButtonValidated() {
- error("TODO: Implement MainMenu function");
+ error("TODO: Implement MainMenu::onBFGUnlockGameButtonValidated");
}
void MainMenu::tryDisableButton(const Common::String &btnName) {
@@ -215,11 +218,11 @@ bool MainMenu::onDisabledTuto() {
}
bool MainMenu::onEnterGameRotateAnimFinished() {
- error("TODO: Implement MainMenu function");
+ error("TODO: Implement MainMenu::onEnterGameRotateAnimFinished");
}
bool MainMenu::onGalleryButtonValidated() {
- error("TODO: Implement MainMenu function");
+ error("TODO: Implement MainMenu::onGalleryButtonValidated");
}
bool MainMenu::onHowToButtonValidated() {
@@ -263,8 +266,8 @@ bool MainMenu::onQuit() {
}
bool MainMenu::onQuitButtonValidated() {
- //Confirm::enter("menus/confirm/confirmQuit.lua", "");
- error("TODO: Implement MainMenu::onQuitButtonValidated");
+ _quitConfirm.enter("menus/confirm/confirmQuit.lua", "");
+ return false;
}
bool MainMenu::onUnlockGameButtonValidated() {
diff --git a/engines/tetraedge/game/object3d.cpp b/engines/tetraedge/game/object3d.cpp
index eb95daa4d34..cfd6377ce96 100644
--- a/engines/tetraedge/game/object3d.cpp
+++ b/engines/tetraedge/game/object3d.cpp
@@ -31,6 +31,23 @@ namespace Tetraedge {
Object3D::Object3D() {
}
+bool Object3D::loadModel(const Common::String &name) {
+ _modelPtr = new TeModel();
+ Common::HashMap<Common::String, ObjectSettings>::iterator settings = _objectSettings->find(name);
+ if (settings != _objectSettings->end()) {
+ _modelFileName = settings->_value._modelFileName;
+ _defaultScale = settings->_value._defaultScale;
+ _modelPtr->_texturePath = Common::Path("objects/Textures");
+ bool loaded = _modelPtr->load(Common::Path("objects").join(_modelFileName));
+ if (loaded) {
+ _modelPtr->setName(name);
+ _modelPtr->setScale(_defaultScale);
+ return true;
+ }
+ }
+ return false;
+}
+
/*static*/ bool Object3D::loadSettings(const Common::String &path) {
ObjectSettingsXmlParser parser;
parser.setAllowText();
diff --git a/engines/tetraedge/game/object3d.h b/engines/tetraedge/game/object3d.h
index ae248fd581a..d1d321bf3cb 100644
--- a/engines/tetraedge/game/object3d.h
+++ b/engines/tetraedge/game/object3d.h
@@ -47,6 +47,8 @@ public:
static bool loadSettings(const Common::String &path);
+ TeIntrusivePtr<TeModel> model() { return _modelPtr; }
+
private:
static Common::HashMap<Common::String, ObjectSettings> *_objectSettings;
diff --git a/engines/tetraedge/game/objectif.cpp b/engines/tetraedge/game/objectif.cpp
index 44c99aba5dc..96a2731f962 100644
--- a/engines/tetraedge/game/objectif.cpp
+++ b/engines/tetraedge/game/objectif.cpp
@@ -108,6 +108,19 @@ bool Objectif::onHelpButtonValidated() {
return false;
}
+void Objectif::pushObjectif(Common::String const &head, Common::String const &sub) {
+ for (const Task &t : _tasks) {
+ if (t._headTask == head && t._subTask == sub)
+ return;
+ }
+
+ _layoutsDirty = true;
+ _tasks.resize(_tasks.size() + 1);
+ _tasks.back()._headTask = head;
+ _tasks.back()._subTask = sub;
+ _tasks.back()._taskFlag = true;
+}
+
void Objectif::reattachLayout(TeLayout *layout) {
TeButtonLayout *btn;
diff --git a/engines/tetraedge/game/objectif.h b/engines/tetraedge/game/objectif.h
index 9e71169ef02..44ae6050f46 100644
--- a/engines/tetraedge/game/objectif.h
+++ b/engines/tetraedge/game/objectif.h
@@ -45,6 +45,7 @@ public:
void leave();
void load();
bool onHelpButtonValidated();
+ void pushObjectif(Common::String const &head, Common::String const &sub);
void reattachLayout(TeLayout *layout);
void removeChildren();
// void save()
diff --git a/engines/tetraedge/game/owner_error_menu.cpp b/engines/tetraedge/game/owner_error_menu.cpp
index 52aef50351d..0519ab69d57 100644
--- a/engines/tetraedge/game/owner_error_menu.cpp
+++ b/engines/tetraedge/game/owner_error_menu.cpp
@@ -24,6 +24,9 @@
#include "tetraedge/game/application.h"
#include "tetraedge/game/owner_error_menu.h"
+#include "tetraedge/te/te_layout.h"
+#include "tetraedge/te/te_text_layout.h"
+
namespace Tetraedge {
OwnerErrorMenu::OwnerErrorMenu() : _entered(false) {
@@ -32,13 +35,13 @@ OwnerErrorMenu::OwnerErrorMenu() : _entered(false) {
void OwnerErrorMenu::enter() {
_entered = true;
static const Common::Path luaPath("menus/ownerError/ownerError.lua");
- load(luaPath.toString());
- error("TODO: Finish implementation of OwnerErrorMenu::enter");
- /*
+ load(luaPath);
Application *app = g_engine->getApplication();
- TeLayout *menuLayout = TeLuaGUI::layout("menu");
- ...
- */
+ TeLayout *menuLayout = layoutChecked("menu");
+ app->_frontLayout.addChild(menuLayout);
+ TeTextLayout *txt = dynamic_cast<TeTextLayout*>(layoutChecked("ownerMenuText"));
+ const Common::String *locname = app->_loc.value(txt->name());
+ txt->setText(value("textAttributs").toString() + (locname ? *locname : txt->name()));
}
void OwnerErrorMenu::leave() {
diff --git a/engines/tetraedge/game/splash_screens.cpp b/engines/tetraedge/game/splash_screens.cpp
index a14519a9b96..adbd33f04d4 100644
--- a/engines/tetraedge/game/splash_screens.cpp
+++ b/engines/tetraedge/game/splash_screens.cpp
@@ -57,7 +57,7 @@ bool SplashScreens::onAlarm() {
const Common::String scriptName = Common::String::format("menus/splashes/splash%d.lua", _splashNo);
_splashNo++;
- if (ConfMan.get("skipsplash") == "true") {
+ if (ConfMan.get("skip_splash") == "true") {
onQuitSplash();
return true;
}
diff --git a/engines/tetraedge/module.mk b/engines/tetraedge/module.mk
index c276c075ceb..bdb10afc5c1 100644
--- a/engines/tetraedge/module.mk
+++ b/engines/tetraedge/module.mk
@@ -60,6 +60,7 @@ MODULE_OBJS := \
te/te_i_layout.o \
te/te_i_loc.o \
te/te_image.o \
+ te/te_images_sequence.o \
te/te_input_mgr.o \
te/te_interpolation.o \
te/te_jpeg.o \
diff --git a/engines/tetraedge/te/te_camera.h b/engines/tetraedge/te/te_camera.h
index f6344d53a24..38dc8adfe29 100644
--- a/engines/tetraedge/te/te_camera.h
+++ b/engines/tetraedge/te/te_camera.h
@@ -43,7 +43,7 @@ public:
void buildPerspectiveMatrix();
void buildPerspectiveMatrix2();
void buildPerspectiveMatrix3();
- void draw();
+ void draw() override;
void getRay(const TeVector2s32 ¶m_1, TeVector3f32 &out1, TeVector3f32 &out2);
@@ -67,6 +67,8 @@ public:
void viewport(int x, int y, uint width, uint height);
TeVector2f32 viewportSize() const { return TeVector2f32(_viewportW, _viewportH); }
+ TeSignal0Param &onViewportChangedSignal() { return _onViewportChangedSignal; }
+
int _projectionMatrixType;
float _orthNearVal;
float _orthFarVal;
diff --git a/engines/tetraedge/te/te_core.cpp b/engines/tetraedge/te/te_core.cpp
index 7ed6efa4b09..0b2ed30ef1b 100644
--- a/engines/tetraedge/te/te_core.cpp
+++ b/engines/tetraedge/te/te_core.cpp
@@ -20,11 +20,14 @@
*/
#include "common/file.h"
+#include "common/fs.h"
#include "common/debug.h"
+#include "common/config-manager.h"
#include "tetraedge/te/te_core.h"
#include "tetraedge/te/te_png.h"
+#include "tetraedge/te/te_images_sequence.h"
#include "tetraedge/te/te_jpeg.h"
#include "tetraedge/te/te_theora.h"
#include "tetraedge/te/te_tga.h"
@@ -66,6 +69,8 @@ TeICodec *TeCore::createVideoCodec(const Common::Path &path) {
return new TeTheora();
} else if (TeTga::matchExtension(extn)) {
return new TeTga();
+ } else if (TeImagesSequence::matchExtension(extn)) {
+ return new TeImagesSequence();
}
error("TTeCore::createVideoCodec: Unrecognised format %s", path.toString().c_str());
}
@@ -111,6 +116,12 @@ Common::Path TeCore::findFile(const Common::Path &path) {
if (Common::File::exists(path))
return path;
+ const Common::String gamePath = ConfMan.get("path");
+ const Common::Path resPath = Common::Path(gamePath).join("Resources");
+ const Common::Path absolutePath = resPath.join(path);
+ if (Common::FSNode(absolutePath).isDirectory())
+ return absolutePath;
+
const Common::Path fname = path.getLastComponent();
const Common::Path dir = path.getParent();
@@ -140,7 +151,7 @@ Common::Path TeCore::findFile(const Common::Path &path) {
testPath.joinInPlace(langs[langtype]);
}
testPath.joinInPlace(fname);
- if (Common::File::exists(testPath)) {
+ if (Common::File::exists(testPath) || Common::FSNode(path).exists()) {
return testPath;
}
}
diff --git a/engines/tetraedge/te/te_frame_anim.cpp b/engines/tetraedge/te/te_frame_anim.cpp
index b0572730753..678d21c5508 100644
--- a/engines/tetraedge/te/te_frame_anim.cpp
+++ b/engines/tetraedge/te/te_frame_anim.cpp
@@ -30,8 +30,8 @@ _numFramesToShow(-1), _startTime(0), _endTime(FLT_MAX), _loopCount(0), _lastFram
}
void TeFrameAnim::update(double amount) {
- int minFrame = MIN((long)_minFrame, _nbFrames);
- int maxFrame = MIN((long)minFrame + _numFramesToShow, _nbFrames);
+ int minFrame = MIN(_minFrame, _nbFrames);
+ int maxFrame = MIN(_minFrame + _numFramesToShow, _nbFrames);
double frameNo = _frameRate * amount / 1000.0;
int loopsDone;
diff --git a/engines/tetraedge/te/te_frame_anim.h b/engines/tetraedge/te/te_frame_anim.h
index c2f241c81a6..c3b1c4869e9 100644
--- a/engines/tetraedge/te/te_frame_anim.h
+++ b/engines/tetraedge/te/te_frame_anim.h
@@ -35,7 +35,7 @@ public:
TeSignal0Param &frameChangedSignal() { return _frameChangedSignal; };
- long _nbFrames;
+ int _nbFrames;
float _frameRate;
int _loopCount;
bool _reversed;
diff --git a/engines/tetraedge/te/te_free_move_zone.cpp b/engines/tetraedge/te/te_free_move_zone.cpp
index 89999b5717e..0713b9c4341 100644
--- a/engines/tetraedge/te/te_free_move_zone.cpp
+++ b/engines/tetraedge/te/te_free_move_zone.cpp
@@ -27,6 +27,9 @@
namespace Tetraedge {
+/*static*/
+//TeIntrusivePtr<TeCamera> TeFreeMoveZone::_globalCamera;
+
class TeFreeMoveZoneGraph : micropather::Graph {
friend class TeFreeMoveZone;
TeVector2s32 _size;
@@ -57,7 +60,9 @@ _transformedVerticiesDirty(true), _bordersDirty(true), _pickMeshDirty(true), _pr
}
TeFreeMoveZone::~TeFreeMoveZone() {
- // TODO: remove signal.
+ if (_camera) {
+ _camera->onViewportChangedSignal().remove(this, &TeFreeMoveZone::onViewportChanged);
+ }
delete _micropather;
}
@@ -77,8 +82,10 @@ void TeFreeMoveZone::clear() {
setNbTriangles(0);
_pickMeshDirty = true;
_projectedPointsDirty = true;
- // TODO: Clear 3 other point vectors here.
- // TODO: _gridDirty = true;
+ _vectorArray.clear();
+ _uintArray2.clear();
+ // TODO: Some other point vector here.
+ _gridDirty = true;
_graph->_flags.clear();
_graph->_size = TeVector2s32(0, 0);
_micropather->Reset();
@@ -91,7 +98,9 @@ Common::Array<TeVector3f32> TeFreeMoveZone::collisions(const TeVector3f32 &v1, c
}
TeVector3f32 TeFreeMoveZone::correctCharacterPosition(const TeVector3f32 &pos, bool *flagout, bool f) {
- error("TODO: Implement TeFreeMoveZone::correctCharacterPosition");
+
+ warning("TODO: Implement TeFreeMoveZone::correctCharacterPosition");
+ return pos;
}
TeIntrusivePtr<TeBezierCurve> TeFreeMoveZone::curve(const TeVector3f32 ¶m_3, const TeVector2s32 ¶m_4, float param_5, bool findMeshFlag) {
@@ -185,8 +194,15 @@ void TeFreeMoveZone::setBordersDistance(float dist) {
_graph->_bordersDistance = dist;
}
-void TeFreeMoveZone::setCamera(TeIntrusivePtr<TeCamera> &cam, bool recalcProjPoints) {
- error("TODO: Implement TeFreeMoveZone::setCamera");
+void TeFreeMoveZone::setCamera(TeIntrusivePtr<TeCamera> &cam, bool noRecalcProjPoints) {
+ if (_camera) {
+ _camera->onViewportChangedSignal().remove(this, &TeFreeMoveZone::onViewportChanged);
+ }
+ //_globalCamera = camera; // Seems like this is never used?
+ _camera = cam;
+ cam->onViewportChangedSignal().add(this, &TeFreeMoveZone::onViewportChanged);
+ if (!noRecalcProjPoints)
+ _projectedPointsDirty = true;
}
void TeFreeMoveZone::setNbTriangles(unsigned long len) {
diff --git a/engines/tetraedge/te/te_free_move_zone.h b/engines/tetraedge/te/te_free_move_zone.h
index 13f0b9856ee..aa4cbd9809a 100644
--- a/engines/tetraedge/te/te_free_move_zone.h
+++ b/engines/tetraedge/te/te_free_move_zone.h
@@ -93,7 +93,7 @@ public:
TeVector3f32 projectOnAStarGrid(const TeVector3f32 &pt);
Common::Array<TeVector3f32> &removeInsignificantPoints(const Common::Array<TeVector3f32> &points);
void setBordersDistance(float dist);
- void setCamera(TeIntrusivePtr<TeCamera> &cam, bool recalcProjPoints);
+ void setCamera(TeIntrusivePtr<TeCamera> &cam, bool noRecalcProjPoints);
void setNbTriangles(unsigned long len);
void setPathFindingOccluder(const TeOBP &occluder);
void setVertex(unsigned long offset, const TeVector3f32 &vertex);
@@ -129,6 +129,8 @@ private:
float _someGridFloat;
TeOBP _obp;
+ TeIntrusivePtr<TeCamera> _camera;
+ //static TeIntrusivePtr<TeCamera> _globalCamera;
bool _gridDirty;
TeFreeMoveZoneGraph *_graph;
diff --git a/engines/tetraedge/te/te_i_codec.h b/engines/tetraedge/te/te_i_codec.h
index ce3b8d26b07..f58bc0c15ff 100644
--- a/engines/tetraedge/te/te_i_codec.h
+++ b/engines/tetraedge/te/te_i_codec.h
@@ -37,7 +37,6 @@ public:
virtual ~TeICodec() {};
virtual bool load(const Common::Path &path) = 0;
- virtual bool load(Common::SeekableReadStream &stream) = 0;
virtual uint width() = 0;
virtual uint height() = 0;
virtual int nbFrames() = 0;
diff --git a/engines/tetraedge/te/te_images_sequence.cpp b/engines/tetraedge/te/te_images_sequence.cpp
new file mode 100644
index 00000000000..0af65ad6777
--- /dev/null
+++ b/engines/tetraedge/te/te_images_sequence.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 "common/file.h"
+#include "image/png.h"
+#include "graphics/surface.h"
+
+#include "tetraedge/te/te_images_sequence.h"
+
+namespace Tetraedge {
+
+TeImagesSequence::TeImagesSequence() : _width(0), _height(0), _curFrame(0) {
+}
+
+TeImagesSequence::~TeImagesSequence() {
+}
+
+/*static*/
+bool TeImagesSequence::matchExtension(const Common::String &extn) {
+ return extn == "anim";
+}
+
+static bool compareNodes(const Common::FSNode &left, const Common::FSNode &right) {
+ return left.getPath() < right.getPath();
+}
+
+bool TeImagesSequence::load(const Common::Path &path) {
+ Common::FSNode directory(path);
+ if (!directory.isDirectory()) {
+ warning("TeImagesSequence::load:: not a directory %s", path.toString().c_str());
+ return false;
+ }
+
+ Common::FSList children;
+ if (!directory.getChildren(children, Common::FSNode::kListFilesOnly) || children.empty()) {
+ warning("TeImagesSequence::load:: couldn't get children of %s", path.toString().c_str());
+ return false;
+ }
+
+ Common::sort(children.begin(), children.end(), compareNodes);
+
+ SearchMan.addDirectory(path.toString(), directory);
+
+ for (Common::FSNode &child : children) {
+ Common::String filePathStr = child.getPath();
+
+ if (filePathStr.size() <= 10 || filePathStr.substr(filePathStr.size() - 7) != "fps.png")
+ continue;
+
+ Common::Path filePath(filePathStr);
+ Common::String fname = filePath.getLastComponent().toString();
+ Common::String fstart = fname.substr(0, fname.size() - 7);
+ unsigned int frameno = 0;
+ unsigned int fps = 0;
+ if (sscanf(fstart.c_str(), "%d-%d", &frameno, &fps) != 2) {
+ warning("TeImagesSequence::load can't match %s", fname.c_str());
+ continue;
+ }
+
+ Common::File file;
+ if (!file.open(filePath)) {
+ warning("TeImagesSequence::load can't open %s", filePath.toString().c_str());
+ continue;
+ }
+
+ // At first only do the deep check for the first file to get dimensions.
+ if (_width) {
+ _files.push_back(filePath);
+ continue;
+ }
+
+ Image::PNGDecoder png;
+ if (!png.loadStream(file)) {
+ warning("Image sequence failed to load png %s", filePath.toString().c_str());
+ return false;
+ }
+
+ const Graphics::Surface *surf = png.getSurface();
+ assert(surf);
+ _width = surf->w;
+ _height = surf->h;
+ _frameRate = fps;
+ }
+
+ return true;
+}
+
+
+bool TeImagesSequence::update(unsigned long i, TeImage &imgout) {
+ _curFrame = i;
+
+ if (i >= _files.size())
+ return false;
+
+ Common::File file;
+ if (file.open(_files[_curFrame]))
+ error("Open %s failed.. it was ok before?", _files[_curFrame].toString().c_str());
+
+ Image::PNGDecoder png;
+ if (png.loadStream(file)) {
+ warning("Image sequence failed to load png %s", _files[_curFrame].toString().c_str());
+ return false;
+ }
+
+ const Graphics::Surface *surf = png.getSurface();
+ assert(surf);
+
+ imgout.setAccessName(_files[_curFrame]);
+
+ if (imgout.w == surf->w && imgout.h == surf->h && imgout.format == surf->format) {
+ imgout.copyFrom(*surf);
+ return true;
+ }
+
+ error("TODO: Implement TeImagesSequence::update for different sizes");
+}
+
+bool TeImagesSequence::isAtEnd() {
+ return _curFrame >= _files.size();
+}
+
+TeImage::Format TeImagesSequence::imageFormat() {
+ return TeImage::RGBA8;
+}
+
+} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_images_sequence.h b/engines/tetraedge/te/te_images_sequence.h
new file mode 100644
index 00000000000..6559d8905cd
--- /dev/null
+++ b/engines/tetraedge/te/te_images_sequence.h
@@ -0,0 +1,71 @@
+/* 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 TETRAEDGE_TE_TE_IMAGES_SEQUENCE_H
+#define TETRAEDGE_TE_TE_IMAGES_SEQUENCE_H
+
+#include "common/str.h"
+#include "tetraedge/te/te_i_codec.h"
+
+namespace Graphics {
+struct Surface;
+};
+
+namespace Tetraedge {
+
+class TeImagesSequence : public TeICodec {
+public:
+ TeImagesSequence();
+ virtual ~TeImagesSequence();
+
+ virtual bool load(const Common::Path &path) override;
+ virtual uint width() override { return _width; }
+ virtual uint height() override { return _height; }
+ virtual int nbFrames() override { return _files.size(); }
+ virtual void setLeftBorderSize(uint val) override { }
+ virtual uint leftBorderSize() override { return 0; }
+ virtual void setRightBorderSize(uint val) override { }
+ virtual uint rightBorderSize() override { return 0; }
+ virtual void setBottomBorderSize(uint val) override { }
+ virtual uint bottomBorderSize() override { return 0; }
+ virtual void setTopBorderSize(uint val) override { }
+ virtual uint topBorderSize() override { return 0; }
+ virtual TeImage::Format imageFormat() override;
+ virtual float frameRate() override { return _frameRate; }
+ virtual bool update(unsigned long i, TeImage &imgout) override;
+ virtual bool isAtEnd() override;
+ virtual void setColorKeyActivated(bool val) override { }
+ virtual void setColorKey(const TeColor &col) override { }
+ virtual void setColorKeyTolerence(float val) override { }
+
+ static bool matchExtension(const Common::String &extn);
+
+private:
+ float _frameRate;
+ unsigned int _width;
+ unsigned int _height;
+ Common::Array<Common::Path> _files;
+ unsigned int _curFrame;
+};
+
+} // end namespace Tetraedge
+
+#endif // TETRAEDGE_TE_TE_IMAGES_SEQUENCE_H
diff --git a/engines/tetraedge/te/te_lua_script.cpp b/engines/tetraedge/te/te_lua_script.cpp
index 4191bb3acad..58422d24195 100644
--- a/engines/tetraedge/te/te_lua_script.cpp
+++ b/engines/tetraedge/te/te_lua_script.cpp
@@ -19,6 +19,7 @@
*
*/
+#include "common/debug.h"
#include "common/textconsole.h"
#include "common/file.h"
#include "tetraedge/te/te_lua_script.h"
@@ -36,6 +37,7 @@ void TeLuaScript::attachToContext(TeLuaContext *context) {
void TeLuaScript::execute() {
if (_luaContext) {
+ debug("TeLuaScript::execute %s", _scriptPath.toString().c_str());
lua_State *state = _luaContext->luaState();
if (state) {
TeLuaThread *thread = TeLuaThread::create(_luaContext);
@@ -48,6 +50,7 @@ void TeLuaScript::execute() {
void TeLuaScript::execute(const Common::String &fname) {
if (_luaContext) {
+ debug("TeLuaScript::execute %s %s", _scriptPath.toString().c_str(), fname.c_str());
TeLuaThread *thread = TeLuaThread::create(_luaContext);
thread->execute(fname);
thread->release();
@@ -56,6 +59,7 @@ void TeLuaScript::execute(const Common::String &fname) {
void TeLuaScript::execute(const Common::String &fname, const TeVariant &p1) {
if (_luaContext) {
+ debug("TeLuaScript::execute %s %s(%s)", _scriptPath.toString().c_str(), fname.c_str(), p1.toString().c_str());
TeLuaThread *thread = TeLuaThread::create(_luaContext);
thread->execute(fname, p1);
thread->release();
diff --git a/engines/tetraedge/te/te_lua_thread.cpp b/engines/tetraedge/te/te_lua_thread.cpp
index baa7bbadb36..a21f3ffda7d 100644
--- a/engines/tetraedge/te/te_lua_thread.cpp
+++ b/engines/tetraedge/te/te_lua_thread.cpp
@@ -125,7 +125,7 @@ void TeLuaThread::execute(const Common::String &fname, const TeVariant &p1, cons
} else {
if (!fname.contains("Update"))
warning("[TeLuaThread::Execute3] La fonction : \"%s\" n'existe pas.", fname.c_str());
- lua_settop(_luaThread, -2);
+ lua_settop(_luaThread, -4);
}
}
diff --git a/engines/tetraedge/te/te_mesh.cpp b/engines/tetraedge/te/te_mesh.cpp
index bdf7075fda5..2c18fd9f4f8 100644
--- a/engines/tetraedge/te/te_mesh.cpp
+++ b/engines/tetraedge/te/te_mesh.cpp
@@ -72,7 +72,7 @@ void TeMesh::draw() {
if (_matrixForced)
renderer->multiplyMatrix(_forceMatrix);
else
- renderer->multiplyMatrix(transformationMatrix());
+ renderer->multiplyMatrix(worldTransformationMatrix());
Common::Array<TeVector3f32> &normals = (_updatedVerticies.empty() ? _normals : _updatedNormals);
Common::Array<TeVector3f32> &verticies = (_updatedVerticies.empty() ? _verticies : _updatedVerticies);
@@ -138,7 +138,8 @@ void TeMesh::draw() {
} else {
int totalfacecount = 0;
for (unsigned int i = 0; i < _materials.size(); i++) {
- if (_faceCounts[i]) {
+ if (!_faceCounts[i])
+ continue;
if (!hasAlpha(i) || renderer->shadowMode() == TeRenderer::ShadowMode1 || !_shouldDraw) {
_materials[i].apply();
glDrawElements(_glMeshMode, _faceCounts[i] * 3, GL_UNSIGNED_SHORT, _indexes.data() + totalfacecount * 3);
@@ -146,7 +147,6 @@ void TeMesh::draw() {
renderer->disableTexture();
}
totalfacecount += _faceCounts[i];
- }
}
}
@@ -164,27 +164,11 @@ void TeMesh::draw() {
TeLight::disableAll();
glBegin(GL_LINES);
renderer->setCurrentColor(TeColor(255, 255, 255, 255));
- if (!_verticies.empty()) {
- error("TODO: Implement wire drawing here in TeMesh::draw..");
- /*
- offset1 = 1;
- offset2 = 2;
- do {
- i = (ulong)offset2;
- uVar5 = (ulong)(offset2 - 1);
- totalfacecount = (ulong)(offset2 - 2);
- glVertex3f
- ((&verticiesbuf->f1)[totalfacecount],(&verticiesbuf->f1)[uVar5],
- (&verticiesbuf->f1)[i]);
- glVertex3f
- ((&verticiesbuf->f1)[totalfacecount] + (&normalsbuf->f1)[totalfacecount],
- (&verticiesbuf->f1)[uVar5] + (&normalsbuf->f1)[uVar5],
- (&verticiesbuf->f1)[i] + (&normalsbuf->f1)[i]);
- offset2 = offset2 + 3;
- i = (ulong)offset1;
- offset1 = offset1 + 1;
- } while (i < (this->verticiesArray).len);
- */
+ for (unsigned int i = 0; i < verticies.size(); i++) {
+ glVertex3f(verticies[i].x(), verticies[i].y(), verticies[i].z());
+ glVertex3f(verticies[i].x() + normals[i].x(),
+ verticies[i].y() + normals[i].y(),
+ verticies[i].z() + normals[i].z());
}
glEnd();
}
@@ -328,14 +312,17 @@ TeVector3f32 TeMesh::vertex(uint idx) const {
return _verticies[idx];
}
-void TeMesh::attachMaterial(uint idx, const TeMaterial &material) {
- TeMaterial &mat = _materials[idx];
- mat._texture = material._texture;
- mat._enableLights = material._enableLights;
- mat._enableSomethingDefault0 = material._enableSomethingDefault0;
- mat._emissionColor = material._emissionColor;
- mat._diffuseColor = material._diffuseColor;
- mat._mode = material._mode;
+void TeMesh::attachMaterial(uint idx, const TeMaterial &src) {
+ TeMaterial &dest = _materials[idx];
+ dest._texture = src._texture;
+ dest._enableLights = src._enableLights;
+ dest._enableSomethingDefault0 = src._enableSomethingDefault0;
+ dest._emissionColor = src._emissionColor;
+ dest._shininess = src._shininess;
+ dest._diffuseColor = src._diffuseColor;
+ dest._specularColor = src._specularColor;
+ dest._mode = src._mode;
+ dest._ambientColor = src._ambientColor;
}
void TeMesh::facesPerMaterial(uint idx, unsigned short value) {
diff --git a/engines/tetraedge/te/te_model.cpp b/engines/tetraedge/te/te_model.cpp
index 5b22b028a4d..c5a500332e5 100644
--- a/engines/tetraedge/te/te_model.cpp
+++ b/engines/tetraedge/te/te_model.cpp
@@ -104,6 +104,16 @@ void TeModel::draw() {
renderer->sendModelMatrix(transform);
renderer->pushMatrix();
renderer->multiplyMatrix(transform);
+ if (name() == "Kate") {
+ debug("Draw model %p (%s, %d meshes)", this, name().empty() ? "no name" : name().c_str(), _meshes.size());
+ debug(" renderMatrix %s", renderer->currentMatrix().toString().c_str());
+ debug(" position %s", position().dump().c_str());
+ debug(" worldPos %s", worldPosition().dump().c_str());
+ debug(" scale %s", scale().dump().c_str());
+ debug(" worldScale %s", worldScale().dump().c_str());
+ debug(" rotation %s", rotation().dump().c_str());
+ debug(" worldRot %s", worldRotation().dump().c_str());
+ }
for (TeMesh &mesh : _meshes) {
// TODO: Set some flag in the mesh here to this->field_0x158??
mesh.draw();
@@ -118,7 +128,7 @@ void TeModel::forceMatrix(const TeMatrix4x4 &matrix) {
_forcedMatrix = matrix;
}
-TeTRS TeModel::getBone(TeIntrusivePtr<TeModelAnimation> anim, unsigned long num) {
+TeTRS TeModel::getBone(TeIntrusivePtr<TeModelAnimation> anim, unsigned int num) {
if (anim) {
int bone = anim->findBone(_bones[num]._name);
if (bone != -1)
@@ -154,8 +164,30 @@ void TeModel::update() {
matricies[i] = matricies[b._x] * matrix;
}
}
- if (_bones.size()) {
- //warning("TODO: Finish TeModel::update. (disasm 190 ~ 697)");
+ for (unsigned int b = 0; b < _bones.size(); b++) {
+ TeTRS startTRS = getBone(_modelAnim, b);
+ for (unsigned int i = 0; i < _boneBlenders.size(); i++) {
+ BonesBlender *blender = _boneBlenders[i];
+ float complete = MIN((blender->_timer.getTimeFromStart() / 1000000.0f) / blender->_seconds, 1.0f);
+ TeTRS trs;
+ TeTRS endTRS = getBone(blender->_anim, b);
+ if (complete == 1.0f) {
+ delete blender;
+ _boneBlenders.remove_at(i);
+ trs = endTRS;
+ i--;
+ } else {
+ trs = startTRS.lerp(endTRS, complete);
+ }
+ TeMatrix4x4 matrix;
+ if (!_matrixForced) {
+ matrix = TeMatrix4x4::fromTRS(trs);
+ } else {
+ matrix = _forcedMatrix;
+ _matrixForced = false;
+ }
+ }
+ //warning("TODO: Finish TeModel::update. (disasm 295 ~ 693)");
}
for (TeMesh &mesh : _meshes) {
if (!_modelVertexAnim) {
@@ -211,8 +243,14 @@ bool TeModel::load(Common::SeekableReadStream &stream) {
error("[TeModel::load] Unsupported version %d", version);
}
- _meshes.resize(stream.readUint32LE());
- _weightElements.resize(stream.readUint32LE());
+ uint32 meshCount = stream.readUint32LE();
+ if (meshCount > 100000)
+ error("TeModel::load: Unexpected number of meshes %d", meshCount);
+ _meshes.resize(meshCount);
+ uint32 weightCount = stream.readUint32LE();
+ if (weightCount > 100000)
+ error("TeModel::load: Unexpected number of weights %d", weightCount);
+ _weightElements.resize(weightCount);
uint32 bonecount = stream.readUint32LE();
if (bonecount > 100000)
error("TeModel::load: Unexpected number of bones %d", bonecount);
diff --git a/engines/tetraedge/te/te_model.h b/engines/tetraedge/te/te_model.h
index 10166e37a2c..bdf61c9173c 100644
--- a/engines/tetraedge/te/te_model.h
+++ b/engines/tetraedge/te/te_model.h
@@ -96,7 +96,7 @@ public:
int findModelBone(const Common::String &name);
int findOrAddWeights(const Common::Array<weightElement> &weights);
void forceMatrix(const TeMatrix4x4 &matrix);
- TeTRS getBone(TeIntrusivePtr<TeModelAnimation> anim, unsigned long num);
+ TeTRS getBone(TeIntrusivePtr<TeModelAnimation> anim, unsigned int num);
TeMatrix4x4 lerpElementsMatrix(unsigned long num, Common::Array<TeMatrix4x4> &matricies);
/* Align the stream to the nearest 4 byte boudary*/
diff --git a/engines/tetraedge/te/te_pick_mesh2.cpp b/engines/tetraedge/te/te_pick_mesh2.cpp
index 4b279900895..09a019ec17b 100644
--- a/engines/tetraedge/te/te_pick_mesh2.cpp
+++ b/engines/tetraedge/te/te_pick_mesh2.cpp
@@ -44,7 +44,7 @@ void TePickMesh2::draw() {
TeRenderer *renderer = g_engine->getRenderer();
- TeColor prevCol = renderer->currentColor();
+ const TeColor prevCol = renderer->currentColor();
renderer->setCurrentColor(TeColor(0xff, 0, 0, 0xff));
renderer->pushMatrix();
diff --git a/engines/tetraedge/te/te_pick_mesh2.h b/engines/tetraedge/te/te_pick_mesh2.h
index c43ee54f5ac..817b518b384 100644
--- a/engines/tetraedge/te/te_pick_mesh2.h
+++ b/engines/tetraedge/te/te_pick_mesh2.h
@@ -52,6 +52,7 @@ public:
Common::Array<TeVector3f32> &verticies() { return _verticies; }
const Common::Array<TeVector3f32> &verticies() const { return _verticies; }
+
private:
Common::Array<TeVector3f32> _verticies;
unsigned long _lastTriangleHit;
diff --git a/engines/tetraedge/te/te_quaternion.cpp b/engines/tetraedge/te/te_quaternion.cpp
index 9a1c4086b2e..0ed7d3c3b9e 100644
--- a/engines/tetraedge/te/te_quaternion.cpp
+++ b/engines/tetraedge/te/te_quaternion.cpp
@@ -26,4 +26,8 @@ namespace Tetraedge {
TeQuaternion::TeQuaternion() {
}
+Common::String TeQuaternion::dump() const {
+ return Common::String::format("TeQuat(%.02f %.02f %.02f %.02f)", x(), y(), z(), w());
+}
+
} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_quaternion.h b/engines/tetraedge/te/te_quaternion.h
index 3cfa597a962..cc8ae96ce42 100644
--- a/engines/tetraedge/te/te_quaternion.h
+++ b/engines/tetraedge/te/te_quaternion.h
@@ -37,13 +37,37 @@ public:
static TeQuaternion fromAxisAndAngle(const TeVector3f32 &axis, float angle) {
TeQuaternion ret;
float f = sinf(angle * 0.5);
- ret.w() = axis.x() * f;
- ret.x() = axis.y() * f;
- ret.y() = axis.z() * f;
- ret.z() = cosf(angle * 0.5);
+ ret.x() = axis.x() * f;
+ ret.y() = axis.y() * f;
+ ret.z() = axis.z() * f;
+ ret.w() = cosf(angle * 0.5);
return ret;
}
+ static TeQuaternion fromEuler(const TeVector3f32 &euler) {
+ TeQuaternion rot;
+
+ rot.x() = sinf(euler.x() / 2.0);
+ rot.y() = 0.0;
+ rot.z() = 0.0;
+ rot.w() = cosf(euler.x() / 2.0);
+ TeQuaternion retval = rot;
+
+ rot.x() = 0.0;
+ rot.y() = sinf(euler.y() / 2.0);
+ rot.z() = 0.0;
+ rot.w() = cosf(euler.y() / 2.0);
+ retval *= rot;
+
+ rot.x() = 0.0;
+ rot.y() = 0.0;
+ rot.z() = sinf(euler.z() / 2.0);
+ rot.w() = cosf(euler.z() / 2.0);
+ retval *= rot;
+
+ return retval;
+ }
+
static void deserialize(Common::ReadStream &stream, TeQuaternion &dest) {
dest.value(0) = stream.readFloatLE();
dest.value(1) = stream.readFloatLE();
@@ -58,6 +82,7 @@ public:
stream.writeFloatLE(src.value(3));
}
+ Common::String dump() const;
};
} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_scene.cpp b/engines/tetraedge/te/te_scene.cpp
index 3df69b9b559..bdb826d9fc0 100644
--- a/engines/tetraedge/te/te_scene.cpp
+++ b/engines/tetraedge/te/te_scene.cpp
@@ -66,6 +66,7 @@ void TeScene::draw() {
currentCamera()->apply();
for (auto &m : _models) {
+ //debug("Draw scene model %s", m->name().c_str());
m->draw();
}
TeCamera::restore();
diff --git a/engines/tetraedge/te/te_scene.h b/engines/tetraedge/te/te_scene.h
index 4302a16c81f..0bdf12059d6 100644
--- a/engines/tetraedge/te/te_scene.h
+++ b/engines/tetraedge/te/te_scene.h
@@ -37,7 +37,7 @@ public:
TeScene();
virtual ~TeScene() {};
- void close();
+ virtual void close();
TeIntrusivePtr<TeCamera> camera(const Common::String &name);
TeIntrusivePtr<TeModel> model(const Common::String &name);
@@ -46,7 +46,7 @@ public:
int currentCameraIndex() const { return _currentCameraIndex; }
Common::String currentCameraName() const;
- void draw();
+ virtual void draw();
virtual bool load(const Common::Path &path) { return false; };
void removeModel(const Common::String &name);
@@ -55,7 +55,7 @@ public:
_currentCameraIndex = index;
}
- void update();
+ virtual void update();
Common::Array<TeIntrusivePtr<TeModel>> &models() { return _models; }
diff --git a/engines/tetraedge/te/te_scummvm_codec.h b/engines/tetraedge/te/te_scummvm_codec.h
index 3fdb429d92d..dad39372c7d 100644
--- a/engines/tetraedge/te/te_scummvm_codec.h
+++ b/engines/tetraedge/te/te_scummvm_codec.h
@@ -33,7 +33,7 @@ public:
virtual ~TeScummvmCodec();
virtual bool load(const Common::Path &path) override;
- virtual bool load(Common::SeekableReadStream &stream) override = 0;
+ virtual bool load(Common::SeekableReadStream &stream) = 0;
virtual uint width() override;
virtual uint height() override;
virtual int nbFrames() override { return 1; }
diff --git a/engines/tetraedge/te/te_sound_manager.cpp b/engines/tetraedge/te/te_sound_manager.cpp
index 6104d233c34..42588e7ed45 100644
--- a/engines/tetraedge/te/te_sound_manager.cpp
+++ b/engines/tetraedge/te/te_sound_manager.cpp
@@ -67,6 +67,13 @@ void TeSoundManager::playFreeSound(const Common::Path &path, float vol, const Co
mixer->playStream(Audio::Mixer::kMusicSoundType, &_handles[channel], stream, channelId, bvol);
}
-// TODO: Add more functions here.
+void TeSoundManager::stopFreeSound(const Common::String &name) {
+ if (!_handles.contains(name))
+ return;
+ Audio::Mixer *mixer = g_system->getMixer();
+ mixer->stopHandle(_handles.getVal(name));
+ _handles.erase(name);
+}
+
} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_sound_manager.h b/engines/tetraedge/te/te_sound_manager.h
index cac071ec110..dbce36199cd 100644
--- a/engines/tetraedge/te/te_sound_manager.h
+++ b/engines/tetraedge/te/te_sound_manager.h
@@ -33,6 +33,7 @@ public:
TeSoundManager();
void playFreeSound(const Common::Path &path, float vol, const Common::String &channel);
+ void stopFreeSound(const Common::String &channel);
private:
Common::HashMap<Common::String, Audio::SoundHandle> _handles;
diff --git a/engines/tetraedge/te/te_theora.cpp b/engines/tetraedge/te/te_theora.cpp
index b2947a80359..47c9b985e79 100644
--- a/engines/tetraedge/te/te_theora.cpp
+++ b/engines/tetraedge/te/te_theora.cpp
@@ -43,10 +43,6 @@ bool TeTheora::load(const Common::Path &path) {
return _decoder->loadFile(path);
}
-bool TeTheora::load(Common::SeekableReadStream &stream) {
- return _decoder->loadStream(&stream);
-}
-
uint TeTheora::width() {
return _decoder->getWidth();
}
diff --git a/engines/tetraedge/te/te_theora.h b/engines/tetraedge/te/te_theora.h
index b4302d5e148..517777b9dda 100644
--- a/engines/tetraedge/te/te_theora.h
+++ b/engines/tetraedge/te/te_theora.h
@@ -37,7 +37,6 @@ public:
virtual ~TeTheora();
virtual bool load(const Common::Path &path) override;
- virtual bool load(Common::SeekableReadStream &stream) override;
virtual uint width() override;
virtual uint height() override;
virtual int nbFrames() override;
diff --git a/engines/tetraedge/te/te_tiled_surface.h b/engines/tetraedge/te/te_tiled_surface.h
index e081f5c1df9..9e9c77a42ea 100644
--- a/engines/tetraedge/te/te_tiled_surface.h
+++ b/engines/tetraedge/te/te_tiled_surface.h
@@ -41,7 +41,7 @@ public:
virtual int bufferSize() { return 1; } // unused?
void cont();
- void draw();
+ void draw() override;
virtual void entry() {};
byte isLoaded();
bool load(const Common::Path &path);
diff --git a/engines/tetraedge/te/te_timer.cpp b/engines/tetraedge/te/te_timer.cpp
index 02b2085a9b0..79db37f7649 100644
--- a/engines/tetraedge/te/te_timer.cpp
+++ b/engines/tetraedge/te/te_timer.cpp
@@ -112,6 +112,10 @@ unsigned long TeTimer::timeElapsed() {
return elapsed;
}
+unsigned long TeTimer::timeFromLastTimeElapsed() {
+ return realTimer()->time_() - _lastTimeElapsed;
+}
+
unsigned long TeTimer::time_() {
return realTimer()->time_();
}
diff --git a/engines/tetraedge/te/te_timer.h b/engines/tetraedge/te/te_timer.h
index fa7962516ee..6d04e5bd2d4 100644
--- a/engines/tetraedge/te/te_timer.h
+++ b/engines/tetraedge/te/te_timer.h
@@ -39,6 +39,7 @@ public:
unsigned long getTimeFromStart();
void setAlarmIn(unsigned long offset);
unsigned long timeElapsed();
+ unsigned long timeFromLastTimeElapsed();
unsigned long time_();
void setTime(unsigned long time);
diff --git a/engines/tetraedge/te/te_xml_gui.cpp b/engines/tetraedge/te/te_xml_gui.cpp
index f31d84e1866..e9ba7c0bd62 100644
--- a/engines/tetraedge/te/te_xml_gui.cpp
+++ b/engines/tetraedge/te/te_xml_gui.cpp
@@ -30,7 +30,9 @@ TeXmlGui::TeXmlGui() {
}
Common::String TeXmlGui::value(const Common::String &key) {
- error("TODO: TeXmlGui::value Implement me.");
+ if (_map.contains(key))
+ return _map.getVal(key);
+ return "";
}
void TeXmlGui::load(const Common::Path &path) {
@@ -44,9 +46,8 @@ void TeXmlGui::load(const Common::Path &path) {
}
void TeXmlGui::clear() {
-
+ _map.clear();
+ // TODO: probably more here.
}
-// TODO: Add more functions here.
-
} // end namespace Tetraedge
Commit: 2c873918031f2ed1e436c99d3a3b4ee88f43da9d
https://github.com/scummvm/scummvm/commit/2c873918031f2ed1e436c99d3a3b4ee88f43da9d
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2023-01-16T17:36:43+01:00
Commit Message:
TETRAEDGE: WIP, fixed loads of TODOs.
Changed paths:
engines/tetraedge/game/application.cpp
engines/tetraedge/game/bonus_menu.cpp
engines/tetraedge/game/bonus_menu.h
engines/tetraedge/game/character.cpp
engines/tetraedge/game/character.h
engines/tetraedge/game/game.cpp
engines/tetraedge/game/game.h
engines/tetraedge/game/game_sound.cpp
engines/tetraedge/game/game_sound.h
engines/tetraedge/game/how_to.cpp
engines/tetraedge/game/in_game_scene.cpp
engines/tetraedge/game/in_game_scene.h
engines/tetraedge/game/inventory.cpp
engines/tetraedge/game/lua_binds.cpp
engines/tetraedge/game/main_menu.cpp
engines/tetraedge/game/object3d.cpp
engines/tetraedge/game/object3d.h
engines/tetraedge/te/te_camera.cpp
engines/tetraedge/te/te_camera.h
engines/tetraedge/te/te_extended_text_layout.cpp
engines/tetraedge/te/te_free_move_zone.cpp
engines/tetraedge/te/te_free_move_zone.h
engines/tetraedge/te/te_i_layout.h
engines/tetraedge/te/te_images_sequence.cpp
engines/tetraedge/te/te_images_sequence.h
engines/tetraedge/te/te_list_layout.h
engines/tetraedge/te/te_lua_context.cpp
engines/tetraedge/te/te_lua_script.cpp
engines/tetraedge/te/te_model.cpp
engines/tetraedge/te/te_model.h
engines/tetraedge/te/te_model_animation.cpp
engines/tetraedge/te/te_model_animation.h
engines/tetraedge/te/te_pick_mesh2.cpp
engines/tetraedge/te/te_pick_mesh2.h
engines/tetraedge/te/te_scene.cpp
engines/tetraedge/te/te_scene.h
engines/tetraedge/te/te_scrolling_layout.h
engines/tetraedge/te/te_tiled_surface.cpp
engines/tetraedge/te/te_tiled_texture.cpp
diff --git a/engines/tetraedge/game/application.cpp b/engines/tetraedge/game/application.cpp
index 174870ef10f..6fc5150494a 100644
--- a/engines/tetraedge/game/application.cpp
+++ b/engines/tetraedge/game/application.cpp
@@ -69,7 +69,7 @@ _drawShadows(true) {
}
void Application::create() {
- warning("TODO: Move mainWindowCamera to mainWindow");
+ // TODO: Move mainWindowCamera to mainWindow?
const int winWidth = g_engine->getDefaultScreenWidth();
const int winHeight = g_engine->getDefaultScreenHeight();
@@ -284,7 +284,7 @@ void Application::destroy() {
void Application::startGame(bool newGame, int difficulty) {
_appSpriteLayout.setVisible(false);
- // TODO: there's another virtual call to appsprite surface here here.. not needed?
+ _appSpriteLayout.pause();
_appSpriteLayout.unload();
if (newGame)
_difficulty = difficulty;
@@ -299,8 +299,7 @@ bool Application::run() {
if (_created) {
TeTimer::updateAll();
if (!_dontUpdateWhenApplicationPaused) {
- // TODO: finish commented-out bits??
- // we run the inputmgr separately.. is that ok?
+ // Note: we run the inputmgr separately.. probably no need for this.
//_inputmgr->update();
TeAnimation::updateAll();
//TeVideo::updateAll();
@@ -506,6 +505,4 @@ const char *Application::inAppUnlockFullVersionID() {
error("TODO: Implement Application::inAppUnlockFullVersionID");
}
-// TODO: Add more functions here.
-
} // end namespace Tetraedge
diff --git a/engines/tetraedge/game/bonus_menu.cpp b/engines/tetraedge/game/bonus_menu.cpp
index d91c2c66437..bc734d7cc4f 100644
--- a/engines/tetraedge/game/bonus_menu.cpp
+++ b/engines/tetraedge/game/bonus_menu.cpp
@@ -24,7 +24,7 @@
#include "common/textconsole.h"
#include "tetraedge/tetraedge.h"
#include "tetraedge/game/application.h"
-//#include "tetraedge/te/te_input_manager"
+#include "tetraedge/te/te_input_mgr.h"
namespace Tetraedge {
@@ -79,15 +79,11 @@ bool BonusMenu::onRightButton() {
return false;
}
-bool BonusMenu::onSideButtonDown() {
- /*
- TeInputManager *inputmgr = g_engine->getInputManager();
- TeVector2s32 mousepos = inputmgr->getMousePos();
- _slideBtnStartMousePos = mousepos;
- buttonLayout("slideButton");
- // TODO set some flag in super (TeLuaGUI)
- */
- error("TODO: implement me.");
+bool BonusMenu::onSlideButtonDown() {
+ TeInputMgr *inputmgr = g_engine->getInputMgr();
+ TeVector2s32 mousepos = inputmgr->lastMousePos();
+ _slideBtnStartMousePos = mousepos;
+ buttonLayoutChecked("slideButton")->setClickPassThrough(true);
return false;
}
diff --git a/engines/tetraedge/game/bonus_menu.h b/engines/tetraedge/game/bonus_menu.h
index 0c87516159b..4cb63291fa1 100644
--- a/engines/tetraedge/game/bonus_menu.h
+++ b/engines/tetraedge/game/bonus_menu.h
@@ -53,7 +53,7 @@ public:
bool onPictureButton();
bool onQuitButton();
bool onRightButton();
- bool onSideButtonDown();
+ bool onSlideButtonDown();
// empty? bool onLoadGameConfirmed() { };
diff --git a/engines/tetraedge/game/character.cpp b/engines/tetraedge/game/character.cpp
index e231c0c32f9..62aaff289d5 100644
--- a/engines/tetraedge/game/character.cpp
+++ b/engines/tetraedge/game/character.cpp
@@ -56,7 +56,7 @@ void Character::WalkSettings::clear() {
Character::Character() : _curveOffset(0), _lastFrame(-1), _callbacksChanged(false),
_missingCurrentAnim(false), _someRepeatFlag(false), _walkModeStr("Walk"),
-_needsSomeUpdate(false), _positionFlag(false),
+_needsSomeUpdate(false), _positionFlag(false), _lookingAtTallThing(false),
_stepSound1("sounds/SFX/PAS_H_BOIS1.ogg"), _stepSound2("sounds/SFX/PAS_H_BOIS2.ogg"),
_freeMoveZone(nullptr), _animSoundOffset(0), _lastAnimFrame(0), _charLookingAt(nullptr) {
_curModelAnim.setDeleteFn(&TeModelAnimation::deleteLater);
@@ -125,7 +125,6 @@ float Character::animLengthFromFile(const Common::String &animname, uint *pframe
int frameCount = anim->lastFrame() + 1 - anim->firstFrame();
*pframeCount = frameCount;
- // TODO: Check this maths.. is this really what it does?
return animLen * _model->scale().z();
}
@@ -236,7 +235,7 @@ int Character::rightStepFrame(enum Character::WalkPart walkpart) {
return -1;
}
-bool Character::loadModel(const Common::String &name, bool unused) {
+bool Character::loadModel(const Common::String &mname, bool unused) {
assert(_globalCharacterSettings);
if (_model) {
//TODO
@@ -245,10 +244,10 @@ bool Character::loadModel(const Common::String &name, bool unused) {
_model = new TeModel();
//_model->bonesUpdateSignal().add(this, &Character::onBonesUpdate);
- if (!_globalCharacterSettings->contains(name))
+ if (!_globalCharacterSettings->contains(mname))
return false;
- _characterSettings = _globalCharacterSettings->getVal(name);
+ _characterSettings = _globalCharacterSettings->getVal(mname);
_model->_texturePath = Common::Path("models/Textures");
_model->_enableLights = true;
Common::Path modelPath("models");
@@ -256,7 +255,7 @@ bool Character::loadModel(const Common::String &name, bool unused) {
if (!_model->load(modelPath))
return false;
- _model->setName(name);
+ _model->setName(mname);
_model->setScale(_characterSettings._defaultScale);
for (auto &mesh : _model->_meshes)
@@ -270,11 +269,11 @@ bool Character::loadModel(const Common::String &name, bool unused) {
_model->setVisibleByName(_characterSettings._defaultMouth, true);
_model->setVisibleByName(_characterSettings._defaultBody, true);
- setAnimation(_characterSettings._walkFileName, true, false, false, -1, 9999);
+ setAnimation(_characterSettings._walkFileName, true);
- _walkPart0AnimLen = animLengthFromFile(walkAnim(WalkPart_Start), &_walkPart0AnimFrameCount, 9999);
- _walkPart3AnimLen = animLengthFromFile(walkAnim(WalkPart_EndG), &_walkPart3AnimFrameCount, 9999);
- _walkPart1AnimLen = animLengthFromFile(walkAnim(WalkPart_Loop), &_walkPart1AnimFrameCount, 9999);
+ _walkPart0AnimLen = animLengthFromFile(walkAnim(WalkPart_Start), &_walkPart0AnimFrameCount);
+ _walkPart3AnimLen = animLengthFromFile(walkAnim(WalkPart_EndG), &_walkPart3AnimFrameCount);
+ _walkPart1AnimLen = animLengthFromFile(walkAnim(WalkPart_Loop), &_walkPart1AnimFrameCount);
TeIntrusivePtr<Te3DTexture> shadow = new Te3DTexture();
shadow->load("models/Textures/simple_shadow_alpha.tga");
@@ -373,17 +372,17 @@ void Character::removeFromCurve() {
_curve.release();
}
-bool Character::setAnimation(const Common::String &name, bool repeat, bool param_3, bool unused, int startFrame, int endFrame) {
- if (name.empty())
+bool Character::setAnimation(const Common::String &aname, bool repeat, bool param_3, bool unused, int startFrame, int endFrame) {
+ if (aname.empty())
return false;
Common::Path animPath("models/Anims");
- animPath.joinInPlace(name);
- bool validAnim = (name.contains(_characterSettings._walkFileName) ||
- name.contains(walkAnim(WalkPart_Start)) ||
- name.contains(walkAnim(WalkPart_Loop)) ||
- name.contains(walkAnim(WalkPart_EndD)) ||
- name.contains(walkAnim(WalkPart_EndG)));
+ animPath.joinInPlace(aname);
+ bool validAnim = (aname.contains(_characterSettings._walkFileName) ||
+ aname.contains(walkAnim(WalkPart_Start)) ||
+ aname.contains(walkAnim(WalkPart_Loop)) ||
+ aname.contains(walkAnim(WalkPart_EndD)) ||
+ aname.contains(walkAnim(WalkPart_EndG)));
_missingCurrentAnim = !validAnim;
if (_curModelAnim) {
@@ -397,16 +396,16 @@ bool Character::setAnimation(const Common::String &name, bool repeat, bool param
_model->setAnim(_curModelAnim, repeat);
_lastFrame = -1;
_curModelAnim->play();
- _setAnimName = name;
- _curAnimName = name;
+ _setAnimName = aname;
+ _curAnimName = aname;
_someRepeatFlag = !(repeat | !param_3);
return true;
}
-void Character::setAnimationSound(const Common::String &name, uint offset) {
+void Character::setAnimationSound(const Common::String &sname, uint offset) {
warning("TODO: Set field 0x2f8 to 0 in Character::setAnimationSound.");
- _animSound = name;
+ _animSound = sname;
_animSoundOffset = offset;
}
@@ -463,9 +462,12 @@ void Character::updateAnimFrame() {
void Character::updatePosition(float curveOffset) {
if (!_curve->controlPoints().empty()) {
- //TeVector3f32 pt = _curve->retrievePoint(curveOffset);
- // add field 0x214
- error("TODO: Implement Character::updatePosition");
+ TeVector3f32 pt = _curve->retrievePoint(curveOffset) + _curveStartLocation;
+ if (_freeMoveZone) {
+ bool flag;
+ pt = _freeMoveZone->correctCharacterPosition(pt, &flag, true);
+ }
+ _model->setPosition(pt);
}
}
diff --git a/engines/tetraedge/game/character.h b/engines/tetraedge/game/character.h
index 9e13e8b89c7..d9c005f2de4 100644
--- a/engines/tetraedge/game/character.h
+++ b/engines/tetraedge/game/character.h
@@ -99,7 +99,7 @@ public:
static TeIntrusivePtr<TeModelAnimation> animCacheLoad(const Common::Path &path);
float animLength(const TeModelAnimation &modelanim, long bone, long lastframe);
- float animLengthFromFile(const Common::String &animname, uint *pframeCount, uint lastframe);
+ float animLengthFromFile(const Common::String &animname, uint *pframeCount, uint lastframe = 9999);
bool blendAnimation(const Common::String &animname, float amount, bool repeat, bool param_4);
TeVector3f32 correctPosition(const TeVector3f32 &pos);
float curveOffset();
@@ -126,7 +126,7 @@ public:
void removeFromCurve();
static Common::String rootBone() { return "Pere"; }
- bool setAnimation(const Common::String &name, bool repeat, bool param_3, bool param_4, int startFrame, int endFrame);
+ bool setAnimation(const Common::String &name, bool repeat, bool param_3 = false, bool param_4 = false, int startFrame = -1, int endFrame = 9999);
void setAnimationSound(const Common::String &name, uint offset);
void setCurveOffset(float offset);
void setFreeMoveZone(TeFreeMoveZone *zone);
@@ -158,13 +158,26 @@ public:
bool needsSomeUpdate() const { return _needsSomeUpdate; }
void setNeedsSomeUpdate(bool val) { _needsSomeUpdate = val; }
void setCharLookingAt(Character *other) { _charLookingAt = other; }
+ const TeVector3f32 &positionCharacter() const { return _positionCharacter; }
void setPositionCharacter(const TeVector3f32 &val) { _positionCharacter = val; }
bool positionFlag() const { return _positionFlag; }
void setPositionFlag(bool val) { _positionFlag = val; }
+ void setCurveStartLocation(const TeVector3f32 &val) { _curveStartLocation = val; }
+ bool hasAnchor() const { return _hasAnchor; }
+ void setHasAnchor(bool val) { _hasAnchor = val; }
+ const TeVector2f32 &headRotation() const { return _headRotation; }
+ void setHeadRotation(const TeVector2f32 &val) { _headRotation = val; }
+ void setLastHeadRotation(const TeVector2f32 &val) { _lastHeadRotation = val; }
+ Character *charLookingAt() { return _charLookingAt; }
+ bool lookingAtTallThing() const { return _lookingAtTallThing; }
+ void setLookingAtTallThing(bool val) { _lookingAtTallThing = val; }
+
private:
float _curveOffset;
TeIntrusivePtr<TeBezierCurve> _curve;
+ TeVector3f32 _curveStartLocation;
+
TeFreeMoveZone *_freeMoveZone;
Common::String _freeMoveZoneName;
Common::String _stepSound1;
@@ -193,8 +206,13 @@ private:
bool _missingCurrentAnim;
bool _someRepeatFlag; // TODO: what is this?
bool _callbacksChanged;
- bool _needsSomeUpdate; // TODO: what is this? Field 0x85.
+ bool _needsSomeUpdate;
bool _positionFlag;
+ bool _lookingAtTallThing;
+
+ bool _hasAnchor;
+ TeVector2f32 _headRotation;
+ TeVector2f32 _lastHeadRotation;
TeVector3f32 _positionCharacter;
diff --git a/engines/tetraedge/game/game.cpp b/engines/tetraedge/game/game.cpp
index 6bfc12cc8c4..4c646a33a67 100644
--- a/engines/tetraedge/game/game.cpp
+++ b/engines/tetraedge/game/game.cpp
@@ -47,10 +47,16 @@ namespace Tetraedge {
Game::Game() : _objectsTakenVal(0), _score(0), _entered(false), _gameLoadState(0),
_noScaleLayout(nullptr), _noScaleLayout2(nullptr), _warped(false), _saveRequested(false),
_firstInventory(true), _movePlayerCharacterDisabled(false), _enteredFlag2(false),
-_luaShowOwnerError(false), _markersVisible(true), _running(false), _loadName("save.xml") {
+_luaShowOwnerError(false), _markersVisible(true), _running(false), _loadName("save.xml"),
+_randomSoundFinished(false), _randomSource("SyberiaGameRandom") {
for (int i = 0; i < NUM_OBJECTS_TAKEN_IDS; i++) {
_objectsTakenBits[i] = false;
}
+ _randomSound = new RandomSound();
+}
+
+Game::~Game() {
+ delete _randomSound;
}
/*static*/ const char *Game::OBJECTS_TAKEN_IDS[5] = {
@@ -137,14 +143,14 @@ void Game::addNoScaleChildren() {
_noScaleLayout->addChild(&_documentsBrowser.zoomedLayout());
}
-void Game::addRandomSound(const Common::String &name, const Common::String &path, float f1, float f2) {
+void Game::addRandomSound(const Common::String &name, const Common::String &path, float f1, float volume) {
if (!_randomSounds.contains(name)) {
_randomSounds[name] = Common::Array<RandomSound*>();
}
RandomSound *randsound = new RandomSound();
randsound->_path = path;
randsound->_f1 = f1;
- randsound->_f2 = f2;
+ randsound->_volume = volume;
randsound->_name = name;
_randomSounds[name].push_back(randsound);
}
@@ -431,7 +437,7 @@ bool Game::initWarp(const Common::String &zone, const Common::String &scene, boo
_scene._character->_model->setVisible(true);
_scene._character->deleteAllCallback();
_scene._character->stop();
- _scene._character->setAnimation(_scene._character->characterSettings()._walkFileName, true, false, false, -1, 9999);
+ _scene._character->setAnimation(_scene._character->characterSettings()._walkFileName, true);
if (!_scene.findKate()) {
_scene.models().push_back(_scene._character->_model);
_scene.models().push_back(_scene._character->_shadowModel[0]);
@@ -526,9 +532,8 @@ bool Game::initWarp(const Common::String &zone, const Common::String &scene, boo
TeButtonLayout *vidbgbtn = _inGameGui.buttonLayout("videoBackgroundButton");
vidbgbtn->setVisible(false);
- /* TODO: Restore the original behavior here (onLockVideoButtonValidated) */
- vidbgbtn->onMouseClickValidated().remove(this, &Game::onSkipVideoButtonValidated);
- vidbgbtn->onMouseClickValidated().add(this, &Game::onSkipVideoButtonValidated);
+ vidbgbtn->onMouseClickValidated().remove(this, &Game::onLockVideoButtonValidated);
+ vidbgbtn->onMouseClickValidated().add(this, &Game::onLockVideoButtonValidated);
TeSpriteLayout *video = _inGameGui.spriteLayout("video");
video->setVisible(false);
@@ -606,10 +611,11 @@ bool Game::initWarp(const Common::String &zone, const Common::String &scene, boo
_luaScript.execute("OnSelectedObject", _inventory.selectedObject());
}
- if (!_gameSounds.empty()) {
- //for (auto & sound : _gameSounds) {
- warning("TODO: Game::initWarp: Do game sound stuff here");
+ for (GameSound *sound : _gameSounds) {
+ sound->stop();
+ sound->deleteLater();
}
+ _gameSounds.clear();
for (auto &randsoundlist : _randomSounds) {
for (auto *randsound : randsoundlist._value) {
@@ -771,7 +777,7 @@ bool Game::onDialogFinished(const Common::String &val) {
bool Game::onDisplacementFinished() {
_sceneCharacterVisibleFromLoad = true;
_scene._character->stop();
- _scene._character->setAnimation(_scene._character->characterSettings()._walkFileName, true, false, false, -1, 9999);
+ _scene._character->setAnimation(_scene._character->characterSettings()._walkFileName, true);
// TODO: Twiddle flags 0x424b and 0x4249
/*
@@ -946,7 +952,7 @@ bool Game::onMouseClick(const Common::Point &pt) {
TeIntrusivePtr<TeBezierCurve> curve = character->freeMoveZone()->curve(charPos, TeVector2s32(pt), 8.0, true);
if (curve) {
_scene.setCurve(curve);
- // TODO: set character field_0x214 to TeVector3f32(0,0,0)
+ character->setCurveStartLocation(TeVector3f32());
if (curve->controlPoints().size() == 1) {
character->endMove();
} else {
@@ -962,7 +968,7 @@ bool Game::onMouseClick(const Common::Point &pt) {
character->placeOnCurve(curve);
character->setCurveOffset(0.0);
if (charAnim != character->walkAnim(Character::WalkPart_Start)) {
- character->setAnimation(character->walkAnim(Character::WalkPart_Start), false, false, false, -1, 9999);
+ character->setAnimation(character->walkAnim(Character::WalkPart_Start), false);
}
character->walkTo(1.0, false);
_sceneCharacterVisibleFromLoad = false;
@@ -972,13 +978,11 @@ bool Game::onMouseClick(const Common::Point &pt) {
return false;
}
}
- // TOOD: Finis this (line ~180 onward)
- warning("TODO: Finish Game::onMouseClick");
}
TeVector3f32 lastPoint = _scene.curve()->controlPoints().back();
- character->setAnimation(character->walkAnim(Character::WalkPart_Loop), true, false, false, -1, 9999);
+ character->setAnimation(character->walkAnim(Character::WalkPart_Loop), true);
character->walkTo(1.0, false);
- // TODO: Set app field field_0x910b
+ // TODO: Set app field field_0x424b to true
_posPlayer = lastPoint;
}
@@ -1173,11 +1177,86 @@ void Game::playRandomSound(const Common::String &name) {
warning("Game::playRandomSound: can't find sound list %s", name.c_str());
return;
}
- warning("TODO: Implemet Game::playRandomSound");
+
+ if (!_randomSoundFinished) {
+ _randomSoundTimer.start();
+ int r = _randomSource.getRandomNumber(RAND_MAX);
+ float f = (r + 1 + (r / 100) * -100);
+ long time = 1000000;
+ if (f >= 25.0) {
+ time = f * 45000.0;
+ }
+ _randomSoundTimer.setAlarmIn(time);
+ _randomSoundTimer.alarmSignal().remove(_randomSound, &RandomSound::onSoundFinished);
+ _randomSoundTimer.alarmSignal().add(_randomSound, &RandomSound::onSoundFinished);
+ _randomSound->_name = name;
+ } else {
+ Common::Array<RandomSound *> &sndlist = _randomSounds[name];
+ float total = 0.0;
+ for (auto *snd : sndlist) {
+ total += snd->_f1;
+ }
+ int r = _randomSource.getRandomNumber(RAND_MAX);
+ float total2 = 0.0;
+ unsigned int i = 0;
+ while (i < sndlist.size() && total2 <= r * 4.656613e-10 * total) {
+ total2 += sndlist[i]->_f1;
+ i++;
+ }
+ assert(i > 0);
+ i--;
+ RandomSound *sound = sndlist[i];
+ sound->_music.volume(sound->_volume);
+ sound->_music.onStopSignal().remove(sound, &RandomSound::onSoundFinished);
+ sound->_music.onStopSignal().add(sound, &RandomSound::onSoundFinished);
+ sound->_music.load(sound->_path.toString());
+ sound->_music.repeat(false);
+ sound->_music.play();
+ // TODO: set a flag that it's playing?
+ }
}
-void Game::playSound(const Common::String &name, int param_2, float param_3) {
- warning("TODO: Implemet Game::playSound");
+void Game::playSound(const Common::String &name, int repeats, float volume) {
+ Game *game = g_engine->getGame();
+
+ assert(repeats == 1 || repeats == -1);
+ if (repeats == 1) {
+ GameSound *sound = new GameSound();
+ sound->setName(name);
+ sound->setChannelName("sfx");
+ sound->repeat(false);
+ sound->load(name);
+ sound->volume(volume);
+ if (!sound->play()) {
+ game->luaScript().execute("OnFreeSoundFinished", name);
+ game->luaScript().execute("OnCellFreeSoundFinished", name);
+ // TODO: original seems to leak sound here??
+ } else {
+ sound->onStopSignal().add(sound, &GameSound::onSoundStopped);
+ // TODO: set snd->field_0x201
+ _gameSounds.push_back(sound);
+ }
+ } else if (repeats == -1) {
+ for (GameSound *snd : _gameSounds) {
+ if (snd->getAccessName() == name) {
+ // TODO: set snd->field_0x201
+ return;
+ }
+ }
+
+ GameSound *sound = new GameSound();
+ sound->setChannelName("sfx");
+ sound->load(name);
+ sound->volume(volume);
+ if (!sound->play()) {
+ game->luaScript().execute("OnFreeSoundFinished", name);
+ game->luaScript().execute("OnCellFreeSoundFinished", name);
+ delete sound;
+ } else {
+ // TODO: set snd->field_0x201
+ _gameSounds.push_back(sound);
+ }
+ }
}
void Game::removeNoScale2Child(TeLayout *layout) {
@@ -1341,26 +1420,34 @@ void Game::update() {
else
warning("Game::update: InventoryButton is null.");
- if (_scene._character) {
- TeIntrusivePtr<TeModel> model = _scene._character->_model;
+ Character *player = _scene._character;
+ if (player) {
+ TeIntrusivePtr<TeModel> model = player->_model;
bool modelVisible = model->visible();
if (!model->anim().get())
- _scene._character->permanentUpdate();
+ player->permanentUpdate();
if (modelVisible) {
- if (_scene._character->needsSomeUpdate()) {
+ if (player->needsSomeUpdate()) {
Game *game = g_engine->getGame();
game->_sceneCharacterVisibleFromLoad = false;
- TeVector3f32 charPos = _scene._character->_model->position();
- const Common::String charName = _scene._character->_model->name();
- TeFreeMoveZone *zone = _scene.pathZone(_scene._character->freeMoveZoneName());
+ TeVector3f32 charPos = player->_model->position();
+ const Common::String charName = player->_model->name();
+ TeFreeMoveZone *zone = _scene.pathZone(player->freeMoveZoneName());
if (zone) {
TeIntrusivePtr<TeCamera> cam = _scene.currentCamera();
zone->setCamera(cam, false);
- _scene._character->setFreeMoveZone(zone);
- _scene.setPositionCharacter(charName, _scene._character->freeMoveZoneName(), charPos);
- error("TODO: Game::update: Finish bit after permanentUpdate");
+ player->setFreeMoveZone(zone);
+ _scene.setPositionCharacter(charName, player->freeMoveZoneName(), charPos);
+ TeIntrusivePtr<TeBezierCurve> curve = zone->curve(model->position(), player->positionCharacter());
+ _scene.setCurve(curve);
+ player->setCurveStartLocation(TeVector3f32(0, 0, 0));
+ player->placeOnCurve(curve);
+ player->setCurveOffset(0.0f);
+ player->setAnimation(player->walkAnim(Character::WalkPart_Start), false);
+ player->walkTo(1.0f, false);
+ // TODO: Set app field field_0x424b
}
- _scene._character->setNeedsSomeUpdate(false);
+ player->setNeedsSomeUpdate(false);
}
const Common::String &charAnim = _scene._character->curAnimName();
@@ -1407,22 +1494,37 @@ bool Game::HitObject::onChangeWarp() {
bool Game::HitObject::onDown() {
_game->luaScript().execute("OnButtonDown", _name);
- // TODO: set this field _game->field_0x4249 = 1;
+ // TODO: set this field _game->field_0x4249 = true;
return false;
}
bool Game::HitObject::onUp() {
_game->luaScript().execute("OnButtonUp", _name);
- // TODO: set this field _game->field_0x4249 = 1;
+ // TODO: set this field _game->field_0x4249 = true;
return false;
}
bool Game::HitObject::onValidated() {
if (!g_engine->getApplication()->isLockCursor()) {
_game->luaScript().execute("OnWarpObjectHit", _name);
- // TODO: set this field _game->field_0x4249 = 1;
+ // TODO: set this field _game->field_0x4249 = true;
+ }
+ return false;
+}
+
+bool Game::RandomSound::onSoundFinished() {
+ Game *game = g_engine->getGame();
+ _music.onStopSignal().remove(this, &RandomSound::onSoundFinished);
+ if (game->_randomSoundFinished) {
+ game->_randomSoundFinished = false;
+ } else {
+ game->_randomSoundFinished = true;
+ game->_randomSound->_music.onStopSignal().remove(this, &RandomSound::onSoundFinished);
+ game->_randomSoundTimer.stop();
}
+ game->playRandomSound(_name);
return false;
}
+
} // end namespace Tetraedge
diff --git a/engines/tetraedge/game/game.h b/engines/tetraedge/game/game.h
index f383f899f3a..d95807a978c 100644
--- a/engines/tetraedge/game/game.h
+++ b/engines/tetraedge/game/game.h
@@ -24,6 +24,8 @@
#include "common/types.h"
#include "common/str.h"
+#include "common/random.h"
+
#include "tetraedge/game/documents_browser.h"
#include "tetraedge/game/inventory.h"
#include "tetraedge/game/inventory_menu.h"
@@ -46,6 +48,7 @@ class TeLuaThread;
class Game {
public:
Game();
+ ~Game();
struct HitObject {
bool onChangeWarp();
@@ -65,8 +68,8 @@ public:
Common::String _name;
TeMusic _music;
float _f1;
- float _f2;
- byte onSoundFinished();
+ float _volume;
+ bool onSoundFinished();
};
struct YieldedCallback {
@@ -139,7 +142,7 @@ public:
void pauseSounds() {}; // does nothing?
void playMovie(const Common::String &vidPath, const Common::String &musicPath);
void playRandomSound(const Common::String &name);
- void playSound(const Common::String &name, int param_2, float param_3);
+ void playSound(const Common::String &name, int param_2, float volume);
void removeNoScale2Child(TeLayout *layout);
void removeNoScale2Children();
void removeNoScaleChildren();
@@ -173,12 +176,13 @@ public:
const Common::String ¤tScene() { return _currentScene; }
const Common::Path &sceneZonePath() { return _sceneZonePath; }
TeLuaScript &luaScript() { return _luaScript; }
+ TeLuaContext &luaContext() { return _luaContext; }
InGameScene &scene() { return _scene; }
Dialog2 &dialog2() { return _dialog2; }
Question2 &question2() { return _question2; }
TeLuaGUI &gui3() { return _gui3; }
Objectif &objectif() { return _objectif; }
- Common::Array<YieldedCallback> yieldedCallbacks() { return _yieldedCallbacks; }
+ Common::Array<YieldedCallback> &yieldedCallbacks() { return _yieldedCallbacks; }
void setSaveRequested() { _saveRequested = true; }
bool markersVisible() const { return _markersVisible; }
@@ -225,7 +229,7 @@ private:
Common::Array<YieldedCallback> _yieldedCallbacks;
Common::HashMap<Common::String, bool> _unlockedArtwork;
- Common::HashMap<Common::String, Common::Array<RandomSound*>> _randomSounds;
+ Common::HashMap<Common::String, Common::Array<RandomSound *>> _randomSounds;
int _gameLoadState;
@@ -251,6 +255,11 @@ private:
bool _sceneCharacterVisibleFromLoad;
bool _markersVisible;
bool _saveRequested;
+ bool _randomSoundFinished;
+
+ Common::RandomSource _randomSource;
+ RandomSound *_randomSound;
+ TeTimer _randomSoundTimer;
TeLayout *_noScaleLayout;
TeLayout *_noScaleLayout2;
diff --git a/engines/tetraedge/game/game_sound.cpp b/engines/tetraedge/game/game_sound.cpp
index 257f2b89d33..16a86615ce3 100644
--- a/engines/tetraedge/game/game_sound.cpp
+++ b/engines/tetraedge/game/game_sound.cpp
@@ -20,12 +20,37 @@
*/
#include "tetraedge/game/game_sound.h"
+#include "tetraedge/game/game.h"
+#include "tetraedge/tetraedge.h"
+
+#include "tetraedge/te/te_lua_thread.h"
namespace Tetraedge {
GameSound::GameSound() {
}
-// TODO: Add more functions here.
+bool GameSound::onSoundStopped() {
+ Game *game = g_engine->getGame();
+ if (!game->luaContext().isCreated())
+ return false;
+
+ Common::Array<Game::YieldedCallback> &callbacks = game->yieldedCallbacks();
+ for (unsigned int i = 0; i < callbacks.size(); i++) {
+ if (callbacks[i]._luaFnName == "OnFreeSoundFinished" && callbacks[i]._luaParam == _name) {
+ TeLuaThread *thread = callbacks[i]._luaThread;
+ callbacks.remove_at(i);
+ if (thread) {
+ thread->resume();
+ return false;
+ }
+ break;
+ }
+ }
+ game->luaScript().execute("OnFreeSoundFinished", _name);
+ game->luaScript().execute("OnCellFreeSoundFinished", _name);
+ return false;
+}
+
} // end namespace Tetraedge
diff --git a/engines/tetraedge/game/game_sound.h b/engines/tetraedge/game/game_sound.h
index 2ea73e8edfd..cd2a4177b99 100644
--- a/engines/tetraedge/game/game_sound.h
+++ b/engines/tetraedge/game/game_sound.h
@@ -31,7 +31,9 @@ class GameSound : public TeMusic {
public:
GameSound();
- void onSoundStopped();
+ bool onSoundStopped();
+ const Common::String &name() const { return _name; }
+ void setName(const Common::String &val) { _name = val; }
private:
Common::String _name;
diff --git a/engines/tetraedge/game/how_to.cpp b/engines/tetraedge/game/how_to.cpp
index a863d4e8729..e0448d47923 100644
--- a/engines/tetraedge/game/how_to.cpp
+++ b/engines/tetraedge/game/how_to.cpp
@@ -27,12 +27,19 @@ HowTo::HowTo() : _entered(false) {
}
void HowTo::leave() {
-
+ error("TODO: Implement HowTo::leave");
}
void HowTo::enter() {
+ error("TODO: Implement HowTo::enter");
+}
+
+bool HowTo::onDefaultPadButtonUp(uint32 flags) {
+ error("TODO: Implement HowTo::onDefaultPadButtonUp");
+}
+bool HowTo::updateDisplay(uint oldval, uint newval) {
+ error("TODO: Implement HowTo::updateDisplay");
}
-// TODO: Add more functions here.
} // end namespace Tetraedge
diff --git a/engines/tetraedge/game/in_game_scene.cpp b/engines/tetraedge/game/in_game_scene.cpp
index 157ef41ff73..2fb70cdbdda 100644
--- a/engines/tetraedge/game/in_game_scene.cpp
+++ b/engines/tetraedge/game/in_game_scene.cpp
@@ -64,7 +64,25 @@ void InGameScene::addAnchorZone(const Common::String &s1, const Common::String &
return;
}
}
- warning("TODO: Finish InGameScene::addAnchorZone");
+
+ currentCamera()->apply();
+ AnchorZone *zone = new AnchorZone();
+ zone->_name = name;
+ zone->_radius = radius;
+ zone->_activated = true;
+
+ if (s1.contains("Int")) {
+ TeButtonLayout *btn = hitObjectGui().buttonLayout(name);
+ TeVector3f32 pos = btn->position();
+ pos.x() += g_engine->getDefaultScreenWidth() / 2.0f;
+ pos.y() += g_engine->getDefaultScreenHeight() / 2.0f;
+ zone->_loc = currentCamera()->worldTransformationMatrix() * currentCamera()->transformPoint2Dto3D(pos);
+ } else {
+ if (s1.contains("Dummy")) {
+ Dummy d = dummy(name);
+ zone->_loc = d._position;
+ }
+ }
}
bool InGameScene::addMarker(const Common::String &markerName, const Common::String &imgPath, float x, float y, const Common::String &locType, const Common::String &markerVal) {
@@ -219,7 +237,13 @@ TeIntrusivePtr<TeBezierCurve> InGameScene::curve(const Common::String &curveName
}
void InGameScene::deleteAllCallback() {
- warning("TODO: implement InGameScene::deleteAllCallback");
+ for (auto &pair : _callbacks) {
+ for (auto *cb : pair._value) {
+ delete cb;
+ }
+ pair._value.clear();
+ }
+ _callbacks.clear();
}
void InGameScene::deleteMarker(const Common::String &markerName) {
@@ -530,11 +554,11 @@ bool InGameScene::load(const Common::Path &path) {
deserializeModel(scenefile, model, pickmesh);
if (modelname.contains("Clic")) {
_hitObjects.push_back(model);
- // TODO: double-check this, probably right?
model->setVisible(false);
model->setColor(TeColor(0, 0xff, 0, 0xff));
models().push_back(model);
pickmesh->setName(modelname);
+ _pickMeshes.push_back(pickmesh);
} else {
delete pickmesh;
if (modelname.substr(0, 2) != "ZB") {
@@ -805,18 +829,17 @@ void InGameScene::moveCharacterTo(const Common::String &charName, const Common::
if (c != nullptr && c != _character) {
Game *game = g_engine->getGame();
if (!game->_movePlayerCharacterDisabled) {
- // TODO: c->field_0x214 = c->characterSettings()._cutSceneCurveDemiPosition;
+ c->setCurveStartLocation(c->characterSettings()._cutSceneCurveDemiPosition);
TeIntrusivePtr<TeBezierCurve> crve = curve(curveName);
c->placeOnCurve(crve);
c->setCurveOffset(curveOffset);
const Common::String walkStartAnim = c->walkAnim(Character::WalkPart_Start);
if (walkStartAnim.empty()) {
- c->setAnimation(c->walkAnim(Character::WalkPart_Loop), true, false, false, -1, 9999);
+ c->setAnimation(c->walkAnim(Character::WalkPart_Loop), true);
} else {
- c->setAnimation(c->walkAnim(Character::WalkPart_Start), false, false, false, -1, 9999);
+ c->setAnimation(c->walkAnim(Character::WalkPart_Start), false);
}
c->walkTo(curveEnd, false);
- error("TODO: Finish InGameScene::moveCharacterTo");
}
}
}
@@ -965,12 +988,61 @@ void InGameScene::update() {
_bgGui.layoutChecked("background")->setZPosition(0.0f);
}
if (_character) {
- // TODO: Do some stuff for character here.
+ _character->setHasAnchor(false);
+ for (AnchorZone *zone : _anchorZones) {
+ if (aroundAnchorZone(zone)) {
+ TeVector2f32 headRot(getHeadHorizontalRotation(_character, zone->_loc),
+ getHeadVerticalRotation(_character, zone->_loc));
+ if (headRot.getX() * 180.0 / M_PI > 90.0 || headRot.getY() * 180.0 / M_PI > 45.0) {
+ _character->setHasAnchor(false);
+ _character->setLastHeadRotation(_character->headRotation());
+ } else {
+ _character->setHeadRotation(headRot);
+ _character->setHasAnchor(true);
+ }
+ }
+ }
+ if (_character->charLookingAt()) {
+ TeVector3f32 targetpos = _character->charLookingAt()->_model->position();
+ if (_character->lookingAtTallThing())
+ targetpos.y() += 17;
+ TeVector2f32 headRot(getHeadHorizontalRotation(_character, targetpos),
+ getHeadVerticalRotation(_character, targetpos));
+ float hangle = headRot.getX() * 180.0 / M_PI;
+ if (hangle > 90)
+ headRot.setX(M_PI_2);
+ else if (hangle < -90)
+ headRot.setX(-M_PI_2);
+ _character->setHeadRotation(headRot);
+ _character->setHasAnchor(true);
+ }
}
for (Character *c : _characters) {
- // TODO: Something with other characters.
+ if (c->charLookingAt()) {
+ TeVector3f32 targetpos = c->charLookingAt()->_model->position();
+ if (c->lookingAtTallThing())
+ targetpos.y() += 17;
+ TeVector2f32 headRot(getHeadHorizontalRotation(c, targetpos),
+ getHeadVerticalRotation(c, targetpos));
+ float hangle = headRot.getX() * 180.0 / M_PI;
+ if (hangle > 90)
+ headRot.setX(M_PI_2);
+ else if (hangle < -90)
+ headRot.setX(-M_PI_2);
+ c->setHeadRotation(headRot);
+ c->setHasAnchor(true);
+ }
}
+
// TODO: some other stuff with callbacks and spritelayouts here
+ for (auto &callback : _callbacks) {
+
+ }
+
+ TeLuaGUI::StringMap<TeSpriteLayout *> &sprites = bgGui().spriteLayouts();
+ for (auto &sprite : sprites) {
+
+ }
TeScene::update();
@@ -991,7 +1063,13 @@ void InGameScene::update() {
}
for (Object3D *obj : _object3Ds) {
- // TODO: something with object3ds
+ // TODO: update object3ds if they are translating or rotating.
+ if (obj->_translateTime >= 0) {
+
+ }
+ if (obj->_rotateTime >= 0) {
+
+ }
}
}
diff --git a/engines/tetraedge/game/in_game_scene.h b/engines/tetraedge/game/in_game_scene.h
index cc8dcf76f61..18e72dd540a 100644
--- a/engines/tetraedge/game/in_game_scene.h
+++ b/engines/tetraedge/game/in_game_scene.h
@@ -53,6 +53,11 @@ public:
Common::String _name;
TeSpriteLayout *_layout;
};
+
+ struct Callback {
+ float _f;
+ Common::String _name;
+ };
struct SoundStep {
Common::String _stepSound1;
@@ -137,18 +142,18 @@ public:
void loadInteractions(const Common::Path &path);
bool loadLights(const Common::Path &path);
void loadMarkers(const Common::Path &path);
- bool loadObject(const Common::String &name);
+ bool loadObject(const Common::String &oname);
void loadObjectMaterials(const Common::String &name);
void loadObjectMaterials(const Common::String &path, const Common::String &name);
- bool loadPlayerCharacter(const Common::String &name);
+ bool loadPlayerCharacter(const Common::String &cname);
void moveCharacterTo(const Common::String &charName, const Common::String &curveName, float curveOffset, float curveEnd);
- int object(const Common::String &name);
- Object3D *object3D(const Common::String &name);
+ int object(const Common::String &oname);
+ Object3D *object3D(const Common::String &oname);
void onMainWindowSizeChanged();
- TeFreeMoveZone *pathZone(const Common::String &name);
- TeVector3f32 positionMarker(const Common::String &name);
- void removeBlockingObject(const Common::String &name);
+ TeFreeMoveZone *pathZone(const Common::String &zname);
+ TeVector3f32 positionMarker(const Common::String &mname);
+ void removeBlockingObject(const Common::String &oname);
void reset();
void setImagePathMarker(const Common::String &markerName, const Common::String &path);
@@ -211,6 +216,7 @@ private:
Common::Array<TePickMesh2 *> _pickMeshes;
Common::HashMap<Common::String, SoundStep> _soundSteps;
+ Common::HashMap<Common::String, Common::Array<Callback*>> _callbacks;
Common::Array<TeIntrusivePtr<TeModel>> _hitObjects;
Common::Array<Object> _objects;
diff --git a/engines/tetraedge/game/inventory.cpp b/engines/tetraedge/game/inventory.cpp
index 2ad6b17d88b..bb888e0a407 100644
--- a/engines/tetraedge/game/inventory.cpp
+++ b/engines/tetraedge/game/inventory.cpp
@@ -42,7 +42,7 @@ void Inventory::enter() {
Game *game = g_engine->getGame();
Character *character = game->scene()._character;
character->stop();
- character->setAnimation(character->characterSettings()._walkFileName, true, false, false, -1, 9999);
+ character->setAnimation(character->characterSettings()._walkFileName, true);
_gui.layoutChecked("textObject")->setVisible(false);
if (!game->_firstInventory) {
diff --git a/engines/tetraedge/game/lua_binds.cpp b/engines/tetraedge/game/lua_binds.cpp
index 88745e3c0e3..e39d09f19ef 100644
--- a/engines/tetraedge/game/lua_binds.cpp
+++ b/engines/tetraedge/game/lua_binds.cpp
@@ -270,7 +270,28 @@ static int tolua_ExportedFunctions_RequestAutoSave00(lua_State *L) {
}
static void HideObject(const Common::String &objName) {
- warning("TODO: HideObject");
+ Game *game = g_engine->getGame();
+ TeIntrusivePtr<TeModel> model = game->scene().model(objName);
+ if (model) {
+ model->setVisible(false);
+ return;
+ }
+
+ debug("[HideObject] Object 3D \"%s\" doesn't exist.", objName.c_str());
+ TeLayout *layout = game->scene().bgGui().layout(objName);
+ if (layout) {
+ layout->setVisible(false);
+ return;
+ }
+
+ debug("[HideObject] \"Set\" Object 2D \"%s\" doesn't exist.", objName.c_str());
+ layout = game->gui3().layout(objName);
+ if (layout) {
+ layout->setVisible(false);
+ return;
+ }
+
+ debug("[HideObject] \"For\" Object 2D \"%s\" doesn't exist.", objName.c_str());
}
static int tolua_ExportedFunctions_HideObject00(lua_State *L) {
@@ -284,7 +305,28 @@ static int tolua_ExportedFunctions_HideObject00(lua_State *L) {
}
static void ShowObject(const Common::String &objName) {
- warning("TODO: ShowObject");
+ Game *game = g_engine->getGame();
+ TeIntrusivePtr<TeModel> model = game->scene().model(objName);
+ if (model) {
+ model->setVisible(true);
+ return;
+ }
+
+ debug("[ShowObject] Object 3D \"%s\" doesn't exist.", objName.c_str());
+ TeLayout *layout = game->scene().bgGui().layout(objName);
+ if (layout) {
+ layout->setVisible(true);
+ return;
+ }
+
+ debug("[ShowObject] \"Set\" Object 2D \"%s\" doesn't exist.", objName.c_str());
+ layout = game->gui3().layout(objName);
+ if (layout) {
+ layout->setVisible(true);
+ return;
+ }
+
+ debug("[ShowObject] \"For\" Object 2D \"%s\" doesn't exist.", objName.c_str());
}
static int tolua_ExportedFunctions_ShowObject00(lua_State *L) {
@@ -375,8 +417,15 @@ static int tolua_ExportedFunctions_SetCharacterPosition00(lua_State *L) {
error("#ferror in function 'SetCharacterPosition': %d %d %s", err.index, err.array, err.type);
}
-static void SetGroundObjectPosition(const Common::String &objname, float f1, float f2, float f3) {
- warning("TODO: Implement SetGroundObjectPosition");
+static void SetGroundObjectPosition(const Common::String &objname, float x, float y, float z) {
+ Game *game = g_engine->getGame();
+ Object3D *obj = game->scene().object3D(objname);
+ if (!obj) {
+ warning("[SetGroundObjectPosition] Object not found %s", objname.c_str());
+ return;
+ }
+ obj->model()->setPosition(TeVector3f32(x, y, z));
+ obj->model()->setVisible(true);
}
static int tolua_ExportedFunctions_SetGroundObjectPosition00(lua_State *L) {
@@ -394,8 +443,17 @@ static int tolua_ExportedFunctions_SetGroundObjectPosition00(lua_State *L) {
error("#ferror in function 'SetGroundObjectPosition': %d %d %s", err.index, err.array, err.type);
}
-static void SetGroundObjectRotation(const Common::String &objname, float f1, float f2, float f3) {
- warning("TODO: Implement SetGroundObjectRotation");
+static void SetGroundObjectRotation(const Common::String &objname, float x, float y, float z) {
+ Game *game = g_engine->getGame();
+ Object3D *obj = game->scene().object3D(objname);
+ if (!obj) {
+ warning("[SetGroundObjectRotation] Object not found %s", objname.c_str());
+ return;
+ }
+
+ TeVector3f32 rotvec(x * M_PI / 180.0, y * M_PI / 180.0, z * M_PI / 180.0);
+ obj->model()->setRotation(TeQuaternion::fromEuler(rotvec));
+ obj->model()->setVisible(true);
}
static int tolua_ExportedFunctions_SetGroundObjectRotation00(lua_State *L) {
diff --git a/engines/tetraedge/game/main_menu.cpp b/engines/tetraedge/game/main_menu.cpp
index 7c56dccb83d..ec92bbee2ce 100644
--- a/engines/tetraedge/game/main_menu.cpp
+++ b/engines/tetraedge/game/main_menu.cpp
@@ -143,14 +143,14 @@ void MainMenu::leave() {
_entered= false;
}
-bool MainMenu::deleteFile(const Common::String &name) {
+bool MainMenu::deleteFile(const Common::String &fname) {
error("TODO: Implement MainMenu::deleteFile");
}
bool MainMenu::onActivedTuto() {
Application *app = g_engine->getApplication();
app->setTutoActivated(true);
- // TODO: Set game val false too?
+ g_engine->getGame()->_firstInventory = true;
app->captureFade();
leave();
app->startGame(true, 1);
diff --git a/engines/tetraedge/game/object3d.cpp b/engines/tetraedge/game/object3d.cpp
index cfd6377ce96..a05d032198e 100644
--- a/engines/tetraedge/game/object3d.cpp
+++ b/engines/tetraedge/game/object3d.cpp
@@ -28,7 +28,7 @@ namespace Tetraedge {
/*static*/ Common::HashMap<Common::String, Object3D::ObjectSettings> *Object3D::_objectSettings = nullptr;
-Object3D::Object3D() {
+Object3D::Object3D() : _translateTime(-1), _rotateTime(-1) {
}
bool Object3D::loadModel(const Common::String &name) {
diff --git a/engines/tetraedge/game/object3d.h b/engines/tetraedge/game/object3d.h
index d1d321bf3cb..b1f1e9a1e0a 100644
--- a/engines/tetraedge/game/object3d.h
+++ b/engines/tetraedge/game/object3d.h
@@ -49,6 +49,16 @@ public:
TeIntrusivePtr<TeModel> model() { return _modelPtr; }
+ float _rotateTime;
+ TeTimer _rotateTimer;
+ TeVector3f32 _rotateStart;
+ TeVector3f32 _rotateAmount;
+
+ float _translateTime;
+ TeTimer _translateTimer;
+ TeVector3f32 _translateStart;
+ TeVector3f32 _translateAmount;
+
private:
static Common::HashMap<Common::String, ObjectSettings> *_objectSettings;
diff --git a/engines/tetraedge/te/te_camera.cpp b/engines/tetraedge/te/te_camera.cpp
index f41baa6d4c4..65817da15fa 100644
--- a/engines/tetraedge/te/te_camera.cpp
+++ b/engines/tetraedge/te/te_camera.cpp
@@ -36,9 +36,9 @@ TeCamera::TeCamera() : _projectionMatrixType(0), _orthogonalParamL(1.0f),
}
void TeCamera::apply() {
- /*debug("TeCamera::apply %13s mtype %d fov %.2f persp %.2f orth(%.2f %.2f) pos %s scale %s", name().c_str(),
- _projectionMatrixType, _fov, _somePerspectiveVal, _orthNearVal, _orthFarVal,
- position().dump().c_str(), scale().dump().c_str());*/
+ //debug("TeCamera::apply %13s mtype %d fov %.2f persp %.2f orth(%.2f %.2f) pos %s scale %s rot %s", name().c_str(),
+ // _projectionMatrixType, _fov, _somePerspectiveVal, _orthNearVal, _orthFarVal,
+ // position().dump().c_str(), scale().dump().c_str(), rotation().dump().c_str());
applyProjection();
applyTransformations();
}
@@ -105,7 +105,7 @@ void TeCamera::buildPerspectiveMatrix() {
_projectionMatrix.setValue(0, 0, (1.0 / f) / ((float)_viewportW / _viewportH));
_projectionMatrix.setValue(1, 1, 1.0 / f);
_projectionMatrix.setValue(2, 2, (_orthNearVal + _orthFarVal) / (_orthNearVal - _orthFarVal));
- _projectionMatrix.setValue(2, 2, (_orthNearVal * _orthFarVal) / (_orthNearVal - _orthFarVal));
+ _projectionMatrix.setValue(3, 2, (_orthNearVal * _orthFarVal) / (_orthNearVal - _orthFarVal));
_projectionMatrix.setValue(2, 3, -1);
_projectionMatrix.setValue(3, 3, 0.0);
}
@@ -219,11 +219,11 @@ TeVector3f32 TeCamera::transformCoord(const TeVector3f32 &pt) {
return pt;
}
-TeVector3f32 TeCamera::transformPoint2Dto3D(const TeVector2f32 &pt) {
+TeVector3f32 TeCamera::transformPoint2Dto3D(const TeVector3f32 &pt) {
TeVector3f32 retval;
TeVector3f32 vp_br(_viewportX + _viewportW, _viewportY + _viewportH, 0.0f);
- float x = (pt.getX() - _viewportX) / (vp_br.x() - _viewportX);
- float y = (pt.getY() - _viewportY) / (vp_br.y() - _viewportY);
+ float x = (pt.x() - _viewportX) / (vp_br.x() - _viewportX);
+ float y = (pt.y() - _viewportY) / (vp_br.y() - _viewportY);
return TeVector3f32(x * 2 - 1.0f, -(y * 2 - 1.0f), 0.0);
}
diff --git a/engines/tetraedge/te/te_camera.h b/engines/tetraedge/te/te_camera.h
index 38dc8adfe29..8ab03c86b15 100644
--- a/engines/tetraedge/te/te_camera.h
+++ b/engines/tetraedge/te/te_camera.h
@@ -61,7 +61,7 @@ public:
static void restore();
TeMatrix4x4 transformationMatrix();
TeVector3f32 transformCoord(const TeVector3f32 &pt);
- TeVector3f32 transformPoint2Dto3D(const TeVector2f32 &pt);
+ TeVector3f32 transformPoint2Dto3D(const TeVector3f32 &pt);
void updateProjectionMatrix();
void viewport(int x, int y, uint width, uint height);
diff --git a/engines/tetraedge/te/te_extended_text_layout.cpp b/engines/tetraedge/te/te_extended_text_layout.cpp
index d7e5025144c..d355b761fb8 100644
--- a/engines/tetraedge/te/te_extended_text_layout.cpp
+++ b/engines/tetraedge/te/te_extended_text_layout.cpp
@@ -35,6 +35,5 @@ void TeExtendedTextLayout::setAutoScrollSpeed(float val) {
_scrollingLayout.setAutoScrollAnimation2Speed(val);
}
-// TODO: Add more functions here.
} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_free_move_zone.cpp b/engines/tetraedge/te/te_free_move_zone.cpp
index 0713b9c4341..218974136e8 100644
--- a/engines/tetraedge/te/te_free_move_zone.cpp
+++ b/engines/tetraedge/te/te_free_move_zone.cpp
@@ -97,17 +97,26 @@ Common::Array<TeVector3f32> TeFreeMoveZone::collisions(const TeVector3f32 &v1, c
error("TODO: Implement TeFreeMoveZone::collisions");
}
-TeVector3f32 TeFreeMoveZone::correctCharacterPosition(const TeVector3f32 &pos, bool *flagout, bool f) {
-
- warning("TODO: Implement TeFreeMoveZone::correctCharacterPosition");
- return pos;
+TeVector3f32 TeFreeMoveZone::correctCharacterPosition(const TeVector3f32 &pos, bool *flagout, bool intersectFlag) {
+ float f = 0.0;
+ TeVector3f32 intersectPoint;
+ if (!intersect(pos, TeVector3f32(0, -1, 0), intersectPoint, f, intersectFlag, nullptr)) {
+ if (!intersect(pos, TeVector3f32(0, 1, 0), intersectPoint, f, intersectFlag, nullptr)) {
+ if (*flagout)
+ *flagout = false;
+ return pos;
+ }
+ }
+ if (flagout)
+ *flagout = true;
+ return intersectPoint;
}
TeIntrusivePtr<TeBezierCurve> TeFreeMoveZone::curve(const TeVector3f32 ¶m_3, const TeVector2s32 ¶m_4, float param_5, bool findMeshFlag) {
error("TODO: Implement TeFreeMoveZone::curve");
}
-TeIntrusivePtr<TeBezierCurve> TeFreeMoveZone::curve(const TeVector3f32 ¶m_3, const TeVector2s32 ¶m_4) {
+TeIntrusivePtr<TeBezierCurve> TeFreeMoveZone::curve(const TeVector3f32 ¶m_3, const TeVector3f32 ¶m_4) {
error("TODO: Implement TeFreeMoveZone::curve");
}
@@ -205,7 +214,7 @@ void TeFreeMoveZone::setCamera(TeIntrusivePtr<TeCamera> &cam, bool noRecalcProjP
_projectedPointsDirty = true;
}
-void TeFreeMoveZone::setNbTriangles(unsigned long len) {
+void TeFreeMoveZone::setNbTriangles(unsigned int len) {
_freeMoveZoneVerticies.resize(len * 3);
_gridDirty = true;
@@ -219,7 +228,7 @@ void TeFreeMoveZone::setPathFindingOccluder(const TeOBP &occluder) {
error("TODO: Implement TeFreeMoveZone::setPathFindingOccluder");
}
-void TeFreeMoveZone::setVertex(unsigned long offset, const TeVector3f32 &vertex) {
+void TeFreeMoveZone::setVertex(unsigned int offset, const TeVector3f32 &vertex) {
_freeMoveZoneVerticies[offset] = vertex;
_gridDirty = true;
diff --git a/engines/tetraedge/te/te_free_move_zone.h b/engines/tetraedge/te/te_free_move_zone.h
index aa4cbd9809a..74daafb8d23 100644
--- a/engines/tetraedge/te/te_free_move_zone.h
+++ b/engines/tetraedge/te/te_free_move_zone.h
@@ -72,7 +72,7 @@ public:
TeVector3f32 correctCharacterPosition(const TeVector3f32 &pos, bool *flagout, bool f);
TeIntrusivePtr<TeBezierCurve> curve(const TeVector3f32 ¶m_3, const TeVector2s32 ¶m_4, float param_5, bool findMeshFlag);
- TeIntrusivePtr<TeBezierCurve> curve(const TeVector3f32 ¶m_3, const TeVector2s32 ¶m_4);
+ TeIntrusivePtr<TeBezierCurve> curve(const TeVector3f32 ¶m_3, const TeVector3f32 ¶m_4);
void draw() override;
TeVector3f32 findNearestPointOnBorder(const TeVector2f32 &pt);
@@ -94,9 +94,9 @@ public:
Common::Array<TeVector3f32> &removeInsignificantPoints(const Common::Array<TeVector3f32> &points);
void setBordersDistance(float dist);
void setCamera(TeIntrusivePtr<TeCamera> &cam, bool noRecalcProjPoints);
- void setNbTriangles(unsigned long len);
+ void setNbTriangles(unsigned int len);
void setPathFindingOccluder(const TeOBP &occluder);
- void setVertex(unsigned long offset, const TeVector3f32 &vertex);
+ void setVertex(unsigned int offset, const TeVector3f32 &vertex);
TeVector2s32 transformAStarGridInWorldSpace(const TeVector2s32 &gridpt);
float transformHeightMin(float minval);
TeVector3f32 transformVectorInWorldSpace(float param_3,float param_4);
diff --git a/engines/tetraedge/te/te_i_layout.h b/engines/tetraedge/te/te_i_layout.h
index 0819de8b316..cabbb55622a 100644
--- a/engines/tetraedge/te/te_i_layout.h
+++ b/engines/tetraedge/te/te_i_layout.h
@@ -45,9 +45,6 @@ public:
RATIO_MODE_PAN_SCAN
};
-private:
- // TODO add private members
-
};
} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_images_sequence.cpp b/engines/tetraedge/te/te_images_sequence.cpp
index 0af65ad6777..5b991656697 100644
--- a/engines/tetraedge/te/te_images_sequence.cpp
+++ b/engines/tetraedge/te/te_images_sequence.cpp
@@ -75,29 +75,30 @@ bool TeImagesSequence::load(const Common::Path &path) {
continue;
}
- Common::File file;
- if (!file.open(filePath)) {
+ Common::SeekableReadStream *stream = child.createReadStream();
+ if (!stream) {
warning("TeImagesSequence::load can't open %s", filePath.toString().c_str());
continue;
}
- // At first only do the deep check for the first file to get dimensions.
- if (_width) {
- _files.push_back(filePath);
- continue;
- }
-
- Image::PNGDecoder png;
- if (!png.loadStream(file)) {
- warning("Image sequence failed to load png %s", filePath.toString().c_str());
- return false;
+ // Only do the deep check for the first file to get dimensions.
+ if (!_width) {
+ Image::PNGDecoder png;
+ if (!png.loadStream(*stream)) {
+ warning("Image sequence failed to load png %s", filePath.toString().c_str());
+ delete stream;
+ return false;
+ }
+
+ const Graphics::Surface *surf = png.getSurface();
+ assert(surf);
+ _width = surf->w;
+ _height = surf->h;
+ _frameRate = fps;
}
- const Graphics::Surface *surf = png.getSurface();
- assert(surf);
- _width = surf->w;
- _height = surf->h;
- _frameRate = fps;
+ _files.push_back(child);
+ delete stream;
}
return true;
@@ -110,23 +111,25 @@ bool TeImagesSequence::update(unsigned long i, TeImage &imgout) {
if (i >= _files.size())
return false;
- Common::File file;
- if (file.open(_files[_curFrame]))
- error("Open %s failed.. it was ok before?", _files[_curFrame].toString().c_str());
+ Common::SeekableReadStream *stream = _files[_curFrame].createReadStream();
+ if (!stream)
+ error("Open %s failed.. it was ok before?", _files[_curFrame].getName().c_str());
Image::PNGDecoder png;
- if (png.loadStream(file)) {
- warning("Image sequence failed to load png %s", _files[_curFrame].toString().c_str());
+ if (!png.loadStream(*stream)) {
+ warning("Image sequence failed to load png %s", _files[_curFrame].getName().c_str());
+ delete stream;
return false;
}
const Graphics::Surface *surf = png.getSurface();
assert(surf);
- imgout.setAccessName(_files[_curFrame]);
+ imgout.setAccessName(_files[_curFrame].getPath());
if (imgout.w == surf->w && imgout.h == surf->h && imgout.format == surf->format) {
imgout.copyFrom(*surf);
+ delete stream;
return true;
}
diff --git a/engines/tetraedge/te/te_images_sequence.h b/engines/tetraedge/te/te_images_sequence.h
index 6559d8905cd..e8f4b386adb 100644
--- a/engines/tetraedge/te/te_images_sequence.h
+++ b/engines/tetraedge/te/te_images_sequence.h
@@ -62,7 +62,7 @@ private:
float _frameRate;
unsigned int _width;
unsigned int _height;
- Common::Array<Common::Path> _files;
+ Common::Array<Common::FSNode> _files;
unsigned int _curFrame;
};
diff --git a/engines/tetraedge/te/te_list_layout.h b/engines/tetraedge/te/te_list_layout.h
index 59e345a40f8..b631891c8b3 100644
--- a/engines/tetraedge/te/te_list_layout.h
+++ b/engines/tetraedge/te/te_list_layout.h
@@ -30,8 +30,6 @@ class TeListLayout : public TeLayout {
public:
TeListLayout();
- // TODO add public members
-
TeVector3f32 _minimumMargin;
TeVector3f32 _maximumMargin;
TeVector3f32 _direction;
diff --git a/engines/tetraedge/te/te_lua_context.cpp b/engines/tetraedge/te/te_lua_context.cpp
index 2baa54f76ea..f2df4bda2ba 100644
--- a/engines/tetraedge/te/te_lua_context.cpp
+++ b/engines/tetraedge/te/te_lua_context.cpp
@@ -75,7 +75,7 @@ TeVariant TeLuaContext::global(const Common::String &name) {
lua_settop(_luaState, -2);
return TeVariant(str);
}
- warning("Unexpected type %d for global %s", type, name.c_str());
+ warning("TeLuaContext::global: Unexpected type %d for global %s", type, name.c_str());
return TeVariant();
}
diff --git a/engines/tetraedge/te/te_lua_script.cpp b/engines/tetraedge/te/te_lua_script.cpp
index 58422d24195..c2568451de3 100644
--- a/engines/tetraedge/te/te_lua_script.cpp
+++ b/engines/tetraedge/te/te_lua_script.cpp
@@ -37,7 +37,7 @@ void TeLuaScript::attachToContext(TeLuaContext *context) {
void TeLuaScript::execute() {
if (_luaContext) {
- debug("TeLuaScript::execute %s", _scriptPath.toString().c_str());
+ //debug("TeLuaScript::execute %s", _scriptPath.toString().c_str());
lua_State *state = _luaContext->luaState();
if (state) {
TeLuaThread *thread = TeLuaThread::create(_luaContext);
@@ -50,7 +50,7 @@ void TeLuaScript::execute() {
void TeLuaScript::execute(const Common::String &fname) {
if (_luaContext) {
- debug("TeLuaScript::execute %s %s", _scriptPath.toString().c_str(), fname.c_str());
+ //debug("TeLuaScript::execute %s %s", _scriptPath.toString().c_str(), fname.c_str());
TeLuaThread *thread = TeLuaThread::create(_luaContext);
thread->execute(fname);
thread->release();
@@ -59,7 +59,7 @@ void TeLuaScript::execute(const Common::String &fname) {
void TeLuaScript::execute(const Common::String &fname, const TeVariant &p1) {
if (_luaContext) {
- debug("TeLuaScript::execute %s %s(%s)", _scriptPath.toString().c_str(), fname.c_str(), p1.toString().c_str());
+ //debug("TeLuaScript::execute %s %s(%s)", _scriptPath.toString().c_str(), fname.c_str(), p1.toString().c_str());
TeLuaThread *thread = TeLuaThread::create(_luaContext);
thread->execute(fname, p1);
thread->release();
diff --git a/engines/tetraedge/te/te_model.cpp b/engines/tetraedge/te/te_model.cpp
index c5a500332e5..2a7a0bfc8e6 100644
--- a/engines/tetraedge/te/te_model.cpp
+++ b/engines/tetraedge/te/te_model.cpp
@@ -33,7 +33,7 @@
namespace Tetraedge {
-TeModel::TeModel() : _enableLights(false), _skipBoneMatricies(false), _matrixForced(false) {
+TeModel::TeModel() : _enableLights(false), _skipSkinOffsets(false), _matrixForced(false) {
// TODO: set 0x17c to 1.0
// TODO: set 0x178, 0x170 to 0
_modelAnim.setDeleteFn(&TeModelAnimation::deleteLater);
@@ -45,27 +45,19 @@ TeModel::~TeModel() {
destroy();
}
-void TeModel::create() {
- // TODO: set field_0x158 to 0
- _modelAnim.release();
- _modelVertexAnim.release();
- _matrixForced = false;
- _skipBoneMatricies = false;
+void TeModel::blendAnim(TeIntrusivePtr<TeModelAnimation>& anim, float seconds, bool repeat) {
+ if (!_modelAnim) {
+ setAnim(anim, repeat);
+ } else {
+ BonesBlender *blender = new BonesBlender(anim, seconds);
+ anim->_repeatCount = (repeat ? -1 : 1);
+ anim->play();
+ _boneBlenders.push_back(blender);
+ }
}
-void TeModel::destroy() {
- _weightElements.clear();
- // TODO: clear matrix array 0x148
- _meshes.clear();
- _bones.clear();
- // TODO: clear matrix array 0x190
- _boneMatrices.clear();
- for (MeshBlender *blender : _meshBlenders)
- delete blender;
- _meshBlenders.clear();
- for (BonesBlender *blender : _boneBlenders)
- delete blender;
- _boneBlenders.clear();
+void TeModel::blendMesh(const Common::String &s1, const Common::String &s2, float amount) {
+ _meshBlenders.push_back(new MeshBlender(s1, s2, amount, this));
}
int TeModel::checkFileType(Common::SeekableReadStream &instream) {
@@ -81,19 +73,27 @@ int TeModel::checkFileType(Common::SeekableReadStream &instream) {
return 0;
}
-void TeModel::blendAnim(TeIntrusivePtr<TeModelAnimation>& anim, float seconds, bool repeat) {
- if (!_modelAnim) {
- setAnim(anim, repeat);
- } else {
- BonesBlender *blender = new BonesBlender(anim, seconds);
- anim->_repeatCount = (repeat ? -1 : 1);
- anim->play();
- _boneBlenders.push_back(blender);
- }
+void TeModel::create() {
+ // TODO: set field_0x158 to 0
+ _modelAnim.release();
+ _modelVertexAnim.release();
+ _matrixForced = false;
+ _skipSkinOffsets = false;
}
-void TeModel::blendMesh(const Common::String &s1, const Common::String &s2, float amount) {
- _meshBlenders.push_back(new MeshBlender(s1, s2, amount, this));
+void TeModel::destroy() {
+ _weightElements.clear();
+ // TODO: clear matrix array 0x148
+ _meshes.clear();
+ _bones.clear();
+ _boneMatricies.clear();
+ _skinOffsets.clear();
+ for (MeshBlender *blender : _meshBlenders)
+ delete blender;
+ _meshBlenders.clear();
+ for (BonesBlender *blender : _boneBlenders)
+ delete blender;
+ _boneBlenders.clear();
}
void TeModel::draw() {
@@ -104,16 +104,16 @@ void TeModel::draw() {
renderer->sendModelMatrix(transform);
renderer->pushMatrix();
renderer->multiplyMatrix(transform);
- if (name() == "Kate") {
+ /*if (name() == "Kate") {
debug("Draw model %p (%s, %d meshes)", this, name().empty() ? "no name" : name().c_str(), _meshes.size());
- debug(" renderMatrix %s", renderer->currentMatrix().toString().c_str());
- debug(" position %s", position().dump().c_str());
+ //adebug(" renderMatrix %s", renderer->currentMatrix().toString().c_str());
+ //debug(" position %s", position().dump().c_str());
debug(" worldPos %s", worldPosition().dump().c_str());
- debug(" scale %s", scale().dump().c_str());
+ //debug(" scale %s", scale().dump().c_str());
debug(" worldScale %s", worldScale().dump().c_str());
- debug(" rotation %s", rotation().dump().c_str());
+ //debug(" rotation %s", rotation().dump().c_str());
debug(" worldRot %s", worldRotation().dump().c_str());
- }
+ }*/
for (TeMesh &mesh : _meshes) {
// TODO: Set some flag in the mesh here to this->field_0x158??
mesh.draw();
@@ -137,11 +137,18 @@ TeTRS TeModel::getBone(TeIntrusivePtr<TeModelAnimation> anim, unsigned int num)
return _bones[num]._trs;
}
-void TeModel::setColor(const TeColor &col) {
- Te3DObject2::setColor(col);
- for (TeMesh &mesh : _meshes) {
- mesh.setColor(col);
+TeMatrix4x4 TeModel::lerpElementsMatrix(unsigned long weightsNum, Common::Array<TeMatrix4x4> &matricies) {
+ TeMatrix4x4 retval;
+ for (unsigned int i = 0; i < 4; i++)
+ retval.setValue(i, i, 0);
+
+ // TODO: Finish this.
+ for (auto &weights : _weightElements) {
+
}
+
+
+ return retval;
}
void TeModel::removeAnim() {
@@ -152,51 +159,102 @@ void TeModel::removeAnim() {
_modelAnim.release();
}
-void TeModel::update() {
- Common::Array<TeMatrix4x4> matricies;
- matricies.resize(_bones.size());
- for (unsigned int i = 0; i < _bones.size(); i++) {
- const bone &b = _bones[i];
- TeMatrix4x4 matrix = TeMatrix4x4::fromTRS(b._trs);
- if (b._x == -1 || _bones.size() < 2) {
- matricies[0] = matrix;
- } else {
- matricies[i] = matricies[b._x] * matrix;
- }
+void TeModel::setColor(const TeColor &col) {
+ Te3DObject2::setColor(col);
+ for (TeMesh &mesh : _meshes) {
+ mesh.setColor(col);
}
- for (unsigned int b = 0; b < _bones.size(); b++) {
- TeTRS startTRS = getBone(_modelAnim, b);
- for (unsigned int i = 0; i < _boneBlenders.size(); i++) {
- BonesBlender *blender = _boneBlenders[i];
- float complete = MIN((blender->_timer.getTimeFromStart() / 1000000.0f) / blender->_seconds, 1.0f);
- TeTRS trs;
- TeTRS endTRS = getBone(blender->_anim, b);
- if (complete == 1.0f) {
- delete blender;
- _boneBlenders.remove_at(i);
- trs = endTRS;
- i--;
+}
+
+void TeModel::update() {
+ if (_bones.size()) {
+ Common::Array<TeMatrix4x4> matricies;
+ matricies.resize(_bones.size());
+ for (unsigned int i = 0; i < _bones.size(); i++) {
+ const bone &b = _bones[i];
+ TeMatrix4x4 matrix = TeMatrix4x4::fromTRS(b._trs);
+ if (b._x == -1 || _bones.size() < 2) {
+ matricies[0] = matrix;
} else {
- trs = startTRS.lerp(endTRS, complete);
+ matricies[i] = matricies[b._x] * matrix;
+ }
+ }
+
+ _boneMatricies.resize(_bones.size());
+ _lerpedElements.resize(_weightElements.size());
+
+ TeMatrix4x4 invertx;
+ invertx.scale(TeVector3f32(-1, 1, 1));
+ for (unsigned int b = 0; b < _bones.size(); b++) {
+ TeTRS trs = getBone(_modelAnim, b);
+ for (unsigned int i = 0; i < _boneBlenders.size(); i++) {
+ BonesBlender *blender = _boneBlenders[i];
+ float complete = MIN((blender->_timer.getTimeFromStart() / 1000000.0f) / blender->_seconds, 1.0f);
+ TeTRS trs;
+ TeTRS endTRS = getBone(blender->_anim, b);
+ if (complete == 1.0f) {
+ delete blender;
+ _boneBlenders.remove_at(i);
+ trs = endTRS;
+ i--;
+ } else {
+ trs = trs.lerp(endTRS, complete);
+ }
}
TeMatrix4x4 matrix;
if (!_matrixForced) {
matrix = TeMatrix4x4::fromTRS(trs);
} else {
- matrix = _forcedMatrix;
+ matrix = invertx * _forcedMatrix;
_matrixForced = false;
}
+ if (_bones.size() < 2 || _bones[b]._x == -1) {
+ _boneMatricies[b] = matrix;
+ // TODO: Rotate by _field_0x170
+ } else {
+ _boneMatricies[b] = (invertx * _boneMatricies[_bones[b]._x]) * matrix;
+ }
+ _boneMatricies[b] = invertx * _boneMatricies[b];
+ // TODO: bonesUpdateSignal.call(_bones[b]._name, _boneMatricies[b]);
}
- //warning("TODO: Finish TeModel::update. (disasm 295 ~ 693)");
- }
- for (TeMesh &mesh : _meshes) {
- if (!_modelVertexAnim) {
- mesh.update(nullptr, nullptr);
- } else {
- if (mesh.name() != _modelVertexAnim->head()) {
+
+ if (!_skinOffsets.empty() && !_bones.empty()) {
+ for (unsigned int b = 0; b < _bones.size(); b++) {
+ _boneMatricies[b] = _boneMatricies[b] * _skinOffsets[b];
+ }
+ }
+
+ if (_skipSkinOffsets == 0 && !_weightElements.empty()) {
+ for (unsigned int i = 0; i < _weightElements.size(); i++) {
+ _lerpedElements[i] = lerpElementsMatrix(i, _boneMatricies);
+ }
+ }
+
+ for (unsigned int m = 0; m < _meshes.size(); m++) {
+ if (!_meshes[m].visible())
+ continue;
+ if (!_skipSkinOffsets && _bones.size() < 2 ) {
+ if (_meshes[m].name() == _modelVertexAnim->head()) {
+ _meshes[m].update(_modelVertexAnim);
+ // TODO: lines 440 - 443.. set some vals and goto LAB_doMeshBlends;
+ }
+ _meshes[m].update(&_boneMatricies, &_lerpedElements);
+ // TODO: Set some vals here..
+ } else {
+ //warning("TODO: Finish TeModel::update. (disasm 456 ~ 693)");
+ }
+ }
+ } else {
+ // No bones..
+ for (TeMesh &mesh : _meshes) {
+ if (!_modelVertexAnim) {
mesh.update(nullptr, nullptr);
} else {
- mesh.update(_modelVertexAnim);
+ if (mesh.name() != _modelVertexAnim->head()) {
+ mesh.update(nullptr, nullptr);
+ } else {
+ mesh.update(_modelVertexAnim);
+ }
}
}
}
@@ -255,10 +313,10 @@ bool TeModel::load(Common::SeekableReadStream &stream) {
if (bonecount > 100000)
error("TeModel::load: Unexpected number of bones %d", bonecount);
_bones.resize(bonecount);
- _boneMatrices.resize(bonecount);
+ _skinOffsets.resize(bonecount);
if (version == 13) {
- _skipBoneMatricies = stream.readUint32LE();
+ _skipSkinOffsets = stream.readUint32LE();
}
if (!loadAndCheckFourCC(stream, "SKEL")) {
@@ -270,8 +328,8 @@ bool TeModel::load(Common::SeekableReadStream &stream) {
loadAlign(stream);
_bones[i]._x = stream.readUint32LE();
TeTRS::deserialize(stream, _bones[i]._trs);
- if (!_skipBoneMatricies) {
- _boneMatrices[i].deserialize(stream);
+ if (!_skipSkinOffsets) {
+ _skinOffsets[i].deserialize(stream);
}
}
@@ -474,7 +532,7 @@ void TeModel::setAnim(TeIntrusivePtr<TeModelAnimation> &anim, bool repeat) {
delete blender;
}
_boneBlenders.clear();
- anim->_repeatCount = repeat ? -1 : 1;
+ anim->_repeatCount = (repeat ? -1 : 1);
_modelAnim = anim;
}
@@ -492,9 +550,9 @@ void TeModel::setVisibleByName(const Common::String &name, bool vis) {
}
TeMatrix4x4 TeModel::skinOffset(unsigned long boneno) const {
- if (boneno >= _boneMatrices.size())
+ if (boneno >= _skinOffsets.size())
return TeMatrix4x4();
- return _boneMatrices[boneno];
+ return _skinOffsets[boneno];
}
TeModel::BonesBlender::BonesBlender(TeIntrusivePtr<TeModelAnimation> anim, float seconds) : _anim(anim), _seconds(seconds) {
diff --git a/engines/tetraedge/te/te_model.h b/engines/tetraedge/te/te_model.h
index bdf61c9173c..74ee90aafe9 100644
--- a/engines/tetraedge/te/te_model.h
+++ b/engines/tetraedge/te/te_model.h
@@ -93,11 +93,11 @@ public:
void draw() override;
- int findModelBone(const Common::String &name);
+ int findModelBone(const Common::String &bname);
int findOrAddWeights(const Common::Array<weightElement> &weights);
void forceMatrix(const TeMatrix4x4 &matrix);
TeTRS getBone(TeIntrusivePtr<TeModelAnimation> anim, unsigned int num);
- TeMatrix4x4 lerpElementsMatrix(unsigned long num, Common::Array<TeMatrix4x4> &matricies);
+ TeMatrix4x4 lerpElementsMatrix(unsigned long weightNum, Common::Array<TeMatrix4x4> &matricies);
/* Align the stream to the nearest 4 byte boudary*/
static void loadAlign(Common::SeekableReadStream &stream);
@@ -122,7 +122,7 @@ public:
virtual void setColor(const TeColor &col) override;
void setQuad(const TeIntrusivePtr<Te3DTexture> &tex, const Common::Array<TeVector3f32> &verts, const TeColor &col);
void setVertexAnim(TeIntrusivePtr<TeModelVertexAnimation> &anim, bool repeat);
- void setVisibleByName(const Common::String &name, bool vis);
+ void setVisibleByName(const Common::String &mname, bool vis);
TeMatrix4x4 skinOffset(unsigned long boneno) const;
@@ -131,7 +131,7 @@ public:
Common::Path _texturePath;
bool _enableLights;
- bool _skipBoneMatricies;
+ bool _skipSkinOffsets;
Common::Array<TeMesh> _meshes;
@@ -140,7 +140,9 @@ protected:
TeMatrix4x4 _forcedMatrix;
Common::Array<MeshBlender *> _meshBlenders;
Common::Array<bone> _bones;
- Common::Array<TeMatrix4x4> _boneMatrices;
+ Common::Array<TeMatrix4x4> _skinOffsets;
+ Common::Array<TeMatrix4x4> _boneMatricies;
+ Common::Array<TeMatrix4x4> _lerpedElements;
Common::Array<Common::Array<weightElement>> _weightElements;
Common::Array<BonesBlender *> _boneBlenders;
diff --git a/engines/tetraedge/te/te_model_animation.cpp b/engines/tetraedge/te/te_model_animation.cpp
index 98a0062be70..956e470e39a 100644
--- a/engines/tetraedge/te/te_model_animation.cpp
+++ b/engines/tetraedge/te/te_model_animation.cpp
@@ -76,9 +76,9 @@ void TeModelAnimation::destroy() {
_fbxArrays.clear();
}
-int TeModelAnimation::findBone(const Common::String &name) {
+int TeModelAnimation::findBone(const Common::String &bname) {
for (unsigned int i = 0; i < _boneNames.size(); i++) {
- if (_boneNames[i] == name)
+ if (_boneNames[i] == bname)
return i;
}
return -1;
@@ -90,7 +90,7 @@ int TeModelAnimation::firstFrame() const {
return _firstFrame;
}
-//TeMatrix4x4 TeModelAnimation::getMatrix(const Common::String &name, unsigned long frame, bool param_5);
+//TeMatrix4x4 TeModelAnimation::getMatrix(const Common::String &mname, unsigned long frame, bool param_5);
TeQuaternion TeModelAnimation::getNMORotation(unsigned long boneNo, float amount) const {
if (boneNo < _nmoRotArrays.size()) {
@@ -273,11 +273,11 @@ void TeModelAnimation::resizeNMOArrays(unsigned long len) {
//void TeModelAnimation::saveBone(Common::SeekableWriteStream &stream, uint param_2);
-void TeModelAnimation::setBoneName(uint boneNo, const Common::String &name) {
+void TeModelAnimation::setBoneName(uint boneNo, const Common::String &bname) {
if (_boneNames.size() < boneNo + 1) {
_boneNames.resize(boneNo + 1);
}
- _boneNames[boneNo] = name;
+ _boneNames[boneNo] = bname;
}
void TeModelAnimation::setRotation(unsigned long num, float amount, const TeQuaternion &rot) {
diff --git a/engines/tetraedge/te/te_model_animation.h b/engines/tetraedge/te/te_model_animation.h
index 8765b7ab840..fb30cc66bd6 100644
--- a/engines/tetraedge/te/te_model_animation.h
+++ b/engines/tetraedge/te/te_model_animation.h
@@ -60,7 +60,7 @@ public:
int calcCurrentFrame(double millis);
void cont() override;
void destroy();
- int findBone(const Common::String &name);
+ int findBone(const Common::String &bname);
int firstFrame() const;
TeMatrix4x4 getMatrix(const Common::String &name, unsigned long frame, bool param_5);
TeQuaternion getNMORotation(unsigned long param_3, float param_4) const;
@@ -76,7 +76,7 @@ public:
void resizeNMOArrays(unsigned long len);
void save(Common::SeekableWriteStream &stream);
void saveBone(Common::SeekableWriteStream &stream, uint param_2);
- void setBoneName(uint boneNo, const Common::String &name);
+ void setBoneName(uint boneNo, const Common::String &bname);
void setFrameLimits(int framemin, int framemax) {
_firstFrame = framemin;
_lastFrame = framemax;
@@ -105,7 +105,7 @@ private:
bool _curFrameValFresh;
int _repeatNum;
bool _finishedSignalPending;
- int _useNMOArrays; // TODO: probably a bad name?
+ int _useNMOArrays;
int _numNMOFrames;
float _speed;
diff --git a/engines/tetraedge/te/te_pick_mesh2.cpp b/engines/tetraedge/te/te_pick_mesh2.cpp
index 09a019ec17b..32cd8e53f81 100644
--- a/engines/tetraedge/te/te_pick_mesh2.cpp
+++ b/engines/tetraedge/te/te_pick_mesh2.cpp
@@ -19,11 +19,14 @@
*
*/
+#include "common/util.h"
+
#include "tetraedge/tetraedge.h"
#include "tetraedge/te/te_mesh.h"
#include "tetraedge/te/te_pick_mesh2.h"
#include "tetraedge/te/te_renderer.h"
+#include "tetraedge/te/te_ray_intersection.h"
namespace Tetraedge {
@@ -55,6 +58,54 @@ void TePickMesh2::draw() {
renderer->setCurrentColor(prevCol);
}
+bool TePickMesh2::intersect(const TeVector3f32 &v1, const TeVector3f32 v2, TeVector3f32 &v3, float &fout, bool lastHitFirst, unsigned long *triangleHitOut) {
+ if (_verticies.size() / 3 == 0)
+ return false;
+
+ TeVector3f32 intersection;
+ float f;
+ const TeMatrix4x4 worldTrans = worldTransformationMatrix();
+ if (lastHitFirst) {
+ const TeVector3f32 triv1 = worldTrans * _verticies[_lastTriangleHit * 3 + 0];
+ const TeVector3f32 triv2 = worldTrans * _verticies[_lastTriangleHit * 3 + 1];
+ const TeVector3f32 triv3 = worldTrans * _verticies[_lastTriangleHit * 3 + 2];
+ int result = TeRayIntersection::intersect(v1, v2, triv1, triv2, triv3, intersection, f);
+ if (result == 1 && f >= 0.0 && f < FLT_MAX) {
+ v3 = v1 + v2 * f;
+ fout = f;
+ if (triangleHitOut)
+ *triangleHitOut = _lastTriangleHit;
+ return true;
+ }
+ }
+
+ float hitf = FLT_MAX;
+ for (unsigned int i = 0; i < _verticies.size() / 3; i++) {
+ const TeVector3f32 triv1 = worldTrans * _verticies[i * 3 + 0];
+ const TeVector3f32 triv2 = worldTrans * _verticies[i * 3 + 1];
+ const TeVector3f32 triv3 = worldTrans * _verticies[i * 3 + 2];
+ int result = TeRayIntersection::intersect(v1, v2, triv1, triv2, triv3, intersection, f);
+ if (result == 1 && f >= 0.0 && f < FLT_MAX) {
+ _lastTriangleHit = i;
+ hitf = f;
+ if (lastHitFirst)
+ break;
+ }
+ }
+ if (hitf != FLT_MAX) {
+ v3 = v1 + v2 * hitf;
+ fout = hitf;
+ if (triangleHitOut)
+ *triangleHitOut = _lastTriangleHit;
+ return true;
+ }
+ return false;
+}
+
+bool TePickMesh2::intersect2D(const TeVector2f32 &pt) {
+ error("TODO: Implement TePickMesh2::intersect2D");
+}
+
unsigned long TePickMesh2::lastTriangleHit() const {
if (_lastTriangleHit < _verticies.size() / 3)
return _lastTriangleHit;
@@ -85,12 +136,12 @@ bool TePickMesh2::pointInTriangle(const TeVector2f32 &p1, const TeVector2f32 &p2
return f1 != f2;
}
-void TePickMesh2::setNbTriangles(unsigned long num) {
+void TePickMesh2::setNbTriangles(unsigned int num) {
_verticies.resize(num * 3);
_lastTriangleHit = 0;
}
-void TePickMesh2::setTriangle(unsigned long num, const TeVector3f32 &v1, const TeVector3f32 &v2, const TeVector3f32 &v3) {
+void TePickMesh2::setTriangle(unsigned int num, const TeVector3f32 &v1, const TeVector3f32 &v2, const TeVector3f32 &v3) {
assert(num <= _verticies.size() / 3);
_verticies[num * 3 + 0] = v1;
_verticies[num * 3 + 1] = v2;
diff --git a/engines/tetraedge/te/te_pick_mesh2.h b/engines/tetraedge/te/te_pick_mesh2.h
index 817b518b384..fd823128a8a 100644
--- a/engines/tetraedge/te/te_pick_mesh2.h
+++ b/engines/tetraedge/te/te_pick_mesh2.h
@@ -35,17 +35,17 @@ public:
void draw() override;
- // bool intersect(TeVector3f32 const&, TeVector3f32 const&, TeVector3f32&, float&, bool flag, unsigned long *triangleHitOut);
+ bool intersect(const TeVector3f32 &v1, const TeVector3f32 v2, TeVector3f32 &v3, float &fout, bool useLastHit, unsigned long *triangleHitOut);
bool intersect2D(const TeVector2f32 &pt);
unsigned long lastTriangleHit() const;
bool pointInTriangle(const TeVector2f32 &p1, const TeVector2f32 &p2, const TeVector2f32 &p3, const TeVector2f32 &p4) const;
- void setLastTriangleHit(unsigned long lastHit) { _lastTriangleHit = lastHit; }
- void setNbTriangles(unsigned long num);
+ void setLastTriangleHit(unsigned int lastHit) { _lastTriangleHit = lastHit; }
+ void setNbTriangles(unsigned int num);
- void setTriangle(unsigned long num, const TeVector3f32 &v1, const TeVector3f32 &v2, const TeVector3f32 &v3);
- void triangle(unsigned long num, TeVector3f32 &v1out, TeVector3f32 &v2out, TeVector3f32 &v3out) const;
+ void setTriangle(unsigned int num, const TeVector3f32 &v1, const TeVector3f32 &v2, const TeVector3f32 &v3);
+ void triangle(unsigned int num, TeVector3f32 &v1out, TeVector3f32 &v2out, TeVector3f32 &v3out) const;
static void serialize(Common::WriteStream &stream, const TePickMesh2 &mesh);
static void deserialize(Common::ReadStream &stream, TePickMesh2 &mesh);
@@ -55,7 +55,7 @@ public:
private:
Common::Array<TeVector3f32> _verticies;
- unsigned long _lastTriangleHit;
+ unsigned int _lastTriangleHit;
};
diff --git a/engines/tetraedge/te/te_scene.cpp b/engines/tetraedge/te/te_scene.cpp
index bdb826d9fc0..7fd23f0b239 100644
--- a/engines/tetraedge/te/te_scene.cpp
+++ b/engines/tetraedge/te/te_scene.cpp
@@ -31,17 +31,17 @@ void TeScene::close() {
_models.clear();
}
-TeIntrusivePtr<TeCamera> TeScene::camera(const Common::String &name) {
+TeIntrusivePtr<TeCamera> TeScene::camera(const Common::String &cname) {
for (auto &c : _cameras) {
- if (c->name() == name)
+ if (c->name() == cname)
return c;
}
return TeIntrusivePtr<TeCamera>();
}
-TeIntrusivePtr<TeModel> TeScene::model(const Common::String &name) {
+TeIntrusivePtr<TeModel> TeScene::model(const Common::String &mname) {
for (auto &m : _models) {
- if (m->name() == name)
+ if (m->name() == mname)
return m;
}
return TeIntrusivePtr<TeModel>();
@@ -72,32 +72,32 @@ void TeScene::draw() {
TeCamera::restore();
}
-void TeScene::removeModel(const Common::String &name) {
+void TeScene::removeModel(const Common::String &mname) {
uint n = _models.size();
for (uint i = 0; i < n; i++) {
- if (_models[i]->name() == name) {
+ if (_models[i]->name() == mname) {
_models.remove_at(i);
break;
}
}
}
-void TeScene::setCurrentCamera(const Common::String &name) {
+void TeScene::setCurrentCamera(const Common::String &cname) {
uint n = _cameras.size();
uint i = 0;
for (; i < n; i++) {
- if (_cameras[i]->name() == name) {
+ if (_cameras[i]->name() == cname) {
break;
}
}
if (i == n) {
- debug("TeScene::setCurrentCamera: Couldn't find camera %s", name.c_str());
+ debug("TeScene::setCurrentCamera: Couldn't find camera %s", cname.c_str());
return;
}
_currentCameraIndex = i;
TeCamera *c = _cameras[i].get();
assert(c);
- debug("TeScene::setCurrentCamera: Set %s", c->name().c_str());
+ // debug("TeScene::setCurrentCamera: Set %s", c->name().c_str());
}
void TeScene::update() {
diff --git a/engines/tetraedge/te/te_scene.h b/engines/tetraedge/te/te_scene.h
index 0bdf12059d6..8a5174ae7f8 100644
--- a/engines/tetraedge/te/te_scene.h
+++ b/engines/tetraedge/te/te_scene.h
@@ -39,8 +39,8 @@ public:
virtual void close();
- TeIntrusivePtr<TeCamera> camera(const Common::String &name);
- TeIntrusivePtr<TeModel> model(const Common::String &name);
+ TeIntrusivePtr<TeCamera> camera(const Common::String &cname);
+ TeIntrusivePtr<TeModel> model(const Common::String &mname);
TeIntrusivePtr<TeCamera> currentCamera();
int currentCameraIndex() const { return _currentCameraIndex; }
@@ -49,8 +49,8 @@ public:
virtual void draw();
virtual bool load(const Common::Path &path) { return false; };
- void removeModel(const Common::String &name);
- void setCurrentCamera(const Common::String &name);
+ void removeModel(const Common::String &mname);
+ void setCurrentCamera(const Common::String &cname);
void setCurrentCameraIndex(uint index) {
_currentCameraIndex = index;
}
diff --git a/engines/tetraedge/te/te_scrolling_layout.h b/engines/tetraedge/te/te_scrolling_layout.h
index d4eb519f43e..25d36471d89 100644
--- a/engines/tetraedge/te/te_scrolling_layout.h
+++ b/engines/tetraedge/te/te_scrolling_layout.h
@@ -80,8 +80,6 @@ public:
}
void setContentLayout(TeLayout *layout);
- // TODO add public members
-
private:
int _inertiaAnimationDuration;
Common::Array<float> _inertiaAnimationCurve;
diff --git a/engines/tetraedge/te/te_tiled_surface.cpp b/engines/tetraedge/te/te_tiled_surface.cpp
index 3725be41c5a..c299df4e293 100644
--- a/engines/tetraedge/te/te_tiled_surface.cpp
+++ b/engines/tetraedge/te/te_tiled_surface.cpp
@@ -281,6 +281,4 @@ void TeTiledSurface::updateVideoProperties() {
}
}
-// TODO: Add more functions here.
-
} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_tiled_texture.cpp b/engines/tetraedge/te/te_tiled_texture.cpp
index b6aeb9d9c78..6ae69f9dcc3 100644
--- a/engines/tetraedge/te/te_tiled_texture.cpp
+++ b/engines/tetraedge/te/te_tiled_texture.cpp
@@ -179,7 +179,4 @@ void TeTiledTexture::update(const TeImage &image) {
//}
}
-
-// TODO: Add more functions here.
-
} // end namespace Tetraedge
Commit: 710a1b9f1b4ec945ee399db9c1a7672fa1795c73
https://github.com/scummvm/scummvm/commit/710a1b9f1b4ec945ee399db9c1a7672fa1795c73
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2023-01-16T17:36:43+01:00
Commit Message:
TETRAEDGE: More WIP. Idle animations work, character rotation and position now right.
z-order and objects need work.
Changed paths:
engines/tetraedge/game/character.cpp
engines/tetraedge/game/character.h
engines/tetraedge/game/document.cpp
engines/tetraedge/game/document.h
engines/tetraedge/game/documents_browser.cpp
engines/tetraedge/game/game.cpp
engines/tetraedge/game/game.h
engines/tetraedge/game/in_game_scene.cpp
engines/tetraedge/game/in_game_scene.h
engines/tetraedge/game/inventory.cpp
engines/tetraedge/game/lua_binds.cpp
engines/tetraedge/game/object3d.h
engines/tetraedge/te/te_3d_object2.cpp
engines/tetraedge/te/te_3d_texture.cpp
engines/tetraedge/te/te_act_zone.h
engines/tetraedge/te/te_bezier_curve.cpp
engines/tetraedge/te/te_camera.cpp
engines/tetraedge/te/te_free_move_zone.cpp
engines/tetraedge/te/te_interpolation.cpp
engines/tetraedge/te/te_layout.cpp
engines/tetraedge/te/te_lua_thread.cpp
engines/tetraedge/te/te_matricies_stack.cpp
engines/tetraedge/te/te_matrix4x4.cpp
engines/tetraedge/te/te_matrix4x4.h
engines/tetraedge/te/te_mesh.cpp
engines/tetraedge/te/te_mesh.h
engines/tetraedge/te/te_model.cpp
engines/tetraedge/te/te_model.h
engines/tetraedge/te/te_model_animation.cpp
engines/tetraedge/te/te_pick_mesh2.cpp
engines/tetraedge/te/te_quaternion.h
engines/tetraedge/te/te_renderer.cpp
engines/tetraedge/te/te_renderer.h
engines/tetraedge/te/te_signal.h
engines/tetraedge/te/te_text_base2.cpp
engines/tetraedge/te/te_trs.cpp
engines/tetraedge/te/te_vector3f32.cpp
diff --git a/engines/tetraedge/game/character.cpp b/engines/tetraedge/game/character.cpp
index 62aaff289d5..1ffe18054ab 100644
--- a/engines/tetraedge/game/character.cpp
+++ b/engines/tetraedge/game/character.cpp
@@ -24,7 +24,9 @@
#include "common/file.h"
#include "common/debug.h"
+#include "tetraedge/tetraedge.h"
#include "tetraedge/game/character.h"
+#include "tetraedge/game/game.h"
#include "tetraedge/game/character_settings_xml_parser.h"
#include "tetraedge/te/te_model_animation.h"
@@ -62,6 +64,29 @@ _freeMoveZone(nullptr), _animSoundOffset(0), _lastAnimFrame(0), _charLookingAt(n
_curModelAnim.setDeleteFn(&TeModelAnimation::deleteLater);
}
+Character::~Character() {
+ _model->setVisible(false);
+ _model->bonesUpdatedSignal().remove(this, &Character::onBonesUpdate);
+ deleteAnim();
+ Game *game = g_engine->getGame();
+ Common::Array<TeIntrusivePtr<TeModel>> &models = game->scene().models();
+ for (unsigned int i = 0; i < models.size(); i++) {
+ if (models[i] == _model) {
+ models.remove_at(i);
+ break;
+ }
+ }
+ removeAnim();
+ for (unsigned int s = 0; s < 2; s++) {
+ for (unsigned int i = 0; i < models.size(); i++) {
+ if (models[i] == _shadowModel[s]) {
+ models.remove_at(i);
+ break;
+ }
+ }
+ }
+}
+
void Character::addCallback(const Common::String &key, const Common::String &s2, float f1, float f2) {
/*Callback *c = new Callback();
c->x = (int)f1;
@@ -89,7 +114,9 @@ void Character::addCallback(const Common::String &key, const Common::String &s2,
return _cache.getVal(pathStr);
TeIntrusivePtr<TeModelAnimation> modelAnim = new TeModelAnimation();
- modelAnim->load(path);
+ if (!modelAnim->load(path)) {
+ warning("Failed to load anim %s", path.toString().c_str());
+ }
_cache.setVal(pathStr, modelAnim);
return modelAnim;
@@ -138,8 +165,10 @@ bool Character::blendAnimation(const Common::String &animname, float amount, boo
|| animname.contains(walkAnim(WalkPart_EndG))
|| animname.contains(walkAnim(WalkPart_EndD)));
- if (_curModelAnim)
+ if (_curModelAnim) {
_curModelAnim->onFinished().remove(this, &Character::onModelAnimationFinished);
+ _curModelAnim->unbind();
+ }
_curModelAnim = animCacheLoad(animpath);
_curModelAnim->onFinished().add(this, &Character::onModelAnimationFinished);
@@ -238,11 +267,10 @@ int Character::rightStepFrame(enum Character::WalkPart walkpart) {
bool Character::loadModel(const Common::String &mname, bool unused) {
assert(_globalCharacterSettings);
if (_model) {
- //TODO
- //_model->bonesUpdateSignal().remove(this, &Character::onBonesUpdate);
+ _model->bonesUpdatedSignal().remove(this, &Character::onBonesUpdate);
}
_model = new TeModel();
- //_model->bonesUpdateSignal().add(this, &Character::onBonesUpdate);
+ _model->bonesUpdatedSignal().add(this, &Character::onBonesUpdate);
if (!_globalCharacterSettings->contains(mname))
return false;
@@ -339,9 +367,100 @@ bool Character::loadModel(const Common::String &mname, bool unused) {
return false;
}
-bool Character::onBonesUpdate(const Common::String &boneName, const TeMatrix4x4 ¶m_2) {
- error("TODO: Implement Character::onBonesUpdate");
- return false;
+bool Character::onBonesUpdate(const Common::String &boneName, TeMatrix4x4 &boneMatrix) {
+ if (!_model || !_model->anim())
+ return false;
+
+ Game *game = g_engine->getGame();
+ if (boneName == "Pere") {
+ const Common::String animfile = _model->anim()->_loadedPath.getLastComponent().toString();
+ bool resetX = false;
+ if (game->scene()._character == this) {
+ for (const auto &walkSettings : _characterSettings._walkSettings) {
+ resetX |= (walkSettings._key.contains("Walk") || walkSettings._key.contains("Jog"));
+ resetX |= (walkSettings._value._walkParts[0]._file == animfile ||
+ walkSettings._value._walkParts[1]._file == animfile ||
+ walkSettings._value._walkParts[2]._file == animfile ||
+ walkSettings._value._walkParts[3]._file == animfile);
+ }
+ resetX |= animfile.contains(_characterSettings._walkFileName);
+ } else {
+ resetX = (animfile.contains(_characterSettings._walkFileName) ||
+ animfile.contains(walkAnim(WalkPart_Start)) ||
+ animfile.contains(walkAnim(WalkPart_Loop)) ||
+ animfile.contains(walkAnim(WalkPart_EndD)) ||
+ animfile.contains(walkAnim(WalkPart_EndG)));
+ }
+ if (resetX) {
+ boneMatrix.setValue(0, 3, 0.0f);
+ boneMatrix.setValue(2, 3, 0.0f);
+ }
+ }
+
+ if (boneName.contains("Bip01 Head")) {
+ if (_hasAnchor) {
+ game->scene().currentCamera()->apply();
+ _lastHeadRotation = _headRotation;
+ TeQuaternion rot1 = TeQuaternion::fromAxisAndAngle(TeVector3f32(-1, 0, 0), _lastHeadRotation.getX());
+ TeQuaternion rot2 = TeQuaternion::fromAxisAndAngle(TeVector3f32(0, 0, 1), _lastHeadRotation.getY());
+ boneMatrix.rotate(rot1);
+ boneMatrix.rotate(rot2);
+ } else {
+ float lastHeadX = _lastHeadRotation.getX();
+ float minX = (lastHeadX > 0) ? -0.1 : 0.1;
+ float newX = (fabs(minX) > fabs(lastHeadX)) ? 0.0 : minX + lastHeadX;
+ _lastHeadRotation.setX(newX);
+
+ float lastHeadY = _lastHeadRotation.getY();
+ float minY = (lastHeadY > 0) ? -0.1 : 0.1;
+ float newY = (fabs(minY) > fabs(lastHeadY)) ? 0.0 : minY + lastHeadY;
+ _lastHeadRotation.setY(newY);
+
+ _headRotation.setX(_lastHeadRotation.getX());
+ _headRotation.setY(_lastHeadRotation.getY());
+
+ TeQuaternion rot1 = TeQuaternion::fromAxisAndAngle(TeVector3f32(-1, 0, 0), _lastHeadRotation.getX());
+ TeQuaternion rot2 = TeQuaternion::fromAxisAndAngle(TeVector3f32(0, 0, 1), _lastHeadRotation.getY());
+ boneMatrix.rotate(rot1);
+ boneMatrix.rotate(rot2);
+ _lastHeadBoneTrans = boneMatrix.translation();
+ }
+ }
+
+ if (boneName.contains("Bip01 L Foot") || boneName.contains("Bip01 R Foot")) {
+ TeVector3f32 trans = boneMatrix.translation();
+ trans.rotate(_model->rotation());
+ const TeVector3f32 modelScale = _model->scale();
+ trans.x() *= modelScale.x();
+ trans.y() = 0.0;
+ trans.z() *= modelScale.z();
+ TeVector3f32 pos = _model->position() + trans;
+ if (_freeMoveZone) {
+ bool flag;
+ pos = _freeMoveZone->correctCharacterPosition(pos, &flag, true);
+ }
+ _shadowModel[1]->setPosition(pos);
+ _shadowModel[1]->setRotation(_model->rotation());
+ _shadowModel[1]->setScale(_model->scale());
+ }
+
+ // Move any objects attached to the bone
+ for (Object3D *obj : game->scene().object3Ds()) {
+ if (obj->_onCharName == _model->name() && boneName == obj->_onCharBone) {
+ obj->model()->setVisible(true);
+ TeMatrix4x4 objmatrix = boneMatrix;
+ objmatrix.scale(obj->_objScale);
+ objmatrix.rotate(obj->_objRotation);
+ objmatrix.scale(obj->_objScale);
+ objmatrix.translate(obj->_objTranslation);
+ obj->model()->forceMatrix(objmatrix);
+ obj->model()->setPosition(_model->position());
+ obj->model()->setRotation(_model->rotation());
+ obj->model()->setScale(_model->scale());
+ }
+ }
+
+ return true;
}
bool Character::onModelAnimationFinished() {
@@ -361,6 +480,7 @@ void Character::placeOnCurve(TeIntrusivePtr<TeBezierCurve> &curve) {
void Character::removeAnim() {
if (_curModelAnim) {
_curModelAnim->onFinished().remove(this, &Character::onModelAnimationFinished);
+ _curModelAnim->unbind();
}
_model->removeAnim();
if (_curModelAnim) {
@@ -378,12 +498,12 @@ bool Character::setAnimation(const Common::String &aname, bool repeat, bool para
Common::Path animPath("models/Anims");
animPath.joinInPlace(aname);
- bool validAnim = (aname.contains(_characterSettings._walkFileName) ||
+ bool isWalkAnim = (aname.contains(_characterSettings._walkFileName) ||
aname.contains(walkAnim(WalkPart_Start)) ||
aname.contains(walkAnim(WalkPart_Loop)) ||
aname.contains(walkAnim(WalkPart_EndD)) ||
aname.contains(walkAnim(WalkPart_EndG)));
- _missingCurrentAnim = !validAnim;
+ _missingCurrentAnim = !isWalkAnim;
if (_curModelAnim) {
_curModelAnim->onFinished().remove(this, &Character::onModelAnimationFinished);
@@ -451,6 +571,10 @@ TeTRS Character::trsFromAnim(const TeModelAnimation &anim, long bone, long frame
}
void Character::update(double percentval) {
+ if (!_curve || !_runTimer.running())
+ return;
+ //float speed = speedFromAnim(percentval);
+
error("TODO: Implement Character::update");
}
diff --git a/engines/tetraedge/game/character.h b/engines/tetraedge/game/character.h
index d9c005f2de4..5d3ea7c85b1 100644
--- a/engines/tetraedge/game/character.h
+++ b/engines/tetraedge/game/character.h
@@ -40,7 +40,7 @@ namespace Tetraedge {
class Character : public TeAnimation {
public:
Character();
- virtual ~Character() {}
+ virtual ~Character();
struct AnimSettings {
AnimSettings() : _stepLeft(0), _stepRight(0) {};
@@ -117,7 +117,7 @@ public:
bool loadModel(const Common::String &name, bool param_2);
static bool loadSettings(const Common::String &path);
- bool onBonesUpdate(const Common::String &boneName, const TeMatrix4x4 ¶m_2);
+ bool onBonesUpdate(const Common::String &boneName, TeMatrix4x4 &boneMatrix);
bool onModelAnimationFinished();
void permanentUpdate();
void placeOnCurve(TeIntrusivePtr<TeBezierCurve> &curve);
@@ -137,7 +137,7 @@ public:
float translationFromAnim(const TeModelAnimation &anim, long bone, long frame);
TeVector3f32 translationVectorFromAnim(const TeModelAnimation &anim, long bone, long frame);
TeTRS trsFromAnim(const TeModelAnimation &anim, long bone, long frame);
- void update(double percentval);
+ void update(double percentval) override;
void updateAnimFrame();
void updatePosition(float curveOffset);
Common::String walkAnim(WalkPart part);
@@ -171,7 +171,6 @@ public:
Character *charLookingAt() { return _charLookingAt; }
bool lookingAtTallThing() const { return _lookingAtTallThing; }
void setLookingAtTallThing(bool val) { _lookingAtTallThing = val; }
-
private:
float _curveOffset;
@@ -209,10 +208,11 @@ private:
bool _needsSomeUpdate;
bool _positionFlag;
bool _lookingAtTallThing;
-
bool _hasAnchor;
+
TeVector2f32 _headRotation;
TeVector2f32 _lastHeadRotation;
+ TeVector3f32 _lastHeadBoneTrans;
TeVector3f32 _positionCharacter;
diff --git a/engines/tetraedge/game/document.cpp b/engines/tetraedge/game/document.cpp
index be6ccd15604..e31e7b29a44 100644
--- a/engines/tetraedge/game/document.cpp
+++ b/engines/tetraedge/game/document.cpp
@@ -23,9 +23,26 @@
namespace Tetraedge {
-Document::Document() {
+Document::Document(DocumentsBrowser *browser) : _browser(browser) {
+
+}
+
+void Document::load(const Common::String &name) {
+ error("TODO: Implement Document::load");
+}
+
+void Document::unload() {
+ removeChild(_gui.layoutChecked("object"));
+ _gui.unload();
+}
+
+bool Document::onButtonDown() {
+ _onButtonDownSignal.call(*this);
+ return false;
}
-// TODO: Add more functions here.
+Common::Path Document::spritePath() const {
+ return Common::Path("DocumentsBrowser/Documents").join(name()).append(".png");
+}
} // end namespace Tetraedge
diff --git a/engines/tetraedge/game/document.h b/engines/tetraedge/game/document.h
index 9c6bbeb8a65..33647fe574c 100644
--- a/engines/tetraedge/game/document.h
+++ b/engines/tetraedge/game/document.h
@@ -24,28 +24,37 @@
#include "common/str.h"
+#include "tetraedge/te/te_layout.h"
+#include "tetraedge/te/te_lua_gui.h"
+
namespace Tetraedge {
-class Document {
+class DocumentsBrowser;
+
+class Document : public TeLayout {
public:
- Document();
+ Document(DocumentsBrowser *browser);
~Document() {
unload();
- // TODO: check for other destructor things.
+ if (parent()) {
+ // TODO: do something with parent here.
+ }
}
void load(const Common::String &name);
//void loadFromBackup(TiXmlElement &node) {
// load(node->Attribute("id");
//}
+
bool onButtonDown();
//void saveToBackup(TiXmlElement &node);
- Common::String spritePath() const;
+ Common::Path spritePath() const;
void unload();
private:
- // TODO add private members
-
+ DocumentsBrowser *_browser;
+ TeLuaGUI _gui;
+ TeSignal1Param<Document &> _onButtonDownSignal;
};
} // end namespace Tetraedge
diff --git a/engines/tetraedge/game/documents_browser.cpp b/engines/tetraedge/game/documents_browser.cpp
index e9f29b577a2..1e37a00fad6 100644
--- a/engines/tetraedge/game/documents_browser.cpp
+++ b/engines/tetraedge/game/documents_browser.cpp
@@ -89,7 +89,13 @@ void DocumentsBrowser::currentPage(long page) {
}
bool DocumentsBrowser::onQuitDocumentDoubleClickTimer() {
- error("TODO: Implement DocumentsBrowser::onQuitDocumentDoubleClickTimer");
+ long time = _timer.getTimeFromStart();
+ _timer.stop();
+ if (time >= 200000)
+ error("TODO: Implement DocumentsBrowser::onQuitDocumentDoubleClickTimer");
+ else
+ hideDocument();
+ return false;
}
bool DocumentsBrowser::onNextPage() {
diff --git a/engines/tetraedge/game/game.cpp b/engines/tetraedge/game/game.cpp
index 4c646a33a67..b57fbeef487 100644
--- a/engines/tetraedge/game/game.cpp
+++ b/engines/tetraedge/game/game.cpp
@@ -270,7 +270,7 @@ void Game::enter(bool newgame) {
Common::SharedPtr<TeCallback1Param<Game, const Common::Point &>> callbackptr(new TeCallback1Param<Game, const Common::Point &>(this, &Game::onMouseClick, -1000.0f));
g_engine->getInputMgr()->_mouseLUpSignal.insert(callbackptr);
_movePlayerCharacterDisabled = false;
- warning("TODO: Game::enter set some other fields here");
+ warning("TODO: Game::enter set some other field here");
_sceneCharacterVisibleFromLoad = false;
Character::loadSettings("models/ModelsSettings.xml");
Object3D::loadSettings("objects/ObjectsSettings.xml");
@@ -1163,7 +1163,7 @@ void Game::playMovie(const Common::String &vidPath, const Common::String &musicP
music.play();
videoSpriteLayout->play();
- // FIXME TODO!! Stop the movie and soundearly for testing.
+ // Stop the movie and sound early for testing if skip_videos set
if (ConfMan.get("skip_videos") == "true") {
videoSpriteLayout->_tiledSurfacePtr->_frameAnim._nbFrames = 10;
music.stop();
@@ -1243,7 +1243,7 @@ void Game::playSound(const Common::String &name, int repeats, float volume) {
return;
}
}
-
+
GameSound *sound = new GameSound();
sound->setChannelName("sfx");
sound->load(name);
diff --git a/engines/tetraedge/game/game.h b/engines/tetraedge/game/game.h
index d95807a978c..081bd5ec52b 100644
--- a/engines/tetraedge/game/game.h
+++ b/engines/tetraedge/game/game.h
@@ -256,7 +256,7 @@ private:
bool _markersVisible;
bool _saveRequested;
bool _randomSoundFinished;
-
+
Common::RandomSource _randomSource;
RandomSound *_randomSound;
TeTimer _randomSoundTimer;
diff --git a/engines/tetraedge/game/in_game_scene.cpp b/engines/tetraedge/game/in_game_scene.cpp
index 2fb70cdbdda..705fbe78243 100644
--- a/engines/tetraedge/game/in_game_scene.cpp
+++ b/engines/tetraedge/game/in_game_scene.cpp
@@ -301,9 +301,13 @@ void InGameScene::deserializeModel(Common::ReadStream &stream, TeIntrusivePtr<Te
uint32 indexcount = stream.readUint32LE();
uint32 vertexcount = stream.readUint32LE();
+ if (indexcount > 100000 || vertexcount > 100000)
+ error("InGameScene::deserializeModel: Unxpected counts %d %d", indexcount, vertexcount);
+
mesh.setConf(vertexcount, indexcount, TeMesh::MeshMode_Triangles, 0, 0);
for (unsigned int i = 0; i < indexcount; i++)
mesh.setIndex(i, stream.readUint32LE());
+
for (unsigned int i = 0; i < vertexcount; i++) {
TeVector3f32::deserialize(stream, vec);
mesh.setVertex(i, vec);
@@ -527,7 +531,7 @@ bool InGameScene::load(const Common::Path &path) {
if (!Common::File::exists(path))
return false;
- TeScene::close();
+ close();
_loadedPath = path;
Common::File scenefile;
if (!scenefile.open(path))
@@ -563,7 +567,7 @@ bool InGameScene::load(const Common::Path &path) {
delete pickmesh;
if (modelname.substr(0, 2) != "ZB") {
if (objname.empty()) {
- warning("[InGameScene::load] Unknown type of object named : %s", modelname.c_str());
+ debug("[InGameScene::load] Unknown type of object named : %s", modelname.c_str());
} else {
InGameScene::Object obj;
obj._name = objname;
@@ -620,12 +624,6 @@ bool InGameScene::load(const Common::Path &path) {
_charactersShadow->create(this);
onMainWindowSizeChanged();
- // FIXME: For some reason the game never re-adds kate's model to the list here..
- // how does it ever get drawn???
- if (!findKate()) {
- models().push_back(_character->_model);
- }
-
return true;
}
@@ -755,6 +753,8 @@ void InGameScene::loadBlockers() {
blockersfile.seek(0);
uint32 nblockers = blockersfile.readUint32LE();
+ if (nblockers > 1024)
+ error("Improbable number of blockers %d", nblockers);
_blockers.resize(nblockers);
for (unsigned int i = 0; i < nblockers; i++) {
_blockers[i]._s = Te3DObject2::deserializeString(blockersfile);
@@ -765,6 +765,8 @@ void InGameScene::loadBlockers() {
if (hasHeader) {
uint32 nrectblockers = blockersfile.readUint32LE();
+ if (nrectblockers > 1024)
+ error("Improbable number of rectblockers %d", nrectblockers);
_rectBlockers.resize(nrectblockers);
for (unsigned int i = 0; i < nrectblockers; i++) {
_rectBlockers[i]._s = Te3DObject2::deserializeString(blockersfile);
@@ -1034,14 +1036,11 @@ void InGameScene::update() {
}
}
- // TODO: some other stuff with callbacks and spritelayouts here
- for (auto &callback : _callbacks) {
-
- }
-
TeLuaGUI::StringMap<TeSpriteLayout *> &sprites = bgGui().spriteLayouts();
for (auto &sprite : sprites) {
-
+ if (_callbacks.contains(sprite._key)) {
+ error("TODO: handle sprite callback in InGameScene::update");
+ }
}
TeScene::update();
@@ -1065,10 +1064,10 @@ void InGameScene::update() {
for (Object3D *obj : _object3Ds) {
// TODO: update object3ds if they are translating or rotating.
if (obj->_translateTime >= 0) {
-
+ error("TODO: handle _translateTime > 0 in InGameScene::update");
}
if (obj->_rotateTime >= 0) {
-
+ error("TODO: handle _rotateTime > 0 in InGameScene::update");
}
}
}
diff --git a/engines/tetraedge/game/in_game_scene.h b/engines/tetraedge/game/in_game_scene.h
index 18e72dd540a..eee8bc31785 100644
--- a/engines/tetraedge/game/in_game_scene.h
+++ b/engines/tetraedge/game/in_game_scene.h
@@ -53,7 +53,7 @@ public:
Common::String _name;
TeSpriteLayout *_layout;
};
-
+
struct Callback {
float _f;
Common::String _name;
@@ -193,6 +193,7 @@ public:
void setCurve(TeIntrusivePtr<TeBezierCurve> &c) { c = _curve; }
Common::Array<TeIntrusivePtr<TeModel>> &zoneModels() { return _zoneModels; }
Common::Array<TeRectBlocker> &rectBlockers() { return _rectBlockers; }
+ Common::Array<Object3D *> object3Ds() { return _object3Ds; }
private:
TeColor _shadowColor;
diff --git a/engines/tetraedge/game/inventory.cpp b/engines/tetraedge/game/inventory.cpp
index bb888e0a407..5b6573564a7 100644
--- a/engines/tetraedge/game/inventory.cpp
+++ b/engines/tetraedge/game/inventory.cpp
@@ -270,7 +270,7 @@ bool Inventory::onZoomed() {
void Inventory::pauseAnims() {
Game *game = g_engine->getGame();
if (game->scene()._character) {
-
+
}
error("TODO: implement Inventory::pauseAnims");
}
@@ -278,7 +278,7 @@ void Inventory::pauseAnims() {
void Inventory::unPauseAnims() {
Game *game = g_engine->getGame();
if (game->scene()._character) {
-
+
}
error("TODO: implement Inventory::unPauseAnims");
}
diff --git a/engines/tetraedge/game/lua_binds.cpp b/engines/tetraedge/game/lua_binds.cpp
index e39d09f19ef..4a927e8fdf1 100644
--- a/engines/tetraedge/game/lua_binds.cpp
+++ b/engines/tetraedge/game/lua_binds.cpp
@@ -25,6 +25,7 @@
#include "tetraedge/game/character.h"
#include "tetraedge/game/game.h"
#include "tetraedge/game/lua_binds.h"
+#include "tetraedge/game/object3d.h"
#include "tetraedge/to_lua.h"
namespace Tetraedge {
@@ -41,7 +42,7 @@ static void PlayMovie(const Common::String &vidpath, const Common::String &music
}
static int tolua_ExportedFunctions_PlayMovie00(lua_State *L) {
-tolua_Error err;
+ tolua_Error err;
if (tolua_isstring(L, 1, 0, &err) && tolua_isstring(L, 2, 0, &err) && tolua_isnoobj(L, 3, &err)) {
Common::String s1(tolua_tostring(L, 1, nullptr));
Common::String s2(tolua_tostring(L, 2, nullptr));
@@ -220,7 +221,7 @@ static void SetVisibleMarker(const Common::String &markerName, bool val) {
}
static int tolua_ExportedFunctions_SetVisibleMarker00(lua_State *L) {
-tolua_Error err;
+ tolua_Error err;
if (tolua_isstring(L, 1, 0, &err) && tolua_isboolean(L, 2, 0, &err) && tolua_isnoobj(L, 3, &err)) {
Common::String s(tolua_tostring(L, 1, nullptr));
bool b = tolua_toboolean(L, 2, 0);
@@ -369,9 +370,9 @@ static int tolua_ExportedFunctions_UnloadObject00(lua_State *L) {
error("#ferror in function 'UnloadObject': %d %d %s", err.index, err.array, err.type);
}
-static void SetCharacterRotation(const Common::String &charname, float f1, float f2, float f3) {
+static void SetCharacterRotation(const Common::String &charname, float rx, float ry, float rz) {
// TODO: check if this is good.
- TeQuaternion quat = TeQuaternion::fromEuler(TeVector3f32(f1 * M_PI / 180.0, f2 * M_PI / 180.0, f3 * M_PI / 180.0));
+ TeQuaternion quat = TeQuaternion::fromEuler(TeVector3f32(rx * M_PI / 180.0, ry * M_PI / 180.0, rz * M_PI / 180.0));
Game *game = g_engine->getGame();
Character *c = game->scene().character(charname);
if (c) {
@@ -389,7 +390,7 @@ static int tolua_ExportedFunctions_SetCharacterRotation00(lua_State *L) {
Common::String s1(tolua_tostring(L, 1, nullptr));
float f1 = tolua_tonumber(L, 2, 0.0);
float f2 = tolua_tonumber(L, 3, 0.0);
- float f3 = tolua_tonumber(L, 4, 1.0);
+ float f3 = tolua_tonumber(L, 4, 0.0);
SetCharacterRotation(s1, f1, f2, f3);
return 0;
}
@@ -409,7 +410,7 @@ static int tolua_ExportedFunctions_SetCharacterPosition00(lua_State *L) {
Common::String s1(tolua_tostring(L, 1, nullptr));
Common::String s2(tolua_tostring(L, 2, nullptr));
float f1 = tolua_tonumber(L, 3, 0.0);
- float f2 = tolua_tonumber(L, 4, 1.0);
+ float f2 = tolua_tonumber(L, 4, 0.0);
float f3 = tolua_tonumber(L, 5, 0.0);
SetCharacterPosition(s1, s2, f1, f2, f3);
return 0;
@@ -450,7 +451,7 @@ static void SetGroundObjectRotation(const Common::String &objname, float x, floa
warning("[SetGroundObjectRotation] Object not found %s", objname.c_str());
return;
}
-
+
TeVector3f32 rotvec(x * M_PI / 180.0, y * M_PI / 180.0, z * M_PI / 180.0);
obj->model()->setRotation(TeQuaternion::fromEuler(rotvec));
obj->model()->setVisible(true);
@@ -675,6 +676,119 @@ static int tolua_ExportedFunctions_PlayMusic00(lua_State *L) {
error("#ferror in function 'PlayMusic': %d %d %s", err.index, err.array, err.type);
}
+static void SetObjectOnCharacter(const Common::String &obj, const Common::String &charName, const Common::String &boneName) {
+ Game *game = g_engine->getGame();
+ Object3D *obj3d = game->scene().object3D(obj);
+ if (!obj3d)
+ warning("[SetObjectOnCharacter] Object not found %s", obj.c_str());
+
+ obj3d->_onCharName = charName;
+ obj3d->_onCharBone = boneName;
+}
+
+static int tolua_ExportedFunctions_SetObjectOnCharacter00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isstring(L, 2, 0, &err) && tolua_isstring(L, 3, 0, &err) && tolua_isnoobj(L, 4, &err)) {
+ Common::String s1(tolua_tostring(L, 1, nullptr));
+ Common::String s2(tolua_tostring(L, 2, nullptr));
+ Common::String s3(tolua_tostring(L, 3, nullptr));
+ SetObjectOnCharacter(s1, s2, s3);
+ return 0;
+ }
+ error("#ferror in function 'SetObjectOnCharacter': %d %d %s", err.index, err.array, err.type);
+}
+
+static void SetObjectRotation(const Common::String &obj, float xr, float yr, float zr) {
+ Game *game = g_engine->getGame();
+ Object3D *obj3d = game->scene().object3D(obj);
+ if (!obj3d)
+ warning("[SetObjectRotation] Object not found %s", obj.c_str());
+ const TeVector3f32 rot(xr * M_PI / 180.0, yr * M_PI / 180.0, zr * M_PI / 180.0);
+ obj3d->_objRotation = TeQuaternion::fromEuler(rot);
+}
+
+static int tolua_ExportedFunctions_SetObjectRotation00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isnumber(L, 2, 0, &err)
+ && tolua_isnumber(L, 3, 0, &err) && tolua_isnumber(L, 4, 0, &err)
+ && tolua_isnoobj(L, 5, &err)) {
+ Common::String s1(tolua_tostring(L, 1, nullptr));
+ float f1 = tolua_tonumber(L, 2, 0.0);
+ float f2 = tolua_tonumber(L, 3, 0.0);
+ float f3 = tolua_tonumber(L, 4, 0.0);
+ SetObjectRotation(s1, f1, f2, f3);
+ return 0;
+ }
+ error("#ferror in function 'SetObjectRotation': %d %d %s", err.index, err.array, err.type);
+}
+
+static void SetObjectTranslation(const Common::String &obj, float x, float y, float z) {
+ Game *game = g_engine->getGame();
+ Object3D *obj3d = game->scene().object3D(obj);
+ if (!obj3d)
+ warning("[SetObjectTranslation] Object not found %s", obj.c_str());
+ obj3d->_objTranslation = TeVector3f32(x, y, z);
+}
+
+static int tolua_ExportedFunctions_SetObjectTranslation00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isnumber(L, 2, 0, &err)
+ && tolua_isnumber(L, 3, 0, &err) && tolua_isnumber(L, 4, 0, &err)
+ && tolua_isnoobj(L, 5, &err)) {
+ Common::String s1(tolua_tostring(L, 1, nullptr));
+ float f1 = tolua_tonumber(L, 2, 0.0);
+ float f2 = tolua_tonumber(L, 3, 0.0);
+ float f3 = tolua_tonumber(L, 4, 0.0);
+ SetObjectTranslation(s1, f1, f2, f3);
+ return 0;
+ }
+ error("#ferror in function 'SetObjectTranslation': %d %d %s", err.index, err.array, err.type);
+}
+
+static void SetObjectScale(const Common::String &obj, float xs, float ys, float zs) {
+ Game *game = g_engine->getGame();
+ Object3D *obj3d = game->scene().object3D(obj);
+ if (!obj3d)
+ warning("[SetObjectScale] Object not found %s", obj.c_str());
+ obj3d->_objScale = TeVector3f32(xs, ys, zs);
+}
+
+static int tolua_ExportedFunctions_SetObjectScale00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isnumber(L, 2, 0, &err)
+ && tolua_isnumber(L, 3, 0, &err) && tolua_isnumber(L, 4, 0, &err)
+ && tolua_isnoobj(L, 5, &err)) {
+ Common::String s1(tolua_tostring(L, 1, nullptr));
+ float f1 = tolua_tonumber(L, 2, 0.0);
+ float f2 = tolua_tonumber(L, 3, 0.0);
+ float f3 = tolua_tonumber(L, 4, 0.0);
+ SetObjectScale(s1, f1, f2, f3);
+ return 0;
+ }
+ error("#ferror in function 'SetObjectScale': %d %d %s", err.index, err.array, err.type);
+}
+
+static void SetObjectFrames(const Common::String &obj, int start, int end) {
+ Game *game = g_engine->getGame();
+ Object3D *obj3d = game->scene().object3D(obj);
+ if (!obj3d)
+ warning("[SetObjectFrames] Object not found %s", obj.c_str());
+ obj3d->_startFrame = start;
+ obj3d->_endFrame = end;
+}
+
+static int tolua_ExportedFunctions_SetObjectFrames00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isnumber(L, 2, 0, &err)
+ && tolua_isnumber(L, 3, 0, &err) && tolua_isnoobj(L, 4, &err)) {
+ Common::String s1(tolua_tostring(L, 1, nullptr));
+ float f1 = tolua_tonumber(L, 2, 0.0);
+ float f2 = tolua_tonumber(L, 3, 0.0);
+ SetObjectFrames(s1, (int)f1, (int)f2);
+ return 0;
+ }
+ error("#ferror in function 'SetObjectFrames': %d %d %s", err.index, err.array, err.type);
+}
// ////////////////////////////////////////////////////////////////////////
@@ -689,10 +803,10 @@ void LuaOpenBinds(lua_State *L) {
tolua_function(L, "LoadObjectMaterials", tolua_ExportedFunctions_LoadObjectMaterials01);*/
tolua_function(L, "HideObject", tolua_ExportedFunctions_HideObject00);
tolua_function(L, "ShowObject", tolua_ExportedFunctions_ShowObject00);
- /*tolua_function(L, "ShowAllObjects", tolua_ExportedFunctions_ShowAllObjects00);*/
- tolua_function(L, "SetBackground", tolua_ExportedFunctions_SetBackground00);/*
- tolua_function(L, "AddBlockingObject", tolua_ExportedFunctions_AddBlockingObject00);
- tolua_function(L, "RemoveBlockingObject", tolua_ExportedFunctions_RemoveBlockingObject00);*/
+ // tolua_function(L, "ShowAllObjects", tolua_ExportedFunctions_ShowAllObjects00); // Never used
+ tolua_function(L, "SetBackground", tolua_ExportedFunctions_SetBackground00);
+ //tolua_function(L, "AddBlockingObject", tolua_ExportedFunctions_AddBlockingObject00); // Never used
+ //tolua_function(L, "RemoveBlockingObject", tolua_ExportedFunctions_RemoveBlockingObject00); // Never used
tolua_function(L, "ChangeWarp", tolua_ExportedFunctions_ChangeWarp00);
tolua_function(L, "PlayMovie", tolua_ExportedFunctions_PlayMovie00);
/*tolua_function(L, "PlayMovieAndWaitForEnd", tolua_ExportedFunctions_PlayMovieAndWaitForEnd00);
@@ -775,12 +889,12 @@ void LuaOpenBinds(lua_State *L) {
tolua_function(L, "AddCallbackAnimation2D", tolua_ExportedFunctions_AddCallbackAnimation2D00);
tolua_function(L, "DeleteCallback", tolua_ExportedFunctions_DeleteCallback00);
tolua_function(L, "DeleteCallbackPlayer", tolua_ExportedFunctions_DeleteCallbackPlayer00);
- tolua_function(L, "DeleteCallbackAnimation2D", tolua_ExportedFunctions_DeleteCallbackAnimation2D00);
+ tolua_function(L, "DeleteCallbackAnimation2D", tolua_ExportedFunctions_DeleteCallbackAnimation2D00);*/
tolua_function(L, "SetObjectOnCharacter", tolua_ExportedFunctions_SetObjectOnCharacter00);
tolua_function(L, "SetObjectRotation", tolua_ExportedFunctions_SetObjectRotation00);
tolua_function(L, "SetObjectTranslation", tolua_ExportedFunctions_SetObjectTranslation00);
tolua_function(L, "SetObjectScale", tolua_ExportedFunctions_SetObjectScale00);
- tolua_function(L, "SetObjectFrames", tolua_ExportedFunctions_SetObjectFrames00);*/
+ tolua_function(L, "SetObjectFrames", tolua_ExportedFunctions_SetObjectFrames00);
tolua_function(L, "LoadObject", tolua_ExportedFunctions_LoadObject00);
tolua_function(L, "UnloadObject", tolua_ExportedFunctions_UnloadObject00);
tolua_function(L, "SetGroundObjectPosition", tolua_ExportedFunctions_SetGroundObjectPosition00);
@@ -811,7 +925,7 @@ void LuaOpenBinds(lua_State *L) {
tolua_function(L, "BFGReportEventWithValue", tolua_ExportedFunctions_BFGReportEventWithValue00);
tolua_function(L, "BFGReachedFreemiumLimit", tolua_ExportedFunctions_BFGReachedFreemiumLimit00);
tolua_function(L, "TestFileFlagSystemFlag", tolua_ExportedFunctions_TestFileFlagSystemFlag00);
- tolua_function(L, "PrintDebugMessage", tolua_ExportedFunctions_PrintDebugMessage00);
+ // tolua_function(L, "PrintDebugMessage", tolua_ExportedFunctions_PrintDebugMessage00); // Unused
tolua_function(L, "ExitZone", tolua_ExportedFunctions_ExitZone00);*/
tolua_function(L, "EnableRectBlocker", tolua_ExportedFunctions_EnableRectBlocker00);
/*tolua_function(L, "EnableBlocker", tolua_ExportedFunctions_EnableBlocker00);*/
@@ -821,9 +935,9 @@ void LuaOpenBinds(lua_State *L) {
tolua_function(L, "SetCharacterLookChar", tolua_ExportedFunctions_SetCharacterLookChar00);
tolua_function(L, "Random", tolua_ExportedFunctions_Random00);
tolua_function(L, "SetCharacterMeshVisible", tolua_ExportedFunctions_SetCharacterMeshVisible00);
- tolua_function(L, "SetRecallageY", tolua_ExportedFunctions_SetRecallageY00);
- tolua_function(L, "IsFreemiumUnlocked", tolua_ExportedFunctions_IsFreemiumUnlocked00);
- tolua_function(L, "ReachedFreemiumLimit", tolua_ExportedFunctions_ReachedFreemiumLimit00);*/
+ tolua_function(L, "SetRecallageY", tolua_ExportedFunctions_SetRecallageY00);*/
+ // tolua_function(L, "IsFreemiumUnlocked", tolua_ExportedFunctions_IsFreemiumUnlocked00); // Unused
+ // tolua_function(L, "ReachedFreemiumLimit", tolua_ExportedFunctions_ReachedFreemiumLimit00); // Unused
tolua_function(L, "AddUnrecalAnim", tolua_ExportedFunctions_AddUnrecalAnim00);
tolua_function(L, "UnlockArtwork", tolua_ExportedFunctions_UnlockArtwork00);
diff --git a/engines/tetraedge/game/object3d.h b/engines/tetraedge/game/object3d.h
index b1f1e9a1e0a..ccdffbe02b4 100644
--- a/engines/tetraedge/game/object3d.h
+++ b/engines/tetraedge/game/object3d.h
@@ -53,12 +53,23 @@ public:
TeTimer _rotateTimer;
TeVector3f32 _rotateStart;
TeVector3f32 _rotateAmount;
-
+
float _translateTime;
TeTimer _translateTimer;
TeVector3f32 _translateStart;
TeVector3f32 _translateAmount;
+ Common::String _onCharName;
+ Common::String _onCharBone;
+
+ // TRS relative to the character this object is "on"
+ TeVector3f32 _objTranslation;
+ TeQuaternion _objRotation;
+ TeVector3f32 _objScale;
+
+ int _startFrame;
+ int _endFrame;
+
private:
static Common::HashMap<Common::String, ObjectSettings> *_objectSettings;
diff --git a/engines/tetraedge/te/te_3d_object2.cpp b/engines/tetraedge/te/te_3d_object2.cpp
index 8c1ecb8cad0..c4ac06bbb11 100644
--- a/engines/tetraedge/te/te_3d_object2.cpp
+++ b/engines/tetraedge/te/te_3d_object2.cpp
@@ -158,8 +158,7 @@ void Te3DObject2::removeChildren() {
}
void Te3DObject2::rotate(const TeQuaternion &rot) {
- TeQuaternion newRot = rotation();
- newRot *= rot;
+ const TeQuaternion newRot = rotation() * rot;
setRotation(newRot);
}
@@ -243,7 +242,7 @@ void Te3DObject2::setZPosition(float zpos) {
TeMatrix4x4 Te3DObject2::transformationMatrix() {
TeMatrix4x4 retval;
retval.translate(position());
- retval = retval * rotation().toMatrix();
+ retval.rotate(rotation());
retval.scale(scale());
return retval;
}
diff --git a/engines/tetraedge/te/te_3d_texture.cpp b/engines/tetraedge/te/te_3d_texture.cpp
index ca8f6ae00f3..ac1353e59ec 100644
--- a/engines/tetraedge/te/te_3d_texture.cpp
+++ b/engines/tetraedge/te/te_3d_texture.cpp
@@ -148,7 +148,7 @@ bool Te3DTexture::load(const TeImage &img) {
_height = img.h;
_format = img._format;
- // FIXME: set some other fields from the image here.
+ // TODO? set some other fields from the image here.
// for now just set some good defaults.
_flipY = true; //img._flipY;
_leftBorder = 0; //img._leftBorder;
diff --git a/engines/tetraedge/te/te_act_zone.h b/engines/tetraedge/te/te_act_zone.h
index ef4ecc34911..c3b1e427618 100644
--- a/engines/tetraedge/te/te_act_zone.h
+++ b/engines/tetraedge/te/te_act_zone.h
@@ -38,7 +38,6 @@ public:
bool flag2;
private:
- // TODO add private members
};
diff --git a/engines/tetraedge/te/te_bezier_curve.cpp b/engines/tetraedge/te/te_bezier_curve.cpp
index d30beb5191c..2985bcb6ee6 100644
--- a/engines/tetraedge/te/te_bezier_curve.cpp
+++ b/engines/tetraedge/te/te_bezier_curve.cpp
@@ -105,6 +105,8 @@ void TeBezierCurve::deserialize(Common::ReadStream &stream, TeBezierCurve &curve
curve._lengthNeedsUpdate = false;
curve._length = stream.readFloatLE();
uint32 npoints = stream.readUint32LE();
+ if (npoints > 1000000)
+ error("TeBezierCurve::deserialize improbable number of control ponts %d", npoints);
for (unsigned int i = 0; i < npoints; i++) {
TeVector3f32 vec;
diff --git a/engines/tetraedge/te/te_camera.cpp b/engines/tetraedge/te/te_camera.cpp
index 65817da15fa..12ca0e7dcb5 100644
--- a/engines/tetraedge/te/te_camera.cpp
+++ b/engines/tetraedge/te/te_camera.cpp
@@ -152,7 +152,7 @@ void TeCamera::getRay(const TeVector2s32 &pxloc, TeVector3f32 &out1, TeVector3f3
TeQuaternion rot = rotation();
out1 = pos;
rot.normalize();
- TeMatrix4x4 rotmatrix = rot.toMatrix();
+ TeMatrix4x4 rotmatrix = rot.toTeMatrix();
out2 = rotmatrix * out2;
}
diff --git a/engines/tetraedge/te/te_free_move_zone.cpp b/engines/tetraedge/te/te_free_move_zone.cpp
index 218974136e8..53d0779ba9d 100644
--- a/engines/tetraedge/te/te_free_move_zone.cpp
+++ b/engines/tetraedge/te/te_free_move_zone.cpp
@@ -317,7 +317,7 @@ void TeFreeMoveZoneGraph::deserialize(Common::ReadStream &stream) {
TeVector2s32::deserialize(stream, _size);
uint32 flaglen = stream.readUint32LE();
if (flaglen > 1000000 || (int)flaglen != _size._x * _size._y)
- error("Flags unexpected size, expect %d got %d", _size._x * _size._y, flaglen);
+ error("TeFreeMoveZoneGraph: Flags unexpected size, expect %d got %d", _size._x * _size._y, flaglen);
_flags.resize(flaglen);
for (unsigned int i = 0; i < flaglen; i++) {
_flags[i] = stream.readByte();
diff --git a/engines/tetraedge/te/te_interpolation.cpp b/engines/tetraedge/te/te_interpolation.cpp
index 2f6402c53e8..11a82fac83c 100644
--- a/engines/tetraedge/te/te_interpolation.cpp
+++ b/engines/tetraedge/te/te_interpolation.cpp
@@ -31,7 +31,7 @@ TeInterpolation::TeInterpolation() {
void TeInterpolation::load(Common::ReadStream &stream) {
uint32 len = stream.readUint32LE();
if (len > 1000000)
- error("Unexpected interpolation length");
+ error("TeInterpolation: Unexpected interpolation length %d", len);
_array.resize(len);
for (uint32 i = 0; i < len && !stream.err(); i++)
_array[i] = stream.readFloatLE();
diff --git a/engines/tetraedge/te/te_layout.cpp b/engines/tetraedge/te/te_layout.cpp
index 02072ef0511..387e4f56256 100644
--- a/engines/tetraedge/te/te_layout.cpp
+++ b/engines/tetraedge/te/te_layout.cpp
@@ -406,13 +406,12 @@ void TeLayout::updateSize() {
}
}
- // FIXME: Original doesn't call this here, but I seem to need it.
- updateMesh();
-
_updatingSize = false;
// TODO: check this, is it the right flag to set?
_positionChanged = true;
+ updateMesh();
+
if (_size != oldSize) {
onSizeChanged().call();
}
diff --git a/engines/tetraedge/te/te_lua_thread.cpp b/engines/tetraedge/te/te_lua_thread.cpp
index a21f3ffda7d..928a4d8eb01 100644
--- a/engines/tetraedge/te/te_lua_thread.cpp
+++ b/engines/tetraedge/te/te_lua_thread.cpp
@@ -60,9 +60,8 @@ void TeLuaThread::_resume(int nargs) {
const char *msg = lua_tolstring(_luaThread, -1, nullptr);
warning("TeLuaThread::_resume: %s", msg);
}
- // TODO: This seems suspicous... but it's what the original does.
if (_lastResumeResult != 1 && _released) {
- warning("TeLuaThread:: deleting this??");
+ warning("TeLuaThread:: deleting this.");
delete this;
}
}
diff --git a/engines/tetraedge/te/te_matricies_stack.cpp b/engines/tetraedge/te/te_matricies_stack.cpp
index 89405b873cc..8ab5e133796 100644
--- a/engines/tetraedge/te/te_matricies_stack.cpp
+++ b/engines/tetraedge/te/te_matricies_stack.cpp
@@ -57,11 +57,11 @@ void TeMatriciesStack::pushMatrix() {
}
void TeMatriciesStack::rotate(const TeQuaternion &rot) {
- _stack.top() = _stack.top() * rot.toMatrix();
+ _stack.top() = _stack.top() * rot.toTeMatrix();
}
void TeMatriciesStack::rotate(float angle, const TeVector3f32 &axis) {
- _stack.top() = _stack.top() * TeQuaternion::fromAxisAndAngle(axis, angle).toMatrix();
+ rotate(TeQuaternion::fromAxisAndAngle(axis, angle));
}
void TeMatriciesStack::scale(const TeVector3f32 &scale) {
diff --git a/engines/tetraedge/te/te_matrix4x4.cpp b/engines/tetraedge/te/te_matrix4x4.cpp
index 1f54fbec634..a26a2fad065 100644
--- a/engines/tetraedge/te/te_matrix4x4.cpp
+++ b/engines/tetraedge/te/te_matrix4x4.cpp
@@ -97,6 +97,15 @@ void TeMatrix4x4::translate(const TeVector3f32 &vec) {
*this = (*this * translMatrix);
}
+void TeMatrix4x4::rotate(const TeQuaternion &rot) {
+ const TeMatrix4x4 rotMatrix = rot.toTeMatrix();
+ *this = (*this * rotMatrix);
+}
+
+TeVector3f32 TeMatrix4x4::translation() const {
+ return TeVector3f32(_data[12], _data[13], _data[14]);
+}
+
TeVector3f32 TeMatrix4x4::mult4x3(const TeVector3f32 &vec) const {
const float f1 = vec.x();
const float f2 = vec.y();
@@ -324,21 +333,19 @@ TeMatrix4x4 TeMatrix4x4::fromTRS(const TeTRS &trs) {
TeMatrix4x4 result;
const TeVector3f32 trans = trs.getTranslation();
TeMatrix4x4 transm;
- float *tm = transm.getData();
- tm[12] = trans.x();
- tm[13] = trans.y();
- tm[14] = trans.z();
+ transm(0, 3) = trans.x();
+ transm(1, 3) = trans.y();
+ transm(2, 3) = trans.z();
result = result * transm;
- const TeMatrix4x4 rotm = trs.getRotation().toMatrix();
+ const TeMatrix4x4 rotm = trs.getRotation().toTeMatrix();
result = result * rotm;
const TeVector3f32 scle = trs.getScale();
TeMatrix4x4 scalem;
- float *sm = scalem.getData();
- sm[0] = scle.x();
- sm[5] = scle.y();
- sm[10] = scle.z();
+ scalem(0, 0) = scle.x();
+ scalem(1, 1) = scle.y();
+ scalem(2, 2) = scle.z();
result = result * scalem;
return result;
diff --git a/engines/tetraedge/te/te_matrix4x4.h b/engines/tetraedge/te/te_matrix4x4.h
index 68159bac5bd..6d9d4599973 100644
--- a/engines/tetraedge/te/te_matrix4x4.h
+++ b/engines/tetraedge/te/te_matrix4x4.h
@@ -59,6 +59,8 @@ public:
void scale(const TeVector3f32 &vec);
void translate(const TeVector3f32 &vec);
+ void rotate(const TeQuaternion &rot);
+ TeVector3f32 translation() const;
TeVector3f32 mult3x3(const TeVector3f32 &vec) const;
TeVector3f32 mult4x3(const TeVector3f32 &vec) const;
diff --git a/engines/tetraedge/te/te_mesh.cpp b/engines/tetraedge/te/te_mesh.cpp
index 2c18fd9f4f8..d4aa310c98d 100644
--- a/engines/tetraedge/te/te_mesh.cpp
+++ b/engines/tetraedge/te/te_mesh.cpp
@@ -83,15 +83,16 @@ void TeMesh::draw() {
renderer->popMatrix();
return;
}
- } else if (!_materials.empty()) {
+ } else {
+ assert(_faceCounts.size() == _materials.size());
+ int totalFaceCount = 0;
for (unsigned int i = 0; i < _faceCounts.size(); i++) {
- int totalFaceCount = 0;
- if (_faceCounts[i]) {
- if (hasAlpha(i)) {
- renderer->addTransparentMesh(*this, totalFaceCount, _faceCounts[i], i);
- }
- totalFaceCount += _faceCounts[i];
+ if (!_faceCounts[i])
+ continue;
+ if (hasAlpha(i)) {
+ renderer->addTransparentMesh(*this, totalFaceCount, _faceCounts[i], i);
}
+ totalFaceCount += _faceCounts[i];
}
}
}
@@ -136,17 +137,18 @@ void TeMesh::draw() {
renderer->disableTexture();
}
} else {
- int totalfacecount = 0;
+ int totalFaceCount = 0;
+ assert(_faceCounts.size() == _materials.size());
for (unsigned int i = 0; i < _materials.size(); i++) {
if (!_faceCounts[i])
continue;
if (!hasAlpha(i) || renderer->shadowMode() == TeRenderer::ShadowMode1 || !_shouldDraw) {
_materials[i].apply();
- glDrawElements(_glMeshMode, _faceCounts[i] * 3, GL_UNSIGNED_SHORT, _indexes.data() + totalfacecount * 3);
+ glDrawElements(_glMeshMode, _faceCounts[i] * 3, GL_UNSIGNED_SHORT, _indexes.data() + totalFaceCount * 3);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
renderer->disableTexture();
}
- totalfacecount += _faceCounts[i];
+ totalFaceCount += _faceCounts[i];
}
}
@@ -179,7 +181,7 @@ void TeMesh::draw() {
}
TeMesh::Mode TeMesh::getMode() const {
- // Do the reverse translation of setMode... why? I dunno.. the game does that..
+ // Do the reverse translation of setConf... why? I dunno.. the game does that..
switch(_glMeshMode) {
case GL_POINTS:
return MeshMode_Points;
@@ -365,7 +367,7 @@ void TeMesh::updateTo(const Common::Array<TeMatrix4x4> *matricies1, const Common
Common::Array<TeVector3f32> &verts, Common::Array<TeVector3f32> &normals) {
static const TeMatrix4x4 emptyMatrix;
for (unsigned int i = 0; i < _verticies.size(); i++) {
- unsigned long m = _matricies[i];
+ unsigned int m = _matricies[i];
const TeMatrix4x4 *mat;
if (m < matricies1->size()) {
mat = &((*matricies1)[m]);
diff --git a/engines/tetraedge/te/te_mesh.h b/engines/tetraedge/te/te_mesh.h
index 9e3fa5612b9..fb0a9aa6df1 100644
--- a/engines/tetraedge/te/te_mesh.h
+++ b/engines/tetraedge/te/te_mesh.h
@@ -115,6 +115,11 @@ public:
void setHasAlpha(bool val) { _hasAlpha = val; }
Common::Array<TeMaterial> &materials() { return _materials; }
+ void setUpdatedVertex(unsigned int idx, const TeVector3f32 &val) { _updatedVerticies[idx] = val; }
+ void setUpdatedNormal(unsigned int idx, const TeVector3f32 &val) { _updatedNormals[idx] = val; }
+
+ const TeVector3f32 &preUpdatedVertex(unsigned int idx) const { return _verticies[idx]; }
+ const TeVector3f32 &preUpdatedNormal(unsigned int idx) const { return _normals[idx]; }
private:
Common::Array<unsigned char> _materialIndexes;
diff --git a/engines/tetraedge/te/te_model.cpp b/engines/tetraedge/te/te_model.cpp
index 2a7a0bfc8e6..5e5290e066f 100644
--- a/engines/tetraedge/te/te_model.cpp
+++ b/engines/tetraedge/te/te_model.cpp
@@ -34,8 +34,6 @@
namespace Tetraedge {
TeModel::TeModel() : _enableLights(false), _skipSkinOffsets(false), _matrixForced(false) {
- // TODO: set 0x17c to 1.0
- // TODO: set 0x178, 0x170 to 0
_modelAnim.setDeleteFn(&TeModelAnimation::deleteLater);
_modelVertexAnim.setDeleteFn(&TeModelVertexAnimation::deleteLater);
create();
@@ -45,7 +43,7 @@ TeModel::~TeModel() {
destroy();
}
-void TeModel::blendAnim(TeIntrusivePtr<TeModelAnimation>& anim, float seconds, bool repeat) {
+void TeModel::blendAnim(TeIntrusivePtr<TeModelAnimation> &anim, float seconds, bool repeat) {
if (!_modelAnim) {
setAnim(anim, repeat);
} else {
@@ -83,7 +81,7 @@ void TeModel::create() {
void TeModel::destroy() {
_weightElements.clear();
- // TODO: clear matrix array 0x148
+ _lerpedElements.clear();
_meshes.clear();
_bones.clear();
_boneMatricies.clear();
@@ -104,18 +102,18 @@ void TeModel::draw() {
renderer->sendModelMatrix(transform);
renderer->pushMatrix();
renderer->multiplyMatrix(transform);
- /*if (name() == "Kate") {
+ if (name() == "Kate") {
debug("Draw model %p (%s, %d meshes)", this, name().empty() ? "no name" : name().c_str(), _meshes.size());
//adebug(" renderMatrix %s", renderer->currentMatrix().toString().c_str());
//debug(" position %s", position().dump().c_str());
debug(" worldPos %s", worldPosition().dump().c_str());
//debug(" scale %s", scale().dump().c_str());
- debug(" worldScale %s", worldScale().dump().c_str());
+ //debug(" worldScale %s", worldScale().dump().c_str());
//debug(" rotation %s", rotation().dump().c_str());
debug(" worldRot %s", worldRotation().dump().c_str());
- }*/
+ }
for (TeMesh &mesh : _meshes) {
- // TODO: Set some flag in the mesh here to this->field_0x158??
+ // TODO: Set some flag (_drawWires?) in mesh to this->field_0x158??
mesh.draw();
}
renderer->popMatrix();
@@ -137,17 +135,18 @@ TeTRS TeModel::getBone(TeIntrusivePtr<TeModelAnimation> anim, unsigned int num)
return _bones[num]._trs;
}
-TeMatrix4x4 TeModel::lerpElementsMatrix(unsigned long weightsNum, Common::Array<TeMatrix4x4> &matricies) {
+TeMatrix4x4 TeModel::lerpElementsMatrix(unsigned int weightsNum, const Common::Array<TeMatrix4x4> &matricies) {
TeMatrix4x4 retval;
+ // Start with a 0 matrix.
for (unsigned int i = 0; i < 4; i++)
retval.setValue(i, i, 0);
- // TODO: Finish this.
- for (auto &weights : _weightElements) {
-
+ const Common::Array<weightElement> &weights = _weightElements[weightsNum];
+ for (const auto &weight : weights) {
+ const TeMatrix4x4 offset = matricies[weight._x].meshScale(weight._weight);
+ retval.meshAdd(offset);
}
-
return retval;
}
@@ -172,14 +171,14 @@ void TeModel::update() {
matricies.resize(_bones.size());
for (unsigned int i = 0; i < _bones.size(); i++) {
const bone &b = _bones[i];
- TeMatrix4x4 matrix = TeMatrix4x4::fromTRS(b._trs);
+ const TeMatrix4x4 matrix = TeMatrix4x4::fromTRS(b._trs);
if (b._x == -1 || _bones.size() < 2) {
matricies[0] = matrix;
} else {
matricies[i] = matricies[b._x] * matrix;
}
}
-
+
_boneMatricies.resize(_bones.size());
_lerpedElements.resize(_weightElements.size());
@@ -210,38 +209,83 @@ void TeModel::update() {
}
if (_bones.size() < 2 || _bones[b]._x == -1) {
_boneMatricies[b] = matrix;
- // TODO: Rotate by _field_0x170
+ _boneMatricies[b].rotate(_boneRotation);
} else {
_boneMatricies[b] = (invertx * _boneMatricies[_bones[b]._x]) * matrix;
}
_boneMatricies[b] = invertx * _boneMatricies[b];
- // TODO: bonesUpdateSignal.call(_bones[b]._name, _boneMatricies[b]);
+ _bonesUpdatedSignal.call(_bones[b]._name, _boneMatricies[b]);
}
-
+
if (!_skinOffsets.empty() && !_bones.empty()) {
for (unsigned int b = 0; b < _bones.size(); b++) {
_boneMatricies[b] = _boneMatricies[b] * _skinOffsets[b];
}
}
-
- if (_skipSkinOffsets == 0 && !_weightElements.empty()) {
+
+ if (!_skipSkinOffsets && !_weightElements.empty()) {
for (unsigned int i = 0; i < _weightElements.size(); i++) {
_lerpedElements[i] = lerpElementsMatrix(i, _boneMatricies);
}
}
-
+
for (unsigned int m = 0; m < _meshes.size(); m++) {
- if (!_meshes[m].visible())
+ TeMesh &mesh = _meshes[m];
+ if (!mesh.visible())
continue;
+
if (!_skipSkinOffsets && _bones.size() < 2 ) {
- if (_meshes[m].name() == _modelVertexAnim->head()) {
- _meshes[m].update(_modelVertexAnim);
- // TODO: lines 440 - 443.. set some vals and goto LAB_doMeshBlends;
+ if (_modelVertexAnim && mesh.name() == _modelVertexAnim->head()) {
+ mesh.update(_modelVertexAnim);
+ // TODO: lines 422 - 427.. set some vals and goto LAB_doMeshBlends;
}
- _meshes[m].update(&_boneMatricies, &_lerpedElements);
- // TODO: Set some vals here..
+ mesh.update(&_boneMatricies, &_lerpedElements);
} else {
- //warning("TODO: Finish TeModel::update. (disasm 456 ~ 693)");
+ mesh.resizeUpdatedTables(mesh.numVerticies());
+ const Common::Array<TeVector3f32> *verticies = nullptr;
+ if (_modelVertexAnim && mesh.name() == _modelVertexAnim->head())
+ verticies = &_modelVertexAnim->getVertices();
+
+ for (unsigned int i = 0; i < mesh.numVerticies(); i++) {
+ TeVector3f32 vertex;
+ if (!verticies) {
+ vertex = mesh.preUpdatedVertex(i);
+ } else {
+ if (i < verticies->size())
+ vertex = (*verticies)[i];
+ }
+ TeVector3f32 normal = mesh.preUpdatedNormal(i);
+ int idx = (int)mesh.matrixIndex(i);
+
+ TeVector3f32 updatedvertex;
+ TeVector3f32 updatednormal;
+
+ if (idx < (int)_bones.size()) {
+ updatedvertex = vertex;
+ if (!verticies)
+ updatedvertex = _boneMatricies[idx] * updatedvertex;
+ updatednormal = _boneMatricies[idx] * normal;
+ } else {
+ idx -= _bones.size();
+ for (unsigned int w = 0; w < _weightElements[idx].size(); w++) {
+ const TeMatrix4x4 &wmatrix = _boneMatricies[_weightElements[idx][w]._x];
+ float weight = _weightElements[idx][w]._weight;
+ updatedvertex = updatedvertex + ((wmatrix * vertex) * weight);
+ updatednormal = updatednormal + (wmatrix.mult3x3(normal) * weight);
+ }
+ }
+
+ mesh.setUpdatedVertex(i, updatedvertex);
+ mesh.setUpdatedNormal(i, updatednormal);
+ }
+ }
+
+ for (MeshBlender *mb : _meshBlenders) {
+ if (mesh.name().contains(mb->_name)) {
+ // TODO: Finish TeModel::update. (disasm 585 ~ 644), LAB_doMeshBlends
+ //float blendamount = MIN(mb->_timer.getTimeFromStart() / 1000000.0f, 1.0f);
+
+ }
}
}
} else {
@@ -394,7 +438,7 @@ bool TeModel::loadWeights(Common::ReadStream &stream, Common::Array<weightElemen
error("Improbable number of weights %d", (int)nweights);
weights.resize(nweights);
for (unsigned int i = 0; i < nweights; i++) {
- weights[i]._w = stream.readFloatLE();
+ weights[i]._weight = stream.readFloatLE();
weights[i]._x = stream.readUint16LE();
stream.readUint16LE();
}
@@ -413,7 +457,7 @@ bool TeModel::loadMesh(Common::SeekableReadStream &stream, TeMesh &mesh) {
if (vertcount > 100000 || matcount > 100000 || matidxcount > 100000 || idxcount > 100000)
error("Improbable mesh sizes %d %d %d %d", vertcount, matcount, matidxcount, idxcount);
- mesh.setConf(vertcount, idxcount, TeMesh::MeshMode_TriangleFan, matcount, matidxcount);
+ mesh.setConf(vertcount, idxcount, TeMesh::MeshMode_Triangles, matcount, matidxcount);
uint32 flags = stream.readUint32LE();
if (flags & 1)
diff --git a/engines/tetraedge/te/te_model.h b/engines/tetraedge/te/te_model.h
index 74ee90aafe9..3c097b63377 100644
--- a/engines/tetraedge/te/te_model.h
+++ b/engines/tetraedge/te/te_model.h
@@ -32,6 +32,7 @@
#include "tetraedge/te/te_model_vertex_animation.h"
#include "tetraedge/te/te_tiled_texture.h"
#include "tetraedge/te/te_intrusive_ptr.h"
+#include "tetraedge/te/te_quaternion.h"
namespace Tetraedge {
@@ -55,7 +56,6 @@ public:
class MeshBlender {
public:
MeshBlender(const Common::String &s1, const Common::String &s2, float amount, TeModel *model);
- private:
Common::String _name;
uint _meshNo;
float _amount;
@@ -69,7 +69,7 @@ public:
};
struct weightElement {
- float _w;
+ float _weight;
unsigned short _x;
};
@@ -97,7 +97,7 @@ public:
int findOrAddWeights(const Common::Array<weightElement> &weights);
void forceMatrix(const TeMatrix4x4 &matrix);
TeTRS getBone(TeIntrusivePtr<TeModelAnimation> anim, unsigned int num);
- TeMatrix4x4 lerpElementsMatrix(unsigned long weightNum, Common::Array<TeMatrix4x4> &matricies);
+ TeMatrix4x4 lerpElementsMatrix(unsigned int weightNum, const Common::Array<TeMatrix4x4> &matricies);
/* Align the stream to the nearest 4 byte boudary*/
static void loadAlign(Common::SeekableReadStream &stream);
@@ -126,6 +126,8 @@ public:
TeMatrix4x4 skinOffset(unsigned long boneno) const;
+ TeSignal2Param<const Common::String &, TeMatrix4x4 &> &bonesUpdatedSignal() { return _bonesUpdatedSignal; }
+
static Common::SeekableReadStream *tryLoadZlibStream(Common::SeekableReadStream &instr);
TeIntrusivePtr<TeTiledTexture> _tiledTexture;
@@ -146,9 +148,12 @@ protected:
Common::Array<Common::Array<weightElement>> _weightElements;
Common::Array<BonesBlender *> _boneBlenders;
+ TeQuaternion _boneRotation;
+
TeIntrusivePtr<TeModelAnimation> _modelAnim;
TeIntrusivePtr<TeModelVertexAnimation> _modelVertexAnim;
+ TeSignal2Param<const Common::String &, TeMatrix4x4 &> _bonesUpdatedSignal;
};
} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_model_animation.cpp b/engines/tetraedge/te/te_model_animation.cpp
index 956e470e39a..e8759bb8701 100644
--- a/engines/tetraedge/te/te_model_animation.cpp
+++ b/engines/tetraedge/te/te_model_animation.cpp
@@ -100,6 +100,9 @@ TeQuaternion TeModelAnimation::getNMORotation(unsigned long boneNo, float amount
while (i < arr.size() && arr[i]._f < amount)
i++;
+ if (i == 0)
+ return arr.front()._rot;
+
if (i == arr.size() || arr.size() == 1 || arr[i]._f - arr[i-1]._f == 0) {
return arr.back()._rot;
}
@@ -119,6 +122,9 @@ TeVector3f32 TeModelAnimation::getNMOTranslation(unsigned long boneNo, float amo
while (i < arr.size() && arr[i]._f < amount)
i++;
+ if (i == 0)
+ return arr.front()._trans;
+
if (i == arr.size() || arr.size() == 1 || arr[i]._f - arr[i-1]._f == 0) {
return arr.back()._trans;
}
@@ -201,8 +207,12 @@ bool TeModelAnimation::load(Common::SeekableReadStream &stream) {
}
_useNMOArrays = stream.readUint32LE();
- _numNMOFrames = stream.readUint32LE();
+ uint32 nmoFrames = stream.readUint32LE();
+ if (_useNMOArrays)
+ _numNMOFrames = nmoFrames;
uint32 numBones = stream.readUint32LE();
+ if (numBones > 100000)
+ error("TeModelAnimation::load: Improbable number of bones %d", numBones);
if (_useNMOArrays == 0) {
_fbxArrays.resize(numBones);
@@ -217,24 +227,29 @@ bool TeModelAnimation::load(Common::SeekableReadStream &stream) {
if (!Te3DObject2::loadAndCheckFourCC(stream, "BONE"))
return false;
const Common::String boneName = Te3DObject2::deserializeString(stream);
+ TeModel::loadAlign(stream);
setBoneName(i, boneName);
if (!Te3DObject2::loadAndCheckFourCC(stream, "BTRA"))
return false;
uint32 numTrans = stream.readUint32LE();
+ if (numTrans > 100000)
+ error("TeModelAnimation::load: Improbable number of bone translations %d", numTrans);
for (unsigned int j = 0; j < numTrans; j++) {
float f = stream.readFloatLE();
TeVector3f32 trans;
TeVector3f32::deserialize(stream, trans);
- setTranslation(j, f, trans);
+ setTranslation(i, f, trans);
}
if (!Te3DObject2::loadAndCheckFourCC(stream, "BROT"))
return false;
uint32 numRots = stream.readUint32LE();
+ if (numRots > 100000)
+ error("TeModelAnimation::load: Improbable number of bone rotations %d", numRots);
for (unsigned int j = 0; j < numRots; j++) {
float f = stream.readFloatLE();
TeQuaternion rot;
TeQuaternion::deserialize(stream, rot);
- setRotation(j, f, rot);
+ setRotation(i, f, rot);
}
}
return true;
diff --git a/engines/tetraedge/te/te_pick_mesh2.cpp b/engines/tetraedge/te/te_pick_mesh2.cpp
index 32cd8e53f81..e28a7a1663d 100644
--- a/engines/tetraedge/te/te_pick_mesh2.cpp
+++ b/engines/tetraedge/te/te_pick_mesh2.cpp
@@ -78,7 +78,7 @@ bool TePickMesh2::intersect(const TeVector3f32 &v1, const TeVector3f32 v2, TeVec
return true;
}
}
-
+
float hitf = FLT_MAX;
for (unsigned int i = 0; i < _verticies.size() / 3; i++) {
const TeVector3f32 triv1 = worldTrans * _verticies[i * 3 + 0];
@@ -157,6 +157,9 @@ void TePickMesh2::serialize(Common::WriteStream &stream, const TePickMesh2 &mesh
void TePickMesh2::deserialize(Common::ReadStream &stream, TePickMesh2 &mesh) {
Te3DObject2::deserialize(stream, mesh);
uint32 ntriangles = stream.readUint32LE();
+ if (ntriangles > 100000)
+ error("TePickMesh2::deserialize: Improbable number of triangles %d", ntriangles);
+
mesh._verticies.resize(ntriangles * 3);
mesh._lastTriangleHit = 0;
diff --git a/engines/tetraedge/te/te_quaternion.h b/engines/tetraedge/te/te_quaternion.h
index cc8ae96ce42..26ef8e5103a 100644
--- a/engines/tetraedge/te/te_quaternion.h
+++ b/engines/tetraedge/te/te_quaternion.h
@@ -25,6 +25,7 @@
#include "math/quat.h"
#include "tetraedge/te/te_vector3f32.h"
+#include "tetraedge/te/te_matrix4x4.h"
namespace Tetraedge {
@@ -68,18 +69,23 @@ public:
return retval;
}
+ TeMatrix4x4 toTeMatrix() const {
+ const TeMatrix4x4 retval = toMatrix();
+ return retval.transpose();
+ }
+
static void deserialize(Common::ReadStream &stream, TeQuaternion &dest) {
- dest.value(0) = stream.readFloatLE();
- dest.value(1) = stream.readFloatLE();
- dest.value(2) = stream.readFloatLE();
- dest.value(3) = stream.readFloatLE();
+ dest.x() = stream.readFloatLE();
+ dest.y() = stream.readFloatLE();
+ dest.z() = stream.readFloatLE();
+ dest.w() = stream.readFloatLE();
}
static void serialize(Common::WriteStream &stream, const TeQuaternion &src) {
- stream.writeFloatLE(src.value(0));
- stream.writeFloatLE(src.value(1));
- stream.writeFloatLE(src.value(2));
- stream.writeFloatLE(src.value(3));
+ stream.writeFloatLE(src.x());
+ stream.writeFloatLE(src.y());
+ stream.writeFloatLE(src.z());
+ stream.writeFloatLE(src.w());
}
Common::String dump() const;
diff --git a/engines/tetraedge/te/te_renderer.cpp b/engines/tetraedge/te/te_renderer.cpp
index 6250e74b634..8830f3bcbbe 100644
--- a/engines/tetraedge/te/te_renderer.cpp
+++ b/engines/tetraedge/te/te_renderer.cpp
@@ -326,7 +326,7 @@ void TeRenderer::multiplyMatrix(const TeMatrix4x4 &matrix) {
void TeRenderer::optimiseTransparentMeshProperties() {
if (!_transparentMeshProperties.empty()) {
- //warning("FIXME: Implement TeRenderer::optimiseTransparentMeshProperties.");
+ // TODO: Implement TeRenderer::optimiseTransparentMeshProperties.
}
}
diff --git a/engines/tetraedge/te/te_renderer.h b/engines/tetraedge/te/te_renderer.h
index 09d0cbe70d8..0a8b479a34e 100644
--- a/engines/tetraedge/te/te_renderer.h
+++ b/engines/tetraedge/te/te_renderer.h
@@ -41,9 +41,9 @@ public:
};
enum ShadowMode {
- ShadowMode0,
- ShadowMode1,
- ShadowMode2
+ ShadowMode0 = 0,
+ ShadowMode1 = 1,
+ ShadowMode2 = 2
};
class TransparentMeshProperties {
diff --git a/engines/tetraedge/te/te_signal.h b/engines/tetraedge/te/te_signal.h
index ea860b81efb..105c42b3199 100644
--- a/engines/tetraedge/te/te_signal.h
+++ b/engines/tetraedge/te/te_signal.h
@@ -123,7 +123,7 @@ template<class S, class T> class TeSignal2Param : public Common::SortedArray<TeI
public:
TeSignal2Param() : Common::SortedArray<TeICallback2ParamPtr<S, T>, const TeICallback2ParamPtr<S, T> &>(_teCallbackSorter) {};
- bool call(T t, S s) {
+ bool call(S s, T t) {
typename Common::Array<TeICallback2ParamPtr<S, T>>::iterator i = this->begin();
typename Common::Array<TeICallback2ParamPtr<S, T>>::iterator end_ = this->end();
for (; i < end_; i++) {
diff --git a/engines/tetraedge/te/te_text_base2.cpp b/engines/tetraedge/te/te_text_base2.cpp
index 8de44498a49..45376231122 100644
--- a/engines/tetraedge/te/te_text_base2.cpp
+++ b/engines/tetraedge/te/te_text_base2.cpp
@@ -197,7 +197,7 @@ void TeTextBase2::drawEmptyChar(unsigned int offset) {
void TeTextBase2::drawLine(TeImage &img, const Common::String &str, int yoffset) {
TeIntrusivePtr<TeFont3> font = _fonts[0];
- // FIXME: Add multi-color support if needed.
+ // TODO: Add multi-color support if needed.
font->draw(img, str, _fontSize, yoffset, _globalColor, _alignStyle);
}
diff --git a/engines/tetraedge/te/te_trs.cpp b/engines/tetraedge/te/te_trs.cpp
index ca4aa134207..8e2a13e7e8c 100644
--- a/engines/tetraedge/te/te_trs.cpp
+++ b/engines/tetraedge/te/te_trs.cpp
@@ -41,8 +41,8 @@ TeTRS::TeTRS() {
TeTRS TeTRS::lerp(const TeTRS &other, float amount) {
TeTRS result;
result._rot = _rot.slerpQuat(other._rot, amount);
- result._trans = _trans * (1.0 - amount) + other._trans;
- result._scale = _scale * (1.0 - amount) + other._scale;
+ result._trans = _trans * (1.0 - amount) + other._trans * amount;
+ result._scale = _scale * (1.0 - amount) + other._scale * amount;
return result;
}
diff --git a/engines/tetraedge/te/te_vector3f32.cpp b/engines/tetraedge/te/te_vector3f32.cpp
index 07baa317294..6cebd5c3eae 100644
--- a/engines/tetraedge/te/te_vector3f32.cpp
+++ b/engines/tetraedge/te/te_vector3f32.cpp
@@ -38,8 +38,8 @@ bool TeVector3f32::parse(const Common::String &val) {
}
void TeVector3f32::rotate(const TeQuaternion &rot) {
- Math::Matrix4 matrix = rot.toMatrix();
- matrix.transform(this, false);
+ const TeMatrix4x4 matrix = rot.toTeMatrix();
+ *this = (matrix * *this);
}
TeVector3f32 operator^(const TeVector3f32 &left, const TeVector3f32 &right) {
Commit: a5811c653a5f86971e8817e2d963fa902765819a
https://github.com/scummvm/scummvm/commit/a5811c653a5f86971e8817e2d963fa902765819a
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2023-01-16T17:36:43+01:00
Commit Message:
TETRAEDGE: More WIP. Started work on pathfinding.
Changed paths:
engines/tetraedge/game/character.cpp
engines/tetraedge/game/character.h
engines/tetraedge/game/game.cpp
engines/tetraedge/game/game.h
engines/tetraedge/game/in_game_scene.cpp
engines/tetraedge/game/in_game_scene.h
engines/tetraedge/game/inventory.cpp
engines/tetraedge/game/inventory_objects_xml_parser.cpp
engines/tetraedge/game/lua_binds.cpp
engines/tetraedge/game/lua_binds.h
engines/tetraedge/te/micropather.h
engines/tetraedge/te/te_bezier_curve.cpp
engines/tetraedge/te/te_bezier_curve.h
engines/tetraedge/te/te_button_layout.cpp
engines/tetraedge/te/te_free_move_zone.cpp
engines/tetraedge/te/te_free_move_zone.h
engines/tetraedge/te/te_images_sequence.cpp
engines/tetraedge/te/te_images_sequence.h
engines/tetraedge/te/te_jpeg.h
engines/tetraedge/te/te_model.cpp
engines/tetraedge/te/te_pick_mesh2.cpp
engines/tetraedge/te/te_png.h
engines/tetraedge/te/te_vector2s32.h
engines/tetraedge/tetraedge.cpp
engines/tetraedge/to_lua.cpp
engines/tetraedge/to_lua.h
diff --git a/engines/tetraedge/game/character.cpp b/engines/tetraedge/game/character.cpp
index 1ffe18054ab..c182c34b365 100644
--- a/engines/tetraedge/game/character.cpp
+++ b/engines/tetraedge/game/character.cpp
@@ -57,10 +57,11 @@ void Character::WalkSettings::clear() {
}
Character::Character() : _curveOffset(0), _lastFrame(-1), _callbacksChanged(false),
-_missingCurrentAnim(false), _someRepeatFlag(false), _walkModeStr("Walk"),
+_notWalkAnim(false), _someRepeatFlag(false), _walkModeStr("Walk"),
_needsSomeUpdate(false), _positionFlag(false), _lookingAtTallThing(false),
_stepSound1("sounds/SFX/PAS_H_BOIS1.ogg"), _stepSound2("sounds/SFX/PAS_H_BOIS2.ogg"),
-_freeMoveZone(nullptr), _animSoundOffset(0), _lastAnimFrame(0), _charLookingAt(nullptr) {
+_freeMoveZone(nullptr), _animSoundOffset(0), _lastAnimFrame(0), _charLookingAt(nullptr),
+_recallageY(true) {
_curModelAnim.setDeleteFn(&TeModelAnimation::deleteLater);
}
@@ -159,7 +160,7 @@ bool Character::blendAnimation(const Common::String &animname, float amount, boo
Common::Path animpath("models/Anims");
animpath.joinInPlace(animname);
- _missingCurrentAnim = !(animname.contains(_characterSettings._walkFileName)
+ _notWalkAnim = !(animname.contains(_characterSettings._walkFileName)
|| animname.contains(walkAnim(WalkPart_Start))
|| animname.contains(walkAnim(WalkPart_Loop))
|| animname.contains(walkAnim(WalkPart_EndG))
@@ -239,7 +240,7 @@ bool Character::isFramePassed(int frameno) {
}
bool Character::isWalkEnd() {
- Common::String animFile = _model->anim()->_loadedPath.getLastComponent().toString();
+ const Common::String animFile = _model->anim()->_loadedPath.getLastComponent().toString();
for (const auto & walkSettings : _characterSettings._walkSettings) {
if (walkSettings._value._walkParts[WalkPart_EndD]._file.contains(animFile)
|| walkSettings._value._walkParts[WalkPart_EndG]._file.contains(animFile))
@@ -358,7 +359,7 @@ bool Character::loadModel(const Common::String &mname, bool unused) {
}
}
- if (!parser.loadBuffer((unsigned char *)fixedbuf.c_str(), bufsize))
+ if (!parser.loadBuffer((const byte *)fixedbuf.c_str(), bufsize))
error("Character::loadSettings: Can't open %s", path.c_str());
if (!parser.parse())
@@ -464,7 +465,65 @@ bool Character::onBonesUpdate(const Common::String &boneName, TeMatrix4x4 &boneM
}
bool Character::onModelAnimationFinished() {
- error("TODO: Implement Character::onModelAnimationFinished");
+ const Common::Path &loadedPath = _model->anim()->_loadedPath;
+ const Common::String animfile = loadedPath.getLastComponent().toString();
+
+ // TODO: Do something with _unrecalAnims here.
+
+ Game *game = g_engine->getGame();
+ bool isWalkAnim = false;
+ if (game->scene()._character == this) {
+ // TODO: check if this logic matches..
+ for (const auto &walkSettings : _characterSettings._walkSettings) {
+ isWalkAnim |= (walkSettings._key.contains("Walk") || walkSettings._key.contains("Jog"));
+ isWalkAnim |= (walkSettings._value._walkParts[0]._file == animfile ||
+ walkSettings._value._walkParts[1]._file == animfile ||
+ walkSettings._value._walkParts[2]._file == animfile ||
+ walkSettings._value._walkParts[3]._file == animfile);
+ }
+ isWalkAnim |= animfile.contains(_characterSettings._walkFileName);
+ } else {
+ isWalkAnim = (animfile.contains(_characterSettings._walkFileName) ||
+ animfile.contains(walkAnim(WalkPart_Start)) ||
+ animfile.contains(walkAnim(WalkPart_Loop)) ||
+ animfile.contains(walkAnim(WalkPart_EndD)) ||
+ animfile.contains(walkAnim(WalkPart_EndG)));
+ }
+
+ if (isWalkAnim) {
+ int pereBone = _curModelAnim->findBone("Pere");
+ const TeTRS endTRS = trsFromAnim(*_curModelAnim, pereBone, _curModelAnim->lastFrame());
+ TeVector3f32 trans = endTRS.getTranslation();
+ trans.x() = -trans.x();
+
+ TeVector3f32 newpos;
+ if (!_recallageY) {
+ const TeTRS startTRS = trsFromAnim(*_curModelAnim, pereBone, _curModelAnim->firstFrame());
+ trans = trans - startTRS.getTranslation();
+ const TeTRS nearEndTRS = trsFromAnim(*_curModelAnim, pereBone, _curModelAnim->lastFrame() - 1);
+ trans = trans + (endTRS.getTranslation() - nearEndTRS.getTranslation());
+ newpos = _model->worldTransformationMatrix() * trans;
+ } else if (!_freeMoveZone) {
+ trans.x() = -trans.x();
+ newpos = _model->worldTransformationMatrix() * trans;
+ } else {
+ newpos = correctPosition(_model->worldTransformationMatrix() * trans);
+ }
+ _model->setPosition(newpos);
+ }
+
+ if (game->scene()._character == this) {
+ _characterAnimPlayerFinishedSignal.call(loadedPath.toString());
+ } else {
+ _onCharacterAnimFinishedSignal.call(_model->name());
+ }
+
+ if (_someRepeatFlag && loadedPath.toString().contains(_setAnimName)) {
+ _notWalkAnim = false;
+ _someRepeatFlag = false;
+ setAnimation(_characterSettings._walkFileName, true);
+ }
+
return false;
}
@@ -503,7 +562,7 @@ bool Character::setAnimation(const Common::String &aname, bool repeat, bool para
aname.contains(walkAnim(WalkPart_Loop)) ||
aname.contains(walkAnim(WalkPart_EndD)) ||
aname.contains(walkAnim(WalkPart_EndG)));
- _missingCurrentAnim = !isWalkAnim;
+ _notWalkAnim = !isWalkAnim;
if (_curModelAnim) {
_curModelAnim->onFinished().remove(this, &Character::onModelAnimationFinished);
@@ -511,6 +570,7 @@ bool Character::setAnimation(const Common::String &aname, bool repeat, bool para
}
_curModelAnim = animCacheLoad(animPath);
+ _curModelAnim->onFinished().add(this, &Character::onModelAnimationFinished);
_curModelAnim->bind(_model);
_curModelAnim->setFrameLimits(startFrame, endFrame);
_model->setAnim(_curModelAnim, repeat);
@@ -585,6 +645,7 @@ void Character::updateAnimFrame() {
}
void Character::updatePosition(float curveOffset) {
+ assert(_curve);
if (!_curve->controlPoints().empty()) {
TeVector3f32 pt = _curve->retrievePoint(curveOffset) + _curveStartLocation;
if (_freeMoveZone) {
@@ -605,10 +666,14 @@ Common::String Character::walkAnim(Character::WalkPart part) {
}
void Character::walkMode(const Common::String &mode) {
- error("TODO: Implement Character::walkMode");
+ if (_walkModeStr != mode)
+ _walkModeStr = mode;
+ _walkPart0AnimLen = animLengthFromFile(walkAnim(WalkPart_Start), &_walkPart0AnimFrameCount, 9999);
+ _walkPart3AnimLen = animLengthFromFile(walkAnim(WalkPart_EndG), &_walkPart3AnimFrameCount, 9999);
+ _walkPart1AnimLen = animLengthFromFile(walkAnim(WalkPart_Loop), &_walkPart1AnimFrameCount, 9999);
}
-void Character::walkTo(float param_1, bool param_2) {
+void Character::walkTo(float curveEnd, bool walkFlag) {
error("TODO: Implement Character::walkTo");
}
diff --git a/engines/tetraedge/game/character.h b/engines/tetraedge/game/character.h
index 5d3ea7c85b1..6723305803b 100644
--- a/engines/tetraedge/game/character.h
+++ b/engines/tetraedge/game/character.h
@@ -202,13 +202,14 @@ private:
int _lastFrame;
int _lastAnimFrame;
- bool _missingCurrentAnim;
+ bool _notWalkAnim;
bool _someRepeatFlag; // TODO: what is this?
bool _callbacksChanged;
bool _needsSomeUpdate;
bool _positionFlag;
bool _lookingAtTallThing;
bool _hasAnchor;
+ bool _recallageY;
TeVector2f32 _headRotation;
TeVector2f32 _lastHeadRotation;
diff --git a/engines/tetraedge/game/game.cpp b/engines/tetraedge/game/game.cpp
index b57fbeef487..8205097f4fc 100644
--- a/engines/tetraedge/game/game.cpp
+++ b/engines/tetraedge/game/game.cpp
@@ -204,7 +204,9 @@ bool Game::changeWarp2(const Common::String &zone, const Common::String &scene,
_warped = false;
_movePlayerCharacterDisabled = false;
_sceneCharacterVisibleFromLoad = false;
- // TODO: set 3 other fields here (0x3f40 = -1, 0x4249 = 1, 0x424b = 0)
+ // TODO: set another field here (0x3f40 = -1)
+ _isCharacterIdle = true;
+ _isCharacterWalking = false;
Common::Path luapath("scenes");
luapath.joinInPlace(zone);
luapath.joinInPlace(scene);
@@ -457,13 +459,19 @@ bool Game::initWarp(const Common::String &zone, const Common::String &scene, boo
const Common::Path intLuaPath = scenePath.join(Common::String::format("Int%s.lua", scene.c_str()));
const Common::Path logicLuaPath = scenePath.join(Common::String::format("Logic%s.lua", scene.c_str()));
const Common::Path setLuaPath = scenePath.join(Common::String::format("Set%s.lua", scene.c_str()));
- const Common::Path forLuaPath = scenePath.join(Common::String::format("For%s.lua", scene.c_str()));
+ Common::Path forLuaPath = scenePath.join(Common::String::format("For%s.lua", scene.c_str()));
const Common::Path markerLuaPath = scenePath.join(Common::String::format("Marker%s.lua", scene.c_str()));
bool intLuaExists = Common::File::exists(intLuaPath);
bool logicLuaExists = Common::File::exists(logicLuaPath);
bool setLuaExists = Common::File::exists(setLuaPath);
bool forLuaExists = Common::File::exists(forLuaPath);
+ if (!forLuaExists) {
+ // slight hack.. try an alternate For lua path.
+ forLuaPath = scenePath.join("Android-MacOSX").join(Common::String::format("For%s.lua", scene.c_str()));
+ forLuaExists = Common::File::exists(forLuaPath);
+ debug("searched for %s", forLuaPath.toString().c_str());
+ }
bool markerLuaExists = Common::File::exists(markerLuaPath);
if (!intLuaExists && !logicLuaExists && !setLuaExists && !forLuaExists && !markerLuaExists) {
@@ -751,8 +759,54 @@ bool Game::onCharacterAnimationFinished(const Common::String &val) {
error("TODO: Implemet Game::onCharacterAnimationFinished %s", val.c_str());
}
-bool Game::onCharacterAnimationPlayerFinished(const Common::String &val) {
- error("TODO: Implemet Game::onCharacterAnimationPlayerFinished %s", val.c_str());
+bool Game::onCharacterAnimationPlayerFinished(const Common::String &anim) {
+ if (_gameLoadState != 0)
+ return false;
+
+ bool callScripts = true;
+ for (unsigned int i = 0; i < _yieldedCallbacks.size(); i++) {
+ YieldedCallback &cb = _yieldedCallbacks[i];
+ if (cb._luaFnName == "OnCharacterAnimationFinished" && cb._luaParam == "Kate") {
+ TeLuaThread *lua = cb._luaThread;
+ _yieldedCallbacks.remove_at(i);
+ if (lua) {
+ lua->resume();
+ callScripts = false;
+ return false;
+ }
+ break;
+ }
+ }
+ if (callScripts) {
+ _luaScript.execute("OnCharacterAnimationFinished", "Kate");
+ _luaScript.execute("OnCellCharacterAnimationPlayerFinished", anim);
+ }
+
+ Character *character = scene()._character;
+ assert(character);
+
+ const Common::String &curAnimName = character->curAnimName();
+ if (_currentScene == _someSceneName) {
+ if (curAnimName == character->walkAnim(Character::WalkPart_Start)
+ || curAnimName == character->walkAnim(Character::WalkPart_Loop)
+ || curAnimName == character->walkAnim(Character::WalkPart_EndD)
+ || curAnimName == character->walkAnim(Character::WalkPart_EndG))
+ character->stop();
+ } else {
+ if (!_sceneCharacterVisibleFromLoad && curAnimName != character->walkAnim(Character::WalkPart_Start)) {
+ character->setAnimation(character->walkAnim(Character::WalkPart_Loop), true);
+ return false;
+ }
+ if (curAnimName == character->walkAnim(Character::WalkPart_EndD)
+ || curAnimName == character->walkAnim(Character::WalkPart_EndG)) {
+ character->updatePosition(1.0);
+ character->endMove();
+ // Note: original checks walkAnim again.. is there a reason to do that?
+ character->setAnimation(character->characterSettings()._walkFileName, true);
+ }
+ }
+
+ return false;
}
bool Game::onDialogFinished(const Common::String &val) {
@@ -779,14 +833,12 @@ bool Game::onDisplacementFinished() {
_scene._character->stop();
_scene._character->setAnimation(_scene._character->characterSettings()._walkFileName, true);
- // TODO: Twiddle flags 0x424b and 0x4249
- /*
- if (!_field_0x424b) {
- _field_0x4249 = false;
+ if (!_isCharacterWalking) {
+ _isCharacterWalking = false;
+ _isCharacterIdle = true;
} else {
- _field_0x424b = false;
- _field_0x4249 = true;
- }*/
+ _isCharacterIdle = false;
+ }
TeLuaThread *thread = nullptr;
@@ -848,57 +900,6 @@ bool Game::onMarkersVisible(TeCheckboxLayout::State state) {
return false;
}
-static
-TePickMesh2 *findNearestMesh(TeIntrusivePtr<TeCamera> &camera, const TeVector2s32 &frompt,
- Common::Array<TePickMesh2*> &pickMeshes, TeVector3f32 *outloc, bool lastHitFirst) {
- TeVector3f32 locresult;
- TePickMesh2 *nearest = nullptr;
- float furthest = camera->_orthFarVal;
- if (!pickMeshes.empty()) {
- TeVector3f32 v1;
- TeVector3f32 v2;
- for (unsigned int i = 0; i < pickMeshes.size(); i++) {
- TePickMesh2 *mesh = pickMeshes[i];
- const TeMatrix4x4 transform = mesh->worldTransformationMatrix();
- if (lastHitFirst) {
- unsigned int tricount = mesh->verticies().size() / 3;
- unsigned int vert = mesh->lastTriangleHit() * 3;
- if (mesh->lastTriangleHit() >= tricount)
- vert = 0;
- const TeVector3f32 v3 = transform * mesh->verticies()[vert];
- const TeVector3f32 v4 = transform * mesh->verticies()[vert + 1];
- const TeVector3f32 v5 = transform * mesh->verticies()[vert + 2];
- TeVector3f32 result;
- float fresult;
- int intresult = TeRayIntersection::intersect(v1, v2, v3, v4, v5, result, fresult);
- if (intresult == 1 && fresult < furthest && fresult >= camera->_orthNearVal)
- return mesh;
- }
- for (unsigned int tri = 0; tri < mesh->verticies().size() / 3; tri++) {
- const TeVector3f32 v3 = transform * mesh->verticies()[tri * 3];
- const TeVector3f32 v4 = transform * mesh->verticies()[tri * 3 + 1];
- const TeVector3f32 v5 = transform * mesh->verticies()[tri * 3 + 1];
- camera->getRay(frompt, v1, v2);
- TeVector3f32 result;
- float fresult;
- int intresult = TeRayIntersection::intersect(v1, v2, v3, v4, v5, result, fresult);
- if (intresult == 1 && fresult < furthest && fresult >= camera->_orthNearVal) {
- mesh->setLastTriangleHit(tri);
- locresult = result;
- furthest = fresult;
- nearest = mesh;
- if (lastHitFirst)
- break;
- }
- }
- }
- }
- if (outloc) {
- *outloc = locresult;
- }
- return nearest;
-}
-
bool Game::onMouseClick(const Common::Point &pt) {
Application *app = g_engine->getApplication();
@@ -928,7 +929,7 @@ bool Game::onMouseClick(const Common::Point &pt) {
Common::String nearestMeshName = "None";
TeIntrusivePtr<TeCamera> curCamera = _scene.currentCamera();
Common::Array<TePickMesh2*> pickMeshes = _scene.pickMeshes();
- TePickMesh2 *nearestMesh = findNearestMesh(curCamera, pt, pickMeshes, nullptr, false);
+ TePickMesh2 *nearestMesh = TeFreeMoveZone::findNearestMesh(curCamera, pt, pickMeshes, nullptr, false);
if (nearestMesh) {
nearestMeshName = nearestMesh->name();
_lastCharMoveMousePos = TeVector2s32(0, 0);
@@ -982,14 +983,14 @@ bool Game::onMouseClick(const Common::Point &pt) {
TeVector3f32 lastPoint = _scene.curve()->controlPoints().back();
character->setAnimation(character->walkAnim(Character::WalkPart_Loop), true);
character->walkTo(1.0, false);
- // TODO: Set app field field_0x424b to true
+ _isCharacterWalking = true;
_posPlayer = lastPoint;
}
if (!_sceneCharacterVisibleFromLoad || (character->curAnimName() == character->characterSettings()._walkFileName)) {
_lastCharMoveMousePos = TeVector2s32(0, 0);
_movePlayerCharacterDisabled = true;
- // TODO: Set field 0x4249 to false
+ _isCharacterWalking = false;
if (nearestMesh) {
character->stop();
_luaScript.execute("OnWarpObjectHit", nearestMeshName);
@@ -1445,18 +1446,18 @@ void Game::update() {
player->setCurveOffset(0.0f);
player->setAnimation(player->walkAnim(Character::WalkPart_Start), false);
player->walkTo(1.0f, false);
- // TODO: Set app field field_0x424b
+ _isCharacterWalking = true;
}
player->setNeedsSomeUpdate(false);
}
const Common::String &charAnim = _scene._character->curAnimName();
- bool lockCursor = (charAnim == _scene._character->walkAnim(Character::WalkPart_Start) ||
+ bool unlockCursor = (charAnim == _scene._character->walkAnim(Character::WalkPart_Start) ||
charAnim == _scene._character->walkAnim(Character::WalkPart_Loop) ||
charAnim == _scene._character->walkAnim(Character::WalkPart_EndD) ||
charAnim == _scene._character->walkAnim(Character::WalkPart_EndG) ||
charAnim == _scene._character->characterSettings()._walkFileName);
- app->lockCursor(lockCursor);
+ app->lockCursor(!unlockCursor);
}
}
@@ -1494,20 +1495,20 @@ bool Game::HitObject::onChangeWarp() {
bool Game::HitObject::onDown() {
_game->luaScript().execute("OnButtonDown", _name);
- // TODO: set this field _game->field_0x4249 = true;
+ _game->_isCharacterIdle = true;
return false;
}
bool Game::HitObject::onUp() {
_game->luaScript().execute("OnButtonUp", _name);
- // TODO: set this field _game->field_0x4249 = true;
+ _game->_isCharacterIdle = true;
return false;
}
bool Game::HitObject::onValidated() {
if (!g_engine->getApplication()->isLockCursor()) {
_game->luaScript().execute("OnWarpObjectHit", _name);
- // TODO: set this field _game->field_0x4249 = true;
+ _game->_isCharacterIdle = true;
}
return false;
}
diff --git a/engines/tetraedge/game/game.h b/engines/tetraedge/game/game.h
index 081bd5ec52b..e01d0b4d27d 100644
--- a/engines/tetraedge/game/game.h
+++ b/engines/tetraedge/game/game.h
@@ -171,6 +171,9 @@ public:
bool _returnToMainMenu;
bool _firstInventory;
bool _movePlayerCharacterDisabled;
+ bool _sceneCharacterVisibleFromLoad;
+ bool _isCharacterWalking;
+ bool _isCharacterIdle;
const Common::String ¤tZone() { return _currentZone; }
const Common::String ¤tScene() { return _currentScene; }
@@ -185,6 +188,9 @@ public:
Common::Array<YieldedCallback> &yieldedCallbacks() { return _yieldedCallbacks; }
void setSaveRequested() { _saveRequested = true; }
bool markersVisible() const { return _markersVisible; }
+ const TeVector3f32 &posPlayer() const { return _posPlayer; }
+ void setPosPlayer(const TeVector3f32 &pos) { _posPlayer = pos; }
+ TeTimer &walkTimer() { return _walkTimer; }
private:
bool _luaShowOwnerError;
@@ -219,6 +225,7 @@ private:
Common::String _currentScene;
Common::String _exitZone;
Common::String _prevSceneName;
+ Common::String _someSceneName;
Common::Path _sceneZonePath;
Common::String _loadName;
@@ -252,7 +259,6 @@ private:
int _objectsTakenVal;
int _dialogsTold;
- bool _sceneCharacterVisibleFromLoad;
bool _markersVisible;
bool _saveRequested;
bool _randomSoundFinished;
diff --git a/engines/tetraedge/game/in_game_scene.cpp b/engines/tetraedge/game/in_game_scene.cpp
index 705fbe78243..e72fbca972b 100644
--- a/engines/tetraedge/game/in_game_scene.cpp
+++ b/engines/tetraedge/game/in_game_scene.cpp
@@ -95,25 +95,24 @@ bool InGameScene::addMarker(const Common::String &markerName, const Common::Stri
markerSprite->setAnchor(TeVector3f32(0.0f, 0.0f, 0.0f));
markerSprite->load(imgPath);
markerSprite->setSizeType(TeILayout::RELATIVE_TO_PARENT);
- markerSprite->setPositionType(TeILayout::RELATIVE_TO_PARENT);
- TeVector3f32 newSize;
+ markerSprite->setPositionType(TeILayout::RELATIVE_TO_PARENT);
+ TeVector3f32 newPos;
if (locType == "PERCENT") {
Application *app = g_engine->getApplication();
TeVector3f32 frontLayoutSize = app->_frontLayout.userSize();
- newSize.x() = frontLayoutSize.x() * (x / 100.0);
- newSize.y() = frontLayoutSize.y() * (y / 100.0);
+ newPos.x() = frontLayoutSize.x() * (x / 100.0);
+ newPos.y() = frontLayoutSize.y() * (y / 100.0);
} else {
- newSize.x() = x / 800.0;
- newSize.y() = y / 600.0;
+ newPos.x() = x / 800.0;
+ newPos.y() = y / 600.0;
}
- markerSprite->setSize(newSize);
+ markerSprite->setPosition(newPos);
- float screenWidth = (float)g_engine->getDefaultScreenWidth();
- float screenHeight = (float)g_engine->getDefaultScreenHeight();
+ const TeVector3f32 winSize = g_engine->getApplication()->getMainWindow().size();
if (g_engine->getCore()->fileFlagSystemFlag("definition") == "SD") {
- markerSprite->setPosition(TeVector3f32(0.07, (4.0 / ((screenWidth / screenHeight) * 4.0)) * 0.04, 0.0));
+ markerSprite->setSize(TeVector3f32(0.07, (4.0 / ((winSize.y() / winSize.x()) * 4.0)) * 0.07, 0.0));
} else {
- markerSprite->setPosition(TeVector3f32(0.04, (4.0 / ((screenWidth / screenHeight) * 4.0)) * 0.04, 0.0));
+ markerSprite->setSize(TeVector3f32(0.04, (4.0 / ((winSize.y() / winSize.x()) * 4.0)) * 0.04, 0.0));
}
markerSprite->setVisible(game->markersVisible());
markerSprite->_tiledSurfacePtr->_frameAnim._loopCount = -1;
diff --git a/engines/tetraedge/game/in_game_scene.h b/engines/tetraedge/game/in_game_scene.h
index eee8bc31785..cf08c1e874a 100644
--- a/engines/tetraedge/game/in_game_scene.h
+++ b/engines/tetraedge/game/in_game_scene.h
@@ -190,7 +190,7 @@ public:
int _shadowLightNo;
CharactersShadow *_charactersShadow;
TeIntrusivePtr<TeBezierCurve> curve() { return _curve; }
- void setCurve(TeIntrusivePtr<TeBezierCurve> &c) { c = _curve; }
+ void setCurve(TeIntrusivePtr<TeBezierCurve> &c) { _curve = c; }
Common::Array<TeIntrusivePtr<TeModel>> &zoneModels() { return _zoneModels; }
Common::Array<TeRectBlocker> &rectBlockers() { return _rectBlockers; }
Common::Array<Object3D *> object3Ds() { return _object3Ds; }
diff --git a/engines/tetraedge/game/inventory.cpp b/engines/tetraedge/game/inventory.cpp
index 5b6573564a7..792333c9e7e 100644
--- a/engines/tetraedge/game/inventory.cpp
+++ b/engines/tetraedge/game/inventory.cpp
@@ -135,7 +135,7 @@ void Inventory::loadXMLFile(const Common::Path &path) {
xmlfile.close();
InventoryObjectsXmlParser parser;
- if (!parser.loadBuffer((byte *)xmlContents.c_str(), xmlContents.size()))
+ if (!parser.loadBuffer((const byte *)xmlContents.c_str(), xmlContents.size()))
error("Couldn't load inventory xml.");
if (!parser.parse())
error("Couldn't parse inventory xml.");
diff --git a/engines/tetraedge/game/inventory_objects_xml_parser.cpp b/engines/tetraedge/game/inventory_objects_xml_parser.cpp
index 7467dc6e490..1e366da6817 100644
--- a/engines/tetraedge/game/inventory_objects_xml_parser.cpp
+++ b/engines/tetraedge/game/inventory_objects_xml_parser.cpp
@@ -30,6 +30,6 @@ bool InventoryObjectsXmlParser::parserCallback_Object(ParserNode *node) {
data._isDocument = node->values.contains("isDocument");
_objects.setVal(data._id, data);
return true;
-};
+}
} // end namespace Tetraedge
diff --git a/engines/tetraedge/game/lua_binds.cpp b/engines/tetraedge/game/lua_binds.cpp
index 4a927e8fdf1..a469948ccdf 100644
--- a/engines/tetraedge/game/lua_binds.cpp
+++ b/engines/tetraedge/game/lua_binds.cpp
@@ -790,6 +790,85 @@ static int tolua_ExportedFunctions_SetObjectFrames00(lua_State *L) {
error("#ferror in function 'SetObjectFrames': %d %d %s", err.index, err.array, err.type);
}
+static bool CurrentCharacterAnimation(const Common::String &charname, const Common::String &anim) {
+ Character *character = g_engine->getGame()->scene().character(charname);
+
+ if (!character) {
+ debug("[CurrentCharacterAnimation] Character\'s\"%s\" doesn't exist", charname.c_str());
+ return true;
+ } else {
+ return anim == character->curAnimName();
+ }
+}
+
+static int tolua_ExportedFunctions_CurrentCharacterAnimation00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isstring(L, 2, 0, &err) && tolua_isnoobj(L, 3, &err)) {
+ Common::String s1(tolua_tostring(L, 1, nullptr));
+ Common::String s2(tolua_tostring(L, 2, nullptr));
+ bool result = CurrentCharacterAnimation(s1, s2);
+ tolua_pushboolean(L, result);
+ return 1;
+ }
+ error("#ferror in function 'CurrentCharacterAnimation': %d %d %s", err.index, err.array, err.type);
+}
+
+static void MoveCharacterPlayerTo(float x, float y, float z, bool walkFlag) {
+ Game *game = g_engine->getGame();
+ if (game->_movePlayerCharacterDisabled)
+ return;
+
+ TeVector3f32 loc(x, y, z);
+ game->resetPreviousMousePos();
+
+ Character *character = game->scene()._character;
+ if (loc == game->posPlayer() && character->walkModeStr() == "Walk")
+ return;
+
+ if (game->walkTimer().running() && game->walkTimer().timeElapsed() < 300000) {
+ unsigned long elapsed = game->walkTimer().timeElapsed();
+ game->walkTimer().stop();
+ if (elapsed < 300000) {
+ character->walkMode("Jog");
+ }
+ } else {
+ game->walkTimer().stop();
+ game->walkTimer().start();
+ character->walkMode("Walk");
+ }
+
+ game->_sceneCharacterVisibleFromLoad = false;
+ TeIntrusivePtr<TeBezierCurve> curve = character->freeMoveZone()->curve(character->_model->position(), loc);
+ if (!curve) {
+ game->luaScript().execute("OnDisplacementFinished");
+ } else {
+ game->scene().setCurve(curve);
+ character->setCurveStartLocation(TeVector3f32(0, 0, 0));
+ character->placeOnCurve(curve);
+ character->setCurveOffset(0);
+ character->setAnimation(character->walkAnim(Character::WalkPart_Loop), true);
+ character->walkTo(1.0, walkFlag);
+ game->_isCharacterWalking = true;
+ game->setPosPlayer(loc);
+ }
+}
+
+static int tolua_ExportedFunctions_MoveCharacterPlayerTo00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isnumber(L, 1, 0, &err) && tolua_isnumber(L, 2, 0, &err)
+ && tolua_isnumber(L, 3, 0, &err) && tolua_isboolean(L, 4, 1, &err)
+ && tolua_isnoobj(L, 5, &err)) {
+ float f1 = tolua_tonumber(L, 1, 0.0);
+ float f2 = tolua_tonumber(L, 2, 0.0);
+ float f3 = tolua_tonumber(L, 3, 0.0);
+ bool b1 = tolua_toboolean(L, 4, 0);
+ MoveCharacterPlayerTo(f1, f2, f3, b1);
+ return 0;
+ }
+ error("#ferror in function 'MoveCharacterPlayerTo': %d %d %s", err.index, err.array, err.type);
+}
+
+
// ////////////////////////////////////////////////////////////////////////
@@ -860,9 +939,9 @@ void LuaOpenBinds(lua_State *L) {
tolua_function(L, "GetZPositionCharacter", tolua_ExportedFunctions_GetZPositionCharacter00);
tolua_function(L, "MoveCharacterTo", tolua_ExportedFunctions_MoveCharacterTo00);
tolua_function(L, "MoveCharacterToAndWaitForEnd",
- tolua_ExportedFunctions_MoveCharacterToAndWaitForEnd00);
+ tolua_ExportedFunctions_MoveCharacterToAndWaitForEnd00);*/
tolua_function(L, "MoveCharacterPlayerTo", tolua_ExportedFunctions_MoveCharacterPlayerTo00);
- tolua_function(L, "MoveCharacterPlayerToAndWaitForEnd",
+ /*tolua_function(L, "MoveCharacterPlayerToAndWaitForEnd",
tolua_ExportedFunctions_MoveCharacterPlayerToAndWaitForEnd00);
tolua_function(L, "MoveCharacterPlayerAtTo", tolua_ExportedFunctions_MoveCharacterPlayerAtTo00);*/
tolua_function(L, "SetCharacterPosition", tolua_ExportedFunctions_SetCharacterPosition00);
@@ -874,8 +953,8 @@ void LuaOpenBinds(lua_State *L) {
tolua_ExportedFunctions_SetCharacterAnimationAndWaitForEnd00);
tolua_function(L, "BlendCharacterAnimation", tolua_ExportedFunctions_BlendCharacterAnimation00);
tolua_function(L, "BlendCharacterAnimationAndWaitForEnd",
- tolua_ExportedFunctions_BlendCharacterAnimationAndWaitForEnd00);
- tolua_function(L, "CurrentCharacterAnimation", tolua_ExportedFunctions_CurrentCharacterAnimation00);*/
+ tolua_ExportedFunctions_BlendCharacterAnimationAndWaitForEnd00);*/
+ tolua_function(L, "CurrentCharacterAnimation", tolua_ExportedFunctions_CurrentCharacterAnimation00);
tolua_function(L, "SetCharacterPlayerVisible", tolua_ExportedFunctions_SetCharacterPlayerVisible00);
tolua_function(L, "MoveCharacterPlayerDisabled",
tolua_ExportedFunctions_MoveCharacterPlayerDisabled00);
diff --git a/engines/tetraedge/game/lua_binds.h b/engines/tetraedge/game/lua_binds.h
index c22f39eeeeb..9f6b99a82af 100644
--- a/engines/tetraedge/game/lua_binds.h
+++ b/engines/tetraedge/game/lua_binds.h
@@ -30,7 +30,7 @@ namespace LuaBinds {
void LuaOpenBinds(lua_State *L);
-};
+} // end namespace LuaBinds
} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/micropather.h b/engines/tetraedge/te/micropather.h
index 493c035b583..fa4fe3052ec 100644
--- a/engines/tetraedge/te/micropather.h
+++ b/engines/tetraedge/te/micropather.h
@@ -453,9 +453,9 @@ namespace micropather
PathCache* pathCache;
};
-}; // namespace micropather
+} // namespace micropather
-}; // namespace Tetraedge
+} // namespace Tetraedge
#endif // TETRAEDGE_TE_MICROPATHER
diff --git a/engines/tetraedge/te/te_bezier_curve.cpp b/engines/tetraedge/te/te_bezier_curve.cpp
index 2985bcb6ee6..18f15a71dd5 100644
--- a/engines/tetraedge/te/te_bezier_curve.cpp
+++ b/engines/tetraedge/te/te_bezier_curve.cpp
@@ -77,7 +77,44 @@ float TeBezierCurve::rawLength() {
return _rawLength;
}
-TeVector3f32 TeBezierCurve::retrievePoint(float offset) const {
+TeVector3f32 TeBezierCurve::retrievePoint(float offset) {
+ const unsigned int npoints = _controlPoints.size();
+
+ // Simple cases for small numbers of points.
+ if (npoints == 0)
+ return TeVector3f32();
+ else if (npoints == 1)
+ return _controlPoints[0];
+ else if (npoints == 2)
+ return _controlPoints[0] + (_controlPoints[1] - _controlPoints[0]) * offset;
+
+ // else, there are at least 3 points so need to actually interpolate.
+ TeVector3f32 points[5];
+ const float rawlen = rawLength();
+
+ float proportion = 0.0f;
+ unsigned int i = 0;
+ while (i < npoints) {
+ proportion = _rawLengths[i] / rawlen;
+ if (proportion >= offset)
+ break;
+ i++;
+ }
+ float t;
+ if (proportion == offset) {
+ t = 0.0f;
+ } else {
+ float p1 = _rawLengths[i - 1];
+ float p2 = _rawLengths[i];
+ t = (rawlen * offset - p1) / (p2 - p1);
+ i--;
+ }
+
+ for (unsigned int p = -1; p < 3; p++) {
+
+ }
+ // TODO: Finish this, line 77 to 129.
+
error("TODO: Implement TeBezierCurve::retrievePoint");
}
@@ -115,4 +152,24 @@ void TeBezierCurve::deserialize(Common::ReadStream &stream, TeBezierCurve &curve
}
}
+/*static*/
+TeVector3f32 TeBezierCurve::hermiteInterpolate(float t, const TeVector3f32 *points, float param_4, float param_5) {
+ assert(points);
+ const TeVector3f32 delta1 = ((points[1] - points[0]) * (param_5 + 1.0) * (1.0 - param_4)) / 2.0;
+ const TeVector3f32 delta2a = ((points[2] - points[1]) * (1.0 - param_5) * (1.0 - param_4)) / 2.0;
+ const TeVector3f32 delta2b = ((points[2] - points[1]) * (param_5 + 1.0) * (1.0 - param_4)) / 2.0;
+ const TeVector3f32 delta3 = ((points[3] - points[2]) * (1.0 - param_5) * (1.0 - param_4)) / 2.0;
+
+ const TeVector3f32 x1 = delta1 + delta2a;
+ const TeVector3f32 x2 = delta2b + delta3;
+
+ const float t2 = t * t;
+ const float t3 = t * t * t;
+ const TeVector3f32 h1a = points[1] * ((t3 + t3) - t2 * 3.0);
+ const TeVector3f32 h1b = x1 * ((t3 - (t2 + t2)) + t);
+ const TeVector3f32 h1 = (h1a + h1b) + (x2 * (t3 - t2));
+ return h1 + (points[2] * (t3 * -2.0 + t2 * 3.0));
+}
+
+
} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_bezier_curve.h b/engines/tetraedge/te/te_bezier_curve.h
index 9b201c13f50..de0ca32642b 100644
--- a/engines/tetraedge/te/te_bezier_curve.h
+++ b/engines/tetraedge/te/te_bezier_curve.h
@@ -40,10 +40,12 @@ public:
float rawLength();
- TeVector3f32 retrievePoint(float offset) const;
+ TeVector3f32 retrievePoint(float offset);
void setControlPoints(const Common::Array<TeVector3f32> &points);
void setNbIterations(unsigned long iterations);
+ static TeVector3f32 hermiteInterpolate(float param_2, const TeVector3f32 *points, float param_4, float param_5);
+
static void serialize(Common::WriteStream &stream, const TeBezierCurve &curve);
static void deserialize(Common::ReadStream &stream, TeBezierCurve &curve);
diff --git a/engines/tetraedge/te/te_button_layout.cpp b/engines/tetraedge/te/te_button_layout.cpp
index f0235e3492c..b19681a6b30 100644
--- a/engines/tetraedge/te/te_button_layout.cpp
+++ b/engines/tetraedge/te/te_button_layout.cpp
@@ -40,7 +40,7 @@ namespace Tetraedge {
}
TeButtonLayout::TeButtonLayout() :
-_currentState(BUTTON_STATE_UP), _clickPassThrough(false), _validationSoundVolume(1.0),
+_currentState(BUTTON_STATE_UP), _clickPassThrough(true), _validationSoundVolume(1.0),
_someClickFlag(false), _doubleValidationProtectionEnabled(true), _upLayout(nullptr),
_downLayout(nullptr), _rolloverLayout(nullptr), _disabledLayout(nullptr),
_hitZoneLayout(nullptr)
diff --git a/engines/tetraedge/te/te_free_move_zone.cpp b/engines/tetraedge/te/te_free_move_zone.cpp
index 53d0779ba9d..c49aa2c4fef 100644
--- a/engines/tetraedge/te/te_free_move_zone.cpp
+++ b/engines/tetraedge/te/te_free_move_zone.cpp
@@ -24,6 +24,7 @@
#include "tetraedge/te/te_free_move_zone.h"
#include "tetraedge/te/micropather.h"
#include "tetraedge/te/te_renderer.h"
+#include "tetraedge/te/te_ray_intersection.h"
namespace Tetraedge {
@@ -51,7 +52,8 @@ class TeFreeMoveZoneGraph : micropather::Graph {
TeFreeMoveZone::TeFreeMoveZone() : _actzones(nullptr), _blockers(nullptr), _rectBlockers(nullptr),
-_transformedVerticiesDirty(true), _bordersDirty(true), _pickMeshDirty(true), _projectedPointsDirty(true)
+_transformedVerticiesDirty(true), _bordersDirty(true), _pickMeshDirty(true), _projectedPointsDirty(true),
+_loadedFromBin(false)
{
_graph = new TeFreeMoveZoneGraph();
_graph->_bordersDistance = 2048.0f;
@@ -112,12 +114,52 @@ TeVector3f32 TeFreeMoveZone::correctCharacterPosition(const TeVector3f32 &pos, b
return intersectPoint;
}
-TeIntrusivePtr<TeBezierCurve> TeFreeMoveZone::curve(const TeVector3f32 ¶m_3, const TeVector2s32 ¶m_4, float param_5, bool findMeshFlag) {
+TeIntrusivePtr<TeBezierCurve> TeFreeMoveZone::curve(const TeVector3f32 &startpt, const TeVector2s32 &endpt, float param_5, bool findMeshFlag) {
+ updateGrid(false);
error("TODO: Implement TeFreeMoveZone::curve");
}
-TeIntrusivePtr<TeBezierCurve> TeFreeMoveZone::curve(const TeVector3f32 ¶m_3, const TeVector3f32 ¶m_4) {
- error("TODO: Implement TeFreeMoveZone::curve");
+TeIntrusivePtr<TeBezierCurve> TeFreeMoveZone::curve(const TeVector3f32 &startpt, const TeVector3f32 &endpt) {
+ updateGrid(false);
+ Common::Array<TeVector3f32> points;
+ points.push_back(startpt);
+ points.push_back(endpt);
+
+ TeVector2s32 projectedStart = projectOnAStarGrid(startpt);
+ TeVector2s32 projectedEnd = projectOnAStarGrid(endpt);
+ int xsize = _graph->_size._x;
+ float cost = 0;
+ // Passing an int to void*, yuck? but it's what the original does..
+ Common::Array<void *> path;
+ int pathResult = _micropather->Solve((void *)(xsize * projectedStart._y + projectedStart._x), (void *)(xsize * projectedEnd._y + projectedEnd._x), &path, &cost);
+
+ TeIntrusivePtr<TeBezierCurve> retval;
+
+ if (pathResult == micropather::MicroPather::SOLVED || pathResult == micropather::MicroPather::START_END_SAME) {
+ Common::Array<TeVector2s32> points;
+ points.resize(path.size());
+
+ for (auto &pathpt : path) {
+ // each path point is an array offset
+ int offset = static_cast<int>(reinterpret_cast<long>(pathpt));
+ int yoff = (offset / _graph->_size._x);
+ int xoff = offset % _graph->_size._x;
+ points.push_back(TeVector2s32(xoff, yoff));
+ }
+
+ Common::Array<TeVector3f32> pts3d;
+ for (auto &pt : points) {
+ pts3d.push_back(transformAStarGridInWorldSpace(pt));
+ }
+
+ pts3d.front() = startpt;
+ pts3d.back() = endpt;
+ removeInsignificantPoints(pts3d);
+ retval = new TeBezierCurve();
+ retval->setControlPoints(pts3d);
+ }
+
+ return retval;
}
/*static*/
@@ -191,12 +233,20 @@ void TeFreeMoveZone::preUpdateGrid() {
error("TODO: Implement TeFreeMoveZone::preUpdateGrid");
}
-TeVector3f32 TeFreeMoveZone::projectOnAStarGrid(const TeVector3f32 &pt) {
- error("TODO: Implement TeFreeMoveZone::projectOnAStarGrid");
+TeVector2s32 TeFreeMoveZone::projectOnAStarGrid(const TeVector3f32 &pt) {
+ TeVector2f32 otherpt;
+ if (!_loadedFromBin) {
+ otherpt = TeVector2f32(pt.x() - _someGridVec1.getX(), pt.z() - _someGridVec1.getY());
+ } else {
+ error("TODO: Implement TeFreeMoveZone::projectOnAStarGrid for _loadedFromBin");
+ }
+ TeVector2f32 projected = otherpt / _gridOffsetSomething;
+ return TeVector2s32((int)projected.getX(), (int)projected.getY());
}
-Common::Array<TeVector3f32> &TeFreeMoveZone::removeInsignificantPoints(const Common::Array<TeVector3f32> &points) {
- error("TODO: Implement TeFreeMoveZone::removeInsignificantPoints");
+Common::Array<TeVector3f32> TeFreeMoveZone::removeInsignificantPoints(const Common::Array<TeVector3f32> &points) {
+ warning("TODO: Implement TeFreeMoveZone::removeInsignificantPoints");
+ return points;
}
void TeFreeMoveZone::setBordersDistance(float dist) {
@@ -238,7 +288,14 @@ void TeFreeMoveZone::setVertex(unsigned int offset, const TeVector3f32 &vertex)
_projectedPointsDirty = true;
}
-TeVector2s32 TeFreeMoveZone::transformAStarGridInWorldSpace(const TeVector2s32 &gridpt) {
+TeVector3f32 TeFreeMoveZone::transformAStarGridInWorldSpace(const TeVector2s32 &gridpt) {
+ float offsety = (float)gridpt._y * _gridOffsetSomething.getY() + _someGridVec1.getY() +
+ _gridOffsetSomething.getY() * 0.5;
+ float offsetx = (float)gridpt._x * _gridOffsetSomething.getX() + _someGridVec1.getX() +
+ _gridOffsetSomething.getX() * 0.5;
+ if (!_loadedFromBin) {
+ return TeVector3f32(offsetx, _someGridFloat, offsety);
+ }
error("TODO: Implement TeFreeMoveZone::transformAStarGridInWorldSpace");
}
@@ -289,12 +346,58 @@ void TeFreeMoveZone::updateTransformedVertices() {
/*========*/
-float TeFreeMoveZoneGraph::LeastCostEstimate(void * stateStart, void *stateEnd) {
- error("TODO: Implement TeFreeMoveZone::TeFreeMoveZoneGraph::LeastCostEstimate");
+float TeFreeMoveZoneGraph::LeastCostEstimate(void *stateStart, void *stateEnd) {
+ int startInt = static_cast<int>(reinterpret_cast<long>(stateStart));
+ int endInt = static_cast<int>(reinterpret_cast<long>(stateEnd));
+ int starty = startInt / _size._x;
+ int endy = endInt / _size._x;
+ TeVector2s32 start(startInt - starty * _size._x, starty);
+ TeVector2s32 end(endInt - endy * _size._x, endy);
+ return (end - start).squaredLength();
}
void TeFreeMoveZoneGraph::AdjacentCost(void *state, Common::Array<micropather::StateCost> *adjacent) {
- error("TODO: Implement TeFreeMoveZone::TeFreeMoveZoneGraph::AdjacentCost");
+ int stateInt = static_cast<int>(reinterpret_cast<long>(state));
+ int stateY = stateInt / _size._x;
+ const TeVector2s32 statept(stateInt - stateY * _size._x, stateY);
+
+ micropather::StateCost cost;
+ TeVector2s32 pt;
+
+ pt = TeVector2s32(statept._x - 1, statept._y);
+ cost.state = reinterpret_cast<void *>(_size._x * pt._y + pt._x);
+ cost.cost = (flag(pt) == 1 ? FLT_MAX : _bordersDistance);
+ adjacent->push_back(cost);
+
+ pt = TeVector2s32(statept._x - 1, statept._y + 1);
+ cost.state = reinterpret_cast<void *>(_size._x * pt._y + pt._x);
+ cost.cost = (flag(pt) == 1 ? FLT_MAX : _bordersDistance);
+ adjacent->push_back(cost);
+
+ pt = TeVector2s32(statept._x + 1, statept._y + 1);
+ cost.state = reinterpret_cast<void *>(_size._x * pt._y + pt._x);
+ cost.cost = (flag(pt) == 1 ? FLT_MAX : _bordersDistance);
+ adjacent->push_back(cost);
+
+ pt = TeVector2s32(statept._x + 1, statept._y);
+ cost.state = reinterpret_cast<void *>(_size._x * pt._y + pt._x);
+ cost.cost = (flag(pt) == 1 ? FLT_MAX : _bordersDistance);
+ adjacent->push_back(cost);
+
+ pt = TeVector2s32(statept._x + 1, statept._y - 1);
+ cost.state = reinterpret_cast<void *>(_size._x * pt._y + pt._x);
+ cost.cost = (flag(pt) == 1 ? FLT_MAX : _bordersDistance);
+ adjacent->push_back(cost);
+
+ pt = TeVector2s32(statept._x, statept._y - 1);
+ cost.state = reinterpret_cast<void *>(_size._x * pt._y + pt._x);
+ cost.cost = (flag(pt) == 1 ? FLT_MAX : _bordersDistance);
+ adjacent->push_back(cost);
+
+ pt = TeVector2s32(statept._x - 1, statept._y - 1);
+ cost.state = reinterpret_cast<void *>(_size._x * pt._y + pt._x);
+ cost.cost = (flag(pt) == 1 ? FLT_MAX : _bordersDistance);
+ adjacent->push_back(cost);
}
void TeFreeMoveZoneGraph::PrintStateInfo(void *state) {
@@ -329,5 +432,56 @@ void TeFreeMoveZoneGraph::serialize(Common::WriteStream &stream) const {
error("TODO: Implement TeFreeMoveZoneGraph::serialize");
}
+/*static*/
+TePickMesh2 *TeFreeMoveZone::findNearestMesh(TeIntrusivePtr<TeCamera> &camera, const TeVector2s32 &frompt,
+ Common::Array<TePickMesh2*> &pickMeshes, TeVector3f32 *outloc, bool lastHitFirst) {
+ TeVector3f32 locresult;
+ TePickMesh2 *nearest = nullptr;
+ float furthest = camera->_orthFarVal;
+ if (!pickMeshes.empty()) {
+ TeVector3f32 v1;
+ TeVector3f32 v2;
+ for (unsigned int i = 0; i < pickMeshes.size(); i++) {
+ TePickMesh2 *mesh = pickMeshes[i];
+ const TeMatrix4x4 transform = mesh->worldTransformationMatrix();
+ if (lastHitFirst) {
+ unsigned int tricount = mesh->verticies().size() / 3;
+ unsigned int vert = mesh->lastTriangleHit() * 3;
+ if (mesh->lastTriangleHit() >= tricount)
+ vert = 0;
+ const TeVector3f32 v3 = transform * mesh->verticies()[vert];
+ const TeVector3f32 v4 = transform * mesh->verticies()[vert + 1];
+ const TeVector3f32 v5 = transform * mesh->verticies()[vert + 2];
+ TeVector3f32 result;
+ float fresult;
+ int intresult = TeRayIntersection::intersect(v1, v2, v3, v4, v5, result, fresult);
+ if (intresult == 1 && fresult < furthest && fresult >= camera->_orthNearVal)
+ return mesh;
+ }
+ for (unsigned int tri = 0; tri < mesh->verticies().size() / 3; tri++) {
+ const TeVector3f32 v3 = transform * mesh->verticies()[tri * 3];
+ const TeVector3f32 v4 = transform * mesh->verticies()[tri * 3 + 1];
+ const TeVector3f32 v5 = transform * mesh->verticies()[tri * 3 + 1];
+ camera->getRay(frompt, v1, v2);
+ TeVector3f32 result;
+ float fresult;
+ int intresult = TeRayIntersection::intersect(v1, v2, v3, v4, v5, result, fresult);
+ if (intresult == 1 && fresult < furthest && fresult >= camera->_orthNearVal) {
+ mesh->setLastTriangleHit(tri);
+ locresult = result;
+ furthest = fresult;
+ nearest = mesh;
+ if (lastHitFirst)
+ break;
+ }
+ }
+ }
+ }
+ if (outloc) {
+ *outloc = locresult;
+ }
+ return nearest;
+}
+
} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_free_move_zone.h b/engines/tetraedge/te/te_free_move_zone.h
index 74daafb8d23..706cc679516 100644
--- a/engines/tetraedge/te/te_free_move_zone.h
+++ b/engines/tetraedge/te/te_free_move_zone.h
@@ -71,8 +71,8 @@ public:
Common::Array<TeVector3f32> collisions(const TeVector3f32 &v1, const TeVector3f32 &v2);
TeVector3f32 correctCharacterPosition(const TeVector3f32 &pos, bool *flagout, bool f);
- TeIntrusivePtr<TeBezierCurve> curve(const TeVector3f32 ¶m_3, const TeVector2s32 ¶m_4, float param_5, bool findMeshFlag);
- TeIntrusivePtr<TeBezierCurve> curve(const TeVector3f32 ¶m_3, const TeVector3f32 ¶m_4);
+ TeIntrusivePtr<TeBezierCurve> curve(const TeVector3f32 &startpt, const TeVector2s32 &endpt, float param_5, bool findMeshFlag);
+ TeIntrusivePtr<TeBezierCurve> curve(const TeVector3f32 &startpt, const TeVector3f32 &endpt);
void draw() override;
TeVector3f32 findNearestPointOnBorder(const TeVector2f32 &pt);
@@ -90,14 +90,14 @@ public:
bool onViewportChanged();
void preUpdateGrid();
- TeVector3f32 projectOnAStarGrid(const TeVector3f32 &pt);
- Common::Array<TeVector3f32> &removeInsignificantPoints(const Common::Array<TeVector3f32> &points);
+ TeVector2s32 projectOnAStarGrid(const TeVector3f32 &pt);
+ Common::Array<TeVector3f32> removeInsignificantPoints(const Common::Array<TeVector3f32> &points);
void setBordersDistance(float dist);
void setCamera(TeIntrusivePtr<TeCamera> &cam, bool noRecalcProjPoints);
void setNbTriangles(unsigned int len);
void setPathFindingOccluder(const TeOBP &occluder);
void setVertex(unsigned int offset, const TeVector3f32 &vertex);
- TeVector2s32 transformAStarGridInWorldSpace(const TeVector2s32 &gridpt);
+ TeVector3f32 transformAStarGridInWorldSpace(const TeVector2s32 &gridpt);
float transformHeightMin(float minval);
TeVector3f32 transformVectorInWorldSpace(float param_3,float param_4);
void updateBorders();
@@ -111,6 +111,9 @@ public:
Common::Array<TeRectBlocker> *rectblockers, Common::Array<TeActZone> *actzones);
static void serialize(Common::WriteStream &stream, const TeFreeMoveZone &src, bool updateFirst);
+ static TePickMesh2 *findNearestMesh(TeIntrusivePtr<TeCamera> &camera, const TeVector2s32 &frompt,
+ Common::Array<TePickMesh2*> &pickMeshes, TeVector3f32 *outloc, bool lastHitFirst);
+
private:
Common::Array<TeActZone> *_actzones;
Common::Array<TeBlocker> *_blockers;
@@ -132,12 +135,15 @@ private:
TeIntrusivePtr<TeCamera> _camera;
//static TeIntrusivePtr<TeCamera> _globalCamera;
- bool _gridDirty;
TeFreeMoveZoneGraph *_graph;
+
+ bool _loadedFromBin;
+ bool _gridDirty;
bool _transformedVerticiesDirty;
bool _bordersDirty;
bool _pickMeshDirty;
bool _projectedPointsDirty;
+
micropather::MicroPather *_micropather;
TeTimer _updateTimer;
};
diff --git a/engines/tetraedge/te/te_images_sequence.cpp b/engines/tetraedge/te/te_images_sequence.cpp
index 5b991656697..3f90c9977dc 100644
--- a/engines/tetraedge/te/te_images_sequence.cpp
+++ b/engines/tetraedge/te/te_images_sequence.cpp
@@ -68,8 +68,8 @@ bool TeImagesSequence::load(const Common::Path &path) {
Common::Path filePath(filePathStr);
Common::String fname = filePath.getLastComponent().toString();
Common::String fstart = fname.substr(0, fname.size() - 7);
- unsigned int frameno = 0;
- unsigned int fps = 0;
+ int frameno = 0;
+ int fps = 0;
if (sscanf(fstart.c_str(), "%d-%d", &frameno, &fps) != 2) {
warning("TeImagesSequence::load can't match %s", fname.c_str());
continue;
diff --git a/engines/tetraedge/te/te_images_sequence.h b/engines/tetraedge/te/te_images_sequence.h
index e8f4b386adb..1f0a72bd3d2 100644
--- a/engines/tetraedge/te/te_images_sequence.h
+++ b/engines/tetraedge/te/te_images_sequence.h
@@ -27,7 +27,7 @@
namespace Graphics {
struct Surface;
-};
+}
namespace Tetraedge {
diff --git a/engines/tetraedge/te/te_jpeg.h b/engines/tetraedge/te/te_jpeg.h
index 72e98f767ad..6627ca3066b 100644
--- a/engines/tetraedge/te/te_jpeg.h
+++ b/engines/tetraedge/te/te_jpeg.h
@@ -27,7 +27,7 @@
namespace Graphics {
struct Surface;
-};
+}
namespace Tetraedge {
diff --git a/engines/tetraedge/te/te_model.cpp b/engines/tetraedge/te/te_model.cpp
index 5e5290e066f..195bd2a52a3 100644
--- a/engines/tetraedge/te/te_model.cpp
+++ b/engines/tetraedge/te/te_model.cpp
@@ -102,7 +102,7 @@ void TeModel::draw() {
renderer->sendModelMatrix(transform);
renderer->pushMatrix();
renderer->multiplyMatrix(transform);
- if (name() == "Kate") {
+ /*if (name() == "Kate") {
debug("Draw model %p (%s, %d meshes)", this, name().empty() ? "no name" : name().c_str(), _meshes.size());
//adebug(" renderMatrix %s", renderer->currentMatrix().toString().c_str());
//debug(" position %s", position().dump().c_str());
@@ -111,7 +111,7 @@ void TeModel::draw() {
//debug(" worldScale %s", worldScale().dump().c_str());
//debug(" rotation %s", rotation().dump().c_str());
debug(" worldRot %s", worldRotation().dump().c_str());
- }
+ }*/
for (TeMesh &mesh : _meshes) {
// TODO: Set some flag (_drawWires?) in mesh to this->field_0x158??
mesh.draw();
diff --git a/engines/tetraedge/te/te_pick_mesh2.cpp b/engines/tetraedge/te/te_pick_mesh2.cpp
index e28a7a1663d..8916cf99cc3 100644
--- a/engines/tetraedge/te/te_pick_mesh2.cpp
+++ b/engines/tetraedge/te/te_pick_mesh2.cpp
@@ -20,6 +20,7 @@
*/
#include "common/util.h"
+#include "common/math.h"
#include "tetraedge/tetraedge.h"
diff --git a/engines/tetraedge/te/te_png.h b/engines/tetraedge/te/te_png.h
index 18462b2c328..490a3c22167 100644
--- a/engines/tetraedge/te/te_png.h
+++ b/engines/tetraedge/te/te_png.h
@@ -27,7 +27,7 @@
namespace Graphics {
struct Surface;
-};
+}
namespace Tetraedge {
diff --git a/engines/tetraedge/te/te_vector2s32.h b/engines/tetraedge/te/te_vector2s32.h
index ecaa6e05e08..ca0fdf449c6 100644
--- a/engines/tetraedge/te/te_vector2s32.h
+++ b/engines/tetraedge/te/te_vector2s32.h
@@ -46,6 +46,14 @@ public:
return *this;
}
+ TeVector2s32 operator-(const TeVector2s32 &other) {
+ return TeVector2s32(_x - other._x, _y - other._y);
+ }
+
+ long squaredLength() const {
+ return _x * _x + _y * _y;
+ }
+
static void deserialize(Common::ReadStream &stream, TeVector2s32 &dest);
public:
diff --git a/engines/tetraedge/tetraedge.cpp b/engines/tetraedge/tetraedge.cpp
index d0007ee22e4..2b7329ad40b 100644
--- a/engines/tetraedge/tetraedge.cpp
+++ b/engines/tetraedge/tetraedge.cpp
@@ -127,7 +127,7 @@ Common::String TetraedgeEngine::getGameId() const {
void TetraedgeEngine::configureSearchPaths() {
const Common::FSNode gameDataDir(ConfMan.get("path"));
- SearchMan.addSubDirectoryMatching(gameDataDir, "Resources", 0, 4);
+ SearchMan.addSubDirectoryMatching(gameDataDir, "Resources", 0, 5);
}
int TetraedgeEngine::getDefaultScreenWidth() const {
diff --git a/engines/tetraedge/to_lua.cpp b/engines/tetraedge/to_lua.cpp
index a9ddd9c486c..31280d99aaf 100644
--- a/engines/tetraedge/to_lua.cpp
+++ b/engines/tetraedge/to_lua.cpp
@@ -434,6 +434,10 @@ int tolua_toboolean(lua_State *L, int narg, int def) {
return lua_gettop(L) < abs(narg) ? def : lua_toboolean(L,narg);
}
+void tolua_pushboolean(lua_State *L, bool val) {
+ lua_pushboolean(L, val);
+}
+
} // end namespace ToLua
} // end namespace Tetraedge
diff --git a/engines/tetraedge/to_lua.h b/engines/tetraedge/to_lua.h
index 842838d97dd..0cee065adbf 100644
--- a/engines/tetraedge/to_lua.h
+++ b/engines/tetraedge/to_lua.h
@@ -55,17 +55,19 @@ void tolua_open(lua_State *L);
void tolua_module (lua_State *L, const char *name, int hasvar);
void tolua_beginmodule (lua_State *L, const char *name);
void tolua_endmodule(lua_State *L);
-void tolua_function (lua_State *L, const char *name, lua_CFunction func);
+void tolua_function(lua_State *L, const char *name, lua_CFunction func);
-int tolua_isboolean (lua_State *L, int lo, int def, tolua_Error *err);
-int tolua_isnoobj (lua_State *L, int lo, tolua_Error *err);
-int tolua_isnumber (lua_State *L, int lo, int def, tolua_Error *err);
-int tolua_isstring (lua_State *L, int lo, int def, tolua_Error *err);
+int tolua_isboolean(lua_State *L, int lo, int def, tolua_Error *err);
+int tolua_isnoobj(lua_State *L, int lo, tolua_Error *err);
+int tolua_isnumber(lua_State *L, int lo, int def, tolua_Error *err);
+int tolua_isstring(lua_State *L, int lo, int def, tolua_Error *err);
-double tolua_tonumber (lua_State *L, int narg, double def);
-const char* tolua_tostring (lua_State *L, int narg, const char *def);
-void* tolua_tousertype (lua_State *L, int narg, void *def);
-int tolua_toboolean (lua_State *L, int narg, int def);
+double tolua_tonumber(lua_State *L, int narg, double def);
+const char* tolua_tostring(lua_State *L, int narg, const char *def);
+void* tolua_tousertype(lua_State *L, int narg, void *def);
+int tolua_toboolean(lua_State *L, int narg, int def);
+
+void tolua_pushboolean(lua_State *L, bool val);
} // end namespace ToLua
Commit: d28e9a2212ad6d4e139feb18d36ddfbc6d667c7f
https://github.com/scummvm/scummvm/commit/d28e9a2212ad6d4e139feb18d36ddfbc6d667c7f
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2023-01-16T17:36:43+01:00
Commit Message:
TETRAEDGE: WIP, can almost walk around now.
Changed paths:
engines/tetraedge/game/character.cpp
engines/tetraedge/game/character.h
engines/tetraedge/game/game.cpp
engines/tetraedge/game/in_game_scene.cpp
engines/tetraedge/te/te_bezier_curve.cpp
engines/tetraedge/te/te_bezier_curve.h
engines/tetraedge/te/te_button_layout.cpp
engines/tetraedge/te/te_free_move_zone.cpp
engines/tetraedge/te/te_free_move_zone.h
engines/tetraedge/te/te_model.h
engines/tetraedge/te/te_model_animation.h
engines/tetraedge/te/te_pick_mesh2.cpp
engines/tetraedge/te/te_pick_mesh2.h
engines/tetraedge/te/te_ray_intersection.cpp
engines/tetraedge/te/te_resource.cpp
engines/tetraedge/te/te_vector2f32.h
diff --git a/engines/tetraedge/game/character.cpp b/engines/tetraedge/game/character.cpp
index c182c34b365..190041788bd 100644
--- a/engines/tetraedge/game/character.cpp
+++ b/engines/tetraedge/game/character.cpp
@@ -23,6 +23,7 @@
#include "common/path.h"
#include "common/file.h"
#include "common/debug.h"
+#include "common/util.h"
#include "tetraedge/tetraedge.h"
#include "tetraedge/game/character.h"
@@ -61,7 +62,9 @@ _notWalkAnim(false), _someRepeatFlag(false), _walkModeStr("Walk"),
_needsSomeUpdate(false), _positionFlag(false), _lookingAtTallThing(false),
_stepSound1("sounds/SFX/PAS_H_BOIS1.ogg"), _stepSound2("sounds/SFX/PAS_H_BOIS2.ogg"),
_freeMoveZone(nullptr), _animSoundOffset(0), _lastAnimFrame(0), _charLookingAt(nullptr),
-_recallageY(true) {
+_recallageY(true), _walkToFlag(false), _walkCurveEnd(0.0f), _walkCurveStart(0.0f),
+_walkCurveLen(0.0f), _walkCurveIncrement(0.0f), _walkEndAnimG(false), _walkTotalFrames(0),
+_walkCurveCurOffset(0.0f) {
_curModelAnim.setDeleteFn(&TeModelAnimation::deleteLater);
}
@@ -570,6 +573,7 @@ bool Character::setAnimation(const Common::String &aname, bool repeat, bool para
}
_curModelAnim = animCacheLoad(animPath);
+ _curModelAnim->reset();
_curModelAnim->onFinished().add(this, &Character::onModelAnimationFinished);
_curModelAnim->bind(_model);
_curModelAnim->setFrameLimits(startFrame, endFrame);
@@ -609,9 +613,39 @@ bool Character::setShadowVisible(bool visible) {
return false;
}
-float Character::speedFromAnim(double movepercent) {
- error("TODO: Implement Character::speedFromAnim");
- return 0;
+float Character::speedFromAnim(double msFromStart) {
+ if (!_model)
+ return 0.0f;
+
+ TeIntrusivePtr<TeModelAnimation> modelAnim;
+ if (_model->_boneBlenders.empty()) {
+ modelAnim = _model->anim();
+ } else {
+ modelAnim = _model->_boneBlenders.back()->_anim;
+ }
+
+ if (!modelAnim)
+ return 0.0f;
+
+ const int pereBone = modelAnim->findBone("Pere");
+ int curFrame = modelAnim->calcCurrentFrame(msFromStart);
+
+ float result;
+ if (_lastFrame == -1) {
+ const TeVector3f32 nowvec = translationVectorFromAnim(*modelAnim, pereBone, 0);
+ const TeVector3f32 lastvec = translationVectorFromAnim(*modelAnim, pereBone, 1);
+ result = lastvec.z() - nowvec.z();
+ } else {
+ const TeVector3f32 nowvec = translationVectorFromAnim(*modelAnim, pereBone, curFrame);
+ const TeVector3f32 lastvec = translationVectorFromAnim(*modelAnim, pereBone, _lastFrame);
+ result = nowvec.z() - lastvec.z();
+ if (curFrame < _lastFrame) {
+ result += animLength(*modelAnim, pereBone, 9999);
+ }
+ }
+ _lastFrame = curFrame;
+ result *= _model->scale().z();
+ return result;
}
float Character::translationFromAnim(const TeModelAnimation &anim, long bone, long param_3) {
@@ -630,12 +664,116 @@ TeTRS Character::trsFromAnim(const TeModelAnimation &anim, long bone, long frame
return anim.getTRS(bone, frame, false);
}
-void Character::update(double percentval) {
+void Character::update(double msFromStart) {
if (!_curve || !_runTimer.running())
return;
- //float speed = speedFromAnim(percentval);
- error("TODO: Implement Character::update");
+ _walkCurveCurOffset = speedFromAnim(msFromStart) * _walkCurveIncrement + _walkCurveCurOffset;
+
+ if (_curve->controlPoints().size() < 2) {
+ blendAnimation(_characterSettings._walkFileName, 0.0667, true, false);
+ endMove();
+ return;
+ }
+
+ const float baseAngle = (_curveOffset > _walkCurveEnd ? M_PI : 0);
+ const float sign = (_curveOffset > _walkCurveEnd ? -1 : 1);
+ updatePosition(_walkCurveStart);
+ const TeVector3f32 modelpos = _model->position();
+
+ float lastWalkedLength = _walkedLength;
+ TeVector3f32 lastNextPos = modelpos;
+ TeVector3f32 nextPos = modelpos;
+ TeVector3f32 newPos = modelpos;
+ float lastOffset = _walkCurveStart;
+
+ float endOffset = _walkCurveStart;
+ while (_walkedLength < _walkCurveCurOffset) {
+ lastNextPos = nextPos;
+ float nextOffset = (4.0 / _curve->numIterations() * sign + lastOffset);
+ float offset = CLIP(nextOffset, 0.0f, 1.0f);
+
+ newPos = _curve->retrievePoint(offset) + _curveStartLocation;
+ const TeVector2f32 dist = TeVector2f32(nextPos.x(), nextPos.z()) - TeVector2f32(newPos.x(), newPos.z());
+
+ lastWalkedLength = _walkedLength;
+ _walkedLength += dist.length();
+
+ nextPos = newPos;
+ endOffset = lastOffset;
+ if (offset == 1.0 || offset == 0.0)
+ break;
+ lastOffset = offset;
+ }
+
+ _walkedLength = lastWalkedLength;
+ nextPos = lastNextPos;
+
+ while (_walkedLength < _walkCurveCurOffset) {
+ float nextOffset = (1.0 / _curve->numIterations()) * sign + endOffset;
+ endOffset = CLIP(nextOffset, 0.0f, 1.0f);
+
+ newPos = _curve->retrievePoint(endOffset) + _curveStartLocation;
+ const TeVector2f32 dist = TeVector2f32(nextPos.x(), nextPos.z()) - TeVector2f32(newPos.x(), newPos.z());
+ _walkedLength += dist.length();
+ nextPos = newPos;
+ if (endOffset == 1.0 || endOffset == 0.0)
+ break;
+ }
+
+ if (_freeMoveZone) {
+ bool correctflag;
+ newPos = _freeMoveZone->correctCharacterPosition(newPos, &correctflag, true);
+ }
+
+ _walkCurveStart = endOffset;
+ _model->setPosition(newPos);
+
+ TeVector3f32 t1;
+ TeVector3f32 t2;
+ _curve->pseudoTangent(endOffset, t1, t2);
+ const TeVector3f32 normalizedTangent = (t2 - t1).getNormalized();
+ float angle = TeVector3f32(0.0, 0.0, 1.0).dotProduct(normalizedTangent);
+ TeVector3f32 crossprod = TeVector3f32::crossProduct(TeVector3f32(0.0, 0.0, 1.0), normalizedTangent);
+ angle = acos(angle);
+ if (crossprod.y() >= 0.0f) {
+ angle = -angle;
+ }
+
+ TeQuaternion rot = TeQuaternion::fromAxisAndAngle(TeVector3f32(0.0, 1.0, 0.0), baseAngle + angle);
+ _model->setRotation(rot);
+
+ const Common::String endGAnim = walkAnim(WalkPart_EndG);
+ if (_walkCurveStart == _walkCurveEnd || fabs(_walkCurveEnd - _curveOffset) < fabs(_walkCurveStart - _curveOffset)) {
+ if (_walkToFlag) {
+ _walkToFlag = false;
+ endMove();
+ }
+ if (endGAnim.empty()) {
+ blendAnimation(_characterSettings._walkFileName, 0.0667, true, false);
+ endMove();
+ }
+ }
+
+ if (!endGAnim.empty() && _curAnimName == walkAnim(WalkPart_Loop) &&
+ ((_curModelAnim->speed() * (msFromStart / 1000.0)) >= _walkTotalFrames)) {
+ if (_walkToFlag) {
+ _walkToFlag = false;
+ endMove();
+ } else {
+ if (_walkEndAnimG) {
+ setAnimation(walkAnim(WalkPart_EndG), false);
+ } else {
+ setAnimation(walkAnim(WalkPart_EndD), false);
+ }
+ }
+ }
+
+ // Note:
+ // The game does a bunch of extra things here (line 252 on)
+ // that seem to have no actual effect??
+
+ updateAnimFrame();
}
void Character::updateAnimFrame() {
@@ -674,7 +812,87 @@ void Character::walkMode(const Common::String &mode) {
}
void Character::walkTo(float curveEnd, bool walkFlag) {
- error("TODO: Implement Character::walkTo");
+ _walkToFlag = walkFlag;
+ stop();
+ _walkCurveEnd = curveEnd;
+ _walkCurveStart = _curveOffset;
+ _walkCurveCurOffset = 0.0f;
+ _walkedLength = 0.0f;
+ const float f = (walkFlag ? _walkPart3AnimLen : 0);
+ if (_curve->controlPoints().size()) {
+ _walkCurveLen = _curve->length();
+ _walkEndAnimG = false;
+ const float f2 = ((_walkCurveLen - f) - _walkPart0AnimLen) / _walkPart1AnimLen;
+ float animLen;
+ if (f2 >= 0) {
+ Game *game = g_engine->getGame();
+ if (game->scene()._character == this && _walkModeStr == "Walk") {
+ int part1len = (int)(f2 * _walkPart1AnimFrameCount);
+ int repeats = part1len / _walkPart1AnimFrameCount;
+ uint remainder = part1len % _walkPart1AnimFrameCount;
+
+ uint framecounts[4];
+
+ if (repeats == 0)
+ framecounts[0] = UINT_MAX;
+ else
+ framecounts[0] = (repeats - 1) * _walkPart1AnimFrameCount + 29;
+
+ framecounts[1] = _walkPart1AnimFrameCount * repeats + 13;
+ framecounts[2] = _walkPart1AnimFrameCount * repeats + 29;
+ framecounts[3] = _walkPart1AnimFrameCount * (repeats + 1) + 13;
+
+ for (int i = 0; i < 4; i++) {
+ framecounts[i] = abs((int)(framecounts[i] - (int)(f2 * _walkPart1AnimFrameCount)));
+ }
+
+ int minoffset = 0;
+ for (int i = 0; i < 4; i++) {
+ if (framecounts[i] < framecounts[minoffset])
+ minoffset = i;
+ }
+
+ switch(minoffset) {
+ case 0:
+ remainder = 29;
+ _walkEndAnimG = true;
+ repeats--;
+ break;
+ case 1:
+ remainder = 13;
+ break;
+ case 2:
+ remainder = 29;
+ _walkEndAnimG = true;
+ break;
+ case 3:
+ remainder = 13;
+ repeats++;
+ }
+ _walkTotalFrames = _walkPart1AnimFrameCount * repeats + _walkPart0AnimFrameCount + remainder;
+ animLen = _walkPart1AnimLen;
+ const float loopAnimLen = animLengthFromFile(walkAnim(WalkPart_Loop), &remainder, remainder);
+ _walkCurveIncrement = _walkCurveLen / (repeats * animLen + f + _walkPart0AnimLen + loopAnimLen);
+ play();
+ return; // NOTE: early return here.
+ } else {
+ double intpart;
+ double remainder = modf(f, &intpart);
+ if (remainder >= 0.5) {
+ _walkEndAnimG = true;
+ intpart += 0.75;
+ } else {
+ intpart += 0.25;
+ }
+ _walkTotalFrames = (int)(_walkPart1AnimFrameCount * intpart) + _walkPart0AnimFrameCount;
+ animLen = f + (float)_walkPart0AnimLen + intpart * _walkPart1AnimLen;
+ }
+ } else {
+ animLen = (float)(_walkPart0AnimLen + _walkPart3AnimLen);
+ }
+ _walkCurveIncrement = _walkCurveLen / animLen;
+ }
+ play();
}
} // end namespace Tetraedge
diff --git a/engines/tetraedge/game/character.h b/engines/tetraedge/game/character.h
index 6723305803b..71508f03637 100644
--- a/engines/tetraedge/game/character.h
+++ b/engines/tetraedge/game/character.h
@@ -132,7 +132,7 @@ public:
void setFreeMoveZone(TeFreeMoveZone *zone);
bool setShadowVisible(bool visible);
void setStepSound(const Common::String &stepSound1, const Common::String &stepSound2);
- float speedFromAnim(double movepercent);
+ float speedFromAnim(double amount);
//void stop(); // just maps to TeAnimation::stop();
float translationFromAnim(const TeModelAnimation &anim, long bone, long frame);
TeVector3f32 translationVectorFromAnim(const TeModelAnimation &anim, long bone, long frame);
@@ -174,6 +174,15 @@ public:
private:
float _curveOffset;
+ float _walkCurveStart;
+ float _walkCurveEnd;
+ float _walkCurveLen;
+ float _walkCurveIncrement;
+ float _walkCurveCurOffset;
+ float _walkedLength;
+ int _walkTotalFrames;
+ bool _walkToFlag;
+ bool _walkEndAnimG;
TeIntrusivePtr<TeBezierCurve> _curve;
TeVector3f32 _curveStartLocation;
diff --git a/engines/tetraedge/game/game.cpp b/engines/tetraedge/game/game.cpp
index 8205097f4fc..9c06be767a0 100644
--- a/engines/tetraedge/game/game.cpp
+++ b/engines/tetraedge/game/game.cpp
@@ -47,7 +47,7 @@ namespace Tetraedge {
Game::Game() : _objectsTakenVal(0), _score(0), _entered(false), _gameLoadState(0),
_noScaleLayout(nullptr), _noScaleLayout2(nullptr), _warped(false), _saveRequested(false),
_firstInventory(true), _movePlayerCharacterDisabled(false), _enteredFlag2(false),
-_luaShowOwnerError(false), _markersVisible(true), _running(false), _loadName("save.xml"),
+_luaShowOwnerError(false), _markersVisible(false), _running(false), _loadName("save.xml"),
_randomSoundFinished(false), _randomSource("SyberiaGameRandom") {
for (int i = 0; i < NUM_OBJECTS_TAKEN_IDS; i++) {
_objectsTakenBits[i] = false;
@@ -1177,9 +1177,9 @@ void Game::playRandomSound(const Common::String &name) {
if (!_randomSounds.contains(name)) {
warning("Game::playRandomSound: can't find sound list %s", name.c_str());
return;
- }
-
- if (!_randomSoundFinished) {
+ }
+
+ if (!_randomSoundFinished) {
_randomSoundTimer.start();
int r = _randomSource.getRandomNumber(RAND_MAX);
float f = (r + 1 + (r / 100) * -100);
diff --git a/engines/tetraedge/game/in_game_scene.cpp b/engines/tetraedge/game/in_game_scene.cpp
index e72fbca972b..5be7a135c84 100644
--- a/engines/tetraedge/game/in_game_scene.cpp
+++ b/engines/tetraedge/game/in_game_scene.cpp
@@ -152,7 +152,7 @@ bool InGameScene::aroundAnchorZone(const AnchorZone *zone) {
float xoff = charpos.x() - zone->_loc.x();
float zoff = charpos.z() - zone->_loc.z();
- return sqrt(xoff * xoff + zoff * zoff) <= zone->_radius;
+ return sqrt(xoff * xoff + zoff * zoff) <= zone->_radius;
}
TeLayout *InGameScene::background() {
diff --git a/engines/tetraedge/te/te_bezier_curve.cpp b/engines/tetraedge/te/te_bezier_curve.cpp
index 18f15a71dd5..d55a3203db0 100644
--- a/engines/tetraedge/te/te_bezier_curve.cpp
+++ b/engines/tetraedge/te/te_bezier_curve.cpp
@@ -59,6 +59,18 @@ float TeBezierCurve::length() {
return _length;
}
+void TeBezierCurve::pseudoTangent(float f, TeVector3f32 &v1, TeVector3f32 &v2) {
+ const float numiters = _numiterations;
+
+ if (1.0 / numiters + f <= 1.0) {
+ v1 = retrievePoint(f);
+ v2 = retrievePoint(1.0 / numiters + f);
+ } else {
+ v2 = retrievePoint(f);
+ v1 = retrievePoint(f - 1.0 / numiters);
+ }
+}
+
float TeBezierCurve::rawLength() {
if (_rawLengthNeedsUpdate) {
_rawLengthNeedsUpdate = false;
@@ -78,7 +90,7 @@ float TeBezierCurve::rawLength() {
}
TeVector3f32 TeBezierCurve::retrievePoint(float offset) {
- const unsigned int npoints = _controlPoints.size();
+ const int npoints = _controlPoints.size();
// Simple cases for small numbers of points.
if (npoints == 0)
@@ -89,11 +101,10 @@ TeVector3f32 TeBezierCurve::retrievePoint(float offset) {
return _controlPoints[0] + (_controlPoints[1] - _controlPoints[0]) * offset;
// else, there are at least 3 points so need to actually interpolate.
- TeVector3f32 points[5];
const float rawlen = rawLength();
float proportion = 0.0f;
- unsigned int i = 0;
+ int i = 0;
while (i < npoints) {
proportion = _rawLengths[i] / rawlen;
if (proportion >= offset)
@@ -110,12 +121,35 @@ TeVector3f32 TeBezierCurve::retrievePoint(float offset) {
i--;
}
- for (unsigned int p = -1; p < 3; p++) {
-
+ TeVector3f32 points[4];
+ TeVector3f32 *ptbuf = points;
+ const int maxPt = _controlPoints.size() - 1;
+ int p = -1;
+ do {
+ int ptno = 0;
+ if (i + p >= 0)
+ ptno = MIN(i + p, maxPt);
+ *ptbuf = _controlPoints[ptno];
+ ptbuf = ptbuf + 1;
+ p = p + 1;
+ } while (p != 3);
+
+ if (i < 0) {
+ points[0] += (points[1] - points[2]);
+ } else {
+ int ptno = MIN(i, maxPt);
+ if (ptno == 0)
+ points[0] += (points[1] - points[2]);
}
- // TODO: Finish this, line 77 to 129.
+ int ptno = 0;
+ i++;
+ if (i >= 0)
+ ptno = MIN(i, maxPt);
+
+ if (ptno == maxPt)
+ points[3] += points[2] - points[1];
- error("TODO: Implement TeBezierCurve::retrievePoint");
+ return hermiteInterpolate(t, points, 0.0, 0.0);
}
void TeBezierCurve::setControlPoints(const Common::Array<TeVector3f32> &points) {
@@ -165,7 +199,7 @@ TeVector3f32 TeBezierCurve::hermiteInterpolate(float t, const TeVector3f32 *poin
const float t2 = t * t;
const float t3 = t * t * t;
- const TeVector3f32 h1a = points[1] * ((t3 + t3) - t2 * 3.0);
+ const TeVector3f32 h1a = points[1] * ((t3 + t3) - t2 * 3.0 + 1.0);
const TeVector3f32 h1b = x1 * ((t3 - (t2 + t2)) + t);
const TeVector3f32 h1 = (h1a + h1b) + (x2 * (t3 - t2));
return h1 + (points[2] * (t3 * -2.0 + t2 * 3.0));
diff --git a/engines/tetraedge/te/te_bezier_curve.h b/engines/tetraedge/te/te_bezier_curve.h
index de0ca32642b..2f199203b2f 100644
--- a/engines/tetraedge/te/te_bezier_curve.h
+++ b/engines/tetraedge/te/te_bezier_curve.h
@@ -38,6 +38,8 @@ public:
void draw() override;
float length();
+ void pseudoTangent(float f, TeVector3f32 &v1, TeVector3f32 &v2);
+
float rawLength();
TeVector3f32 retrievePoint(float offset);
@@ -50,6 +52,7 @@ public:
static void deserialize(Common::ReadStream &stream, TeBezierCurve &curve);
const Common::Array<TeVector3f32> &controlPoints() { return _controlPoints; }
+ unsigned int numIterations() const { return _numiterations; }
private:
unsigned int _numiterations;
diff --git a/engines/tetraedge/te/te_button_layout.cpp b/engines/tetraedge/te/te_button_layout.cpp
index b19681a6b30..f0235e3492c 100644
--- a/engines/tetraedge/te/te_button_layout.cpp
+++ b/engines/tetraedge/te/te_button_layout.cpp
@@ -40,7 +40,7 @@ namespace Tetraedge {
}
TeButtonLayout::TeButtonLayout() :
-_currentState(BUTTON_STATE_UP), _clickPassThrough(true), _validationSoundVolume(1.0),
+_currentState(BUTTON_STATE_UP), _clickPassThrough(false), _validationSoundVolume(1.0),
_someClickFlag(false), _doubleValidationProtectionEnabled(true), _upLayout(nullptr),
_downLayout(nullptr), _rolloverLayout(nullptr), _disabledLayout(nullptr),
_hitZoneLayout(nullptr)
diff --git a/engines/tetraedge/te/te_free_move_zone.cpp b/engines/tetraedge/te/te_free_move_zone.cpp
index c49aa2c4fef..cb7cb4437e7 100644
--- a/engines/tetraedge/te/te_free_move_zone.cpp
+++ b/engines/tetraedge/te/te_free_move_zone.cpp
@@ -116,17 +116,21 @@ TeVector3f32 TeFreeMoveZone::correctCharacterPosition(const TeVector3f32 &pos, b
TeIntrusivePtr<TeBezierCurve> TeFreeMoveZone::curve(const TeVector3f32 &startpt, const TeVector2s32 &endpt, float param_5, bool findMeshFlag) {
updateGrid(false);
- error("TODO: Implement TeFreeMoveZone::curve");
+ Common::Array<TePickMesh2 *> meshes;
+ TeVector3f32 newend;
+ meshes.push_back(this);
+
+ TePickMesh2 *nearest = findNearestMesh(_camera, endpt, meshes, &newend, findMeshFlag);
+ if (!nearest)
+ return TeIntrusivePtr<TeBezierCurve>();
+
+ return curve(startpt, newend);
}
TeIntrusivePtr<TeBezierCurve> TeFreeMoveZone::curve(const TeVector3f32 &startpt, const TeVector3f32 &endpt) {
updateGrid(false);
- Common::Array<TeVector3f32> points;
- points.push_back(startpt);
- points.push_back(endpt);
-
- TeVector2s32 projectedStart = projectOnAStarGrid(startpt);
- TeVector2s32 projectedEnd = projectOnAStarGrid(endpt);
+ const TeVector2s32 projectedStart = projectOnAStarGrid(startpt);
+ const TeVector2s32 projectedEnd = projectOnAStarGrid(endpt);
int xsize = _graph->_size._x;
float cost = 0;
// Passing an int to void*, yuck? but it's what the original does..
@@ -137,14 +141,16 @@ TeIntrusivePtr<TeBezierCurve> TeFreeMoveZone::curve(const TeVector3f32 &startpt,
if (pathResult == micropather::MicroPather::SOLVED || pathResult == micropather::MicroPather::START_END_SAME) {
Common::Array<TeVector2s32> points;
- points.resize(path.size());
+ points.resize(path.size() + 2);
- for (auto &pathpt : path) {
+ int i = 1;
+ for (auto pathpt : path) {
// each path point is an array offset
- int offset = static_cast<int>(reinterpret_cast<long>(pathpt));
- int yoff = (offset / _graph->_size._x);
+ int offset = static_cast<int>(reinterpret_cast<size_t>(pathpt));
+ int yoff = offset / _graph->_size._x;
int xoff = offset % _graph->_size._x;
- points.push_back(TeVector2s32(xoff, yoff));
+ points[i] = TeVector2s32(xoff, yoff);
+ i++;
}
Common::Array<TeVector3f32> pts3d;
@@ -157,6 +163,12 @@ TeIntrusivePtr<TeBezierCurve> TeFreeMoveZone::curve(const TeVector3f32 &startpt,
removeInsignificantPoints(pts3d);
retval = new TeBezierCurve();
retval->setControlPoints(pts3d);
+ } else {
+ Common::Array<TeVector3f32> points;
+ points.push_back(startpt);
+ points.push_back(endpt);
+ retval = new TeBezierCurve();
+ retval->setControlPoints(points);
}
return retval;
@@ -244,9 +256,66 @@ TeVector2s32 TeFreeMoveZone::projectOnAStarGrid(const TeVector3f32 &pt) {
return TeVector2s32((int)projected.getX(), (int)projected.getY());
}
+static int segmentIntersection(const TeVector2f32 &s1start, const TeVector2f32 &s1end,
+ const TeVector2f32 &s2start, const TeVector2f32 &s2end,
+ TeVector2f32 *sout, float *fout1, float *fout2) {
+ TeVector2f32 s1len = s1end - s1start;
+ TeVector2f32 s2len = s2end - s2start;
+ float squarelen = s1len.getX() * s2len.getX() + s1len.getY() * s2len.getY();
+ int result = 0;
+ if (squarelen != 0) {
+ result = 1;
+ float intersection1 = -((s1len.getY() * s1start.getX() +
+ (s1len.getX() * s2start.getY() - s1len.getX() * s1start.getY())) -
+ s1len.getY() * s2start.getX()) / squarelen;
+ if (intersection1 >= 0.0f && intersection1 <= 1.0f) {
+ float intersection2 = -((s2len.getY() * s2start.getY() +
+ (s2len.getX() * s1start.getX() - s2len.getX() * s2start.getX())) -
+ s2len.getY() * s1start.getY()) / squarelen;
+ if (intersection2 >= 0.0f && intersection2 <= 1.0f) {
+ result = 2;
+ if (sout || fout1 || fout2) {
+ warning("TODO: implement output in segmentIntersection");
+ }
+ }
+ }
+ }
+ return result;
+}
+
Common::Array<TeVector3f32> TeFreeMoveZone::removeInsignificantPoints(const Common::Array<TeVector3f32> &points) {
- warning("TODO: Implement TeFreeMoveZone::removeInsignificantPoints");
- return points;
+ if (points.size() < 2)
+ return points;
+
+ Common::Array<TeVector3f32> result;
+ result.push_back(points[0]);
+
+ if (points.size() > 2) {
+ int point1 = 0;
+ int point2 = 2;
+ do {
+ const TeVector2f32 pt1(points[point1].x(), points[point1].z());
+ const TeVector2f32 pt2(points[point2].x(), points[point2].z());
+ for (unsigned int i = 0; i * 2 < _uintArray2.size() / 2; i++) {
+ const TeVector3f32 transpt3d1 = worldTransformationMatrix() * verticies()[_uintArray2[i * 2]];
+ const TeVector2f32 transpt1(transpt3d1.x(), transpt3d1.z());
+ const TeVector3f32 transpt3d2 = worldTransformationMatrix() * verticies()[_uintArray2[i * 2 + 1]];
+ const TeVector2f32 transpt2(transpt3d2.x(), transpt3d2.z());
+ if (segmentIntersection(pt1, pt2, transpt1, transpt2, nullptr, nullptr, nullptr) == 2)
+ break;
+ }
+ point1 = point2 - 1;
+ result.push_back(points[point1]);
+ point2++;
+ } while (point2 < points.size());
+ }
+
+ if (result.back() != points[points.size() - 2]) {
+ result.push_back(points[points.size() - 1]);
+ } else {
+ result.back() = points[points.size() - 1];
+ }
+ return result;
}
void TeFreeMoveZone::setBordersDistance(float dist) {
@@ -347,8 +416,8 @@ void TeFreeMoveZone::updateTransformedVertices() {
/*========*/
float TeFreeMoveZoneGraph::LeastCostEstimate(void *stateStart, void *stateEnd) {
- int startInt = static_cast<int>(reinterpret_cast<long>(stateStart));
- int endInt = static_cast<int>(reinterpret_cast<long>(stateEnd));
+ int startInt = static_cast<int>(reinterpret_cast<size_t>(stateStart));
+ int endInt = static_cast<int>(reinterpret_cast<size_t>(stateEnd));
int starty = startInt / _size._x;
int endy = endInt / _size._x;
TeVector2s32 start(startInt - starty * _size._x, starty);
@@ -357,7 +426,7 @@ float TeFreeMoveZoneGraph::LeastCostEstimate(void *stateStart, void *stateEnd) {
}
void TeFreeMoveZoneGraph::AdjacentCost(void *state, Common::Array<micropather::StateCost> *adjacent) {
- int stateInt = static_cast<int>(reinterpret_cast<long>(state));
+ int stateInt = static_cast<int>(reinterpret_cast<size_t>(state));
int stateY = stateInt / _size._x;
const TeVector2s32 statept(stateInt - stateY * _size._x, stateY);
diff --git a/engines/tetraedge/te/te_free_move_zone.h b/engines/tetraedge/te/te_free_move_zone.h
index 706cc679516..b7f5743777b 100644
--- a/engines/tetraedge/te/te_free_move_zone.h
+++ b/engines/tetraedge/te/te_free_move_zone.h
@@ -108,7 +108,7 @@ public:
static float normalizeAngle(float angle);
static void deserialize(Common::ReadStream &stream, TeFreeMoveZone &dest, Common::Array<TeBlocker> *blockers,
- Common::Array<TeRectBlocker> *rectblockers, Common::Array<TeActZone> *actzones);
+ Common::Array<TeRectBlocker> *rectblockers, Common::Array<TeActZone> *actzones);
static void serialize(Common::WriteStream &stream, const TeFreeMoveZone &src, bool updateFirst);
static TePickMesh2 *findNearestMesh(TeIntrusivePtr<TeCamera> &camera, const TeVector2s32 &frompt,
diff --git a/engines/tetraedge/te/te_model.h b/engines/tetraedge/te/te_model.h
index 3c097b63377..d9fa712e01b 100644
--- a/engines/tetraedge/te/te_model.h
+++ b/engines/tetraedge/te/te_model.h
@@ -136,6 +136,7 @@ public:
bool _skipSkinOffsets;
Common::Array<TeMesh> _meshes;
+ Common::Array<BonesBlender *> _boneBlenders;
protected:
bool _matrixForced;
@@ -146,7 +147,6 @@ protected:
Common::Array<TeMatrix4x4> _boneMatricies;
Common::Array<TeMatrix4x4> _lerpedElements;
Common::Array<Common::Array<weightElement>> _weightElements;
- Common::Array<BonesBlender *> _boneBlenders;
TeQuaternion _boneRotation;
diff --git a/engines/tetraedge/te/te_model_animation.h b/engines/tetraedge/te/te_model_animation.h
index fb30cc66bd6..5152b082bd2 100644
--- a/engines/tetraedge/te/te_model_animation.h
+++ b/engines/tetraedge/te/te_model_animation.h
@@ -54,6 +54,10 @@ public:
TeModelAnimation();
+ ~TeModelAnimation() {
+ destroy();
+ }
+
void bind(const TeIntrusivePtr<TeModel> &ptr) {
_model = ptr;
};
@@ -88,6 +92,7 @@ public:
void update(double proportion) override;
int curFrame2() const { return _curFrame2; }
+ float speed() const { return _speed; }
TeIntrusivePtr<TeModel> _model;
int _firstFrame;
diff --git a/engines/tetraedge/te/te_pick_mesh2.cpp b/engines/tetraedge/te/te_pick_mesh2.cpp
index 8916cf99cc3..41fb2c5cbad 100644
--- a/engines/tetraedge/te/te_pick_mesh2.cpp
+++ b/engines/tetraedge/te/te_pick_mesh2.cpp
@@ -59,7 +59,7 @@ void TePickMesh2::draw() {
renderer->setCurrentColor(prevCol);
}
-bool TePickMesh2::intersect(const TeVector3f32 &v1, const TeVector3f32 v2, TeVector3f32 &v3, float &fout, bool lastHitFirst, unsigned long *triangleHitOut) {
+bool TePickMesh2::intersect(const TeVector3f32 &v1, const TeVector3f32 &v2, TeVector3f32 &v3, float &fout, bool lastHitFirst, unsigned long *triangleHitOut) {
if (_verticies.size() / 3 == 0)
return false;
diff --git a/engines/tetraedge/te/te_pick_mesh2.h b/engines/tetraedge/te/te_pick_mesh2.h
index fd823128a8a..584a3cf88b9 100644
--- a/engines/tetraedge/te/te_pick_mesh2.h
+++ b/engines/tetraedge/te/te_pick_mesh2.h
@@ -35,7 +35,7 @@ public:
void draw() override;
- bool intersect(const TeVector3f32 &v1, const TeVector3f32 v2, TeVector3f32 &v3, float &fout, bool useLastHit, unsigned long *triangleHitOut);
+ bool intersect(const TeVector3f32 &v1, const TeVector3f32 &v2, TeVector3f32 &v3, float &fout, bool useLastHit, unsigned long *triangleHitOut);
bool intersect2D(const TeVector2f32 &pt);
unsigned long lastTriangleHit() const;
diff --git a/engines/tetraedge/te/te_ray_intersection.cpp b/engines/tetraedge/te/te_ray_intersection.cpp
index fa1d6080a29..4cfece341c3 100644
--- a/engines/tetraedge/te/te_ray_intersection.cpp
+++ b/engines/tetraedge/te/te_ray_intersection.cpp
@@ -31,7 +31,7 @@ TePickMesh *getMesh(const TeVector3f32 ¶m_1, const TeVector3f32 ¶m_2, co
}
int intersect(const TeVector3f32 &v1, const TeVector3f32 &v2, const TeVector3f32 &v3,
- const TeVector3f32 &v4, const TeVector3f32 &v5, TeVector3f32 &vout, float &fout) {
+ const TeVector3f32 &v4, const TeVector3f32 &v5, TeVector3f32 &vout, float &fout) {
const TeVector3f32 v4_v3 = (v4 - v3);
const TeVector3f32 v5_v3 = (v5 - v3);
TeVector3f32 v = v4_v3 ^ v5_v3;
diff --git a/engines/tetraedge/te/te_resource.cpp b/engines/tetraedge/te/te_resource.cpp
index 2584d7df2e0..b75575768fd 100644
--- a/engines/tetraedge/te/te_resource.cpp
+++ b/engines/tetraedge/te/te_resource.cpp
@@ -49,7 +49,7 @@ void TeResource::generateAccessName() {
name[4] = hexaChars[_idCounter >> 12 & 0xf];
name[5] = hexaChars[_idCounter >> 8 & 0xf];
name[6] = hexaChars[_idCounter >> 4 & 0xf];
- name[7] = hexaChars[_idCounter & 0xf];
+ name[7] = hexaChars[_idCounter & 0xf];
name[8] = '\0';
_idCounter++;
diff --git a/engines/tetraedge/te/te_vector2f32.h b/engines/tetraedge/te/te_vector2f32.h
index 6e3e7501de8..66408fce170 100644
--- a/engines/tetraedge/te/te_vector2f32.h
+++ b/engines/tetraedge/te/te_vector2f32.h
@@ -57,6 +57,10 @@ public:
return getX() * other.getX() - getY() * other.getY();
}
+ float length() const {
+ return sqrt(getX() * getX() + getY() * getY());
+ }
+
/*
TODO: do we need anything that isn't already in Vector2d here?
TeVector2f32(const TeVector2f32 &other);
@@ -64,7 +68,6 @@ public:
TeVector2f32(float *vals);
float dotProduct(const TeVector2f32 &other) const;
- float length() const;
float squaredLength() const;
void normalize();
Commit: 036ad4bc04ba030a1b04d71ce6073f63a63bf2d9
https://github.com/scummvm/scummvm/commit/036ad4bc04ba030a1b04d71ce6073f63a63bf2d9
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2023-01-16T17:36:43+01:00
Commit Message:
TETRAEDGE: WIP, fix suitcase and faces on the floor.
Changed paths:
engines/tetraedge/game/character.cpp
engines/tetraedge/game/lua_binds.cpp
engines/tetraedge/game/object3d.cpp
engines/tetraedge/te/te_mesh.cpp
engines/tetraedge/te/te_model.cpp
engines/tetraedge/te/te_trs.cpp
engines/tetraedge/te/te_trs.h
diff --git a/engines/tetraedge/game/character.cpp b/engines/tetraedge/game/character.cpp
index 190041788bd..1a4d672c7d6 100644
--- a/engines/tetraedge/game/character.cpp
+++ b/engines/tetraedge/game/character.cpp
@@ -292,8 +292,9 @@ bool Character::loadModel(const Common::String &mname, bool unused) {
for (auto &mesh : _model->_meshes)
mesh.setVisible(true);
-
+ // Set all mouthes not visible by default
_model->setVisibleByName("_B_", false);
+ // Set all eyes not visible by default
_model->setVisibleByName("_Y_", false);
// Note: game loops through "faces" here, but it only ever uses the default ones.
@@ -689,8 +690,7 @@ void Character::update(double msFromStart) {
float endOffset = _walkCurveStart;
while (_walkedLength < _walkCurveCurOffset) {
- lastNextPos = nextPos;
- float nextOffset = (4.0 / _curve->numIterations() * sign + lastOffset);
+ float nextOffset = (4.0 / _curve->numIterations()) * sign + lastOffset;
float offset = CLIP(nextOffset, 0.0f, 1.0f);
newPos = _curve->retrievePoint(offset) + _curveStartLocation;
@@ -704,6 +704,7 @@ void Character::update(double msFromStart) {
if (offset == 1.0 || offset == 0.0)
break;
lastOffset = offset;
+ lastNextPos = nextPos;
}
_walkedLength = lastWalkedLength;
diff --git a/engines/tetraedge/game/lua_binds.cpp b/engines/tetraedge/game/lua_binds.cpp
index a469948ccdf..1c11e704b0f 100644
--- a/engines/tetraedge/game/lua_binds.cpp
+++ b/engines/tetraedge/game/lua_binds.cpp
@@ -437,7 +437,7 @@ static int tolua_ExportedFunctions_SetGroundObjectPosition00(lua_State *L) {
Common::String s1(tolua_tostring(L, 1, nullptr));
float f1 = tolua_tonumber(L, 2, 0.0);
float f2 = tolua_tonumber(L, 3, 0.0);
- float f3 = tolua_tonumber(L, 4, 1.0);
+ float f3 = tolua_tonumber(L, 4, 0.0);
SetGroundObjectPosition(s1, f1, f2, f3);
return 0;
}
@@ -465,7 +465,7 @@ static int tolua_ExportedFunctions_SetGroundObjectRotation00(lua_State *L) {
Common::String s1(tolua_tostring(L, 1, nullptr));
float f1 = tolua_tonumber(L, 2, 0.0);
float f2 = tolua_tonumber(L, 3, 0.0);
- float f3 = tolua_tonumber(L, 4, 1.0);
+ float f3 = tolua_tonumber(L, 4, 0.0);
SetGroundObjectRotation(s1, f1, f2, f3);
return 0;
}
@@ -545,7 +545,8 @@ static void AddAnchorZone(const Common::String &s1, const Common::String &s2, fl
static int tolua_ExportedFunctions_AddAnchorZone00(lua_State *L) {
tolua_Error err;
- if (tolua_isstring(L, 1, 0, &err) && tolua_isstring(L, 2, 0, &err) && tolua_isnumber(L, 3, 1, &err) && tolua_isnoobj(L, 4, &err)) {
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isstring(L, 2, 0, &err)
+ && tolua_isnumber(L, 3, 1, &err) && tolua_isnoobj(L, 4, &err)) {
Common::String s1(tolua_tostring(L, 1, nullptr));
Common::String s2(tolua_tostring(L, 2, nullptr));
double d1 = tolua_tonumber(L, 3, 1.0);
diff --git a/engines/tetraedge/game/object3d.cpp b/engines/tetraedge/game/object3d.cpp
index a05d032198e..23609ec05cd 100644
--- a/engines/tetraedge/game/object3d.cpp
+++ b/engines/tetraedge/game/object3d.cpp
@@ -28,7 +28,7 @@ namespace Tetraedge {
/*static*/ Common::HashMap<Common::String, Object3D::ObjectSettings> *Object3D::_objectSettings = nullptr;
-Object3D::Object3D() : _translateTime(-1), _rotateTime(-1) {
+Object3D::Object3D() : _translateTime(-1), _rotateTime(-1), _objScale(1.0f, 1.0f, 1.0f) {
}
bool Object3D::loadModel(const Common::String &name) {
diff --git a/engines/tetraedge/te/te_mesh.cpp b/engines/tetraedge/te/te_mesh.cpp
index d4aa310c98d..0ffbc513073 100644
--- a/engines/tetraedge/te/te_mesh.cpp
+++ b/engines/tetraedge/te/te_mesh.cpp
@@ -67,6 +67,9 @@ void TeMesh::destroy() {
}
void TeMesh::draw() {
+ if (!worldVisible())
+ return;
+
TeRenderer *renderer = g_engine->getRenderer();
renderer->pushMatrix();
if (_matrixForced)
@@ -74,6 +77,17 @@ void TeMesh::draw() {
else
renderer->multiplyMatrix(worldTransformationMatrix());
+ /*
+ debug("Draw mesh %p (%s, %d verts %d norms %d indexes %d materials %d updated)", this, name().empty() ? "no name" : name().c_str(), _verticies.size(), _normals.size(), _indexes.size(), _materials.size(), _updatedVerticies.size());
+ debug(" renderMatrix %s", renderer->currentMatrix().toString().c_str());
+ debug(" position %s", position().dump().c_str());
+ debug(" worldPos %s", worldPosition().dump().c_str());
+ debug(" scale %s", scale().dump().c_str());
+ debug(" worldScale %s", worldScale().dump().c_str());
+ debug(" rotation %s", rotation().dump().c_str());
+ debug(" worldRot %s", worldRotation().dump().c_str());
+ */
+
Common::Array<TeVector3f32> &normals = (_updatedVerticies.empty() ? _normals : _updatedNormals);
Common::Array<TeVector3f32> &verticies = (_updatedVerticies.empty() ? _verticies : _updatedVerticies);
if (renderer->shadowMode() != TeRenderer::ShadowMode1) {
diff --git a/engines/tetraedge/te/te_model.cpp b/engines/tetraedge/te/te_model.cpp
index 195bd2a52a3..60b2a7728da 100644
--- a/engines/tetraedge/te/te_model.cpp
+++ b/engines/tetraedge/te/te_model.cpp
@@ -102,13 +102,14 @@ void TeModel::draw() {
renderer->sendModelMatrix(transform);
renderer->pushMatrix();
renderer->multiplyMatrix(transform);
- /*if (name() == "Kate") {
+ /*
+ if (name().contains("Kate")) {
debug("Draw model %p (%s, %d meshes)", this, name().empty() ? "no name" : name().c_str(), _meshes.size());
- //adebug(" renderMatrix %s", renderer->currentMatrix().toString().c_str());
+ debug(" renderMatrix %s", renderer->currentMatrix().toString().c_str());
//debug(" position %s", position().dump().c_str());
debug(" worldPos %s", worldPosition().dump().c_str());
//debug(" scale %s", scale().dump().c_str());
- //debug(" worldScale %s", worldScale().dump().c_str());
+ debug(" worldScale %s", worldScale().dump().c_str());
//debug(" rotation %s", rotation().dump().c_str());
debug(" worldRot %s", worldRotation().dump().c_str());
}*/
@@ -166,6 +167,8 @@ void TeModel::setColor(const TeColor &col) {
}
void TeModel::update() {
+ //if (name().contains("Kate"))
+ // debug("TeModel::update model %s", name().c_str());
if (_bones.size()) {
Common::Array<TeMatrix4x4> matricies;
matricies.resize(_bones.size());
diff --git a/engines/tetraedge/te/te_trs.cpp b/engines/tetraedge/te/te_trs.cpp
index 8e2a13e7e8c..cc6f351b362 100644
--- a/engines/tetraedge/te/te_trs.cpp
+++ b/engines/tetraedge/te/te_trs.cpp
@@ -24,6 +24,13 @@
namespace Tetraedge {
TeTRS::TeTRS() {
+ setIdentity();
+}
+
+void TeTRS::setIdentity() {
+ _trans = TeVector3f32(0, 0, 0);
+ _rot = TeQuaternion();
+ _scale = TeVector3f32(1, 1, 1);
}
/*static*/ void TeTRS::deserialize(Common::ReadStream &stream, TeTRS &dest) {
diff --git a/engines/tetraedge/te/te_trs.h b/engines/tetraedge/te/te_trs.h
index d3a369098c3..041cd9d3e5e 100644
--- a/engines/tetraedge/te/te_trs.h
+++ b/engines/tetraedge/te/te_trs.h
@@ -35,6 +35,8 @@ public:
static void deserialize(Common::ReadStream &stream, TeTRS &dest);
static void serialize(Common::WriteStream &stream, const TeTRS &src);
+ void setIdentity();
+
void setRotation(const TeQuaternion &rot) {
_rot = rot;
}
Commit: 85ed7742dea857637e0f27c0849b07f7369c435f
https://github.com/scummvm/scummvm/commit/85ed7742dea857637e0f27c0849b07f7369c435f
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2023-01-16T17:36:43+01:00
Commit Message:
TETRAEDGE: More WIP. Can now walk between screens.
Some object interactions work too. Next need to finish
inventory.
Changed paths:
engines/tetraedge/game/character.cpp
engines/tetraedge/game/character.h
engines/tetraedge/game/character_settings_xml_parser.cpp
engines/tetraedge/game/dialog2.cpp
engines/tetraedge/game/dialog2.h
engines/tetraedge/game/game.cpp
engines/tetraedge/game/in_game_scene.cpp
engines/tetraedge/game/inventory.cpp
engines/tetraedge/game/inventory.h
engines/tetraedge/game/inventory_object.cpp
engines/tetraedge/game/inventory_object.h
engines/tetraedge/game/lua_binds.cpp
engines/tetraedge/te/te_3d_object2.cpp
engines/tetraedge/te/te_3d_texture.cpp
engines/tetraedge/te/te_bezier_curve.cpp
engines/tetraedge/te/te_free_move_zone.cpp
engines/tetraedge/te/te_free_move_zone.h
engines/tetraedge/te/te_lua_thread.cpp
engines/tetraedge/te/te_lua_thread.h
engines/tetraedge/te/te_model.cpp
engines/tetraedge/te/te_model_animation.cpp
engines/tetraedge/te/te_model_vertex_animation.cpp
engines/tetraedge/te/te_pick_mesh2.cpp
engines/tetraedge/te/te_ray_intersection.cpp
engines/tetraedge/te/te_timer.cpp
engines/tetraedge/te/te_timer.h
diff --git a/engines/tetraedge/game/character.cpp b/engines/tetraedge/game/character.cpp
index 1a4d672c7d6..fd8b39755cd 100644
--- a/engines/tetraedge/game/character.cpp
+++ b/engines/tetraedge/game/character.cpp
@@ -42,7 +42,7 @@ void Character::CharacterSettings::clear() {
_name.clear();
_modelFileName.clear();
_defaultScale = TeVector3f32();
- _walkFileName.clear();
+ _idleAnimFileName.clear();
_walkSettings.clear();
_walkSpeed = 0.0f;
_cutSceneCurveDemiPosition = TeVector3f32();
@@ -57,14 +57,14 @@ void Character::WalkSettings::clear() {
}
}
-Character::Character() : _curveOffset(0), _lastFrame(-1), _callbacksChanged(false),
+Character::Character() : _walkCurveStart(0), _lastFrame(-1), _callbacksChanged(false),
_notWalkAnim(false), _someRepeatFlag(false), _walkModeStr("Walk"),
_needsSomeUpdate(false), _positionFlag(false), _lookingAtTallThing(false),
_stepSound1("sounds/SFX/PAS_H_BOIS1.ogg"), _stepSound2("sounds/SFX/PAS_H_BOIS2.ogg"),
_freeMoveZone(nullptr), _animSoundOffset(0), _lastAnimFrame(0), _charLookingAt(nullptr),
-_recallageY(true), _walkToFlag(false), _walkCurveEnd(0.0f), _walkCurveStart(0.0f),
+_recallageY(true), _walkToFlag(false), _walkCurveEnd(0.0f), _walkCurveLast(0.0f),
_walkCurveLen(0.0f), _walkCurveIncrement(0.0f), _walkEndAnimG(false), _walkTotalFrames(0),
-_walkCurveCurOffset(0.0f) {
+_walkCurveNextLength(0.0f) {
_curModelAnim.setDeleteFn(&TeModelAnimation::deleteLater);
}
@@ -92,11 +92,20 @@ Character::~Character() {
}
void Character::addCallback(const Common::String &key, const Common::String &s2, float f1, float f2) {
- /*Callback *c = new Callback();
- c->x = (int)f1;
- c->y = (int)f2;
- c->f = (f2 == -1.0 ? -NAN : 0.0f;*/
- error("TODO: Implement Character::addCallback");
+ Callback *c = new Callback();
+ c->_s = s2;
+ c->_x = (int)f1;
+ c->_y = (int)f2;
+ c->_f = (f2 == -1.0 ? -NAN : 0.0f);
+
+ const Common::String animPath = _model->anim()->_loadedPath.toString();
+ if (_callbacks.contains(animPath)) {
+ _callbacks[animPath].push_back(c);
+ } else {
+ Common::Array<Callback *> callbacks;
+ callbacks.push_back(c);
+ _callbacks.setVal(key, callbacks);
+ }
}
/*static*/ void Character::animCacheFreeAll() {
@@ -137,7 +146,7 @@ float Character::animLength(const TeModelAnimation &modelanim, long bone, long l
return ((endtrans.z() - starttrans.z()) + secondtrans.z()) - starttrans.z();
}
-float Character::animLengthFromFile(const Common::String &animname, uint *pframeCount, uint lastframe) {
+float Character::animLengthFromFile(const Common::String &animname, uint *pframeCount, uint lastframe /* = 9999 */) {
if (animname.empty()) {
*pframeCount = 0;
return 0.0f;
@@ -163,7 +172,7 @@ bool Character::blendAnimation(const Common::String &animname, float amount, boo
Common::Path animpath("models/Anims");
animpath.joinInPlace(animname);
- _notWalkAnim = !(animname.contains(_characterSettings._walkFileName)
+ _notWalkAnim = !(animname.contains(_characterSettings._idleAnimFileName)
|| animname.contains(walkAnim(WalkPart_Start))
|| animname.contains(walkAnim(WalkPart_Loop))
|| animname.contains(walkAnim(WalkPart_EndG))
@@ -175,6 +184,7 @@ bool Character::blendAnimation(const Common::String &animname, float amount, boo
}
_curModelAnim = animCacheLoad(animpath);
+ assert(_curModelAnim);
_curModelAnim->onFinished().add(this, &Character::onModelAnimationFinished);
_curModelAnim->bind(_model);
@@ -190,12 +200,12 @@ TeVector3f32 Character::correctPosition(const TeVector3f32 &pos) {
bool flag;
TeVector3f32 result = _freeMoveZone->correctCharacterPosition(pos, &flag, true);
if (!flag)
- result = _model->position();
+ result.y() = _model->position().y();
return result;
}
float Character::curveOffset() {
- return _curveOffset;
+ return _walkCurveStart;
}
void Character::deleteAllCallback() {
@@ -302,11 +312,11 @@ bool Character::loadModel(const Common::String &mname, bool unused) {
_model->setVisibleByName(_characterSettings._defaultMouth, true);
_model->setVisibleByName(_characterSettings._defaultBody, true);
- setAnimation(_characterSettings._walkFileName, true);
+ setAnimation(_characterSettings._idleAnimFileName, true);
- _walkPart0AnimLen = animLengthFromFile(walkAnim(WalkPart_Start), &_walkPart0AnimFrameCount);
- _walkPart3AnimLen = animLengthFromFile(walkAnim(WalkPart_EndG), &_walkPart3AnimFrameCount);
- _walkPart1AnimLen = animLengthFromFile(walkAnim(WalkPart_Loop), &_walkPart1AnimFrameCount);
+ _walkStartAnimLen = animLengthFromFile(walkAnim(WalkPart_Start), &_walkStartAnimFrameCount);
+ _walkEndGAnimLen = animLengthFromFile(walkAnim(WalkPart_EndG), &_walkEndGAnimFrameCount);
+ _walkLoopAnimLen = animLengthFromFile(walkAnim(WalkPart_Loop), &_walkLoopAnimFrameCount);
TeIntrusivePtr<Te3DTexture> shadow = new Te3DTexture();
shadow->load("models/Textures/simple_shadow_alpha.tga");
@@ -388,9 +398,9 @@ bool Character::onBonesUpdate(const Common::String &boneName, TeMatrix4x4 &boneM
walkSettings._value._walkParts[2]._file == animfile ||
walkSettings._value._walkParts[3]._file == animfile);
}
- resetX |= animfile.contains(_characterSettings._walkFileName);
+ resetX |= animfile.contains(_characterSettings._idleAnimFileName);
} else {
- resetX = (animfile.contains(_characterSettings._walkFileName) ||
+ resetX = (animfile.contains(_characterSettings._idleAnimFileName) ||
animfile.contains(walkAnim(WalkPart_Start)) ||
animfile.contains(walkAnim(WalkPart_Loop)) ||
animfile.contains(walkAnim(WalkPart_EndD)) ||
@@ -444,9 +454,10 @@ bool Character::onBonesUpdate(const Common::String &boneName, TeMatrix4x4 &boneM
bool flag;
pos = _freeMoveZone->correctCharacterPosition(pos, &flag, true);
}
- _shadowModel[1]->setPosition(pos);
- _shadowModel[1]->setRotation(_model->rotation());
- _shadowModel[1]->setScale(_model->scale());
+ int shadowNo = boneName.contains("Bip01 L Foot") ? 0 : 1;
+ _shadowModel[shadowNo]->setPosition(pos);
+ _shadowModel[shadowNo]->setRotation(_model->rotation());
+ _shadowModel[shadowNo]->setScale(_model->scale());
}
// Move any objects attached to the bone
@@ -485,20 +496,21 @@ bool Character::onModelAnimationFinished() {
walkSettings._value._walkParts[2]._file == animfile ||
walkSettings._value._walkParts[3]._file == animfile);
}
- isWalkAnim |= animfile.contains(_characterSettings._walkFileName);
+ isWalkAnim |= animfile.contains(_characterSettings._idleAnimFileName);
} else {
- isWalkAnim = (animfile.contains(_characterSettings._walkFileName) ||
+ isWalkAnim = (animfile.contains(_characterSettings._idleAnimFileName) ||
animfile.contains(walkAnim(WalkPart_Start)) ||
animfile.contains(walkAnim(WalkPart_Loop)) ||
animfile.contains(walkAnim(WalkPart_EndD)) ||
animfile.contains(walkAnim(WalkPart_EndG)));
}
- if (isWalkAnim) {
+ if (!isWalkAnim) {
int pereBone = _curModelAnim->findBone("Pere");
const TeTRS endTRS = trsFromAnim(*_curModelAnim, pereBone, _curModelAnim->lastFrame());
TeVector3f32 trans = endTRS.getTranslation();
trans.x() = -trans.x();
+ trans.y() = 0;
TeVector3f32 newpos;
if (!_recallageY) {
@@ -525,7 +537,7 @@ bool Character::onModelAnimationFinished() {
if (_someRepeatFlag && loadedPath.toString().contains(_setAnimName)) {
_notWalkAnim = false;
_someRepeatFlag = false;
- setAnimation(_characterSettings._walkFileName, true);
+ setAnimation(_characterSettings._idleAnimFileName, true);
}
return false;
@@ -537,7 +549,7 @@ void Character::permanentUpdate() {
void Character::placeOnCurve(TeIntrusivePtr<TeBezierCurve> &curve) {
_curve = curve;
- updatePosition(_curveOffset);
+ updatePosition(_walkCurveStart);
}
void Character::removeAnim() {
@@ -561,7 +573,7 @@ bool Character::setAnimation(const Common::String &aname, bool repeat, bool para
Common::Path animPath("models/Anims");
animPath.joinInPlace(aname);
- bool isWalkAnim = (aname.contains(_characterSettings._walkFileName) ||
+ bool isWalkAnim = (aname.contains(_characterSettings._idleAnimFileName) ||
aname.contains(walkAnim(WalkPart_Start)) ||
aname.contains(walkAnim(WalkPart_Loop)) ||
aname.contains(walkAnim(WalkPart_EndD)) ||
@@ -595,7 +607,7 @@ void Character::setAnimationSound(const Common::String &sname, uint offset) {
}
void Character::setCurveOffset(float offset) {
- _curveOffset = offset;
+ _walkCurveStart = offset;
updatePosition(offset);
}
@@ -669,56 +681,60 @@ void Character::update(double msFromStart) {
if (!_curve || !_runTimer.running())
return;
- _walkCurveCurOffset = speedFromAnim(msFromStart) * _walkCurveIncrement + _walkCurveCurOffset;
+ _walkCurveNextLength = speedFromAnim(msFromStart) * _walkCurveIncrement + _walkCurveNextLength;
if (_curve->controlPoints().size() < 2) {
- blendAnimation(_characterSettings._walkFileName, 0.0667, true, false);
+ blendAnimation(_characterSettings._idleAnimFileName, 0.0667, true, false);
endMove();
return;
}
- const float baseAngle = (_curveOffset > _walkCurveEnd ? M_PI : 0);
- const float sign = (_curveOffset > _walkCurveEnd ? -1 : 1);
- updatePosition(_walkCurveStart);
- const TeVector3f32 modelpos = _model->position();
+ const float baseAngle = (_walkCurveStart > _walkCurveEnd ? M_PI : 0);
+ const float sign = (_walkCurveStart > _walkCurveEnd ? -1 : 1);
+ updatePosition(_walkCurveLast);
float lastWalkedLength = _walkedLength;
- TeVector3f32 lastNextPos = modelpos;
- TeVector3f32 nextPos = modelpos;
- TeVector3f32 newPos = modelpos;
- float lastOffset = _walkCurveStart;
+ TeVector3f32 lastNextPos = _model->position();
+ TeVector3f32 nextPos = _model->position();
+ TeVector3f32 newPos = _model->position();
+ float lastOffset = _walkCurveLast;
- float endOffset = _walkCurveStart;
- while (_walkedLength < _walkCurveCurOffset) {
- float nextOffset = (4.0 / _curve->numIterations()) * sign + lastOffset;
- float offset = CLIP(nextOffset, 0.0f, 1.0f);
+ // First do a coarse search for the position, then back up 1 step and do a finer
+ // search.
- newPos = _curve->retrievePoint(offset) + _curveStartLocation;
- const TeVector2f32 dist = TeVector2f32(nextPos.x(), nextPos.z()) - TeVector2f32(newPos.x(), newPos.z());
+ const float coarseStep = (4.0 / _curve->numIterations()) * sign;
+ const float fineStep = (1.0 / _curve->numIterations()) * sign;
+ float offset = _walkCurveLast;
+ while (_walkedLength < _walkCurveNextLength) {
+ lastOffset = offset;
lastWalkedLength = _walkedLength;
+ lastNextPos = nextPos;
+
+ offset = CLIP(lastOffset + coarseStep, 0.0f, 1.0f);
+
+ newPos = _curve->retrievePoint(offset) + _curveStartLocation;
+ const TeVector2f32 dist = TeVector2f32(nextPos.x(), nextPos.z()) - TeVector2f32(newPos.x(), newPos.z());
_walkedLength += dist.length();
nextPos = newPos;
- endOffset = lastOffset;
if (offset == 1.0 || offset == 0.0)
break;
- lastOffset = offset;
- lastNextPos = nextPos;
}
_walkedLength = lastWalkedLength;
nextPos = lastNextPos;
+ offset = lastOffset;
- while (_walkedLength < _walkCurveCurOffset) {
- float nextOffset = (1.0 / _curve->numIterations()) * sign + endOffset;
- endOffset = CLIP(nextOffset, 0.0f, 1.0f);
+ while (_walkedLength < _walkCurveNextLength) {
+ offset = CLIP(offset + fineStep, 0.0f, 1.0f);
- newPos = _curve->retrievePoint(endOffset) + _curveStartLocation;
+ newPos = _curve->retrievePoint(offset) + _curveStartLocation;
const TeVector2f32 dist = TeVector2f32(nextPos.x(), nextPos.z()) - TeVector2f32(newPos.x(), newPos.z());
_walkedLength += dist.length();
+
nextPos = newPos;
- if (endOffset == 1.0 || endOffset == 0.0)
+ if (offset == 1.0 || offset == 0.0)
break;
}
@@ -727,16 +743,19 @@ void Character::update(double msFromStart) {
newPos = _freeMoveZone->correctCharacterPosition(newPos, &correctflag, true);
}
- _walkCurveStart = endOffset;
+ debug("Character::update %4d %.04f %s -> %s %.4f", (int)msFromStart, offset, _model->position().dump().c_str(),
+ newPos.dump().c_str(), (newPos - _model->position()).length());
+
+ _walkCurveLast = offset;
_model->setPosition(newPos);
TeVector3f32 t1;
TeVector3f32 t2;
- _curve->pseudoTangent(endOffset, t1, t2);
+ _curve->pseudoTangent(offset, t1, t2);
const TeVector3f32 normalizedTangent = (t2 - t1).getNormalized();
float angle = TeVector3f32(0.0, 0.0, 1.0).dotProduct(normalizedTangent);
- TeVector3f32 crossprod = TeVector3f32::crossProduct(TeVector3f32(0.0, 0.0, 1.0), normalizedTangent);
angle = acos(angle);
+ TeVector3f32 crossprod = TeVector3f32::crossProduct(TeVector3f32(0.0, 0.0, 1.0), normalizedTangent);
if (crossprod.y() >= 0.0f) {
angle = -angle;
}
@@ -745,13 +764,13 @@ void Character::update(double msFromStart) {
_model->setRotation(rot);
const Common::String endGAnim = walkAnim(WalkPart_EndG);
- if (_walkCurveStart == _walkCurveEnd || fabs(_walkCurveEnd - _curveOffset) < fabs(_walkCurveStart - _curveOffset)) {
+ if (_walkCurveLast == _walkCurveEnd || fabs(_walkCurveEnd - _walkCurveStart) < fabs(_walkCurveLast - _walkCurveStart)) {
if (_walkToFlag) {
_walkToFlag = false;
endMove();
}
if (endGAnim.empty()) {
- blendAnimation(_characterSettings._walkFileName, 0.0667, true, false);
+ blendAnimation(_characterSettings._idleAnimFileName, 0.0667, true, false);
endMove();
}
}
@@ -807,44 +826,45 @@ Common::String Character::walkAnim(Character::WalkPart part) {
void Character::walkMode(const Common::String &mode) {
if (_walkModeStr != mode)
_walkModeStr = mode;
- _walkPart0AnimLen = animLengthFromFile(walkAnim(WalkPart_Start), &_walkPart0AnimFrameCount, 9999);
- _walkPart3AnimLen = animLengthFromFile(walkAnim(WalkPart_EndG), &_walkPart3AnimFrameCount, 9999);
- _walkPart1AnimLen = animLengthFromFile(walkAnim(WalkPart_Loop), &_walkPart1AnimFrameCount, 9999);
+ _walkStartAnimLen = animLengthFromFile(walkAnim(WalkPart_Start), &_walkStartAnimFrameCount);
+ _walkEndGAnimLen = animLengthFromFile(walkAnim(WalkPart_EndG), &_walkEndGAnimFrameCount);
+ _walkLoopAnimLen = animLengthFromFile(walkAnim(WalkPart_Loop), &_walkLoopAnimFrameCount);
}
void Character::walkTo(float curveEnd, bool walkFlag) {
_walkToFlag = walkFlag;
stop();
_walkCurveEnd = curveEnd;
- _walkCurveStart = _curveOffset;
- _walkCurveCurOffset = 0.0f;
+ _walkCurveLast = _walkCurveStart;
+ _walkCurveNextLength = 0.0f;
_walkedLength = 0.0f;
- const float f = (walkFlag ? _walkPart3AnimLen : 0);
+ assert(_curve);
if (_curve->controlPoints().size()) {
+ const float walkEndLen = (walkFlag ? 0 : _walkEndGAnimLen);
_walkCurveLen = _curve->length();
_walkEndAnimG = false;
- const float f2 = ((_walkCurveLen - f) - _walkPart0AnimLen) / _walkPart1AnimLen;
+ const float nloops = (_walkCurveLen - (walkEndLen + _walkStartAnimLen)) / _walkLoopAnimLen;
float animLen;
- if (f2 >= 0) {
+ if (nloops >= 0) {
Game *game = g_engine->getGame();
if (game->scene()._character == this && _walkModeStr == "Walk") {
- int part1len = (int)(f2 * _walkPart1AnimFrameCount);
- int repeats = part1len / _walkPart1AnimFrameCount;
- uint remainder = part1len % _walkPart1AnimFrameCount;
+ int looplen = (int)(nloops * _walkLoopAnimFrameCount);
+ int repeats = looplen / _walkLoopAnimFrameCount;
+ uint remainder = looplen % _walkLoopAnimFrameCount;
uint framecounts[4];
if (repeats == 0)
framecounts[0] = UINT_MAX;
else
- framecounts[0] = (repeats - 1) * _walkPart1AnimFrameCount + 29;
+ framecounts[0] = (repeats - 1) * _walkLoopAnimFrameCount + 29;
- framecounts[1] = _walkPart1AnimFrameCount * repeats + 13;
- framecounts[2] = _walkPart1AnimFrameCount * repeats + 29;
- framecounts[3] = _walkPart1AnimFrameCount * (repeats + 1) + 13;
+ framecounts[1] = _walkLoopAnimFrameCount * repeats + 13;
+ framecounts[2] = _walkLoopAnimFrameCount * repeats + 29;
+ framecounts[3] = _walkLoopAnimFrameCount * (repeats + 1) + 13;
for (int i = 0; i < 4; i++) {
- framecounts[i] = abs((int)(framecounts[i] - (int)(f2 * _walkPart1AnimFrameCount)));
+ framecounts[i] = abs((int)(framecounts[i] - (int)(nloops * _walkLoopAnimFrameCount)));
}
int minoffset = 0;
@@ -870,26 +890,25 @@ void Character::walkTo(float curveEnd, bool walkFlag) {
remainder = 13;
repeats++;
}
- _walkTotalFrames = _walkPart1AnimFrameCount * repeats + _walkPart0AnimFrameCount + remainder;
- animLen = _walkPart1AnimLen;
+ _walkTotalFrames = _walkLoopAnimFrameCount * repeats + _walkStartAnimFrameCount + remainder;
const float loopAnimLen = animLengthFromFile(walkAnim(WalkPart_Loop), &remainder, remainder);
- _walkCurveIncrement = _walkCurveLen / (repeats * animLen + f + _walkPart0AnimLen + loopAnimLen);
+ _walkCurveIncrement = _walkCurveLen / (repeats * _walkLoopAnimLen + walkEndLen + _walkStartAnimLen + loopAnimLen);
play();
return; // NOTE: early return here.
} else {
double intpart;
- double remainder = modf(f, &intpart);
+ double remainder = modf(walkEndLen, &intpart);
if (remainder >= 0.5) {
_walkEndAnimG = true;
intpart += 0.75;
} else {
intpart += 0.25;
}
- _walkTotalFrames = (int)(_walkPart1AnimFrameCount * intpart) + _walkPart0AnimFrameCount;
- animLen = f + (float)_walkPart0AnimLen + intpart * _walkPart1AnimLen;
+ _walkTotalFrames = (int)(_walkLoopAnimFrameCount * intpart) + _walkStartAnimFrameCount;
+ animLen = walkEndLen + (float)_walkStartAnimLen + intpart * _walkLoopAnimLen;
}
} else {
- animLen = (float)(_walkPart0AnimLen + _walkPart3AnimLen);
+ animLen = (float)(_walkStartAnimLen + _walkEndGAnimLen);
}
_walkCurveIncrement = _walkCurveLen / animLen;
}
diff --git a/engines/tetraedge/game/character.h b/engines/tetraedge/game/character.h
index 71508f03637..b8111e0cfdb 100644
--- a/engines/tetraedge/game/character.h
+++ b/engines/tetraedge/game/character.h
@@ -61,7 +61,7 @@ public:
Common::String _name;
Common::String _modelFileName;
TeVector3f32 _defaultScale;
- Common::String _walkFileName;
+ Common::String _idleAnimFileName;
Common::HashMap<Common::String, WalkSettings> _walkSettings; // keys are "Walk", "Jog", etc
float _walkSpeed;
@@ -86,10 +86,10 @@ public:
};
struct Callback {
- int x;
- Common::String s;
- int y;
- float f;
+ int _x;
+ Common::String _s;
+ int _y;
+ float _f;
};
void addCallback(const Common::String &s1, const Common::String &s2, float f1, float f2);
@@ -171,14 +171,15 @@ public:
Character *charLookingAt() { return _charLookingAt; }
bool lookingAtTallThing() const { return _lookingAtTallThing; }
void setLookingAtTallThing(bool val) { _lookingAtTallThing = val; }
+ TeIntrusivePtr<TeBezierCurve> curve() { return _curve; }
private:
- float _curveOffset;
float _walkCurveStart;
+ float _walkCurveLast;
float _walkCurveEnd;
float _walkCurveLen;
float _walkCurveIncrement;
- float _walkCurveCurOffset;
+ float _walkCurveNextLength;
float _walkedLength;
int _walkTotalFrames;
bool _walkToFlag;
@@ -201,13 +202,13 @@ private:
CharacterSettings _characterSettings;
- int _walkPart0AnimLen;
- int _walkPart1AnimLen;
- int _walkPart3AnimLen;
+ float _walkStartAnimLen;
+ float _walkLoopAnimLen;
+ float _walkEndGAnimLen;
- uint32 _walkPart0AnimFrameCount;
- uint32 _walkPart1AnimFrameCount;
- uint32 _walkPart3AnimFrameCount;
+ uint32 _walkStartAnimFrameCount;
+ uint32 _walkLoopAnimFrameCount;
+ uint32 _walkEndGAnimFrameCount;
int _lastFrame;
int _lastAnimFrame;
diff --git a/engines/tetraedge/game/character_settings_xml_parser.cpp b/engines/tetraedge/game/character_settings_xml_parser.cpp
index 2c306c32351..abb8fc55d68 100644
--- a/engines/tetraedge/game/character_settings_xml_parser.cpp
+++ b/engines/tetraedge/game/character_settings_xml_parser.cpp
@@ -141,7 +141,7 @@ bool CharacterSettingsXmlParser::textCallback(const Common::String &val) {
_curCharacter->_defaultScale.parse(val);
break;
case TagAnimationFileName:
- _curCharacter->_walkFileName = val;
+ _curCharacter->_idleAnimFileName = val;
break;
case TagEyes:
_curCharacter->_defaultEyes = val;
diff --git a/engines/tetraedge/game/dialog2.cpp b/engines/tetraedge/game/dialog2.cpp
index 07847b0845d..8b210514963 100644
--- a/engines/tetraedge/game/dialog2.cpp
+++ b/engines/tetraedge/game/dialog2.cpp
@@ -19,7 +19,10 @@
*
*/
+#include "tetraedge/tetraedge.h"
#include "tetraedge/game/dialog2.h"
+#include "tetraedge/game/game.h"
+#include "tetraedge/game/character.h"
#include "tetraedge/te/te_button_layout.h"
namespace Tetraedge {
@@ -39,7 +42,53 @@ bool Dialog2::isDialogPlaying() {
}
void Dialog2::launchNextDialog() {
- error("TODO: Implement Dialog2::launchNextDialog.");
+ Game *game = g_engine->getGame();
+ if (_dialogs.empty()) {
+ game->showMarkers(false);
+ _gui.buttonLayoutChecked("dialogLockButton")->setVisible(false);
+ return;
+ }
+
+ TeButtonLayout *dialog = _gui.buttonLayoutChecked("dialog");
+ if (dialog->anchor().y() >= 1.0) {
+ TeCurveAnim2<TeLayout, TeVector3f32> *anim = _gui.layoutAnchorLinearAnimation("dialogAnimationDown");
+ anim->stop();
+ anim->play();
+ } else {
+ dialog->setSizeType(CoordinatesType::ABSOLUTE);
+ TeButtonLayout *lockBtn = _gui.buttonLayoutChecked("dialogLockButton");
+ dialog->setSize(lockBtn->size());
+ _currentDialogData = _dialogs.front();
+ _dialogs.remove_at(0);
+ const Common::String formatStr = _gui.value("textFormat").toString();
+ Common::String formattedVal = Common::String::format(formatStr.c_str(), _currentDialogData._stringVal.c_str());
+ _gui.textLayout("text")->setText(formattedVal);
+ _music.load(_currentDialogData._sound.toString());
+ _music.setChannelName("dialog");
+ _music.play();
+ if (!_currentDialogData._charname.empty()) {
+ Character *c = game->scene().character(_currentDialogData._charname);
+ if (!c) {
+ error("[Dialog2::launchNextDialog] Character's \"%s\" doesn\'t exist", _currentDialogData._charname.c_str());
+ }
+
+ if (_currentDialogData._animBlend == 0.0f) {
+ if (!c->setAnimation(_currentDialogData._animfile, false))
+ error("[Dialog2::launchNextDialog] Character's animation \"%s\" doesn't exist for the character\"%s\" \n",
+ _currentDialogData._animfile.c_str(), _currentDialogData._charname.c_str());
+ } else {
+ if (!c->blendAnimation(_currentDialogData._animfile, _currentDialogData._animBlend, false, true))
+ error("[Dialog2::launchNextDialog] Character's animation \"%s\" doesn't exist for the character\"%s\" \n",
+ _currentDialogData._animfile.c_str(), _currentDialogData._charname.c_str());
+ }
+ }
+ _gui.buttonLayoutChecked("dialogLockButton")->setVisible(true);
+ TeCurveAnim2<TeLayout, TeVector3f32> *anim = _gui.layoutAnchorLinearAnimation("dialogAnimationDown");
+ anim->stop();
+ anim->play();
+ _minimumTimeTimer.start();
+ _minimumTimeTimer.setAlarmIn(1500000);
+ }
}
void Dialog2::load() {
@@ -115,13 +164,29 @@ bool Dialog2::onSoundFinished() {
return false;
}
-void Dialog2::pushDialog(const Common::String ¶m_1, const Common::String ¶m_2, const Common::String ¶m_3, int param_4) {
+void Dialog2::pushDialog(const Common::String &name, const Common::String &textVal, const Common::String &sound, int param_4) {
error("TODO: Implement Dialog2::pushDialog");
}
-void Dialog2::pushDialog(const Common::String ¶m_1, const Common::String ¶m_2, const Common::String ¶m_3,
- const Common::String ¶m_4, const Common::String ¶m_5, float param_6) {
- error("TODO: Implement Dialog2::pushDialog");
+void Dialog2::pushDialog(const Common::String &name, const Common::String &textVal, const Common::String &sound,
+ const Common::String &charname, const Common::String &animfile, float animBlend) {
+ DialogData data;
+ data._name = name;
+ data._stringVal = textVal;
+ data._charname = charname;
+ data._animfile = animfile;
+ data._sound = Common::Path("sounds/Dialogs").join(sound);
+ data._animBlend = animBlend;
+ if (sound.empty()) {
+ data._sound = Common::Path("sounds/dialogs/silence5s.ogg");
+ }
+ _dialogs.push_back(data);
+ if (_dialogs.size() == 1) {
+ Game *game = g_engine->getGame();
+ game->showMarkers(true);
+ }
+ if (!_music.isPlaying())
+ launchNextDialog();
}
//void saveToBackup(TiXmlNode *node)
diff --git a/engines/tetraedge/game/dialog2.h b/engines/tetraedge/game/dialog2.h
index 9e2a8f025ad..a4c4a269a29 100644
--- a/engines/tetraedge/game/dialog2.h
+++ b/engines/tetraedge/game/dialog2.h
@@ -32,8 +32,13 @@ class Dialog2 : public TeLayout {
public:
Dialog2();
- class DialogData {
- bool operator=(const DialogData &other);
+ struct DialogData {
+ Common::String _name;
+ Common::String _stringVal;
+ Common::Path _sound;
+ Common::String _charname;
+ Common::String _animfile;
+ float _animBlend;
};
bool isDialogPlaying();
@@ -46,9 +51,9 @@ public:
bool onSkipButton();
bool onSoundFinished();
- void pushDialog(const Common::String ¶m_1, const Common::String ¶m_2, const Common::String ¶m_3, int param_4);
- void pushDialog(const Common::String ¶m_1, const Common::String ¶m_2, const Common::String ¶m_3,
- const Common::String ¶m_4, const Common::String ¶m_5, float param_6);
+ void pushDialog(const Common::String &name, const Common::String &textVal, const Common::String &sound, int param_4);
+ void pushDialog(const Common::String &name, const Common::String &textVal, const Common::String &sound,
+ const Common::String &charName, const Common::String &animFile, float animBlend);
//void saveToBackup(TiXmlNode *node)
void startDownAnimation();
void unload();
@@ -58,6 +63,8 @@ public:
Common::String prevSceneName() { return _prevSceneName; };
private:
+ Common::Array<DialogData> _dialogs;
+
TeTimer _minimumTimeTimer;
Common::String _prevSceneName;
@@ -65,6 +72,8 @@ private:
TeLuaGUI _gui;
TeMusic _music;
+
+ DialogData _currentDialogData;
TeSignal1Param<const Common::String &> _onAnimationDownFinishedSignal;
};
diff --git a/engines/tetraedge/game/game.cpp b/engines/tetraedge/game/game.cpp
index 9c06be767a0..b65287d92d0 100644
--- a/engines/tetraedge/game/game.cpp
+++ b/engines/tetraedge/game/game.cpp
@@ -439,7 +439,7 @@ bool Game::initWarp(const Common::String &zone, const Common::String &scene, boo
_scene._character->_model->setVisible(true);
_scene._character->deleteAllCallback();
_scene._character->stop();
- _scene._character->setAnimation(_scene._character->characterSettings()._walkFileName, true);
+ _scene._character->setAnimation(_scene._character->characterSettings()._idleAnimFileName, true);
if (!_scene.findKate()) {
_scene.models().push_back(_scene._character->_model);
_scene.models().push_back(_scene._character->_shadowModel[0]);
@@ -648,10 +648,31 @@ bool Game::isMoviePlaying() {
return false;
}
+static const char *DIALOG_IDS[20] = {
+ "KFJ1", "KH", "KJ", "KL",
+ "KO", "KS", "KCa", "KFE2",
+ "KFE3", "KG", "KMa", "KP",
+ "KR", "KCo", "KD", "KA",
+ "KFJ", "KM", "KN", "KFM"};
+
bool Game::launchDialog(const Common::String &dname, uint param_2, const Common::String &charname,
const Common::String &animfile, float param_5) {
- error("TODO: Implemet Game::launchDialog %s %d %s %s %f", dname.c_str(),
- param_2, charname.c_str(), animfile.c_str(), param_5);
+ Application *app = g_engine->getApplication();
+ const Common::String *locdname = app->_loc.value(dname);
+ if (!locdname)
+ locdname = &dname;
+
+ if (!locdname)
+ return false;
+
+ for (unsigned int i = 0; i < ARRAYSIZE(DIALOG_IDS); i++) {
+ if (dname.contains(Common::String::format("_%s_", DIALOG_IDS[i])))
+ _dialogsTold++;
+ }
+
+ const Common::String sndfile = dname + ".ogg";
+ _dialog2.pushDialog(*locdname, *locdname, sndfile, charname, animfile, param_5);
+ return true;
}
void Game::leave(bool flag) {
@@ -793,7 +814,7 @@ bool Game::onCharacterAnimationPlayerFinished(const Common::String &anim) {
|| curAnimName == character->walkAnim(Character::WalkPart_EndG))
character->stop();
} else {
- if (!_sceneCharacterVisibleFromLoad && curAnimName != character->walkAnim(Character::WalkPart_Start)) {
+ if (!_sceneCharacterVisibleFromLoad && curAnimName == character->walkAnim(Character::WalkPart_Start)) {
character->setAnimation(character->walkAnim(Character::WalkPart_Loop), true);
return false;
}
@@ -802,7 +823,7 @@ bool Game::onCharacterAnimationPlayerFinished(const Common::String &anim) {
character->updatePosition(1.0);
character->endMove();
// Note: original checks walkAnim again.. is there a reason to do that?
- character->setAnimation(character->characterSettings()._walkFileName, true);
+ character->setAnimation(character->characterSettings()._idleAnimFileName, true);
}
}
@@ -831,7 +852,7 @@ bool Game::onDialogFinished(const Common::String &val) {
bool Game::onDisplacementFinished() {
_sceneCharacterVisibleFromLoad = true;
_scene._character->stop();
- _scene._character->setAnimation(_scene._character->characterSettings()._walkFileName, true);
+ _scene._character->setAnimation(_scene._character->characterSettings()._idleAnimFileName, true);
if (!_isCharacterWalking) {
_isCharacterWalking = false;
@@ -941,7 +962,7 @@ bool Game::onMouseClick(const Common::Point &pt) {
Character *character = _scene._character;
const Common::String &charAnim = character->curAnimName();
- if (charAnim == character->characterSettings()._walkFileName
+ if (charAnim == character->characterSettings()._idleAnimFileName
|| charAnim == character->walkAnim(Character::WalkPart_Start)
|| charAnim == character->walkAnim(Character::WalkPart_Loop)
|| charAnim == character->walkAnim(Character::WalkPart_EndD)
@@ -987,7 +1008,7 @@ bool Game::onMouseClick(const Common::Point &pt) {
_posPlayer = lastPoint;
}
- if (!_sceneCharacterVisibleFromLoad || (character->curAnimName() == character->characterSettings()._walkFileName)) {
+ if (!_sceneCharacterVisibleFromLoad || (character->curAnimName() == character->characterSettings()._idleAnimFileName)) {
_lastCharMoveMousePos = TeVector2s32(0, 0);
_movePlayerCharacterDisabled = true;
_isCharacterWalking = false;
@@ -1456,7 +1477,7 @@ void Game::update() {
charAnim == _scene._character->walkAnim(Character::WalkPart_Loop) ||
charAnim == _scene._character->walkAnim(Character::WalkPart_EndD) ||
charAnim == _scene._character->walkAnim(Character::WalkPart_EndG) ||
- charAnim == _scene._character->characterSettings()._walkFileName);
+ charAnim == _scene._character->characterSettings()._idleAnimFileName);
app->lockCursor(!unlockCursor);
}
}
diff --git a/engines/tetraedge/game/in_game_scene.cpp b/engines/tetraedge/game/in_game_scene.cpp
index 5be7a135c84..6df97b971d5 100644
--- a/engines/tetraedge/game/in_game_scene.cpp
+++ b/engines/tetraedge/game/in_game_scene.cpp
@@ -42,6 +42,8 @@
#include "tetraedge/te/te_lua_script.h"
#include "tetraedge/te/te_lua_thread.h"
+#define DEBUG_PATHFINDING 1
+
namespace Tetraedge {
InGameScene::InGameScene() : _character(nullptr), _charactersShadow(nullptr),
@@ -338,6 +340,19 @@ void InGameScene::draw() {
return;
currentCamera()->apply();
+
+#if DEBUG_PATHFINDING
+ if (_character && _character->curve()) {
+ _character->curve()->setVisible(true);
+ _character->curve()->draw();
+ }
+
+ for (TeFreeMoveZone *zone : _freeMoveZones) {
+ zone->setVisible(true);
+ zone->draw();
+ }
+#endif
+
TeLight::updateGlobal();
for (unsigned int i = 0; i < _lights.size(); i++)
_lights[i].update(i);
@@ -920,8 +935,8 @@ void InGameScene::setPositionCharacter(const Common::String &charName, const Com
TeFreeMoveZone *zone = pathZone(freeMoveZoneName);
if (!zone) {
warning("[SetCharacterPosition] PathZone not found %s", freeMoveZoneName.c_str());
- for (TeFreeMoveZone *zone : _freeMoveZones)
- warning("zone: %s", zone->name().c_str());
+ for (TeFreeMoveZone *z : _freeMoveZones)
+ warning("zone: %s", z->name().c_str());
return;
}
TeIntrusivePtr<TeCamera> cam = currentCamera();
@@ -973,7 +988,13 @@ void InGameScene::unloadCharacter(const Common::String &name) {
}
void InGameScene::unloadObject(const Common::String &name) {
- error("TODO: InGameScene::unloadObject");
+ for (unsigned int i = 0; i < _object3Ds.size(); i++) {
+ if (_object3Ds[i]->model()->name() == name) {
+ _object3Ds[i]->deleteLater();
+ _object3Ds.remove_at(i);
+ break;
+ }
+ }
}
void InGameScene::unloadSpriteLayouts() {
diff --git a/engines/tetraedge/game/inventory.cpp b/engines/tetraedge/game/inventory.cpp
index 792333c9e7e..6b42aebf130 100644
--- a/engines/tetraedge/game/inventory.cpp
+++ b/engines/tetraedge/game/inventory.cpp
@@ -42,7 +42,7 @@ void Inventory::enter() {
Game *game = g_engine->getGame();
Character *character = game->scene()._character;
character->stop();
- character->setAnimation(character->characterSettings()._walkFileName, true);
+ character->setAnimation(character->characterSettings()._idleAnimFileName, true);
_gui.layoutChecked("textObject")->setVisible(false);
if (!game->_firstInventory) {
@@ -188,9 +188,62 @@ void Inventory::addObject(const Common::String &objId) {
}
bool Inventory::addObject(InventoryObject &obj) {
- _invObjects.push_back(&obj);
+ _invObjects.push_front(&obj);
obj.selectedSignal().add(this, &Inventory::onObjectSelected);
- error("TODO: implement Inventory::addObject.");
+ if (_invObjects.size() > 1) {
+ int pageno = 0;
+ while (true) {
+ TeLayout *page = _gui.layout(Common::String::format("page%d", pageno));
+ int slotno = 0;
+ if (!page)
+ break;
+ while (true) {
+ TeLayout *slot = _gui.layout(Common::String::format("page%dSlot%d", pageno, slotno));
+ if (!slot)
+ break;
+ for (unsigned int c = 0; c < slot->childCount(); c++) {
+ Te3DObject2 *child = slot->child(c);
+ InventoryObject *obj = dynamic_cast<InventoryObject *>(child);
+ if (obj) {
+ slot->removeChild(child);
+ c--;
+ }
+ }
+ }
+ pageno++;
+ }
+ }
+
+ int pageno = 0;
+ unsigned int totalSlots = 0;
+ bool retval;
+ while (true) {
+ TeLayout *page = _gui.layout(Common::String::format("page%d", pageno));
+ retval = false;
+ if (!page)
+ break;
+ int slotno = 0;
+ while (true) {
+ TeLayout *slot = _gui.layout(Common::String::format("page%dSlot%d", pageno, slotno));
+ if (!slot)
+ break;
+ retval = true;
+
+ if (totalSlots == _invObjects.size()) {
+ // break from both loops (slight hack..)
+ pageno = 9999;
+ break;
+ }
+
+ TeTextLayout *newText = new TeTextLayout();
+ error("TODO: finish Inventory::addObject.");
+
+ totalSlots++;
+ slotno++;
+ }
+ pageno++;
+ }
+ return retval;
}
bool Inventory::isDocument(const Common::String &objId) {
diff --git a/engines/tetraedge/game/inventory.h b/engines/tetraedge/game/inventory.h
index aa81722db0e..53661da3ae5 100644
--- a/engines/tetraedge/game/inventory.h
+++ b/engines/tetraedge/game/inventory.h
@@ -84,7 +84,7 @@ private:
void loadXMLFile(const Common::Path &path);
TeLuaGUI _gui;
- Common::Array<InventoryObject *> _invObjects;
+ Common::List<InventoryObject *> _invObjects;
Cellphone *_cellphone;
InventoryObject *_selectedObject;
Common::HashMap<Common::String, InventoryObjectData> _objectData;
diff --git a/engines/tetraedge/game/inventory_object.cpp b/engines/tetraedge/game/inventory_object.cpp
index f12e169b6fb..8bf17bc5662 100644
--- a/engines/tetraedge/game/inventory_object.cpp
+++ b/engines/tetraedge/game/inventory_object.cpp
@@ -26,12 +26,12 @@ namespace Tetraedge {
InventoryObject::InventoryObject() {
}
-void InventoryObject::load(const Common::String &name) {
+void InventoryObject::load(const Common::String &newName) {
setSizeType(RELATIVE_TO_PARENT);
setSize(TeVector3f32(1.0f, 1.0f, 1.0f));
_gui.load("Inventory/InventoryObject.lua");
addChild(_gui.layoutChecked("object"));
- setName(name);
+ setName(newName);
_gui.spriteLayoutChecked("upLayout")->load(spritePath());
TeButtonLayout *btn = _gui.buttonLayoutChecked("object");
btn->onMouseClickValidated().add(this, &InventoryObject::onButtonDown);
diff --git a/engines/tetraedge/game/inventory_object.h b/engines/tetraedge/game/inventory_object.h
index 5464f813811..ccee9fe5a14 100644
--- a/engines/tetraedge/game/inventory_object.h
+++ b/engines/tetraedge/game/inventory_object.h
@@ -28,7 +28,7 @@
namespace Tetraedge {
-class InventoryObject : TeLayout {
+class InventoryObject : public TeLayout {
public:
InventoryObject();
@@ -37,9 +37,7 @@ public:
bool onButtonDown();
TeSignal1Param<InventoryObject&> &selectedSignal() { return _selectedSignal; };
- const Common::String &name() const { return _name; }
private:
- Common::String _name;
TeLuaGUI _gui;
TeSignal1Param<InventoryObject&> _selectedSignal;
};
diff --git a/engines/tetraedge/game/lua_binds.cpp b/engines/tetraedge/game/lua_binds.cpp
index 1c11e704b0f..290d94b2546 100644
--- a/engines/tetraedge/game/lua_binds.cpp
+++ b/engines/tetraedge/game/lua_binds.cpp
@@ -27,6 +27,7 @@
#include "tetraedge/game/lua_binds.h"
#include "tetraedge/game/object3d.h"
#include "tetraedge/to_lua.h"
+#include "tetraedge/te/te_lua_thread.h"
namespace Tetraedge {
@@ -90,6 +91,40 @@ static int tolua_ExportedFunctions_SetSoundStep00(lua_State *L) {
error("#ferror in function 'SetSoundStep': %d %d %s", err.index, err.array, err.type);
}
+static bool Selected(const Common::String &obj) {
+ Game *game = g_engine->getGame();
+ return game->inventory().selectedObject() == obj;
+}
+
+static int tolua_ExportedFunctions_Selected00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isnoobj(L, 2, &err)) {
+ Common::String s1(tolua_tostring(L, 1, nullptr));
+ bool result = Selected(s1);
+ tolua_pushboolean(L, result);
+ return 1;
+ }
+ error("#ferror in function 'Selected': %d %d %s", err.index, err.array, err.type);
+}
+
+static void TakeObject(const Common::String &obj) {
+ Game *game = g_engine->getGame();
+ warning("TODO: Set global _lastHitObjectName");
+ //game->luaContext().setGlobal(_lastHitObjectName, true);
+ if (!obj.empty())
+ game->addToBag(obj);
+}
+
+static int tolua_ExportedFunctions_TakeObject00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isnoobj(L, 2, &err)) {
+ Common::String s1(tolua_tostring(L, 1, nullptr));
+ TakeObject(s1);
+ return 0;
+ }
+ error("#ferror in function 'TakeObject': %d %d %s", err.index, err.array, err.type);
+}
+
static void AddNumber(const Common::String &number) {
Game *game = g_engine->getGame();
if (!game->inventory().cellphone()->addNumber(number))
@@ -191,6 +226,32 @@ static int tolua_ExportedFunctions_MoveCharacterPlayerDisabled00(lua_State *L) {
error("#ferror in function 'MoveCharacterPlayerDisabled': %d %d %s", err.index, err.array, err.type);
}
+static void AddCallback(const Common::String &charName, const Common::String &key, const Common::String &s1, float f1, float f2) {
+ Game *game = g_engine->getGame();
+ Character *c = game->scene().character(charName);
+ if (c) {
+ c->addCallback(key, s1, f1, f2);
+ } else {
+ warning("[AddCallback] Character's \"%s\" doesn't exist", charName.c_str());
+ }
+}
+
+static int tolua_ExportedFunctions_AddCallback00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isstring(L, 2, 0, &err)
+ && tolua_isstring(L, 3, 0, &err) && tolua_isnumber(L, 4, 0, &err)
+ && tolua_isnumber(L, 5, 1, &err) && tolua_isnoobj(L, 6, &err)) {
+ Common::String s1(tolua_tostring(L, 1, nullptr));
+ Common::String s2(tolua_tostring(L, 2, nullptr));
+ Common::String s3(tolua_tostring(L, 2, nullptr));
+ double n1 = tolua_tonumber(L, 3, 0.0);
+ double n2 = tolua_tonumber(L, 4, -1.0);
+ AddCallback(s1, s2, s3, n1, n2);
+ return 0;
+ }
+ error("#ferror in function 'AddMarker': %d %d %s", err.index, err.array, err.type);
+}
+
static void AddMarker(const Common::String &markerName, const Common::String &imgPath, float x, float y,
const Common::String &loctype, const Common::String &markerVal) {
Game *game = g_engine->getGame();
@@ -371,7 +432,6 @@ static int tolua_ExportedFunctions_UnloadObject00(lua_State *L) {
}
static void SetCharacterRotation(const Common::String &charname, float rx, float ry, float rz) {
- // TODO: check if this is good.
TeQuaternion quat = TeQuaternion::fromEuler(TeVector3f32(rx * M_PI / 180.0, ry * M_PI / 180.0, rz * M_PI / 180.0));
Game *game = g_engine->getGame();
Character *c = game->scene().character(charname);
@@ -397,6 +457,60 @@ static int tolua_ExportedFunctions_SetCharacterRotation00(lua_State *L) {
error("#ferror in function 'SetCharacterRotation': %d %d %s", err.index, err.array, err.type);
}
+static void SetCharacterOrientation(const Common::String &charname, float x, float y) {
+ Game *game = g_engine->getGame();
+ Character *c = game->scene().character(charname);
+ if (c) {
+ const TeVector3f32 pos = c->_model->position();
+ TeVector3f32 euler(0, atan2f(abs(x - pos.x()), y - pos.z()), 0);
+ c->_model->setRotation(TeQuaternion::fromEuler(euler));
+ } else {
+ warning("[SetCharacterRotation] Character not found %s", charname.c_str());
+ }
+}
+
+static int tolua_ExportedFunctions_SetCharacterOrientation00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isnumber(L, 2, 0, &err)
+ && tolua_isnumber(L, 3, 0, &err) && tolua_isnoobj(L, 4, &err)) {
+ Common::String s1(tolua_tostring(L, 1, nullptr));
+ float f1 = tolua_tonumber(L, 2, 0.0);
+ float f2 = tolua_tonumber(L, 3, 0.0);
+ SetCharacterOrientation(s1, f1, f2);
+ return 0;
+ }
+ error("#ferror in function 'SetCharacterOrientation': %d %d %s", err.index, err.array, err.type);
+}
+
+static void SetCharacterAnimation(const Common::String &charname, const Common::String &animname, bool repeat, bool b2, int i1, int i2) {
+ Game *game = g_engine->getGame();
+ Character *c = game->scene().character(charname);
+ bool result = c->setAnimation(animname, repeat, b2, i1, i2);
+ if (!result) {
+ warning("[SetCharacterAnimation] Character's animation \"%s\" doesn't exist for the character\"%s\" ",
+ animname.c_str(), charname.c_str());
+ }
+}
+
+static int tolua_ExportedFunctions_SetCharacterAnimation00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isstring(L, 2, 0, &err)
+ && tolua_isboolean(L, 3, 1, &err) && tolua_isboolean(L, 4, 1, &err)
+ && tolua_isnumber(L, 5, 1, &err) && tolua_isnumber(L, 6, 1, &err)
+ && tolua_isnoobj(L, 7, &err)) {
+ Common::String s1(tolua_tostring(L, 1, nullptr));
+ Common::String s2(tolua_tostring(L, 2, nullptr));
+ bool b1 = tolua_toboolean(L, 3, 1);
+ bool b2 = tolua_toboolean(L, 4, 0);
+ double f3 = tolua_tonumber(L, 5, -1.0);
+ double f4 = tolua_tonumber(L, 6, 9999.0);
+ SetCharacterAnimation(s1, s2, b1, b2, (int)f3, (int)f4);
+ return 0;
+ }
+ error("#ferror in function 'SetCharacterAnimation': %d %d %s", err.index, err.array, err.type);
+}
+
+
static void SetCharacterPosition(const Common::String &charname, const Common::String &zonename, float f1, float f2, float f3) {
Game *game = g_engine->getGame();
game->scene().setPositionCharacter(charname, zonename, TeVector3f32(f1, f2, f3));
@@ -488,6 +602,58 @@ static int tolua_ExportedFunctions_SetBackground00(lua_State *L) {
error("#ferror in function 'SetBackground': %d %d %s", err.index, err.array, err.type);
}
+static void LaunchDialog(const Common::String &name, uint param_2, const Common::String &charname,
+ const Common::String &animfile, float param_5) {
+ Game *game = g_engine->getGame();
+
+ if (!game->launchDialog(name, param_2, charname, animfile, param_5))
+ warning("[LaunchDialog] Dialog \"%s\" doesn't exist.", name.c_str());
+}
+
+static int tolua_ExportedFunctions_LaunchDialog00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isnumber(L, 2, 1, &err)
+ && tolua_isstring(L, 3, 1, &err) && tolua_isstring(L, 4, 1, &err)
+ && tolua_isnumber(L, 5, 1, &err) && tolua_isnoobj(L, 6, &err)) {
+ Common::String s1(tolua_tostring(L, 1, nullptr));
+ float f1 = tolua_tonumber(L, 2, 1.0);
+ Common::String s2(tolua_tostring(L, 3, ""));
+ Common::String s3(tolua_tostring(L, 4, ""));
+ float f2 = tolua_tonumber(L, 5, 0.0);
+ LaunchDialog(s1, f1, s2, s3, f2);
+ return 0;
+ }
+ error("#ferror in function 'LaunchDialog': %d %d %s", err.index, err.array, err.type);
+}
+
+static int tolua_ExportedFunctions_LaunchDialogAndWaitForEnd00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isnumber(L, 2, 1, &err)
+ && tolua_isstring(L, 3, 1, &err) && tolua_isstring(L, 4, 1, &err)
+ && tolua_isnumber(L, 5, 1, &err) && tolua_isnoobj(L, 6, &err)) {
+ Common::String s1(tolua_tostring(L, 1, nullptr));
+ float f1 = tolua_tonumber(L, 2, 1.0);
+ Common::String s2(tolua_tostring(L, 3, ""));
+ Common::String s3(tolua_tostring(L, 4, ""));
+ float f2 = tolua_tonumber(L, 5, 0.0);
+ LaunchDialog(s1, f1, s2, s3, f2);
+
+ Game::YieldedCallback callback;
+ callback._luaThread = TeLuaThread::threadFromState(L);
+ callback._luaFnName = "OnDialogFinished";
+ callback._luaParam = s1;
+
+ Game *game = g_engine->getGame();
+ for (const auto &cb : game->yieldedCallbacks()) {
+ if (cb._luaFnName == callback._luaFnName && cb._luaParam == callback._luaParam)
+ error("LaunchDialogAndWaitForEnd: Reentrency error, your are already in a yielded/sync function call");
+ }
+
+ return callback._luaThread->yield();
+ }
+ error("#ferror in function 'LaunchDialogAndWaitForEnd': %d %d %s", err.index, err.array, err.type);
+}
+
static void PushTask(const Common::String &s1, const Common::String &s2) {
Game *game = g_engine->getGame();
game->objectif().pushObjectif(s1, s2);
@@ -556,6 +722,24 @@ static int tolua_ExportedFunctions_AddAnchorZone00(lua_State *L) {
error("#ferror in function 'AddAnchorZone': %d %d %s", err.index, err.array, err.type);
}
+static void ActivateAnchorZone(const Common::String &name, bool b) {
+ if (!name.empty()) {
+ Game *game = g_engine->getGame();
+ game->scene().activateAnchorZone(name, b);
+ }
+}
+
+static int tolua_ExportedFunctions_ActivateAnchorZone00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isboolean(L, 2, 0, &err) && tolua_isnoobj(L, 3, &err)) {
+ Common::String s(tolua_tostring(L, 1, nullptr));
+ bool b = tolua_toboolean(L, 2, 0);
+ ActivateAnchorZone(s, b);
+ return 0;
+ }
+ error("#ferror in function 'ActivateAnchorZone': %d %d %s", err.index, err.array, err.type);
+}
+
static void DisabledZone(const Common::String &s1, bool b) {
Game *game = g_engine->getGame();
if (!game->scene().markerGui().loaded())
@@ -819,11 +1003,11 @@ static void MoveCharacterPlayerTo(float x, float y, float z, bool walkFlag) {
if (game->_movePlayerCharacterDisabled)
return;
- TeVector3f32 loc(x, y, z);
+ TeVector3f32 dest(x, y, z);
game->resetPreviousMousePos();
Character *character = game->scene()._character;
- if (loc == game->posPlayer() && character->walkModeStr() == "Walk")
+ if (dest == game->posPlayer() && character->walkModeStr() == "Walk")
return;
if (game->walkTimer().running() && game->walkTimer().timeElapsed() < 300000) {
@@ -839,7 +1023,7 @@ static void MoveCharacterPlayerTo(float x, float y, float z, bool walkFlag) {
}
game->_sceneCharacterVisibleFromLoad = false;
- TeIntrusivePtr<TeBezierCurve> curve = character->freeMoveZone()->curve(character->_model->position(), loc);
+ TeIntrusivePtr<TeBezierCurve> curve = character->freeMoveZone()->curve(character->_model->position(), dest);
if (!curve) {
game->luaScript().execute("OnDisplacementFinished");
} else {
@@ -850,7 +1034,7 @@ static void MoveCharacterPlayerTo(float x, float y, float z, bool walkFlag) {
character->setAnimation(character->walkAnim(Character::WalkPart_Loop), true);
character->walkTo(1.0, walkFlag);
game->_isCharacterWalking = true;
- game->setPosPlayer(loc);
+ game->setPosPlayer(dest);
}
}
@@ -906,10 +1090,10 @@ void LuaOpenBinds(lua_State *L) {
tolua_function(L, "LockCursor", tolua_ExportedFunctions_LockCursor00);
/*tolua_function(L, "SetCondition", tolua_ExportedFunctions_SetCondition00);
tolua_function(L, "UnsetCondition", tolua_ExportedFunctions_UnsetCondition00);
- tolua_function(L, "TutoActive", tolua_ExportedFunctions_TutoActive00);
+ tolua_function(L, "TutoActive", tolua_ExportedFunctions_TutoActive00);*/
tolua_function(L, "LaunchDialog", tolua_ExportedFunctions_LaunchDialog00);
tolua_function(L, "LaunchDialogAndWaitForEnd", tolua_ExportedFunctions_LaunchDialogAndWaitForEnd00);
- tolua_function(L, "PushAnswer", tolua_ExportedFunctions_PushAnswer00);
+ /*tolua_function(L, "PushAnswer", tolua_ExportedFunctions_PushAnswer00);
tolua_function(L, "HideAnswers", tolua_ExportedFunctions_HideAnswers00);*/
tolua_function(L, "PushTask", tolua_ExportedFunctions_PushTask00);
/*tolua_function(L, "DeleteTask", tolua_ExportedFunctions_DeleteTask00);
@@ -922,9 +1106,9 @@ void LuaOpenBinds(lua_State *L) {
tolua_function(L, "PlayRandomSound", tolua_ExportedFunctions_PlayRandomSound00);
tolua_function(L, "PlayMusic", tolua_ExportedFunctions_PlayMusic00);
tolua_function(L, "SetSoundStep", tolua_ExportedFunctions_SetSoundStep00);
- /*tolua_function(L, "Selected", tolua_ExportedFunctions_Selected00);
+ tolua_function(L, "Selected", tolua_ExportedFunctions_Selected00);
tolua_function(L, "TakeObject", tolua_ExportedFunctions_TakeObject00);
- tolua_function(L, "TakeObjectInHand", tolua_ExportedFunctions_TakeObjectInHand00);
+ /*tolua_function(L, "TakeObjectInHand", tolua_ExportedFunctions_TakeObjectInHand00);
tolua_function(L, "RemoveObject", tolua_ExportedFunctions_RemoveObject00);
tolua_function(L, "RemoveObject", tolua_ExportedFunctions_RemoveObject01);*/
tolua_function(L, "AddNumber", tolua_ExportedFunctions_AddNumber00);
@@ -948,9 +1132,9 @@ void LuaOpenBinds(lua_State *L) {
tolua_function(L, "SetCharacterPosition", tolua_ExportedFunctions_SetCharacterPosition00);
/*tolua_function(L, "PlaceCharacterOnDummy", tolua_ExportedFunctions_PlaceCharacterOnDummy00);*/
tolua_function(L, "SetCharacterRotation", tolua_ExportedFunctions_SetCharacterRotation00);
- /*tolua_function(L, "SetCharacterOrientation", tolua_ExportedFunctions_SetCharacterOrientation00);
+ tolua_function(L, "SetCharacterOrientation", tolua_ExportedFunctions_SetCharacterOrientation00);
tolua_function(L, "SetCharacterAnimation", tolua_ExportedFunctions_SetCharacterAnimation00);
- tolua_function(L, "SetCharacterAnimationAndWaitForEnd",
+ /*tolua_function(L, "SetCharacterAnimationAndWaitForEnd",
tolua_ExportedFunctions_SetCharacterAnimationAndWaitForEnd00);
tolua_function(L, "BlendCharacterAnimation", tolua_ExportedFunctions_BlendCharacterAnimation00);
tolua_function(L, "BlendCharacterAnimationAndWaitForEnd",
@@ -963,9 +1147,9 @@ void LuaOpenBinds(lua_State *L) {
tolua_function(L, "SetRunMode2", tolua_ExportedFunctions_SetRunMode200);
tolua_function(L, "SetCharacterColor", tolua_ExportedFunctions_SetCharacterColor00);
tolua_function(L, "SetCharacterSound", tolua_ExportedFunctions_SetCharacterSound00);
- tolua_function(L, "SetCharacterShadow", tolua_ExportedFunctions_SetCharacterShadow00);
+ tolua_function(L, "SetCharacterShadow", tolua_ExportedFunctions_SetCharacterShadow00);*/
tolua_function(L, "AddCallback", tolua_ExportedFunctions_AddCallback00);
- tolua_function(L, "AddCallbackPlayer", tolua_ExportedFunctions_AddCallbackPlayer00);
+ /*tolua_function(L, "AddCallbackPlayer", tolua_ExportedFunctions_AddCallbackPlayer00);
tolua_function(L, "AddCallbackAnimation2D", tolua_ExportedFunctions_AddCallbackAnimation2D00);
tolua_function(L, "DeleteCallback", tolua_ExportedFunctions_DeleteCallback00);
tolua_function(L, "DeleteCallbackPlayer", tolua_ExportedFunctions_DeleteCallbackPlayer00);
@@ -1009,9 +1193,9 @@ void LuaOpenBinds(lua_State *L) {
tolua_function(L, "ExitZone", tolua_ExportedFunctions_ExitZone00);*/
tolua_function(L, "EnableRectBlocker", tolua_ExportedFunctions_EnableRectBlocker00);
/*tolua_function(L, "EnableBlocker", tolua_ExportedFunctions_EnableBlocker00);*/
- tolua_function(L, "AddAnchorZone", tolua_ExportedFunctions_AddAnchorZone00);/*
+ tolua_function(L, "AddAnchorZone", tolua_ExportedFunctions_AddAnchorZone00);
tolua_function(L, "ActivateAnchorZone", tolua_ExportedFunctions_ActivateAnchorZone00);
- tolua_function(L, "SetCharacterAnchor", tolua_ExportedFunctions_SetCharacterAnchor00);
+ /*tolua_function(L, "SetCharacterAnchor", tolua_ExportedFunctions_SetCharacterAnchor00);
tolua_function(L, "SetCharacterLookChar", tolua_ExportedFunctions_SetCharacterLookChar00);
tolua_function(L, "Random", tolua_ExportedFunctions_Random00);
tolua_function(L, "SetCharacterMeshVisible", tolua_ExportedFunctions_SetCharacterMeshVisible00);
diff --git a/engines/tetraedge/te/te_3d_object2.cpp b/engines/tetraedge/te/te_3d_object2.cpp
index c4ac06bbb11..d4997914a24 100644
--- a/engines/tetraedge/te/te_3d_object2.cpp
+++ b/engines/tetraedge/te/te_3d_object2.cpp
@@ -196,6 +196,11 @@ void Te3DObject2::setPosition(const TeVector3f32 &pos) {
if (_position == pos)
return;
+ if ((_position - pos).length() > 2.0f && name() == "Kate" && _position != TeVector3f32()) {
+ debug("Large position move %s %s -> %s", name().c_str(),
+ _position.dump().c_str(), pos.dump().c_str());
+ }
+
_position = pos;
_onPositionChangedSignal.call();
_onParentWorldTransformationMatrixChangedSignal.call();
diff --git a/engines/tetraedge/te/te_3d_texture.cpp b/engines/tetraedge/te/te_3d_texture.cpp
index ac1353e59ec..ac94154adbc 100644
--- a/engines/tetraedge/te/te_3d_texture.cpp
+++ b/engines/tetraedge/te/te_3d_texture.cpp
@@ -170,17 +170,17 @@ bool Te3DTexture::load(const TeImage &img) {
const void *imgdata = img.getPixels();
if (_format == TeImage::RGB8) {
- GLenum glpxformat = GL_RGB;
+ /*GLenum glpxformat = GL_RGB;
if (_glPixelFormat != GL_INVALID_ENUM) {
glpxformat = _glPixelFormat;
- }
+ }*/
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, _texWidth, _texHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, img.pitch / 3, img.h, GL_RGB, GL_UNSIGNED_BYTE, imgdata);
} else if (_format == TeImage::RGBA8) {
- GLenum glpxformat = GL_RGBA8;
+ /*GLenum glpxformat = GL_RGBA8;
if (_glPixelFormat != GL_INVALID_ENUM) {
glpxformat = _glPixelFormat;
- }
+ }*/
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, _texWidth, _texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, img.w, img.h, GL_RGBA, GL_UNSIGNED_BYTE, imgdata);
} else {
diff --git a/engines/tetraedge/te/te_bezier_curve.cpp b/engines/tetraedge/te/te_bezier_curve.cpp
index d55a3203db0..8846cbbfd3a 100644
--- a/engines/tetraedge/te/te_bezier_curve.cpp
+++ b/engines/tetraedge/te/te_bezier_curve.cpp
@@ -20,6 +20,10 @@
*/
#include "tetraedge/te/te_bezier_curve.h"
+#include "tetraedge/te/te_mesh.h"
+#include "tetraedge/te/te_renderer.h"
+#include "tetraedge/tetraedge.h"
+
namespace Tetraedge {
@@ -37,7 +41,36 @@ void TeBezierCurve::clear() {
}
void TeBezierCurve::draw() {
- error("TODO: Implement TeBezierCurve::draw");
+ if (!worldVisible() || _controlPoints.empty())
+ return;
+
+ TeMesh mesh1;
+ TeMesh mesh2;
+ unsigned int npoints = _controlPoints.size();
+
+ mesh1.setConf(npoints, npoints, TeMesh::MeshMode_Points, 0, 0);
+ for (unsigned int i = 0; i < npoints; i++) {
+ mesh1.setVertex(i, _controlPoints[i]);
+ mesh1.setIndex(i, i);
+ }
+
+ mesh2.setConf(npoints, npoints, TeMesh::MeshMode_LineStrip, 0, 0);
+ for (unsigned int i = 0; i < npoints; i++) {
+ mesh2.setVertex(i, _controlPoints[i]);
+ mesh2.setNormal(i, TeVector3f32(0.0f, 1.0f, 0.0));
+ mesh2.setIndex(i, i);
+ }
+
+ TeRenderer *renderer = g_engine->getRenderer();
+ const TeColor prevColor = renderer->currentColor();
+ renderer->pushMatrix();
+ renderer->multiplyMatrix(worldTransformationMatrix());
+ renderer->setCurrentColor(TeColor(0, 0xff, 0xff, 0xff));
+ mesh2.draw();
+ renderer->setCurrentColor(TeColor(0xff, 0, 0xff, 0xff));
+ mesh1.draw();
+ renderer->popMatrix();
+ renderer->setCurrentColor(prevColor);
}
float TeBezierCurve::length() {
@@ -47,9 +80,11 @@ float TeBezierCurve::length() {
_lengths.clear();
TeVector3f32 lastpt = _controlPoints[0];
+ lastpt.y() = 0;
for (unsigned int i = 0; i < _numiterations; i++) {
float amount = (float)i / _numiterations;
- const TeVector3f32 pt = retrievePoint(amount);
+ TeVector3f32 pt = retrievePoint(amount);
+ pt.y() = 0;
float len = (lastpt - pt).length();
_length += len;
_lengths.push_back(_length);
@@ -59,15 +94,14 @@ float TeBezierCurve::length() {
return _length;
}
-void TeBezierCurve::pseudoTangent(float f, TeVector3f32 &v1, TeVector3f32 &v2) {
- const float numiters = _numiterations;
-
- if (1.0 / numiters + f <= 1.0) {
- v1 = retrievePoint(f);
- v2 = retrievePoint(1.0 / numiters + f);
+void TeBezierCurve::pseudoTangent(float offset, TeVector3f32 &v1, TeVector3f32 &v2) {
+ const float step = 1.0f / _numiterations;
+ if (step + offset <= 1.0f) {
+ v1 = retrievePoint(offset);
+ v2 = retrievePoint(step + offset);
} else {
- v2 = retrievePoint(f);
- v1 = retrievePoint(f - 1.0 / numiters);
+ v1 = retrievePoint(offset - step);
+ v2 = retrievePoint(offset);
}
}
@@ -77,13 +111,10 @@ float TeBezierCurve::rawLength() {
_rawLength = 0.0;
_rawLengths.clear();
_rawLengths.push_back(0.0);
- if (_controlPoints.size() > 1) {
- for (unsigned int i = 1; i < _controlPoints.size(); i++) {
- const TeVector3f32 diff = _controlPoints[i] - _controlPoints[i - 1];
- float len = diff.length();
- _rawLength += len;
- _rawLengths.push_back(_rawLength);
- }
+ for (unsigned int i = 1; i < _controlPoints.size(); i++) {
+ const TeVector3f32 diff = _controlPoints[i] - _controlPoints[i - 1];
+ _rawLength += diff.length();
+ _rawLengths.push_back(_rawLength);
}
}
return _rawLength;
@@ -104,50 +135,40 @@ TeVector3f32 TeBezierCurve::retrievePoint(float offset) {
const float rawlen = rawLength();
float proportion = 0.0f;
- int i = 0;
- while (i < npoints) {
- proportion = _rawLengths[i] / rawlen;
+ int startpt = 0;
+ while (startpt < npoints) {
+ proportion = _rawLengths[startpt] / rawlen;
if (proportion >= offset)
break;
- i++;
+ startpt++;
}
+
float t;
if (proportion == offset) {
+ // Exactly on a point
t = 0.0f;
} else {
- float p1 = _rawLengths[i - 1];
- float p2 = _rawLengths[i];
+ // Proportion between two points
+ float p1 = _rawLengths[startpt - 1];
+ float p2 = _rawLengths[startpt];
t = (rawlen * offset - p1) / (p2 - p1);
- i--;
+ startpt--;
}
+ // Collect 4 points around the startpt (1 before, 2 after)
TeVector3f32 points[4];
- TeVector3f32 *ptbuf = points;
const int maxPt = _controlPoints.size() - 1;
- int p = -1;
- do {
- int ptno = 0;
- if (i + p >= 0)
- ptno = MIN(i + p, maxPt);
- *ptbuf = _controlPoints[ptno];
- ptbuf = ptbuf + 1;
- p = p + 1;
- } while (p != 3);
-
- if (i < 0) {
- points[0] += (points[1] - points[2]);
- } else {
- int ptno = MIN(i, maxPt);
- if (ptno == 0)
- points[0] += (points[1] - points[2]);
+ for (int p = 0; p < 4; p++) {
+ int ptno = CLIP(startpt + p - 1, 0, maxPt);
+ points[p] = _controlPoints[ptno];
}
- int ptno = 0;
- i++;
- if (i >= 0)
- ptno = MIN(i, maxPt);
- if (ptno == maxPt)
- points[3] += points[2] - points[1];
+ // If we hit the end, linearly extend the last gradient.
+ if (startpt <= 0)
+ points[0] += (points[1] - points[2]);
+
+ if (startpt + 1 >= maxPt)
+ points[3] += (points[2] - points[1]);
return hermiteInterpolate(t, points, 0.0, 0.0);
}
diff --git a/engines/tetraedge/te/te_free_move_zone.cpp b/engines/tetraedge/te/te_free_move_zone.cpp
index cb7cb4437e7..1703f16a61f 100644
--- a/engines/tetraedge/te/te_free_move_zone.cpp
+++ b/engines/tetraedge/te/te_free_move_zone.cpp
@@ -53,7 +53,7 @@ class TeFreeMoveZoneGraph : micropather::Graph {
TeFreeMoveZone::TeFreeMoveZone() : _actzones(nullptr), _blockers(nullptr), _rectBlockers(nullptr),
_transformedVerticiesDirty(true), _bordersDirty(true), _pickMeshDirty(true), _projectedPointsDirty(true),
-_loadedFromBin(false)
+_loadedFromBin(false), _gridWorldY(0.0), _gridOffsetSomething(5.0f, 5.0f), _gridDirty(true)
{
_graph = new TeFreeMoveZoneGraph();
_graph->_bordersDistance = 2048.0f;
@@ -102,8 +102,9 @@ Common::Array<TeVector3f32> TeFreeMoveZone::collisions(const TeVector3f32 &v1, c
TeVector3f32 TeFreeMoveZone::correctCharacterPosition(const TeVector3f32 &pos, bool *flagout, bool intersectFlag) {
float f = 0.0;
TeVector3f32 intersectPoint;
- if (!intersect(pos, TeVector3f32(0, -1, 0), intersectPoint, f, intersectFlag, nullptr)) {
- if (!intersect(pos, TeVector3f32(0, 1, 0), intersectPoint, f, intersectFlag, nullptr)) {
+ TeVector3f32 testPos(pos.x(), 0, pos.z());
+ if (!intersect(testPos, TeVector3f32(0, -1, 0), intersectPoint, f, intersectFlag, nullptr)) {
+ if (!intersect(testPos, TeVector3f32(0, 1, 0), intersectPoint, f, intersectFlag, nullptr)) {
if (*flagout)
*flagout = false;
return pos;
@@ -131,7 +132,7 @@ TeIntrusivePtr<TeBezierCurve> TeFreeMoveZone::curve(const TeVector3f32 &startpt,
updateGrid(false);
const TeVector2s32 projectedStart = projectOnAStarGrid(startpt);
const TeVector2s32 projectedEnd = projectOnAStarGrid(endpt);
- int xsize = _graph->_size._x;
+ const int xsize = _graph->_size._x;
float cost = 0;
// Passing an int to void*, yuck? but it's what the original does..
Common::Array<void *> path;
@@ -147,9 +148,7 @@ TeIntrusivePtr<TeBezierCurve> TeFreeMoveZone::curve(const TeVector3f32 &startpt,
for (auto pathpt : path) {
// each path point is an array offset
int offset = static_cast<int>(reinterpret_cast<size_t>(pathpt));
- int yoff = offset / _graph->_size._x;
- int xoff = offset % _graph->_size._x;
- points[i] = TeVector2s32(xoff, yoff);
+ points[i] = TeVector2s32(offset % xsize, offset / xsize);
i++;
}
@@ -195,7 +194,7 @@ void TeFreeMoveZone::deserialize(Common::ReadStream &stream, TeFreeMoveZone &des
TeVector2f32::deserialize(stream, dest._someGridVec1);
TeVector2f32::deserialize(stream, dest._someGridVec2);
- dest._someGridFloat = stream.readFloatLE();
+ dest._gridWorldY = stream.readFloatLE();
dest._graph->deserialize(stream);
if (dest.name().contains("19000")) {
@@ -216,8 +215,22 @@ void TeFreeMoveZone::draw() {
TePickMesh2::draw();
TeMesh mesh;
mesh.setConf(_uintArray2.size(), _uintArray2.size(), TeMesh::MeshMode_Lines, 0, 0);
+ for (unsigned int i = 0; i < _uintArray2.size(); i++) {
+ mesh.setIndex(i, i);
+ mesh.setVertex(i, verticies()[_uintArray2[i]]);
+ }
+
+ const TeColor prevColor = renderer->currentColor();
+ renderer->pushMatrix();
+ renderer->multiplyMatrix(worldTransformationMatrix());
+ renderer->setCurrentColor(TeColor(0, 0x80, 0xff, 0xff));
+ mesh.draw();
+ renderer->popMatrix();
+ renderer->setCurrentColor(prevColor);
+
+ // TODO: do a bunch of other drawing stuff here.
- error("TODO: Finish TeFreeMoveZone::draw");
+ renderer->disableWireFrame();
}
TeVector3f32 TeFreeMoveZone::findNearestPointOnBorder(const TeVector2f32 &pt) {
@@ -363,7 +376,7 @@ TeVector3f32 TeFreeMoveZone::transformAStarGridInWorldSpace(const TeVector2s32 &
float offsetx = (float)gridpt._x * _gridOffsetSomething.getX() + _someGridVec1.getX() +
_gridOffsetSomething.getX() * 0.5;
if (!_loadedFromBin) {
- return TeVector3f32(offsetx, _someGridFloat, offsety);
+ return TeVector3f32(offsetx, _gridWorldY, offsety);
}
error("TODO: Implement TeFreeMoveZone::transformAStarGridInWorldSpace");
}
diff --git a/engines/tetraedge/te/te_free_move_zone.h b/engines/tetraedge/te/te_free_move_zone.h
index b7f5743777b..f98231f7a4a 100644
--- a/engines/tetraedge/te/te_free_move_zone.h
+++ b/engines/tetraedge/te/te_free_move_zone.h
@@ -129,7 +129,7 @@ private:
TeVector2f32 _someGridVec1;
TeVector2f32 _someGridVec2;
- float _someGridFloat;
+ float _gridWorldY;
TeOBP _obp;
TeIntrusivePtr<TeCamera> _camera;
diff --git a/engines/tetraedge/te/te_lua_thread.cpp b/engines/tetraedge/te/te_lua_thread.cpp
index 928a4d8eb01..b56aab1b937 100644
--- a/engines/tetraedge/te/te_lua_thread.cpp
+++ b/engines/tetraedge/te/te_lua_thread.cpp
@@ -140,6 +140,11 @@ void TeLuaThread::executeFile(const Common::Path &path) {
scriptFile.read(buf, fileLen);
buf[fileLen] = 0;
scriptFile.close();
+ // WORKAROUND: Some script files have rogue ";" lines in them with nothing else, clean those up.
+ char *fixline = strstr(buf, "\n\t;");
+ if (fixline)
+ fixline[2] = '\t';
+
_lastResumeResult = luaL_loadbuffer(_luaThread, buf, fileLen, path.toString().c_str());
if (_lastResumeResult) {
const char *msg = lua_tostring(_luaThread, -1);
@@ -228,8 +233,8 @@ void TeLuaThread::resume(const TeVariant &p1, const TeVariant &p2, const TeVaria
return nullptr;
}
-void TeLuaThread::yield() {
- lua_yield(_luaThread, 0);
+int TeLuaThread::yield() {
+ return lua_yield(_luaThread, 0);
}
} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_lua_thread.h b/engines/tetraedge/te/te_lua_thread.h
index ac2be3cd209..a7c96efffea 100644
--- a/engines/tetraedge/te/te_lua_thread.h
+++ b/engines/tetraedge/te/te_lua_thread.h
@@ -57,7 +57,7 @@ public:
void resume(const TeVariant &p1, const TeVariant &p2, const TeVariant &p3);
static TeLuaThread *threadFromState(lua_State *state);
- void yield();
+ int yield();
private:
void _resume(int nargs);
diff --git a/engines/tetraedge/te/te_model.cpp b/engines/tetraedge/te/te_model.cpp
index 60b2a7728da..7f560f57f5e 100644
--- a/engines/tetraedge/te/te_model.cpp
+++ b/engines/tetraedge/te/te_model.cpp
@@ -192,7 +192,6 @@ void TeModel::update() {
for (unsigned int i = 0; i < _boneBlenders.size(); i++) {
BonesBlender *blender = _boneBlenders[i];
float complete = MIN((blender->_timer.getTimeFromStart() / 1000000.0f) / blender->_seconds, 1.0f);
- TeTRS trs;
TeTRS endTRS = getBone(blender->_anim, b);
if (complete == 1.0f) {
delete blender;
diff --git a/engines/tetraedge/te/te_model_animation.cpp b/engines/tetraedge/te/te_model_animation.cpp
index e8759bb8701..85b5cd84d45 100644
--- a/engines/tetraedge/te/te_model_animation.cpp
+++ b/engines/tetraedge/te/te_model_animation.cpp
@@ -103,12 +103,14 @@ TeQuaternion TeModelAnimation::getNMORotation(unsigned long boneNo, float amount
if (i == 0)
return arr.front()._rot;
- if (i == arr.size() || arr.size() == 1 || arr[i]._f - arr[i-1]._f == 0) {
+ if (i == arr.size() || arr.size() == 1)
return arr.back()._rot;
- }
- float interp = (amount - arr[i-1]._f) / (arr[i]._f - arr[i-1]._f);
- return arr[i-1]._rot.slerpQuat(arr[i]._rot, interp);
+ if (arr[i]._f - arr[i-1]._f == 0)
+ return arr[i]._rot;
+
+ float interp = (amount - arr[i - 1]._f) / (arr[i]._f - arr[i - 1]._f);
+ return arr[i - 1]._rot.slerpQuat(arr[i]._rot, interp);
}
}
return TeQuaternion(0, 0, 0, 1.0);
@@ -125,12 +127,14 @@ TeVector3f32 TeModelAnimation::getNMOTranslation(unsigned long boneNo, float amo
if (i == 0)
return arr.front()._trans;
- if (i == arr.size() || arr.size() == 1 || arr[i]._f - arr[i-1]._f == 0) {
+ if (i == arr.size() || arr.size() == 1)
return arr.back()._trans;
- }
- float interp = (amount - arr[i-1]._f) / (arr[i]._f - arr[i-1]._f);
- return arr[i-1]._trans * (1.0 - interp) + arr[i]._trans * interp;
+ if (arr[i]._f - arr[i - 1]._f == 0)
+ return arr[i - 1]._trans;
+
+ float interp = (amount - arr[i - 1]._f) / (arr[i]._f - arr[i - 1]._f);
+ return arr[i - 1]._trans * (1.0 - interp) + arr[i]._trans * interp;
}
}
return TeVector3f32(0, 0, 0);
diff --git a/engines/tetraedge/te/te_model_vertex_animation.cpp b/engines/tetraedge/te/te_model_vertex_animation.cpp
index cef7f635c47..2735fba1f80 100644
--- a/engines/tetraedge/te/te_model_vertex_animation.cpp
+++ b/engines/tetraedge/te/te_model_vertex_animation.cpp
@@ -70,7 +70,7 @@ const Common::Array<TeVector3f32> &TeModelVertexAnimation::getVertices() {
for (unsigned int i = 0; i < _keydata[0]._vectors.size(); i++) {
const TeVector3f32 prevVector = getKeyVertex(keyno, i);
const TeVector3f32 nextVector = getKeyVertex(keyno + 1, i);
- lerpVtx.push_back(prevVector * (1.0 - interp) + nextVector * interp);
+ lerpVtx[i] = prevVector * (1.0 - interp) + nextVector * interp;
}
return lerpVtx;
diff --git a/engines/tetraedge/te/te_pick_mesh2.cpp b/engines/tetraedge/te/te_pick_mesh2.cpp
index 41fb2c5cbad..91f4eb85da0 100644
--- a/engines/tetraedge/te/te_pick_mesh2.cpp
+++ b/engines/tetraedge/te/te_pick_mesh2.cpp
@@ -59,7 +59,7 @@ void TePickMesh2::draw() {
renderer->setCurrentColor(prevCol);
}
-bool TePickMesh2::intersect(const TeVector3f32 &v1, const TeVector3f32 &v2, TeVector3f32 &v3, float &fout, bool lastHitFirst, unsigned long *triangleHitOut) {
+bool TePickMesh2::intersect(const TeVector3f32 &v1, const TeVector3f32 &v2, TeVector3f32 &vout, float &fout, bool lastHitFirst, unsigned long *triangleHitOut) {
if (_verticies.size() / 3 == 0)
return false;
@@ -72,7 +72,7 @@ bool TePickMesh2::intersect(const TeVector3f32 &v1, const TeVector3f32 &v2, TeVe
const TeVector3f32 triv3 = worldTrans * _verticies[_lastTriangleHit * 3 + 2];
int result = TeRayIntersection::intersect(v1, v2, triv1, triv2, triv3, intersection, f);
if (result == 1 && f >= 0.0 && f < FLT_MAX) {
- v3 = v1 + v2 * f;
+ vout = v1 + v2 * f;
fout = f;
if (triangleHitOut)
*triangleHitOut = _lastTriangleHit;
@@ -94,7 +94,7 @@ bool TePickMesh2::intersect(const TeVector3f32 &v1, const TeVector3f32 &v2, TeVe
}
}
if (hitf != FLT_MAX) {
- v3 = v1 + v2 * hitf;
+ vout = v1 + v2 * hitf;
fout = hitf;
if (triangleHitOut)
*triangleHitOut = _lastTriangleHit;
@@ -167,7 +167,7 @@ void TePickMesh2::deserialize(Common::ReadStream &stream, TePickMesh2 &mesh) {
for (unsigned int i = 0; i < ntriangles * 3; i++) {
TeVector3f32 vec;
TeVector3f32::deserialize(stream, vec);
- mesh._verticies.push_back(vec);
+ mesh._verticies[i] = vec;
}
}
diff --git a/engines/tetraedge/te/te_ray_intersection.cpp b/engines/tetraedge/te/te_ray_intersection.cpp
index 4cfece341c3..ddbbd9e6dae 100644
--- a/engines/tetraedge/te/te_ray_intersection.cpp
+++ b/engines/tetraedge/te/te_ray_intersection.cpp
@@ -45,6 +45,7 @@ int intersect(const TeVector3f32 &v1, const TeVector3f32 &v2, const TeVector3f32
if (fabs(f2) > 1e-9) {
f2 = -f1 / f2;
fout = f2;
+ result = 0;
if (f2 >= 0.0) {
vout = v1 + (v2 * f2);
float dot1 = v4_v3.dotProduct(v4_v3);
@@ -64,6 +65,10 @@ int intersect(const TeVector3f32 &v1, const TeVector3f32 &v2, const TeVector3f32
}
}
}
+ } else {
+ // Sorry about the logic.. this is what the decompiler gave me
+ // and I'm not brave enough to figure it out.
+ result = (-(uint)(f1 == -0.0) & 1) * 2;
}
return result;
}
diff --git a/engines/tetraedge/te/te_timer.cpp b/engines/tetraedge/te/te_timer.cpp
index 79db37f7649..4802c446729 100644
--- a/engines/tetraedge/te/te_timer.cpp
+++ b/engines/tetraedge/te/te_timer.cpp
@@ -39,6 +39,17 @@ _startTime(0), _lastTimeElapsed(0), _startTimeOffset(0), _updated(false) {
}
}
+TeTimer::~TeTimer() {
+ if (!_stopped) {
+ for (uint i = 0; i < _timers.size(); i++) {
+ if (_timers[i] == this) {
+ _timers.remove_at(i);
+ break;
+ }
+ }
+ }
+}
+
void TeTimer::stop() {
pause();
_lastTimeElapsed = 0;
diff --git a/engines/tetraedge/te/te_timer.h b/engines/tetraedge/te/te_timer.h
index 6d04e5bd2d4..1cf59ac72ff 100644
--- a/engines/tetraedge/te/te_timer.h
+++ b/engines/tetraedge/te/te_timer.h
@@ -31,6 +31,7 @@ namespace Tetraedge {
class TeTimer {
public:
TeTimer();
+ ~TeTimer();
void stop();
void start();
Commit: 194b1a80813f0869a5a4d1d55023721a1a001783
https://github.com/scummvm/scummvm/commit/194b1a80813f0869a5a4d1d55023721a1a001783
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2023-01-16T17:36:43+01:00
Commit Message:
TETRAEDGE: Work in progress, some inventory stuff done.
Changed paths:
engines/tetraedge/game/billboard.cpp
engines/tetraedge/game/game.cpp
engines/tetraedge/game/game.h
engines/tetraedge/game/inventory.cpp
engines/tetraedge/game/lua_binds.cpp
engines/tetraedge/game/objectif.cpp
engines/tetraedge/game/objectif.h
diff --git a/engines/tetraedge/game/billboard.cpp b/engines/tetraedge/game/billboard.cpp
index eef7974e0b1..068abcb0f36 100644
--- a/engines/tetraedge/game/billboard.cpp
+++ b/engines/tetraedge/game/billboard.cpp
@@ -36,17 +36,17 @@ bool Billboard::load(const Common::String &path) {
Game *game = g_engine->getGame();
Common::Path texpath = game->sceneZonePath().join(path);
texture->load(texpath);
- _model->setName(texpath.toString());
+ _model->setName(path);
Common::Array<TeVector3f32> quad;
quad.resize(4);
_model->setQuad(texture, quad, TeColor(0xff, 0xff, 0xff, 0xff));
game->scene().models().push_back(_model);
- return false;
+ return true;
}
void Billboard::calcVertex() {
//Game *game = g_engine->getGame();
- error("TODO: implement Billboard::calcVertex");
+ warning("TODO: implement Billboard::calcVertex");
}
void Billboard::position(const TeVector3f32 &pos) {
diff --git a/engines/tetraedge/game/game.cpp b/engines/tetraedge/game/game.cpp
index b65287d92d0..d8fc15069a6 100644
--- a/engines/tetraedge/game/game.cpp
+++ b/engines/tetraedge/game/game.cpp
@@ -155,16 +155,16 @@ void Game::addRandomSound(const Common::String &name, const Common::String &path
_randomSounds[name].push_back(randsound);
}
-void Game::addToBag(const Common::String &objname) {
- if (_inventory.objectCount(objname) != 0)
+void Game::addToBag(const Common::String &objid) {
+ if (_inventory.objectCount(objid) != 0)
return;
- _inventory.addObject(objname);
+ _inventory.addObject(objid);
Common::String imgpath("Inventory/Objects/");
- imgpath += _inventory.objectName(objname);
+ imgpath += objid;
imgpath += ".png";
- _notifier.push(objname, imgpath);
+ _notifier.push(_inventory.objectName(objid), imgpath);
for (int i = 0; i < NUM_OBJECTS_TAKEN_IDS; i++) {
- if (objname == OBJECTS_TAKEN_IDS[i] && !_objectsTakenBits[i]) {
+ if (objid == OBJECTS_TAKEN_IDS[i] && !_objectsTakenBits[i]) {
_objectsTakenBits[i] = true;
_objectsTakenVal++;
}
diff --git a/engines/tetraedge/game/game.h b/engines/tetraedge/game/game.h
index e01d0b4d27d..610c7e2c87d 100644
--- a/engines/tetraedge/game/game.h
+++ b/engines/tetraedge/game/game.h
@@ -191,6 +191,7 @@ public:
const TeVector3f32 &posPlayer() const { return _posPlayer; }
void setPosPlayer(const TeVector3f32 &pos) { _posPlayer = pos; }
TeTimer &walkTimer() { return _walkTimer; }
+ void setExitZone(const Common::String &zone) { _exitZone = zone; }
private:
bool _luaShowOwnerError;
diff --git a/engines/tetraedge/game/inventory.cpp b/engines/tetraedge/game/inventory.cpp
index 6b42aebf130..f6cd44a6b9a 100644
--- a/engines/tetraedge/game/inventory.cpp
+++ b/engines/tetraedge/game/inventory.cpp
@@ -213,10 +213,12 @@ bool Inventory::addObject(InventoryObject &obj) {
pageno++;
}
}
-
+
int pageno = 0;
unsigned int totalSlots = 0;
bool retval;
+ const Common::String newObjName = obj.name();
+ auto invObjIter = _invObjects.begin();
while (true) {
TeLayout *page = _gui.layout(Common::String::format("page%d", pageno));
retval = false;
@@ -236,10 +238,22 @@ bool Inventory::addObject(InventoryObject &obj) {
}
TeTextLayout *newText = new TeTextLayout();
- error("TODO: finish Inventory::addObject.");
+ newText->setSizeType(CoordinatesType::RELATIVE_TO_PARENT);
+ newText->setPosition(TeVector3f32(1.0,1.0,0.0));
+ newText->setSize(TeVector3f32(1.0,1.0,0.0));
+ newText->setTextSizeType(1);
+ newText->setTextSizeProportionalToWidth(200);
+ newText->setText(_gui.value("textAttributs").toString() + (*invObjIter)->name());
+ newText->setName((*invObjIter)->name());
+ newText->setVisible(false);
+
+ TeLayout *layout = _gui.layout("textObject");
+ layout->addChild(newText);
+ slot->addChild(*invObjIter);
totalSlots++;
slotno++;
+ invObjIter++;
}
pageno++;
}
@@ -268,7 +282,7 @@ Common::String Inventory::objectDescription(const Common::String &objId) {
Common::String Inventory::objectName(const Common::String &objId) {
if (!_objectData.contains(objId))
return "";
- return _objectData.getVal(objId)._name;
+ return _objectData.getVal(objId)._id;
}
bool Inventory::onMainMenuButton() {
diff --git a/engines/tetraedge/game/lua_binds.cpp b/engines/tetraedge/game/lua_binds.cpp
index 290d94b2546..759af23615e 100644
--- a/engines/tetraedge/game/lua_binds.cpp
+++ b/engines/tetraedge/game/lua_binds.cpp
@@ -22,11 +22,13 @@
#include "tetraedge/tetraedge.h"
#include "tetraedge/game/application.h"
+#include "tetraedge/game/billboard.h"
#include "tetraedge/game/character.h"
#include "tetraedge/game/game.h"
#include "tetraedge/game/lua_binds.h"
#include "tetraedge/game/object3d.h"
#include "tetraedge/to_lua.h"
+#include "tetraedge/te/te_core.h"
#include "tetraedge/te/te_lua_thread.h"
namespace Tetraedge {
@@ -586,6 +588,133 @@ static int tolua_ExportedFunctions_SetGroundObjectRotation00(lua_State *L) {
error("#ferror in function 'SetGroundObjectRotation': %d %d %s", err.index, err.array, err.type);
}
+static void LoadBillBoard(const Common::String &name) {
+ Game *game = g_engine->getGame();
+ game->scene().loadBillboard(name);
+}
+
+static int tolua_ExportedFunctions_LoadBillBoard00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isnoobj(L, 2, &err)) {
+ Common::String s1(tolua_tostring(L, 1, nullptr));
+ LoadBillBoard(s1);
+ return 0;
+ }
+ error("#ferror in function 'LoadBillBoard': %d %d %s", err.index, err.array, err.type);
+}
+
+static void SetBillboardPosition(const Common::String &name, float x, float y, float z) {
+ Game *game = g_engine->getGame();
+ Billboard *bb = game->scene().billboard(name);
+ if (!bb) {
+ error("[SetBillboardPosition] Billboard not found %s", name.c_str());
+ }
+ bb->position(TeVector3f32(x, y, z));
+}
+
+static int tolua_ExportedFunctions_SetBillboardPosition00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isnumber(L, 2, 0, &err)
+ && tolua_isnumber(L, 3, 0, &err) && tolua_isnumber(L, 4, 0, &err)
+ && tolua_isnoobj(L, 5, &err)) {
+ Common::String s1(tolua_tostring(L, 1, nullptr));
+ float f1 = tolua_tonumber(L, 2, 0.0);
+ float f2 = tolua_tonumber(L, 3, 0.0);
+ float f3 = tolua_tonumber(L, 4, 0.0);
+ SetBillboardPosition(s1, f1, f2, f3);
+ return 0;
+ }
+ error("#ferror in function 'SetBillboardPosition': %d %d %s", err.index, err.array, err.type);
+}
+
+static void SetBillboardPosition2(const Common::String &name, float x1, float y1, float x2, float y2, float z) {
+ Game *game = g_engine->getGame();
+ Billboard *bb = game->scene().billboard(name);
+ if (!bb) {
+ error("[SetBillboardPosition2] Billboard not found %s", name.c_str());
+ }
+ bb->position(TeVector3f32(x1, y1, 0.0));
+ bb->position2(TeVector3f32(x2, y2, z));
+}
+
+static int tolua_ExportedFunctions_SetBillboardPosition200(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isnumber(L, 2, 0, &err)
+ && tolua_isnumber(L, 3, 0, &err) && tolua_isnumber(L, 4, 0, &err)
+ && tolua_isnumber(L, 5, 0, &err) && tolua_isnumber(L, 6, 0, &err)
+ && tolua_isnoobj(L, 7, &err)) {
+ Common::String s1(tolua_tostring(L, 1, nullptr));
+ float f1 = tolua_tonumber(L, 2, 0.0);
+ float f2 = tolua_tonumber(L, 3, 0.0);
+ float f3 = tolua_tonumber(L, 4, 0.0);
+ float f4 = tolua_tonumber(L, 5, 0.0);
+ float f5 = tolua_tonumber(L, 6, 0.0);
+ SetBillboardPosition2(s1, f1, f2, f3, f4, f5);
+ return 0;
+ }
+ error("#ferror in function 'SetBillboardPosition2': %d %d %s", err.index, err.array, err.type);
+}
+
+static void SetBillboardSize(const Common::String &name, float xs, float ys) {
+ Game *game = g_engine->getGame();
+ Billboard *bb = game->scene().billboard(name);
+ if (!bb) {
+ error("[SetBillboardSize] Billboard not found %s", name.c_str());
+ }
+ bb->size(TeVector2f32(xs, ys));
+}
+
+static int tolua_ExportedFunctions_SetBillboardSize00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isnumber(L, 2, 0, &err)
+ && tolua_isnumber(L, 3, 0, &err) && tolua_isnoobj(L, 4, &err)) {
+ Common::String s1(tolua_tostring(L, 1, nullptr));
+ float f1 = tolua_tonumber(L, 2, 0.0);
+ float f2 = tolua_tonumber(L, 3, 0.0);
+ SetBillboardSize(s1, f1, f2);
+ return 0;
+ }
+ error("#ferror in function 'SetBillboardSize': %d %d %s", err.index, err.array, err.type);
+}
+
+static void ShowBillboard(const Common::String &name) {
+ Game *game = g_engine->getGame();
+ Billboard *bb = game->scene().billboard(name);
+ if (!bb) {
+ error("[ShowBillboard] Billboard not found %s", name.c_str());
+ }
+ bb->model()->setVisible(true);
+}
+
+static int tolua_ExportedFunctions_ShowBillboard00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isnoobj(L, 2, &err)) {
+ Common::String s1(tolua_tostring(L, 1, nullptr));
+ ShowBillboard(s1);
+ return 0;
+ }
+ error("#ferror in function 'ShowBillboard': %d %d %s", err.index, err.array, err.type);
+}
+
+static void HideBillboard(const Common::String &name) {
+ Game *game = g_engine->getGame();
+ Billboard *bb = game->scene().billboard(name);
+ if (!bb) {
+ error("[HideBillboard] Billboard not found %s", name.c_str());
+ }
+ bb->model()->setVisible(false);
+}
+
+static int tolua_ExportedFunctions_HideBillboard00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isnoobj(L, 2, &err)) {
+ Common::String s1(tolua_tostring(L, 1, nullptr));
+ HideBillboard(s1);
+ return 0;
+ }
+ error("#ferror in function 'HideBillboard': %d %d %s", err.index, err.array, err.type);
+}
+
static void SetBackground(const Common::String &name) {
Game *game = g_engine->getGame();
if (!game->setBackground(name))
@@ -670,6 +799,55 @@ static int tolua_ExportedFunctions_PushTask00(lua_State *L) {
error("#ferror in function 'PushTask': %d %d %s", err.index, err.array, err.type);
}
+static void DeleteTask(const Common::String &s1, const Common::String &s2) {
+ Game *game = g_engine->getGame();
+ game->objectif().deleteObjectif(s1, s2);
+}
+
+static int tolua_ExportedFunctions_DeleteTask00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isstring(L, 2, 0, &err) && tolua_isnoobj(L, 3, &err)) {
+ Common::String s1(tolua_tostring(L, 1, nullptr));
+ Common::String s2(tolua_tostring(L, 2, nullptr));
+ DeleteTask(s1, s2);
+ return 0;
+ }
+ error("#ferror in function 'DeleteTask': %d %d %s", err.index, err.array, err.type);
+}
+
+static bool TestFileFlagSystemFlag(const Common::String &flagname, const Common::String &val) {
+ if (flagname == "platform" && val == "Android")
+ return true;
+ return g_engine->getCore()->fileFlagSystemFlag(flagname) == val;
+}
+
+static int tolua_ExportedFunctions_TestFileFlagSystemFlag00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isstring(L, 2, 0, &err) && tolua_isnoobj(L, 3, &err)) {
+ Common::String s1(tolua_tostring(L, 1, nullptr));
+ Common::String s2(tolua_tostring(L, 2, nullptr));
+ bool result = TestFileFlagSystemFlag(s1, s2);
+ tolua_pushboolean(L, result);
+ return 1;
+ }
+ error("#ferror in function 'TestFileFlagSystemFlag': %d %d %s", err.index, err.array, err.type);
+}
+
+static void ExitZone(const Common::String &zone) {
+ Game *game = g_engine->getGame();
+ game->setExitZone(zone);
+}
+
+static int tolua_ExportedFunctions_ExitZone00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isnoobj(L, 2, &err)) {
+ Common::String s1(tolua_tostring(L, 1, nullptr));
+ ExitZone(s1);
+ return 0;
+ }
+ error("#ferror in function 'ExitZone': %d %d %s", err.index, err.array, err.type);
+}
+
static void EnableRectBlocker(uint offset, bool enabled) {
Game *game = g_engine->getGame();
if (game->scene().rectBlockers().size() < offset)
@@ -1022,6 +1200,7 @@ static void MoveCharacterPlayerTo(float x, float y, float z, bool walkFlag) {
character->walkMode("Walk");
}
+ assert(character->freeMoveZone());
game->_sceneCharacterVisibleFromLoad = false;
TeIntrusivePtr<TeBezierCurve> curve = character->freeMoveZone()->curve(character->_model->position(), dest);
if (!curve) {
@@ -1096,8 +1275,8 @@ void LuaOpenBinds(lua_State *L) {
/*tolua_function(L, "PushAnswer", tolua_ExportedFunctions_PushAnswer00);
tolua_function(L, "HideAnswers", tolua_ExportedFunctions_HideAnswers00);*/
tolua_function(L, "PushTask", tolua_ExportedFunctions_PushTask00);
- /*tolua_function(L, "DeleteTask", tolua_ExportedFunctions_DeleteTask00);
- tolua_function(L, "SetVisibleButtonHelp", tolua_ExportedFunctions_SetVisibleButtonHelp00);
+ tolua_function(L, "DeleteTask", tolua_ExportedFunctions_DeleteTask00);
+ /*tolua_function(L, "SetVisibleButtonHelp", tolua_ExportedFunctions_SetVisibleButtonHelp00);
tolua_function(L, "HideTasks", tolua_ExportedFunctions_HideTasks00);*/
tolua_function(L, "PlaySound", tolua_ExportedFunctions_PlaySound00);
/*tolua_function(L, "PlaySoundAndWaitForEnd", tolua_ExportedFunctions_PlaySoundAndWaitForEnd00);*/
@@ -1170,14 +1349,14 @@ void LuaOpenBinds(lua_State *L) {
tolua_function(L, "EnableLight", tolua_ExportedFunctions_EnableLight00);
tolua_function(L, "SetLightDiffuse", tolua_ExportedFunctions_SetLightDiffuse00);
tolua_function(L, "SetLightAmbient", tolua_ExportedFunctions_SetLightAmbient00);
- tolua_function(L, "SetLightSpecular", tolua_ExportedFunctions_SetLightSpecular00);
+ tolua_function(L, "SetLightSpecular", tolua_ExportedFunctions_SetLightSpecular00);*/
tolua_function(L, "LoadBillBoard", tolua_ExportedFunctions_LoadBillBoard00);
tolua_function(L, "SetBillboardPosition", tolua_ExportedFunctions_SetBillboardPosition00);
tolua_function(L, "SetBillboardPosition2", tolua_ExportedFunctions_SetBillboardPosition200);
tolua_function(L, "SetBillboardSize", tolua_ExportedFunctions_SetBillboardSize00);
tolua_function(L, "ShowBillboard", tolua_ExportedFunctions_ShowBillboard00);
tolua_function(L, "HideBillboard", tolua_ExportedFunctions_HideBillboard00);
- tolua_function(L, "UnlockAchievement", tolua_ExportedFunctions_UnlockAchievement00);
+ /*tolua_function(L, "UnlockAchievement", tolua_ExportedFunctions_UnlockAchievement00);
tolua_function(L, "Save", tolua_ExportedFunctions_Save00);
tolua_function(L, "Wait", tolua_ExportedFunctions_Wait00);
tolua_function(L, "WaitAndWaitForEnd", tolua_ExportedFunctions_WaitAndWaitForEnd00);
@@ -1187,10 +1366,10 @@ void LuaOpenBinds(lua_State *L) {
tolua_function(L, "BFGRateImmediately", tolua_ExportedFunctions_BFGRateImmediately00);
tolua_function(L, "BFGReportEvent", tolua_ExportedFunctions_BFGReportEvent00);
tolua_function(L, "BFGReportEventWithValue", tolua_ExportedFunctions_BFGReportEventWithValue00);
- tolua_function(L, "BFGReachedFreemiumLimit", tolua_ExportedFunctions_BFGReachedFreemiumLimit00);
+ tolua_function(L, "BFGReachedFreemiumLimit", tolua_ExportedFunctions_BFGReachedFreemiumLimit00);*/
tolua_function(L, "TestFileFlagSystemFlag", tolua_ExportedFunctions_TestFileFlagSystemFlag00);
// tolua_function(L, "PrintDebugMessage", tolua_ExportedFunctions_PrintDebugMessage00); // Unused
- tolua_function(L, "ExitZone", tolua_ExportedFunctions_ExitZone00);*/
+ tolua_function(L, "ExitZone", tolua_ExportedFunctions_ExitZone00);
tolua_function(L, "EnableRectBlocker", tolua_ExportedFunctions_EnableRectBlocker00);
/*tolua_function(L, "EnableBlocker", tolua_ExportedFunctions_EnableBlocker00);*/
tolua_function(L, "AddAnchorZone", tolua_ExportedFunctions_AddAnchorZone00);
diff --git a/engines/tetraedge/game/objectif.cpp b/engines/tetraedge/game/objectif.cpp
index 96a2731f962..acc0f042e87 100644
--- a/engines/tetraedge/game/objectif.cpp
+++ b/engines/tetraedge/game/objectif.cpp
@@ -121,6 +121,15 @@ void Objectif::pushObjectif(Common::String const &head, Common::String const &su
_tasks.back()._taskFlag = true;
}
+void Objectif::deleteObjectif(Common::String const &head, Common::String const &sub) {
+ for (Task &t : _tasks) {
+ if (t._taskFlag && t._headTask == head && t._subTask == sub) {
+ t._taskFlag = false;
+ return;
+ }
+ }
+}
+
void Objectif::reattachLayout(TeLayout *layout) {
TeButtonLayout *btn;
diff --git a/engines/tetraedge/game/objectif.h b/engines/tetraedge/game/objectif.h
index 44ae6050f46..cf0b0ca4124 100644
--- a/engines/tetraedge/game/objectif.h
+++ b/engines/tetraedge/game/objectif.h
@@ -42,6 +42,7 @@ public:
bool hideBouton();
bool isMouseIn(const TeVector2s32 &mousept);
bool isVisibleObjectif();
+ void deleteObjectif(Common::String const &head, Common::String const &sub);
void leave();
void load();
bool onHelpButtonValidated();
Commit: 64c72672834651973d7c2986be86e2a1a3713278
https://github.com/scummvm/scummvm/commit/64c72672834651973d7c2986be86e2a1a3713278
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2023-01-16T17:36:43+01:00
Commit Message:
TETRAEDGE: Many small improvements.
Fixed many things, but Z-order of objects is still wrong - UI elements not
showing correctly.
Changed paths:
engines/tetraedge/game/application.cpp
engines/tetraedge/game/billboard.cpp
engines/tetraedge/game/character.cpp
engines/tetraedge/game/dialog2.cpp
engines/tetraedge/game/dialog2.h
engines/tetraedge/game/game.cpp
engines/tetraedge/game/in_game_scene.cpp
engines/tetraedge/game/in_game_scene.h
engines/tetraedge/game/inventory.cpp
engines/tetraedge/game/inventory.h
engines/tetraedge/game/lua_binds.cpp
engines/tetraedge/game/question2.cpp
engines/tetraedge/te/te_3d_texture.cpp
engines/tetraedge/te/te_3d_texture.h
engines/tetraedge/te/te_camera.cpp
engines/tetraedge/te/te_frame_anim.cpp
engines/tetraedge/te/te_free_move_zone.cpp
engines/tetraedge/te/te_layout.cpp
engines/tetraedge/te/te_lua_gui_lua_callbacks.cpp
engines/tetraedge/te/te_material.cpp
engines/tetraedge/te/te_material.h
engines/tetraedge/te/te_mesh.cpp
engines/tetraedge/te/te_mesh.h
engines/tetraedge/te/te_model.cpp
engines/tetraedge/te/te_model_animation.cpp
engines/tetraedge/te/te_renderer.cpp
engines/tetraedge/te/te_renderer.h
engines/tetraedge/te/te_sprite_layout.cpp
engines/tetraedge/te/te_text_base2.cpp
engines/tetraedge/te/te_tiled_surface.cpp
diff --git a/engines/tetraedge/game/application.cpp b/engines/tetraedge/game/application.cpp
index 6fc5150494a..37af6a70bc2 100644
--- a/engines/tetraedge/game/application.cpp
+++ b/engines/tetraedge/game/application.cpp
@@ -252,7 +252,7 @@ void Application::create() {
_autoSaveIcon2.setName("autosaveIcon");
_autoSaveIcon2.setAnchor(TeVector3f32(0.5f, 0.5f, 0.0f));
_autoSaveIcon2.setPosition(TeVector3f32(0.2f, 0.7f, 0.0f));
- _autoSaveIcon2.setSize(TeVector3f32(68.0f, 86.0f, 0.0f));
+ _autoSaveIcon2.setSize(TeVector3f32(64.0f, 86.0f, 0.0f));
_autoSaveIcon2.load("menus/inGame/NoCel.png");
_autoSaveIcon2.setVisible(false);
_frontOrientationLayout.addChild(&_autoSaveIcon2);
diff --git a/engines/tetraedge/game/billboard.cpp b/engines/tetraedge/game/billboard.cpp
index 068abcb0f36..3e95616de21 100644
--- a/engines/tetraedge/game/billboard.cpp
+++ b/engines/tetraedge/game/billboard.cpp
@@ -27,7 +27,7 @@
namespace Tetraedge {
-Billboard::Billboard() {
+Billboard::Billboard() : _hasPos2(false) {
}
bool Billboard::load(const Common::String &path) {
@@ -40,13 +40,52 @@ bool Billboard::load(const Common::String &path) {
Common::Array<TeVector3f32> quad;
quad.resize(4);
_model->setQuad(texture, quad, TeColor(0xff, 0xff, 0xff, 0xff));
+ _model->setVisible(false);
game->scene().models().push_back(_model);
return true;
}
void Billboard::calcVertex() {
- //Game *game = g_engine->getGame();
- warning("TODO: implement Billboard::calcVertex");
+ Game *game = g_engine->getGame();
+ TeIntrusivePtr<TeCamera> currentCam = game->scene().currentCamera();
+ assert(currentCam);
+ currentCam->apply();
+ const TeMatrix4x4 camProjMatrix = currentCam->projectionMatrix();
+ TeMatrix4x4 camWorldInverse = currentCam->worldTransformationMatrix();
+ camWorldInverse.inverse();
+
+ const TeMatrix4x4 camTotalTransform = camProjMatrix * camWorldInverse;
+ TeMatrix4x4 camTotalInverse = camTotalTransform;
+ camTotalInverse.inverse();
+
+ TeVector3f32 posvec(0.0f, 0.0f, _pos.z());
+ if (_hasPos2) {
+ posvec = _pos2;
+ }
+ posvec = camTotalTransform * posvec;
+
+ TeVector3f32 meshVertex;
+ float fx, fy;
+
+ fx = _pos.x();
+ fy = _pos.y();
+ meshVertex = camTotalInverse * TeVector3f32(fx + fx - 1.0f, fy + fy - 1.0f, posvec.z());
+ _model->_meshes[0].setVertex(0, meshVertex);
+
+ fx = _pos.x();
+ fy = _pos.y() + _size.getY();
+ meshVertex = camTotalInverse * TeVector3f32(fx + fx - 1.0f, fy + fy - 1.0f, posvec.z());
+ _model->_meshes[0].setVertex(1, meshVertex);
+
+ fx = _pos.x() + _size.getX();
+ fy = _pos.y();
+ meshVertex = camTotalInverse * TeVector3f32(fx + fx - 1.0f, fy + fy - 1.0f, posvec.z());
+ _model->_meshes[0].setVertex(2, meshVertex);
+
+ fx = _pos.x() + _size.getX();
+ fy = _pos.y() + _size.getY();
+ meshVertex = camTotalInverse * TeVector3f32(fx + fx - 1.0f, fy + fy - 1.0f, posvec.z());
+ _model->_meshes[0].setVertex(3, meshVertex);
}
void Billboard::position(const TeVector3f32 &pos) {
diff --git a/engines/tetraedge/game/character.cpp b/engines/tetraedge/game/character.cpp
index fd8b39755cd..98299ae6323 100644
--- a/engines/tetraedge/game/character.cpp
+++ b/engines/tetraedge/game/character.cpp
@@ -192,7 +192,7 @@ bool Character::blendAnimation(const Common::String &animname, float amount, boo
_lastFrame = -1;
_curModelAnim->play();
_curAnimName = animname;
- warning("TODO: Set field 0x2d1 in Character::blendAnimation");
+ _someRepeatFlag = !(repeat | !param_4);
return true;
}
@@ -743,8 +743,8 @@ void Character::update(double msFromStart) {
newPos = _freeMoveZone->correctCharacterPosition(newPos, &correctflag, true);
}
- debug("Character::update %4d %.04f %s -> %s %.4f", (int)msFromStart, offset, _model->position().dump().c_str(),
- newPos.dump().c_str(), (newPos - _model->position()).length());
+ //debug("Character::update %4d %.04f %s -> %s %.4f", (int)msFromStart, offset, _model->position().dump().c_str(),
+ // newPos.dump().c_str(), (newPos - _model->position()).length());
_walkCurveLast = offset;
_model->setPosition(newPos);
diff --git a/engines/tetraedge/game/dialog2.cpp b/engines/tetraedge/game/dialog2.cpp
index 8b210514963..5437c206270 100644
--- a/engines/tetraedge/game/dialog2.cpp
+++ b/engines/tetraedge/game/dialog2.cpp
@@ -69,7 +69,7 @@ void Dialog2::launchNextDialog() {
if (!_currentDialogData._charname.empty()) {
Character *c = game->scene().character(_currentDialogData._charname);
if (!c) {
- error("[Dialog2::launchNextDialog] Character's \"%s\" doesn\'t exist", _currentDialogData._charname.c_str());
+ error("[Dialog2::launchNextDialog] Character's \"%s\" doesn't exist", _currentDialogData._charname.c_str());
}
if (_currentDialogData._animBlend == 0.0f) {
@@ -82,8 +82,8 @@ void Dialog2::launchNextDialog() {
_currentDialogData._animfile.c_str(), _currentDialogData._charname.c_str());
}
}
- _gui.buttonLayoutChecked("dialogLockButton")->setVisible(true);
- TeCurveAnim2<TeLayout, TeVector3f32> *anim = _gui.layoutAnchorLinearAnimation("dialogAnimationDown");
+ lockBtn->setVisible(true);
+ TeCurveAnim2<TeLayout, TeVector3f32> *anim = _gui.layoutAnchorLinearAnimation("dialogAnimationUp");
anim->stop();
anim->play();
_minimumTimeTimer.start();
@@ -126,7 +126,7 @@ void Dialog2::loadFromBackup() {
}
bool Dialog2::onAnimationDownFinished() {
- Common::String param(_animDownFinishedResultString);
+ Common::String param(_currentDialogData._name);
launchNextDialog();
_onAnimationDownFinishedSignal.call(param);
return false;
@@ -165,7 +165,7 @@ bool Dialog2::onSoundFinished() {
}
void Dialog2::pushDialog(const Common::String &name, const Common::String &textVal, const Common::String &sound, int param_4) {
- error("TODO: Implement Dialog2::pushDialog");
+ error("TODO: Implement Dialog2::pushDialog 3 param");
}
void Dialog2::pushDialog(const Common::String &name, const Common::String &textVal, const Common::String &sound,
@@ -204,10 +204,9 @@ void Dialog2::unload() {
dialogAnimDown->stop();
_music.close();
_gui.unload();
- error("TODO: Finish Dialog2::unload");
- //_dialogDataList.clear();
- //_minimumTimeTimer.stop();
+ _dialogs.clear();
+ _minimumTimeTimer.stop();
}
} // end namespace Tetraedge
diff --git a/engines/tetraedge/game/dialog2.h b/engines/tetraedge/game/dialog2.h
index a4c4a269a29..5c21231e2b7 100644
--- a/engines/tetraedge/game/dialog2.h
+++ b/engines/tetraedge/game/dialog2.h
@@ -60,16 +60,11 @@ public:
TeLuaGUI &gui() { return _gui; }
- Common::String prevSceneName() { return _prevSceneName; };
-
private:
Common::Array<DialogData> _dialogs;
TeTimer _minimumTimeTimer;
- Common::String _prevSceneName;
- Common::String _animDownFinishedResultString;
-
TeLuaGUI _gui;
TeMusic _music;
diff --git a/engines/tetraedge/game/game.cpp b/engines/tetraedge/game/game.cpp
index d8fc15069a6..407a7730b5b 100644
--- a/engines/tetraedge/game/game.cpp
+++ b/engines/tetraedge/game/game.cpp
@@ -44,11 +44,14 @@
namespace Tetraedge {
-Game::Game() : _objectsTakenVal(0), _score(0), _entered(false), _gameLoadState(0),
-_noScaleLayout(nullptr), _noScaleLayout2(nullptr), _warped(false), _saveRequested(false),
-_firstInventory(true), _movePlayerCharacterDisabled(false), _enteredFlag2(false),
-_luaShowOwnerError(false), _markersVisible(false), _running(false), _loadName("save.xml"),
-_randomSoundFinished(false), _randomSource("SyberiaGameRandom") {
+Game::Game() : _objectsTakenVal(0), _returnToMainMenu(false), _entered(false),
+_enteredFlag2(false), _running(false), _movePlayerCharacterDisabled(false),
+_noScaleLayout(nullptr), _noScaleLayout2(nullptr), _isCharacterIdle(true),
+_sceneCharacterVisibleFromLoad(false), _isCharacterWalking(false),
+_lastCharMoveMousePos(0.0f, 0.0f), _randomSoundFinished(false),
+_previousMousePos(-1, -1), _markersVisible(true), _saveRequested(false),
+_gameLoadState(0), _luaShowOwnerError(false), _score(0), _warped(false),
+_firstInventory(true), _loadName("save.xml"), _randomSource("SyberiaGameRandom") {
for (int i = 0; i < NUM_OBJECTS_TAKEN_IDS; i++) {
_objectsTakenBits[i] = false;
}
@@ -337,7 +340,7 @@ void Game::enter(bool newgame) {
_sceneCharacterVisibleFromLoad = true;
_scene._character->onFinished().remove(this, &Game::onDisplacementFinished);
_scene._character->onFinished().add(this, &Game::onDisplacementFinished);
- _dialog2.prevSceneName().clear();
+ _prevSceneName.clear();
_notifier.load();
}
@@ -549,9 +552,9 @@ bool Game::initWarp(const Common::String &zone, const Common::String &scene, boo
video->_tiledSurfacePtr->_frameAnim.onFinished().add(this, &Game::onVideoFinished);
TeButtonLayout *invbtn = _inGameGui.buttonLayout("inventoryButton");
- invbtn->setSizeType(TeILayout::RELATIVE_TO_PARENT); // TODO: Double-check if this is the right virt fn.
invbtn->onMouseClickValidated().remove(this, &Game::onInventoryButtonValidated);
invbtn->onMouseClickValidated().add(this, &Game::onInventoryButtonValidated);
+ invbtn->setSizeType(TeILayout::RELATIVE_TO_PARENT);
const TeVector3f32 winSize = app->getMainWindow().size();
if (g_engine->getCore()->fileFlagSystemFlag("definition") == "SD") {
@@ -1436,11 +1439,8 @@ void Game::update() {
app->_lockCursorButton.setVisible(false);
}
- TeButtonLayout *invbtn = _inGameGui.buttonLayout("inventoryButton");
- if (invbtn)
- invbtn->setVisible(!app->isLockCursor() && !_dialog2.isDialogPlaying());
- else
- warning("Game::update: InventoryButton is null.");
+ TeButtonLayout *invbtn = _inGameGui.buttonLayoutChecked("inventoryButton");
+ invbtn->setVisible(!app->isLockCursor() && !_dialog2.isDialogPlaying());
Character *player = _scene._character;
if (player) {
diff --git a/engines/tetraedge/game/in_game_scene.cpp b/engines/tetraedge/game/in_game_scene.cpp
index 6df97b971d5..7aabee33cfe 100644
--- a/engines/tetraedge/game/in_game_scene.cpp
+++ b/engines/tetraedge/game/in_game_scene.cpp
@@ -700,11 +700,11 @@ bool InGameScene::loadObject(const Common::String &name) {
return true;
}
-void InGameScene::loadObjectMaterials(const Common::String &name) {
+bool InGameScene::loadObjectMaterials(const Common::String &name) {
error("TODO: InGameScene::loadObjectMaterials");
}
-void InGameScene::loadObjectMaterials(const Common::String &path, const Common::String &name) {
+bool InGameScene::loadObjectMaterials(const Common::String &path, const Common::String &name) {
error("TODO: InGameScene::loadObjectMaterials");
}
diff --git a/engines/tetraedge/game/in_game_scene.h b/engines/tetraedge/game/in_game_scene.h
index cf08c1e874a..690e76ec861 100644
--- a/engines/tetraedge/game/in_game_scene.h
+++ b/engines/tetraedge/game/in_game_scene.h
@@ -143,8 +143,8 @@ public:
bool loadLights(const Common::Path &path);
void loadMarkers(const Common::Path &path);
bool loadObject(const Common::String &oname);
- void loadObjectMaterials(const Common::String &name);
- void loadObjectMaterials(const Common::String &path, const Common::String &name);
+ bool loadObjectMaterials(const Common::String &name);
+ bool loadObjectMaterials(const Common::String &path, const Common::String &name);
bool loadPlayerCharacter(const Common::String &cname);
void moveCharacterTo(const Common::String &charName, const Common::String &curveName, float curveOffset, float curveEnd);
diff --git a/engines/tetraedge/game/inventory.cpp b/engines/tetraedge/game/inventory.cpp
index f6cd44a6b9a..dc48f38fb07 100644
--- a/engines/tetraedge/game/inventory.cpp
+++ b/engines/tetraedge/game/inventory.cpp
@@ -69,9 +69,7 @@ void Inventory::load() {
setSizeType(RELATIVE_TO_PARENT);
setSize(TeVector3f32(1.0f, 1.0f, userSize().z()));
_gui.load("Inventory/Inventory.lua");
- TeLayout *invlayout = _gui.layout("inventory");
- if (!invlayout)
- error("Inventory::load: Couldn't find inventory layout after loading");
+ TeLayout *invlayout = _gui.layoutChecked("inventory");
addChild(invlayout);
TeButtonLayout *btn;
@@ -83,7 +81,6 @@ void Inventory::load() {
btn->onMouseClickValidated().add(this, &Inventory::onTakeObjectSelected);
btn = _gui.buttonLayoutChecked("lire");
- btn->setVisible(false);
btn->setEnable(false);
btn->onMouseClickValidated().add(this, &Inventory::onZoomed);
@@ -119,6 +116,7 @@ void Inventory::load() {
TeLayout *layout = _gui.layout("selectionSprite");
layout->setVisible(false);
+ _invObjects.clear();
setVisible(false);
}
@@ -183,13 +181,13 @@ void Inventory::loadCellphone() {
void Inventory::addObject(const Common::String &objId) {
InventoryObject *newobj = new InventoryObject();
newobj->load(objId);
- if (!addObject(*newobj))
+ if (!addObject(newobj))
delete newobj;
}
-bool Inventory::addObject(InventoryObject &obj) {
- _invObjects.push_front(&obj);
- obj.selectedSignal().add(this, &Inventory::onObjectSelected);
+bool Inventory::addObject(InventoryObject *obj) {
+ _invObjects.push_front(obj);
+ obj->selectedSignal().add(this, &Inventory::onObjectSelected);
if (_invObjects.size() > 1) {
int pageno = 0;
while (true) {
@@ -217,9 +215,10 @@ bool Inventory::addObject(InventoryObject &obj) {
int pageno = 0;
unsigned int totalSlots = 0;
bool retval;
- const Common::String newObjName = obj.name();
+ const Common::String newObjName = obj->name();
auto invObjIter = _invObjects.begin();
- while (true) {
+ bool finished = false;
+ while (!finished) {
TeLayout *page = _gui.layout(Common::String::format("page%d", pageno));
retval = false;
if (!page)
@@ -232,8 +231,7 @@ bool Inventory::addObject(InventoryObject &obj) {
retval = true;
if (totalSlots == _invObjects.size()) {
- // break from both loops (slight hack..)
- pageno = 9999;
+ finished = true;
break;
}
@@ -282,7 +280,7 @@ Common::String Inventory::objectDescription(const Common::String &objId) {
Common::String Inventory::objectName(const Common::String &objId) {
if (!_objectData.contains(objId))
return "";
- return _objectData.getVal(objId)._id;
+ return _objectData.getVal(objId)._name;
}
bool Inventory::onMainMenuButton() {
diff --git a/engines/tetraedge/game/inventory.h b/engines/tetraedge/game/inventory.h
index 53661da3ae5..9743a8609d3 100644
--- a/engines/tetraedge/game/inventory.h
+++ b/engines/tetraedge/game/inventory.h
@@ -51,7 +51,7 @@ public:
//void saveToBackup(TiXmlNode *node);
void addObject(const Common::String &objname);
- bool addObject(InventoryObject &obj);
+ bool addObject(InventoryObject *obj);
bool isDocument(const Common::String &objname);
int objectCount(const Common::String &objname);
diff --git a/engines/tetraedge/game/lua_binds.cpp b/engines/tetraedge/game/lua_binds.cpp
index 759af23615e..e8c74ffb3dd 100644
--- a/engines/tetraedge/game/lua_binds.cpp
+++ b/engines/tetraedge/game/lua_binds.cpp
@@ -37,6 +37,44 @@ namespace LuaBinds {
using namespace ToLua;
+static void LoadObjectMaterials(const Common::String &objname) {
+ Game *game = g_engine->getGame();
+ bool result = game->scene().loadObjectMaterials(objname);
+ if (!result)
+ error("[LoadObjectMaterials] Object \"%s\" doesn't exist or no Object in this scene.",
+ objname.c_str());
+}
+
+static int tolua_ExportedFunctions_LoadObjectMaterials00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isnoobj(L, 2, &err)) {
+ Common::String s1(tolua_tostring(L, 1, nullptr));
+ LoadObjectMaterials(s1);
+ return 0;
+ }
+ error("#ferror in function 'LoadObjectMaterials': %d %d %s", err.index, err.array, err.type);
+}
+
+static void LoadObjectMaterials(const Common::String &imgname, const Common::String &objname) {
+ Game *game = g_engine->getGame();
+ bool result = game->scene().loadObjectMaterials(imgname, objname);
+ if (!result)
+ error("[LoadObjectMaterials] Object \"%s\" doesn't exist in scene : \"%s\" or there is no material for this object.",
+ objname.c_str(), imgname.c_str());
+}
+
+static int tolua_ExportedFunctions_LoadObjectMaterials01(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isstring(L, 2, 0, &err) && tolua_isnoobj(L, 3, &err)) {
+ Common::String s1(tolua_tostring(L, 1, nullptr));
+ Common::String s2(tolua_tostring(L, 2, nullptr));
+ LoadObjectMaterials(s1, s2);
+ return 0;
+ }
+ error("#ferror in function 'LoadObjectMaterials': %d %d %s", err.index, err.array, err.type);
+}
+
+
static void PlayMovie(const Common::String &vidpath, const Common::String &musicpath) {
Application *app = g_engine->getApplication();
app->mouseCursorLayout().load("pictures/cursor.png");
@@ -111,7 +149,7 @@ static int tolua_ExportedFunctions_Selected00(lua_State *L) {
static void TakeObject(const Common::String &obj) {
Game *game = g_engine->getGame();
- warning("TODO: Set global _lastHitObjectName");
+ // TODO: Set global _lastHitObjectName?? How is it used?
//game->luaContext().setGlobal(_lastHitObjectName, true);
if (!obj.empty())
game->addToBag(obj);
@@ -323,6 +361,31 @@ static int tolua_ExportedFunctions_SetVisibleCellphone00(lua_State *L) {
error("#ferror in function 'SetVisibleCellphone': %d %d %s", err.index, err.array, err.type);
}
+static void ShowObject(const Common::String &objName);
+
+static void StartAnimation(const Common::String name, int loops, bool repeat) {
+ ShowObject(name);
+ Game *game = g_engine->getGame();
+ if (game->startAnimation(name, loops, repeat))
+ return;
+
+ error("[StartAnimation] Animation \"%s\" doesn't exist.", name.c_str());
+}
+
+int tolua_ExportedFunctions_StartAnimation00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isnumber(L, 2, 1, &err)
+ && tolua_isboolean(L, 3, 1, &err) && tolua_isnoobj(L, 4, &err)) {
+ Common::String s1(tolua_tostring(L, 1, nullptr));
+ double d1 = tolua_tonumber(L, 2, -1.0);
+ bool b1 = tolua_toboolean(L, 3, 0);
+ StartAnimation(s1, d1, b1);
+ return 0;
+ }
+ error("#ferror in function 'StartAnimation': %d %d %s", err.index, err.array, err.type);
+
+}
+
static void RequestAutoSave() {
Game *game = g_engine->getGame();
game->setSaveRequested();
@@ -433,6 +496,34 @@ static int tolua_ExportedFunctions_UnloadObject00(lua_State *L) {
error("#ferror in function 'UnloadObject': %d %d %s", err.index, err.array, err.type);
}
+static void PlaceCharacterOnDummy(const Common::String &charname, const Common::String &dummyname, float x, float y, float z) {
+ Game *game = g_engine->getGame();
+ Character *c = game->scene().character(charname);
+ if (c) {
+ InGameScene::Dummy dummy = game->scene().dummy(dummyname);
+ c->_model->setPosition(dummy._position + TeVector3f32(x, y, z));
+ } else {
+ warning("[PlaceCharacterOnDummy] Character not found %s", charname.c_str());
+ }
+
+}
+
+static int tolua_ExportedFunctions_PlaceCharacterOnDummy00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isstring(L, 2, 0, &err)
+ && tolua_isnumber(L, 3, 0, &err) && tolua_isnumber(L, 4, 0, &err)
+ && tolua_isnumber(L, 5, 0, &err) && tolua_isnoobj(L, 6, &err)) {
+ Common::String s1(tolua_tostring(L, 1, nullptr));
+ Common::String s2(tolua_tostring(L, 2, nullptr));
+ float f1 = tolua_tonumber(L, 3, 0.0);
+ float f2 = tolua_tonumber(L, 4, 0.0);
+ float f3 = tolua_tonumber(L, 5, 0.0);
+ PlaceCharacterOnDummy(s1, s2, f1, f2, f3);
+ return 0;
+ }
+ error("#ferror in function 'SetCharacterRotation': %d %d %s", err.index, err.array, err.type);
+}
+
static void SetCharacterRotation(const Common::String &charname, float rx, float ry, float rz) {
TeQuaternion quat = TeQuaternion::fromEuler(TeVector3f32(rx * M_PI / 180.0, ry * M_PI / 180.0, rz * M_PI / 180.0));
Game *game = g_engine->getGame();
@@ -783,6 +874,41 @@ static int tolua_ExportedFunctions_LaunchDialogAndWaitForEnd00(lua_State *L) {
error("#ferror in function 'LaunchDialogAndWaitForEnd': %d %d %s", err.index, err.array, err.type);
}
+static void PushAnswer(const Common::String &val, const Common::String &gui) {
+ Application *app = g_engine->getApplication();
+ const Common::String *locVal = app->_loc.value(val);
+ Common::String locValStr;
+ if (locVal) {
+ locValStr = *locVal;
+ }
+ Game *game = g_engine->getGame();
+ game->question2().pushAnswer(val, locValStr, gui);
+}
+
+static int tolua_ExportedFunctions_PushAnswer00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isstring(L, 2, 0, &err) && tolua_isnoobj(L, 3, &err)) {
+ Common::String s1(tolua_tostring(L, 1, nullptr));
+ Common::String s2(tolua_tostring(L, 2, nullptr));
+ PushAnswer(s1, s2);
+ return 0;
+ }
+ error("#ferror in function 'PushAnswer': %d %d %s", err.index, err.array, err.type);
+}
+
+static void HideAnswers() {
+ g_engine->getGame()->question2().leave();
+}
+
+static int tolua_ExportedFunctions_HideAnswers00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isnoobj(L, 1, &err)) {
+ HideAnswers();
+ return 0;
+ }
+ error("#ferror in function 'HideAnswers': %d %d %s", err.index, err.array, err.type);
+}
+
static void PushTask(const Common::String &s1, const Common::String &s2) {
Game *game = g_engine->getGame();
game->objectif().pushObjectif(s1, s2);
@@ -918,6 +1044,37 @@ static int tolua_ExportedFunctions_ActivateAnchorZone00(lua_State *L) {
error("#ferror in function 'ActivateAnchorZone': %d %d %s", err.index, err.array, err.type);
}
+static void SetCharacterLookChar(const Common::String &charname, const Common::String &destname, bool tall) {
+ Game *game = g_engine->getGame();
+ Character *character = game->scene().character(charname);
+ if (!character)
+ error("[SetCharacterLookChar] Character \"%s\" doesn't exist", charname.c_str());
+ character->setLookingAtTallThing(tall);
+ if (destname.empty()) {
+ character->setCharLookingAt(nullptr);
+ } else {
+ Character *destchar = game->scene().character(destname);
+ character->setCharLookingAt(destchar);
+ if (destchar)
+ return;
+ }
+ character->setLastHeadRotation(character->headRotation());
+ character->setHasAnchor(false);
+}
+
+static int tolua_ExportedFunctions_SetCharacterLookChar00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isstring(L, 2, 0, &err)
+ && tolua_isboolean(L, 3, 1, &err) && tolua_isnoobj(L, 4, &err)) {
+ Common::String s1(tolua_tostring(L, 1, nullptr));
+ Common::String s2(tolua_tostring(L, 2, nullptr));
+ bool b = tolua_toboolean(L, 3, 1);
+ SetCharacterLookChar(s1, s2, b);
+ return 0;
+ }
+ error("#ferror in function 'SetCharacterLookChar': %d %d %s", err.index, err.array, err.type);
+}
+
static void DisabledZone(const Common::String &s1, bool b) {
Game *game = g_engine->getGame();
if (!game->scene().markerGui().loaded())
@@ -1042,8 +1199,10 @@ static int tolua_ExportedFunctions_PlayMusic00(lua_State *L) {
static void SetObjectOnCharacter(const Common::String &obj, const Common::String &charName, const Common::String &boneName) {
Game *game = g_engine->getGame();
Object3D *obj3d = game->scene().object3D(obj);
- if (!obj3d)
+ if (!obj3d) {
warning("[SetObjectOnCharacter] Object not found %s", obj.c_str());
+ return;
+ }
obj3d->_onCharName = charName;
obj3d->_onCharBone = boneName;
@@ -1176,6 +1335,56 @@ static int tolua_ExportedFunctions_CurrentCharacterAnimation00(lua_State *L) {
error("#ferror in function 'CurrentCharacterAnimation': %d %d %s", err.index, err.array, err.type);
}
+static void LoadCharacter(const Common::String &name) {
+ Game *game = g_engine->getGame();
+ game->loadCharacter(name);
+}
+
+static int tolua_ExportedFunctions_LoadCharacter00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isnoobj(L, 2, &err)) {
+ Common::String s1(tolua_tostring(L, 1, nullptr));
+ LoadCharacter(s1);
+ return 0;
+ }
+ error("#ferror in function 'LoadCharacter': %d %d %s", err.index, err.array, err.type);
+}
+
+static void UnloadCharacter(const Common::String &name) {
+ Game *game = g_engine->getGame();
+ game->unloadCharacter(name);
+}
+
+static int tolua_ExportedFunctions_UnloadCharacter00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isnoobj(L, 2, &err)) {
+ Common::String s1(tolua_tostring(L, 1, nullptr));
+ UnloadCharacter(s1);
+ return 0;
+ }
+ error("#ferror in function 'UnloadCharacter': %d %d %s", err.index, err.array, err.type);
+}
+
+static void MoveCharacterTo(const Common::String &charName, const Common::String &curveName, float f1,float f2) {
+ Game *game = g_engine->getGame();
+ game->scene().moveCharacterTo(charName, curveName, f1, f2);
+}
+
+static int tolua_ExportedFunctions_MoveCharacterTo00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isstring(L, 2, 0, &err)
+ && tolua_isstring(L, 3, 0, &err) && tolua_isstring(L, 4, 0, &err)
+ && tolua_isnoobj(L, 5, &err)) {
+ Common::String s1(tolua_tostring(L, 1, nullptr));
+ Common::String s2(tolua_tostring(L, 2, nullptr));
+ float f1 = tolua_tonumber(L, 3, 0.0);
+ float f2 = tolua_tonumber(L, 4, 0.0);
+ MoveCharacterTo(s1, s2, f1, f2);
+ return 0;
+ }
+ error("#ferror in function 'MoveCharacterTo': %d %d %s", err.index, err.array, err.type);
+}
+
static void MoveCharacterPlayerTo(float x, float y, float z, bool walkFlag) {
Game *game = g_engine->getGame();
if (game->_movePlayerCharacterDisabled)
@@ -1241,9 +1450,8 @@ void LuaOpenBinds(lua_State *L) {
tolua_open(L);
tolua_module(L, 0, 0);
tolua_beginmodule(L, 0);
- /*
tolua_function(L, "LoadObjectMaterials", tolua_ExportedFunctions_LoadObjectMaterials00);
- tolua_function(L, "LoadObjectMaterials", tolua_ExportedFunctions_LoadObjectMaterials01);*/
+ tolua_function(L, "LoadObjectMaterials", tolua_ExportedFunctions_LoadObjectMaterials01);
tolua_function(L, "HideObject", tolua_ExportedFunctions_HideObject00);
tolua_function(L, "ShowObject", tolua_ExportedFunctions_ShowObject00);
// tolua_function(L, "ShowAllObjects", tolua_ExportedFunctions_ShowAllObjects00); // Never used
@@ -1253,9 +1461,9 @@ void LuaOpenBinds(lua_State *L) {
tolua_function(L, "ChangeWarp", tolua_ExportedFunctions_ChangeWarp00);
tolua_function(L, "PlayMovie", tolua_ExportedFunctions_PlayMovie00);
/*tolua_function(L, "PlayMovieAndWaitForEnd", tolua_ExportedFunctions_PlayMovieAndWaitForEnd00);
- tolua_function(L, "StartAnimationPart", tolua_ExportedFunctions_StartAnimationPart00);
+ tolua_function(L, "StartAnimationPart", tolua_ExportedFunctions_StartAnimationPart00);*/
tolua_function(L, "StartAnimation", tolua_ExportedFunctions_StartAnimation00);
- tolua_function(L, "StartAnimationAndWaitForEnd",
+ /*tolua_function(L, "StartAnimationAndWaitForEnd",
tolua_ExportedFunctions_StartAnimationAndWaitForEnd00);
tolua_function(L, "AddAnimToSet", tolua_ExportedFunctions_AddAnimToSet00); */
tolua_function(L, "RequestAutoSave", tolua_ExportedFunctions_RequestAutoSave00);
@@ -1272,12 +1480,12 @@ void LuaOpenBinds(lua_State *L) {
tolua_function(L, "TutoActive", tolua_ExportedFunctions_TutoActive00);*/
tolua_function(L, "LaunchDialog", tolua_ExportedFunctions_LaunchDialog00);
tolua_function(L, "LaunchDialogAndWaitForEnd", tolua_ExportedFunctions_LaunchDialogAndWaitForEnd00);
- /*tolua_function(L, "PushAnswer", tolua_ExportedFunctions_PushAnswer00);
- tolua_function(L, "HideAnswers", tolua_ExportedFunctions_HideAnswers00);*/
+ tolua_function(L, "PushAnswer", tolua_ExportedFunctions_PushAnswer00);
+ tolua_function(L, "HideAnswers", tolua_ExportedFunctions_HideAnswers00);
tolua_function(L, "PushTask", tolua_ExportedFunctions_PushTask00);
tolua_function(L, "DeleteTask", tolua_ExportedFunctions_DeleteTask00);
- /*tolua_function(L, "SetVisibleButtonHelp", tolua_ExportedFunctions_SetVisibleButtonHelp00);
- tolua_function(L, "HideTasks", tolua_ExportedFunctions_HideTasks00);*/
+ /*tolua_function(L, "SetVisibleButtonHelp", tolua_ExportedFunctions_SetVisibleButtonHelp00);*/
+ // tolua_function(L, "HideTasks", tolua_ExportedFunctions_HideTasks00); Not used.
tolua_function(L, "PlaySound", tolua_ExportedFunctions_PlaySound00);
/*tolua_function(L, "PlaySoundAndWaitForEnd", tolua_ExportedFunctions_PlaySoundAndWaitForEnd00);*/
tolua_function(L, "StopSound", tolua_ExportedFunctions_StopSound00);
@@ -1294,22 +1502,22 @@ void LuaOpenBinds(lua_State *L) {
/*tolua_function(L, "ShowDocument", tolua_ExportedFunctions_ShowDocument00);
tolua_function(L, "ShowDocumentAndWaitForEnd", tolua_ExportedFunctions_ShowDocumentAndWaitForEnd00);
tolua_function(L, "HideDocument", tolua_ExportedFunctions_HideDocument00);
- tolua_function(L, "AddDocument", tolua_ExportedFunctions_AddDocument00);
+ tolua_function(L, "AddDocument", tolua_ExportedFunctions_AddDocument00);*/
tolua_function(L, "LoadCharacter", tolua_ExportedFunctions_LoadCharacter00);
tolua_function(L, "UnloadCharacter", tolua_ExportedFunctions_UnloadCharacter00);
- tolua_function(L, "GetRotationCharacter", tolua_ExportedFunctions_GetRotationCharacter00);
- tolua_function(L, "GetXPositionCharacter", tolua_ExportedFunctions_GetXPositionCharacter00);
- tolua_function(L, "GetYPositionCharacter", tolua_ExportedFunctions_GetYPositionCharacter00);
- tolua_function(L, "GetZPositionCharacter", tolua_ExportedFunctions_GetZPositionCharacter00);
+ // tolua_function(L, "GetRotationCharacter", tolua_ExportedFunctions_GetRotationCharacter00); // Unused
+ // tolua_function(L, "GetXPositionCharacter", tolua_ExportedFunctions_GetXPositionCharacter00); // Unused
+ // tolua_function(L, "GetYPositionCharacter", tolua_ExportedFunctions_GetYPositionCharacter00); // Unused
+ // tolua_function(L, "GetZPositionCharacter", tolua_ExportedFunctions_GetZPositionCharacter00); // Unused
tolua_function(L, "MoveCharacterTo", tolua_ExportedFunctions_MoveCharacterTo00);
- tolua_function(L, "MoveCharacterToAndWaitForEnd",
+ /*tolua_function(L, "MoveCharacterToAndWaitForEnd",
tolua_ExportedFunctions_MoveCharacterToAndWaitForEnd00);*/
tolua_function(L, "MoveCharacterPlayerTo", tolua_ExportedFunctions_MoveCharacterPlayerTo00);
/*tolua_function(L, "MoveCharacterPlayerToAndWaitForEnd",
tolua_ExportedFunctions_MoveCharacterPlayerToAndWaitForEnd00);
tolua_function(L, "MoveCharacterPlayerAtTo", tolua_ExportedFunctions_MoveCharacterPlayerAtTo00);*/
tolua_function(L, "SetCharacterPosition", tolua_ExportedFunctions_SetCharacterPosition00);
- /*tolua_function(L, "PlaceCharacterOnDummy", tolua_ExportedFunctions_PlaceCharacterOnDummy00);*/
+ tolua_function(L, "PlaceCharacterOnDummy", tolua_ExportedFunctions_PlaceCharacterOnDummy00);
tolua_function(L, "SetCharacterRotation", tolua_ExportedFunctions_SetCharacterRotation00);
tolua_function(L, "SetCharacterOrientation", tolua_ExportedFunctions_SetCharacterOrientation00);
tolua_function(L, "SetCharacterAnimation", tolua_ExportedFunctions_SetCharacterAnimation00);
@@ -1374,9 +1582,9 @@ void LuaOpenBinds(lua_State *L) {
/*tolua_function(L, "EnableBlocker", tolua_ExportedFunctions_EnableBlocker00);*/
tolua_function(L, "AddAnchorZone", tolua_ExportedFunctions_AddAnchorZone00);
tolua_function(L, "ActivateAnchorZone", tolua_ExportedFunctions_ActivateAnchorZone00);
- /*tolua_function(L, "SetCharacterAnchor", tolua_ExportedFunctions_SetCharacterAnchor00);
+ //tolua_function(L, "SetCharacterAnchor", tolua_ExportedFunctions_SetCharacterAnchor00); // Unused
tolua_function(L, "SetCharacterLookChar", tolua_ExportedFunctions_SetCharacterLookChar00);
- tolua_function(L, "Random", tolua_ExportedFunctions_Random00);
+ /*tolua_function(L, "Random", tolua_ExportedFunctions_Random00);
tolua_function(L, "SetCharacterMeshVisible", tolua_ExportedFunctions_SetCharacterMeshVisible00);
tolua_function(L, "SetRecallageY", tolua_ExportedFunctions_SetRecallageY00);*/
// tolua_function(L, "IsFreemiumUnlocked", tolua_ExportedFunctions_IsFreemiumUnlocked00); // Unused
@@ -1387,7 +1595,6 @@ void LuaOpenBinds(lua_State *L) {
tolua_endmodule(L);
}
-
}
} // end namespace Tetraedge
diff --git a/engines/tetraedge/game/question2.cpp b/engines/tetraedge/game/question2.cpp
index fbc55be9189..1e86f08ca1d 100644
--- a/engines/tetraedge/game/question2.cpp
+++ b/engines/tetraedge/game/question2.cpp
@@ -88,9 +88,9 @@ bool Question2::onAnswerValidated(Answer &answer) {
return false;
}
-void Question2::pushAnswer(const Common::String &name, const Common::String &unk, const Common::String &path) {
+void Question2::pushAnswer(const Common::String &name, const Common::String &locName, const Common::String &path) {
Answer *answer = new Answer();
- answer->load(name, unk, path);
+ answer->load(name, locName, path);
answer->_onButtonValidatedSignal.add(this, &Question2::onAnswerValidated);
TeLayout *alayout = answer->layout();
if (!alayout)
@@ -134,7 +134,7 @@ TeLayout *Question2::Answer::layout() {
return _gui.layout("answer");
}
-void Question2::Answer::load(const Common::String &name, const Common::String &unk, const Common::String &path) {
+void Question2::Answer::load(const Common::String &name, const Common::String &locName, const Common::String &path) {
_str = name;
_gui.load(path);
TeButtonLayout *answerButton = _gui.buttonLayout("answer");
diff --git a/engines/tetraedge/te/te_3d_texture.cpp b/engines/tetraedge/te/te_3d_texture.cpp
index ac94154adbc..54693085cb7 100644
--- a/engines/tetraedge/te/te_3d_texture.cpp
+++ b/engines/tetraedge/te/te_3d_texture.cpp
@@ -39,7 +39,7 @@ Te3DTexture::~Te3DTexture() {
destroy();
}
-void Te3DTexture::bind() {
+void Te3DTexture::bind() const {
TeRenderer *renderer = g_engine->getRenderer();
glBindTexture(GL_TEXTURE_2D, _glTexture);
renderer->setMatrixMode(TeRenderer::MM_GL_TEXTURE);
@@ -66,11 +66,11 @@ void Te3DTexture::copyCurrentRender(uint xoffset, uint yoffset, uint x, uint y)
}
void Te3DTexture::create() {
- _flipY = true;
+ _flipY = false;
_leftBorder = _btmBorder = _texWidth = _texHeight = 0;
_rightBorder = _topBorder = _width = _height = 0;
_format = TeImage::INVALID;
- _loaded = 0;
+ _loaded = false;
if (!_createdTexture)
glGenTextures(1, &_glTexture);
if (_glTexture == NO_TEXTURE) {
diff --git a/engines/tetraedge/te/te_3d_texture.h b/engines/tetraedge/te/te_3d_texture.h
index cbf228836fe..f3a57e96041 100644
--- a/engines/tetraedge/te/te_3d_texture.h
+++ b/engines/tetraedge/te/te_3d_texture.h
@@ -39,7 +39,7 @@ public:
Te3DTexture();
virtual ~Te3DTexture();
- void bind();
+ void bind() const;
void copyCurrentRender(uint xoffset, uint yoffset, uint x, uint y);
void create();
void destroy();
diff --git a/engines/tetraedge/te/te_camera.cpp b/engines/tetraedge/te/te_camera.cpp
index 12ca0e7dcb5..430d9be686f 100644
--- a/engines/tetraedge/te/te_camera.cpp
+++ b/engines/tetraedge/te/te_camera.cpp
@@ -28,8 +28,8 @@
namespace Tetraedge {
-TeCamera::TeCamera() : _projectionMatrixType(0), _orthogonalParamL(1.0f),
- _orthogonalParamR(0.0f), _orthogonalParamT(1.0f), _orthogonalParamB(0.0f),
+TeCamera::TeCamera() : _projectionMatrixType(0), _orthogonalParamL(0.0f),
+ _orthogonalParamR(1.0f), _orthogonalParamT(1.0f), _orthogonalParamB(0.0f),
_orthNearVal(10.0f), _orthFarVal(4000.0f), _transformA(0), _transformB(0),
_fov(40.0f), _somePerspectiveVal(1.0f)
{
diff --git a/engines/tetraedge/te/te_frame_anim.cpp b/engines/tetraedge/te/te_frame_anim.cpp
index 678d21c5508..c115c8ec994 100644
--- a/engines/tetraedge/te/te_frame_anim.cpp
+++ b/engines/tetraedge/te/te_frame_anim.cpp
@@ -25,7 +25,7 @@
namespace Tetraedge {
-TeFrameAnim::TeFrameAnim() : _nbFrames(0), _frameRate(25.0), _reversed(false), _minFrame(0),
+TeFrameAnim::TeFrameAnim() : _nbFrames(0), _frameRate(25.0f), _reversed(false), _minFrame(0),
_numFramesToShow(-1), _startTime(0), _endTime(FLT_MAX), _loopCount(0), _lastFrameShown(-1) {
}
diff --git a/engines/tetraedge/te/te_free_move_zone.cpp b/engines/tetraedge/te/te_free_move_zone.cpp
index 1703f16a61f..98cafcda9e4 100644
--- a/engines/tetraedge/te/te_free_move_zone.cpp
+++ b/engines/tetraedge/te/te_free_move_zone.cpp
@@ -288,7 +288,8 @@ static int segmentIntersection(const TeVector2f32 &s1start, const TeVector2f32 &
if (intersection2 >= 0.0f && intersection2 <= 1.0f) {
result = 2;
if (sout || fout1 || fout2) {
- warning("TODO: implement output in segmentIntersection");
+ // Seems like these are always null?
+ error("TODO: implement output in segmentIntersection");
}
}
}
diff --git a/engines/tetraedge/te/te_layout.cpp b/engines/tetraedge/te/te_layout.cpp
index 387e4f56256..733eb5ba5ac 100644
--- a/engines/tetraedge/te/te_layout.cpp
+++ b/engines/tetraedge/te/te_layout.cpp
@@ -36,7 +36,7 @@ TeLayout::TeLayout() : Te3DObject2(), _updatingZ(false), _updatingZSize(false),
_safeAreaRatio(1.3333334f), _ratioMode(RATIO_MODE_NONE),
_positionType(CoordinatesType::RELATIVE_TO_PARENT)
{
- _userPosition = _position = TeVector3f32(0.5f, 0.5f, 0.0f);
+ _userPosition = _position = TeVector3f32(0.5f, 0.5f, 0.5f);
_size = TeVector3f32(1.0f, 1.0f, 1.0f);
_onChildSizeChangedCallback.reset(
new TeCallback0Param<TeLayout>(this, &TeLayout::onChildSizeChanged));
diff --git a/engines/tetraedge/te/te_lua_gui_lua_callbacks.cpp b/engines/tetraedge/te/te_lua_gui_lua_callbacks.cpp
index 78850e02155..9d184739831 100644
--- a/engines/tetraedge/te/te_lua_gui_lua_callbacks.cpp
+++ b/engines/tetraedge/te/te_lua_gui_lua_callbacks.cpp
@@ -600,6 +600,7 @@ int layoutAnchorLinearAnimationBindings(lua_State *L) {
static const TeVector3f32 defaultEnd(0.0f, 0.0f, 0.0f);
anim->_endVal = TeLuaToTeVector3f32(L, -1, defaultEnd);
} else if (!strcmp(s, "layout")) {
+ // skip.
} else if (!strcmp(s, "curve")) {
const Common::Array<float> curve = TeLuaToFloatArray(L, -1);
anim->setCurve(curve);
diff --git a/engines/tetraedge/te/te_material.cpp b/engines/tetraedge/te/te_material.cpp
index 143eb035c1a..2f740f45ea4 100644
--- a/engines/tetraedge/te/te_material.cpp
+++ b/engines/tetraedge/te/te_material.cpp
@@ -64,7 +64,7 @@ Common::String TeMaterial::dump() const {
_shininess, _enableLights ? "on" : "off");
}
-void TeMaterial::apply() {
+void TeMaterial::apply() const {
//debug("TeMaterial::apply (%s)", dump().c_str());
static const float constColor[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
TeRenderer *renderer = g_engine->getRenderer();
diff --git a/engines/tetraedge/te/te_material.h b/engines/tetraedge/te/te_material.h
index b1989cdea97..4758d1f5df8 100644
--- a/engines/tetraedge/te/te_material.h
+++ b/engines/tetraedge/te/te_material.h
@@ -43,7 +43,7 @@ public:
TeMaterial(const TeMaterial &other) = default;
TeMaterial(TeIntrusivePtr<Te3DTexture> texture, Mode mode);
- void apply();
+ void apply() const;
void defaultValues();
static void deserialize(Common::SeekableReadStream &stream, TeMaterial &material, const Common::Path &path);
static void serialize(Common::SeekableWriteStream &stream, TeMaterial &material);
diff --git a/engines/tetraedge/te/te_mesh.cpp b/engines/tetraedge/te/te_mesh.cpp
index 0ffbc513073..3b404627c4f 100644
--- a/engines/tetraedge/te/te_mesh.cpp
+++ b/engines/tetraedge/te/te_mesh.cpp
@@ -217,19 +217,19 @@ TeMesh::Mode TeMesh::getMode() const {
}
bool TeMesh::hasAlpha(uint idx) {
- // FIXME: this logic is a bit sketchy. Check it again.
- if (_hasAlpha && !_colors.empty())
- return true;
+ // Note: I don't understand this logic, but it's what the game does..
+ bool hasGlobalAlpha = _hasAlpha && !_colors.empty();
- bool retval = false;
+ bool retval = hasGlobalAlpha;
if (idx < _materials.size()) {
const TeMaterial &material = _materials[idx];
- if (material._enableSomethingDefault0)
+ if (material._enableSomethingDefault0) {
+ retval = false;
+ } else {
retval = true;
- //if (material._mode == TeMaterial::MaterialMode1)
- // return false;
- if (material._ambientColor.a() == 255)
- retval = (material._diffuseColor.a() != 255);
+ if (!hasGlobalAlpha && material._mode != TeMaterial::MaterialMode1 && material._ambientColor.a() == 255)
+ retval = (material._diffuseColor.a() != 255);
+ }
}
return retval;
}
diff --git a/engines/tetraedge/te/te_mesh.h b/engines/tetraedge/te/te_mesh.h
index fb0a9aa6df1..8d6e5cd442d 100644
--- a/engines/tetraedge/te/te_mesh.h
+++ b/engines/tetraedge/te/te_mesh.h
@@ -108,7 +108,7 @@ public:
uint numIndexes() const { return _indexes.size(); }
uint numVerticies() const { return _verticies.size(); }
bool shouldDrawMaybe() const { return _shouldDraw; }
- uint gltexenvMode() const { return _gltexEnvMode; }
+ uint gltexEnvMode() const { return _gltexEnvMode; }
void setShouldDraw(bool val) { _shouldDraw = val; }
void setglTexEnv(unsigned int val) { _gltexEnvMode = val; }
diff --git a/engines/tetraedge/te/te_model.cpp b/engines/tetraedge/te/te_model.cpp
index 7f560f57f5e..4c8bfdbb9f1 100644
--- a/engines/tetraedge/te/te_model.cpp
+++ b/engines/tetraedge/te/te_model.cpp
@@ -343,7 +343,7 @@ bool TeModel::load(Common::SeekableReadStream &stream) {
}
uint version = stream.readUint32LE();
- if (!(version == 11) || (version == 13)) {
+ if (!((version == 11) || (version == 13))) {
error("[TeModel::load] Unsupported version %d", version);
}
@@ -430,8 +430,8 @@ Common::SeekableReadStream *TeModel::tryLoadZlibStream(Common::SeekableReadStrea
return nullptr;
}
uint32 uncompressedSize = stream.readUint32LE();
- Common::SeekableSubReadStream substream(&stream, stream.pos(), stream.size());
- return Common::wrapCompressedReadStream(&substream, uncompressedSize);
+ Common::SeekableSubReadStream *substream = new Common::SeekableSubReadStream(&stream, stream.pos(), stream.size());
+ return Common::wrapCompressedReadStream(substream, uncompressedSize);
}
bool TeModel::loadWeights(Common::ReadStream &stream, Common::Array<weightElement> &weights) {
diff --git a/engines/tetraedge/te/te_model_animation.cpp b/engines/tetraedge/te/te_model_animation.cpp
index 85b5cd84d45..83c1c1f2716 100644
--- a/engines/tetraedge/te/te_model_animation.cpp
+++ b/engines/tetraedge/te/te_model_animation.cpp
@@ -171,7 +171,8 @@ int TeModelAnimation::lastFrame() const {
if (!_useNMOArrays) {
if (_fbxArrays.empty())
result = 0;
- result = _fbxArrays[0].size();
+ else
+ result = _fbxArrays[0].size();
} else {
result = _numNMOFrames;
}
diff --git a/engines/tetraedge/te/te_renderer.cpp b/engines/tetraedge/te/te_renderer.cpp
index 8830f3bcbbe..9c8563934eb 100644
--- a/engines/tetraedge/te/te_renderer.cpp
+++ b/engines/tetraedge/te/te_renderer.cpp
@@ -33,96 +33,82 @@ TeRenderer::TeRenderer() : _textureEnabled(false), _shadowMode(ShadowMode0), _ma
_numTransparentMeshes(0), _pendingTransparentMeshProperties(0) {
}
-void TeRenderer::TransparentMeshProperties::setFromMaterial(const TeMaterial &material) {
- _texture = material._texture;
- _enableLights = material._enableLights;
- _enableSomethingDefault0 = material._enableSomethingDefault0;
- _shininess = material._shininess;
- _emissionColor = material._emissionColor;
- _specularColor = material._specularColor;
- _diffuseColor = material._diffuseColor;
- _ambientColor = material._ambientColor;
- _materialMode = material._mode;
-}
-
-void TeRenderer::addTransparentMesh(const TeMesh &mesh, unsigned long i1, unsigned long meshno, unsigned long materialno) {
+void TeRenderer::addTransparentMesh(const TeMesh &mesh, unsigned long i1, unsigned long tricount, unsigned long materialno) {
const float orthNearVal = _currentCamera->_orthNearVal;
const TeMesh::Mode meshMode = mesh.getMode();
- if (!meshno) {
+ if (!tricount) {
if (meshMode == TeMesh::MeshMode_TriangleStrip) {
- meshno = mesh.numVerticies() - 2;
+ tricount = mesh.numVerticies() - 2;
} else if (meshMode == TeMesh::MeshMode_Triangles) {
- meshno = mesh.numIndexes() / 3;
- } else {
- return;
+ tricount = mesh.numIndexes() / 3;
}
- if (meshno == 0)
+ if (!tricount)
return;
}
- _transparentMeshVertexes.resize((_numTransparentMeshes + meshno) * 3);
- _transparentMeshNormals.resize((_numTransparentMeshes + meshno) * 3);
- _transparentMeshCoords.resize((_numTransparentMeshes + meshno) * 3);
- _transparentMeshColors.resize((_numTransparentMeshes + meshno) * 3);
- _transparentMeshTriangleNums.resize((_numTransparentMeshes + meshno) * 3);
-
- int newPropsSize = mesh.shouldDrawMaybe() ? _pendingTransparentMeshProperties + meshno : _pendingTransparentMeshProperties + 1;
- _transparentMeshProperties.resize(newPropsSize);
- if (meshMode == TeMesh::MeshMode_Triangles && meshno > 0) {
- for (unsigned int i = 0; i < meshno; i++) {
+ _transparentMeshVertexes.resize((_numTransparentMeshes + tricount) * 3);
+ _transparentMeshNormals.resize((_numTransparentMeshes + tricount) * 3);
+ _transparentMeshCoords.resize((_numTransparentMeshes + tricount) * 3);
+ _transparentMeshColors.resize((_numTransparentMeshes + tricount) * 3);
+ _transparentMeshVertexNums.resize((_numTransparentMeshes + tricount) * 3);
+
+ int newPropsSize = _pendingTransparentMeshProperties + (mesh.shouldDrawMaybe() ? tricount : 1);
+ _transparentMeshProps.resize(newPropsSize);
+ if (meshMode == TeMesh::MeshMode_Triangles) {
+ for (unsigned int i = 0; i < tricount; i++) {
const uint meshNo0 = (i1 + i) * 3;
- const uint meshPropNo = (_numTransparentMeshes + i) * 3;
+ const uint propNo = (_numTransparentMeshes + i) * 3;
- _transparentMeshVertexes[meshPropNo] = mesh.vertex(mesh.index(meshNo0));
- _transparentMeshVertexes[meshPropNo + 1] = mesh.vertex(mesh.index(meshNo0 + 1));
- _transparentMeshVertexes[meshPropNo + 2] = mesh.vertex(mesh.index(meshNo0 + 2));
+ _transparentMeshVertexes[propNo] = mesh.vertex(mesh.index(meshNo0));
+ _transparentMeshVertexes[propNo + 1] = mesh.vertex(mesh.index(meshNo0 + 1));
+ _transparentMeshVertexes[propNo + 2] = mesh.vertex(mesh.index(meshNo0 + 2));
- _transparentMeshNormals[meshPropNo] = mesh.normal(mesh.index(meshNo0));
- _transparentMeshNormals[meshPropNo + 1] = mesh.normal(mesh.index(meshNo0 + 1));
- _transparentMeshNormals[meshPropNo + 2] = mesh.normal(mesh.index(meshNo0 + 2));
+ _transparentMeshNormals[propNo] = mesh.normal(mesh.index(meshNo0));
+ _transparentMeshNormals[propNo + 1] = mesh.normal(mesh.index(meshNo0 + 1));
+ _transparentMeshNormals[propNo + 2] = mesh.normal(mesh.index(meshNo0 + 2));
if (mesh.hasUvs()) {
- _transparentMeshCoords[meshPropNo] = mesh.textureUV(mesh.index(meshNo0));
- _transparentMeshCoords[meshPropNo + 1] = mesh.textureUV(mesh.index(meshNo0) + 1);
- _transparentMeshCoords[meshPropNo + 2] = mesh.textureUV(mesh.index(meshNo0) + 2);
+ _transparentMeshCoords[propNo] = mesh.textureUV(mesh.index(meshNo0));
+ _transparentMeshCoords[propNo + 1] = mesh.textureUV(mesh.index(meshNo0 + 1));
+ _transparentMeshCoords[propNo + 2] = mesh.textureUV(mesh.index(meshNo0 + 2));
}
if (!mesh.hasColor()) {
- _transparentMeshColors[meshPropNo] = mesh.material(materialno)->_diffuseColor;
- _transparentMeshColors[meshPropNo + 1] = mesh.material(materialno)->_diffuseColor;
- _transparentMeshColors[meshPropNo + 2] = mesh.material(materialno)->_diffuseColor;
+ _transparentMeshColors[propNo] = mesh.material(materialno)->_diffuseColor;
+ _transparentMeshColors[propNo + 1] = mesh.material(materialno)->_diffuseColor;
+ _transparentMeshColors[propNo + 2] = mesh.material(materialno)->_diffuseColor;
} else {
- _transparentMeshColors[meshPropNo] = mesh.color(mesh.index(meshNo0));
- _transparentMeshColors[meshPropNo + 1] = mesh.color(mesh.index(meshNo0) + 1);
- _transparentMeshColors[meshPropNo + 2] = mesh.color(mesh.index(meshNo0) + 2);
+ _transparentMeshColors[propNo] = mesh.color(mesh.index(meshNo0));
+ _transparentMeshColors[propNo + 1] = mesh.color(mesh.index(meshNo0 + 1));
+ _transparentMeshColors[propNo + 2] = mesh.color(mesh.index(meshNo0 + 2));
}
}
- } else if (meshMode == TeMesh::MeshMode_TriangleStrip && meshno > 0) {
- for (unsigned int i = 0; i < meshno; i++) {
+ } else if (meshMode == TeMesh::MeshMode_TriangleStrip && tricount > 0) {
+ for (unsigned int i = 0; i < tricount; i++) {
const uint meshNo0 = (i1 + i); // TODO: This appears to be the only difference between this and the above?
- const uint meshPropNo = (_numTransparentMeshes + i) * 3;
+ const uint propNo = (_numTransparentMeshes + i) * 3;
- _transparentMeshVertexes[meshPropNo] = mesh.vertex(mesh.index(meshNo0));
- _transparentMeshVertexes[meshPropNo + 1] = mesh.vertex(mesh.index(meshNo0 + 1));
- _transparentMeshVertexes[meshPropNo + 2] = mesh.vertex(mesh.index(meshNo0 + 2));
+ _transparentMeshVertexes[propNo] = mesh.vertex(mesh.index(meshNo0));
+ _transparentMeshVertexes[propNo + 1] = mesh.vertex(mesh.index(meshNo0 + 1));
+ _transparentMeshVertexes[propNo + 2] = mesh.vertex(mesh.index(meshNo0 + 2));
- _transparentMeshNormals[meshPropNo] = mesh.normal(mesh.index(meshNo0));
- _transparentMeshNormals[meshPropNo + 1] = mesh.normal(mesh.index(meshNo0 + 1));
- _transparentMeshNormals[meshPropNo + 2] = mesh.normal(mesh.index(meshNo0 + 2));
+ _transparentMeshNormals[propNo] = mesh.normal(mesh.index(meshNo0));
+ _transparentMeshNormals[propNo + 1] = mesh.normal(mesh.index(meshNo0 + 1));
+ _transparentMeshNormals[propNo + 2] = mesh.normal(mesh.index(meshNo0 + 2));
if (mesh.hasUvs()) {
- _transparentMeshCoords[meshPropNo] = mesh.textureUV(mesh.index(meshNo0));;
- _transparentMeshCoords[meshPropNo + 1] = mesh.textureUV(mesh.index(meshNo0 + 1));
- _transparentMeshCoords[meshPropNo + 2] = mesh.textureUV(mesh.index(meshNo0 + 2));
+ _transparentMeshCoords[propNo] = mesh.textureUV(mesh.index(meshNo0));;
+ _transparentMeshCoords[propNo + 1] = mesh.textureUV(mesh.index(meshNo0 + 1));
+ _transparentMeshCoords[propNo + 2] = mesh.textureUV(mesh.index(meshNo0 + 2));
}
if (!mesh.hasColor()) {
- _transparentMeshColors[meshPropNo] = mesh.material(materialno)->_diffuseColor;
- _transparentMeshColors[meshPropNo + 1] = mesh.material(materialno)->_diffuseColor;
- _transparentMeshColors[meshPropNo + 2] = mesh.material(materialno)->_diffuseColor;
+ _transparentMeshColors[propNo] = mesh.material(materialno)->_diffuseColor;
+ _transparentMeshColors[propNo + 1] = mesh.material(materialno)->_diffuseColor;
+ _transparentMeshColors[propNo + 2] = mesh.material(materialno)->_diffuseColor;
} else {
- _transparentMeshColors[meshPropNo] = mesh.color(mesh.index(meshNo0));
- _transparentMeshColors[meshPropNo + 1] = mesh.color(mesh.index(meshNo0 + 1));
- _transparentMeshColors[meshPropNo + 2] = mesh.color(mesh.index(meshNo0 + 2));
+ _transparentMeshColors[propNo] = mesh.color(mesh.index(meshNo0));
+ _transparentMeshColors[propNo + 1] = mesh.color(mesh.index(meshNo0 + 1));
+ _transparentMeshColors[propNo + 2] = mesh.color(mesh.index(meshNo0 + 2));
}
}
}
@@ -130,34 +116,32 @@ void TeRenderer::addTransparentMesh(const TeMesh &mesh, unsigned long i1, unsign
if (!mesh.shouldDrawMaybe()) {
// TODO: better variable names.
const TeMatrix4x4 ¤tMatrix = _matriciesStacks[MM_GL_MODELVIEW].currentMatrix();
- const TeVector3f32 local_268 = currentMatrix.mult4x3(_transparentMeshVertexes[_numTransparentMeshes * 3]);
- const TeVector3f32 local_278 = currentMatrix.mult4x3(_transparentMeshVertexes[_numTransparentMeshes * 3 + 1]);
- const TeVector3f32 local_288 = currentMatrix.mult4x3(_transparentMeshVertexes[_numTransparentMeshes * 3 + 2]);
- TeVector3f32 local_298 = (local_268 + local_278 + local_288) / 3.0;
+ const TeVector3f32 v1trans = currentMatrix.mult4x3(_transparentMeshVertexes[_numTransparentMeshes * 3]);
+ const TeVector3f32 v2trans = currentMatrix.mult4x3(_transparentMeshVertexes[_numTransparentMeshes * 3 + 1]);
+ const TeVector3f32 v3trans = currentMatrix.mult4x3(_transparentMeshVertexes[_numTransparentMeshes * 3 + 2]);
+ TeVector3f32 midpoint = (v1trans + v2trans + v3trans) / 3.0;
- local_298.z() -= orthNearVal;
- float length;
+ midpoint.z() -= orthNearVal;
+ float zOrder;
if (_currentCamera->_projectionMatrixType < 4) {
- length = -local_298.squaredLength();
+ zOrder = -midpoint.squaredLength();
} else if (_currentCamera->_projectionMatrixType == 4) {
- length = local_298.z() * local_298.z();
+ zOrder = midpoint.z() * midpoint.z();
} else {
- length = local_298.squaredLength();
+ zOrder = midpoint.squaredLength();
}
- TransparentMeshProperties &destProperties = _transparentMeshProperties[_pendingTransparentMeshProperties];
+ TransparentMeshProperties &destProperties = _transparentMeshProps[_pendingTransparentMeshProperties];
- destProperties._triangleCount = meshno * 3;
+ destProperties._vertexCount = tricount * 3;
destProperties._camera = _currentCamera;
- const TeMaterial *material = mesh.material(materialno);
- destProperties.setFromMaterial(*material);
+ destProperties._material = *mesh.material(materialno);
destProperties._matrix = currentMatrix;
-
- destProperties._glTexEnvMode = mesh.gltexenvMode();
+ destProperties._glTexEnvMode = mesh.gltexEnvMode();
destProperties._sourceTransparentMesh = _numTransparentMeshes * 3;
destProperties._hasColor = mesh.hasColor();
- destProperties._zLength = length;
+ destProperties._zOrder = zOrder;
destProperties._scissorEnabled = _scissorEnabled;
destProperties._scissorX = _scissorX;
destProperties._scissorY = _scissorY;
@@ -165,7 +149,7 @@ void TeRenderer::addTransparentMesh(const TeMesh &mesh, unsigned long i1, unsign
destProperties._scissorHeight = _scissorHeight;
destProperties._shouldDraw = false;
} else {
- for (uint i = 0; i < meshno; i++) {
+ for (uint i = 0; i < tricount; i++) {
const TeMatrix4x4 ¤tMatrix = _matriciesStacks[MM_GL_MODELVIEW].currentMatrix();
const int meshPropNo = (_numTransparentMeshes + i) * 3;
@@ -177,28 +161,27 @@ void TeRenderer::addTransparentMesh(const TeMesh &mesh, unsigned long i1, unsign
_transparentMeshNormals[meshPropNo + 1] = currentMatrix.mult3x3(_transparentMeshNormals[meshPropNo + 1]);
_transparentMeshNormals[meshPropNo + 2] = currentMatrix.mult3x3(_transparentMeshNormals[meshPropNo + 2]);
- TeVector3f32 local_208 = (_transparentMeshVertexes[meshPropNo] + _transparentMeshVertexes[meshPropNo + 1] + _transparentMeshVertexes[meshPropNo + 2]) / 3.0;
- local_208.z() -= orthNearVal;
+ TeVector3f32 midpoint = (_transparentMeshVertexes[meshPropNo] + _transparentMeshVertexes[meshPropNo + 1] + _transparentMeshVertexes[meshPropNo + 2]) / 3.0;
+ midpoint.z() -= orthNearVal;
- float length;
+ float zOrder;
if (_currentCamera->_projectionMatrixType < 4) {
- length = -local_208.squaredLength();
+ zOrder = -midpoint.squaredLength();
} else if (_currentCamera->_projectionMatrixType == 4) {
- length = local_208.z() * local_208.z();
+ zOrder = midpoint.z() * midpoint.z();
} else {
- length = local_208.squaredLength();
+ zOrder = midpoint.squaredLength();
}
- TransparentMeshProperties &destProperties = _transparentMeshProperties[_pendingTransparentMeshProperties + i];
- destProperties._triangleCount = 3;
+ TransparentMeshProperties &destProperties = _transparentMeshProps[_pendingTransparentMeshProperties + i];
+ destProperties._vertexCount = 3;
destProperties._camera = _currentCamera;
- const TeMaterial *material = mesh.material(materialno);
- destProperties.setFromMaterial(*material);
- destProperties._glTexEnvMode = mesh.gltexenvMode();
+ destProperties._material = *mesh.material(materialno);
+ destProperties._glTexEnvMode = mesh.gltexEnvMode();
destProperties._sourceTransparentMesh = meshPropNo;
destProperties._hasColor = mesh.hasColor();
- destProperties._zLength = length;
+ destProperties._zOrder = zOrder;
destProperties._scissorEnabled = _scissorEnabled;
destProperties._scissorX = _scissorX;
destProperties._scissorY = _scissorY;
@@ -207,8 +190,8 @@ void TeRenderer::addTransparentMesh(const TeMesh &mesh, unsigned long i1, unsign
destProperties._shouldDraw = true;
}
}
- _numTransparentMeshes += meshno;
- _pendingTransparentMeshProperties = _transparentMeshProperties.size();
+ _numTransparentMeshes += tricount;
+ _pendingTransparentMeshProperties = _transparentMeshProps.size();
}
void TeRenderer::clearBuffer(TeRenderer::Buffer buf) {
@@ -325,8 +308,22 @@ void TeRenderer::multiplyMatrix(const TeMatrix4x4 &matrix) {
}
void TeRenderer::optimiseTransparentMeshProperties() {
- if (!_transparentMeshProperties.empty()) {
- // TODO: Implement TeRenderer::optimiseTransparentMeshProperties.
+ if (_transparentMeshProps.size() > 1) {
+ for (unsigned int i = 0; i < _transparentMeshProps.size() - 1; i++) {
+ if (_transparentMeshProps[i]._camera == _transparentMeshProps[i + 1]._camera
+ && _transparentMeshProps[i]._material == _transparentMeshProps[i + 1]._material
+ && _transparentMeshProps[i]._glTexEnvMode == _transparentMeshProps[i + 1]._glTexEnvMode
+ && _transparentMeshProps[i]._matrix == _transparentMeshProps[i + 1]._matrix
+ && _transparentMeshProps[i]._hasColor == _transparentMeshProps[i + 1]._hasColor
+ && _transparentMeshProps[i]._scissorEnabled == _transparentMeshProps[i + 1]._scissorEnabled
+ && _transparentMeshProps[i]._scissorX == _transparentMeshProps[i + 1]._scissorX
+ && _transparentMeshProps[i]._scissorY == _transparentMeshProps[i + 1]._scissorY
+ && _transparentMeshProps[i]._scissorWidth == _transparentMeshProps[i + 1]._scissorWidth
+ && _transparentMeshProps[i]._scissorHeight == _transparentMeshProps[i + 1]._scissorHeight) {
+ _transparentMeshProps[i]._vertexCount += _transparentMeshProps[i + 1]._vertexCount;
+ _transparentMeshProps[i + 1]._shouldDraw = false;
+ }
+ }
}
}
@@ -345,11 +342,11 @@ Common::String TeRenderer::renderer() {
static int compareTransparentMeshProperties(const TeRenderer::TransparentMeshProperties &p1,
const TeRenderer::TransparentMeshProperties &p2) {
- if (p1._zLength < p2._zLength)
- return -1;
- if (p1._zLength == p2._zLength)
+ if (p1._zOrder > p2._zOrder)
+ return 1;
+ if (p1._zOrder == p2._zOrder)
return 0;
- return 1;
+ return -1;
}
void TeRenderer::dumpTransparentMeshes() const {
@@ -361,7 +358,7 @@ void TeRenderer::dumpTransparentMeshes() const {
_transparentMeshNormals[i].dump().c_str(),
_transparentMeshCoords[i].dump().c_str(),
_transparentMeshColors[i].dump().c_str(),
- _transparentMeshTriangleNums[i]
+ _transparentMeshVertexNums[i]
);
}
}
@@ -371,15 +368,15 @@ void TeRenderer::renderTransparentMeshes() {
return;
glDepthMask(GL_FALSE);
- Common::sort(_transparentMeshProperties.begin(), _transparentMeshProperties.end(),
+ Common::sort(_transparentMeshProps.begin(), _transparentMeshProps.end(),
compareTransparentMeshProperties);
- int triangles = 0;
- for (unsigned int i = 0; i < _transparentMeshProperties.size(); i++) {
- const uint tcount = _transparentMeshProperties[i]._triangleCount;
- for (unsigned int j = 0; j < tcount; j++)
- _transparentMeshTriangleNums[triangles + j] = (short)(_transparentMeshProperties[i]._sourceTransparentMesh + j);
- triangles += tcount;
+ int vertsDrawn = 0;
+ for (unsigned int i = 0; i < _transparentMeshProps.size(); i++) {
+ const uint vcount = _transparentMeshProps[i]._vertexCount;
+ for (unsigned int j = 0; j < vcount; j++)
+ _transparentMeshVertexNums[vertsDrawn + j] = (short)(_transparentMeshProps[i]._sourceTransparentMesh + j);
+ vertsDrawn += vcount;
}
//dumpTransparentMeshes();
@@ -396,24 +393,16 @@ void TeRenderer::renderTransparentMeshes() {
glColorPointer(4, GL_UNSIGNED_BYTE, 4, _transparentMeshColors.data());
TeMaterial lastMaterial;
+ TeMatrix4x4 lastMatrix;
- triangles = 0;
- for (unsigned int i = 0; i < _transparentMeshProperties.size(); i++) {
- const TransparentMeshProperties &meshProperties = _transparentMeshProperties[i];
+ vertsDrawn = 0;
+ for (unsigned int i = 0; i < _transparentMeshProps.size(); i++) {
+ const TransparentMeshProperties &meshProperties = _transparentMeshProps[i];
if (!meshProperties._shouldDraw)
continue;
- const TeIntrusivePtr<Te3DTexture> &texture = meshProperties._texture;
-
- TeMaterial material(texture, meshProperties._materialMode);
- material._ambientColor = meshProperties._ambientColor;
- material._diffuseColor = meshProperties._diffuseColor;
- material._specularColor = meshProperties._specularColor;
- material._emissionColor = meshProperties._emissionColor;
- material._shininess = meshProperties._shininess;
- material._enableLights = meshProperties._enableLights;
- material._enableSomethingDefault0 = meshProperties._enableSomethingDefault0;
-
+ const TeMaterial &material = meshProperties._material;
+
meshProperties._camera->applyProjection();
glMatrixMode(GL_MODELVIEW);
_matrixMode = MM_GL_MODELVIEW;
@@ -422,7 +411,7 @@ void TeRenderer::renderTransparentMeshes() {
_matriciesStacks[_matrixMode].loadMatrix(meshProperties._matrix);
glPushMatrix();
loadCurrentMatrixToGL();
- if (texture) {
+ if (material._texture) {
glEnable(GL_TEXTURE_2D);
_textureEnabled = true;
}
@@ -444,10 +433,10 @@ void TeRenderer::renderTransparentMeshes() {
meshProperties._scissorHeight);
}
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, meshProperties._glTexEnvMode);
- glDrawElements(GL_TRIANGLES, meshProperties._triangleCount, GL_UNSIGNED_SHORT,
- _transparentMeshTriangleNums.data() + triangles);
+ glDrawElements(GL_TRIANGLES, meshProperties._vertexCount, GL_UNSIGNED_SHORT,
+ _transparentMeshVertexNums.data() + vertsDrawn);
- triangles += meshProperties._triangleCount;
+ vertsDrawn += meshProperties._vertexCount;
if (material._enableSomethingDefault0) {
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
@@ -457,7 +446,7 @@ void TeRenderer::renderTransparentMeshes() {
if (meshProperties._scissorEnabled) {
glDisable(GL_SCISSOR_TEST);
}
- if (texture) {
+ if (material._texture) {
glDisable(GL_TEXTURE_2D);
_textureEnabled = false;
}
@@ -473,7 +462,7 @@ void TeRenderer::renderTransparentMeshes() {
_numTransparentMeshes = 0;
_pendingTransparentMeshProperties = 0;
glDepthMask(GL_TRUE);
- _transparentMeshProperties.clear();
+ _transparentMeshProps.clear();
}
void TeRenderer::reset() {
diff --git a/engines/tetraedge/te/te_renderer.h b/engines/tetraedge/te/te_renderer.h
index 0a8b479a34e..e211ebc3f58 100644
--- a/engines/tetraedge/te/te_renderer.h
+++ b/engines/tetraedge/te/te_renderer.h
@@ -48,27 +48,17 @@ public:
class TransparentMeshProperties {
public:
- void setFromMaterial(const TeMaterial &material);
- TeIntrusivePtr<Te3DTexture> _texture;
TeCamera *_camera;
- int _triangleCount;
+ int _vertexCount;
TeMatrix4x4 _matrix;
- bool _enableLights;
- bool _enableSomethingDefault0;
- enum TeMaterial::Mode _materialMode;
-
- TeColor _ambientColor;
- TeColor _diffuseColor;
- TeColor _specularColor;
- TeColor _emissionColor;
- float _shininess;
+ TeMaterial _material;
uint _glTexEnvMode;
uint _sourceTransparentMesh;
bool _hasColor;
- float _zLength;
+ float _zOrder;
bool _scissorEnabled;
int _scissorX;
int _scissorY;
@@ -150,10 +140,10 @@ private:
Common::Array<TeVector3f32> _transparentMeshNormals;
Common::Array<TeVector2f32> _transparentMeshCoords;
Common::Array<TeColor> _transparentMeshColors;
- Common::Array<unsigned short> _transparentMeshTriangleNums;
+ Common::Array<unsigned short> _transparentMeshVertexNums;
int _pendingTransparentMeshProperties;
- Common::Array<TransparentMeshProperties> _transparentMeshProperties;
+ Common::Array<TransparentMeshProperties> _transparentMeshProps;
TeMatriciesStack _matriciesStacks[3]; // one per matrix mode.
diff --git a/engines/tetraedge/te/te_sprite_layout.cpp b/engines/tetraedge/te/te_sprite_layout.cpp
index 009d370f18e..625603d8571 100644
--- a/engines/tetraedge/te/te_sprite_layout.cpp
+++ b/engines/tetraedge/te/te_sprite_layout.cpp
@@ -26,7 +26,7 @@
namespace Tetraedge {
-TeSpriteLayout::TeSpriteLayout() : _tiledSurfacePtr(new TeTiledSurface()), _sizeSet(false), _allowFloatTranslate(false) {
+TeSpriteLayout::TeSpriteLayout() : _tiledSurfacePtr(new TeTiledSurface()), _sizeSet(false) {
_tiledSurfacePtr->setColor(TeColor(255, 255, 255, 255));
updateMesh();
}
@@ -50,7 +50,7 @@ void TeSpriteLayout::draw() {
_tiledSurfacePtr->size().x(), _tiledSurfacePtr->size().y(), color().dump().c_str());*/
TeMatrix4x4 matrix = worldTransformationMatrix();
- if (!_allowFloatTranslate) {
+ if (sizeType() == ABSOLUTE) {
matrix(0, 3) = (int)matrix(0, 3);
matrix(1, 3) = (int)matrix(1, 3);
}
diff --git a/engines/tetraedge/te/te_text_base2.cpp b/engines/tetraedge/te/te_text_base2.cpp
index 45376231122..d03f3b4034a 100644
--- a/engines/tetraedge/te/te_text_base2.cpp
+++ b/engines/tetraedge/te/te_text_base2.cpp
@@ -30,8 +30,7 @@ namespace Tetraedge {
TeTextBase2::TeTextBase2() : _drawRect(0, 0), _size(0, 0),
_alignStyle(TeFont3::AlignLeft), _interLine(0.0f), _globalColor(0xff, 0xff, 0xff, 0xff),
-_wrapMode(WrapModeFixed), _strikethrough(false), _fontSize(10), _valueWasSet(true)
-{
+_wrapMode(WrapModeFixed), _strikethrough(false), _fontSize(10), _valueWasSet(true) {
_mesh.setglTexEnv(GL_BLEND);
_mesh.setShouldDraw(true);
}
@@ -94,25 +93,24 @@ void TeTextBase2::build() {
_mesh.setConf(4, 4, TeMesh::MeshMode_TriangleStrip, 0, 0);
_mesh.defaultMaterial(texture);
- TeColor col(255, 255, 255, 255);
_mesh.setShouldDraw(true);
- _mesh.setColor(col);
+ _mesh.setColor(_globalColor);
_mesh.setVertex(0, TeVector3f32(_size._x * -0.5f, _size._y * -0.5f, 0.0f));
_mesh.setTextureUV(0, TeVector2f32(0, 1));
_mesh.setNormal(0, TeVector3f32(0.0f, 0.0f, 1.0f));
- _mesh.setColor(0, col);
+ _mesh.setColor(0, _globalColor);
_mesh.setVertex(1, TeVector3f32(_size._x * 0.5f, _size._y * -0.5f, 0.0f));
_mesh.setTextureUV(1, TeVector2f32(1, 1));
_mesh.setNormal(1, TeVector3f32(0.0f, 0.0f, 1.0f));
- _mesh.setColor(1, col);
+ _mesh.setColor(1, _globalColor);
_mesh.setVertex(2, TeVector3f32(_size._x * 0.5f, _size._y * 0.5f, 0.0f));
_mesh.setTextureUV(2, TeVector2f32(1, 0));
_mesh.setNormal(2, TeVector3f32(0.0f, 0.0f, 1.0f));
- _mesh.setColor(2, col);
+ _mesh.setColor(2, _globalColor);
_mesh.setVertex(3, TeVector3f32(_size._x * -0.5f, _size._y * 0.5f, 0.0f));
_mesh.setTextureUV(3, TeVector2f32(0, 0));
_mesh.setNormal(3, TeVector3f32(0.0f, 0.0f, 1.0f));
- _mesh.setColor(3, col);
+ _mesh.setColor(3, _globalColor);
_mesh.setIndex(0, 0);
_mesh.setIndex(1, 1);
_mesh.setIndex(2, 3);
@@ -248,7 +246,7 @@ void TeTextBase2::setFont(unsigned int offset, const TeIntrusivePtr<TeFont3> &ne
void TeTextBase2::setFontSize(unsigned long newSize) {
// Bit of a hack here to get the right font size.
- newSize *= 1.5;
+ newSize *= 1.2;
if (_fontSize != newSize) {
_fontSize = newSize;
_valueWasSet = true;
diff --git a/engines/tetraedge/te/te_tiled_surface.cpp b/engines/tetraedge/te/te_tiled_surface.cpp
index c299df4e293..fc087c10ccf 100644
--- a/engines/tetraedge/te/te_tiled_surface.cpp
+++ b/engines/tetraedge/te/te_tiled_surface.cpp
@@ -32,8 +32,8 @@ static void getRangeIntersection(float start1,float end1,float start2,float end2
*pend = MIN(end1, end2);
}
-TeTiledSurface::TeTiledSurface() : _colorKeyActive(false), _colorKeyTolerence(0),
-_bottomCrop(0), _topCrop(0), _leftCrop(0), _rightCrop(0), _codec(nullptr), _imgFormat(TeImage::INVALID), _shouldDraw(true) {
+TeTiledSurface::TeTiledSurface() : _shouldDraw(true), _codec(nullptr), _colorKeyActive(false), _colorKeyTolerence(0),
+_bottomCrop(0), _topCrop(0), _leftCrop(0), _rightCrop(0), _imgFormat(TeImage::INVALID) {
_frameAnim.frameChangedSignal().add<TeTiledSurface>(this, &TeTiledSurface::onFrameAnimCurrentFrameChanged);
}
Commit: c27dca6b829268fdeb2c83a9d936343ab2ec8015
https://github.com/scummvm/scummvm/commit/c27dca6b829268fdeb2c83a9d936343ab2ec8015
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2023-01-16T17:36:43+01:00
Commit Message:
TETRAEDGE: More WIP. Lots of progress
Many pieces of the first room of the game are now working.
Changed paths:
engines/tetraedge/game/application.cpp
engines/tetraedge/game/billboard.cpp
engines/tetraedge/game/character.cpp
engines/tetraedge/game/character.h
engines/tetraedge/game/dialog2.cpp
engines/tetraedge/game/dialog2.h
engines/tetraedge/game/documents_browser.cpp
engines/tetraedge/game/documents_browser.h
engines/tetraedge/game/game.cpp
engines/tetraedge/game/game.h
engines/tetraedge/game/in_game_scene.cpp
engines/tetraedge/game/inventory.cpp
engines/tetraedge/game/lua_binds.cpp
engines/tetraedge/game/question2.h
engines/tetraedge/te/te_3d_object2.cpp
engines/tetraedge/te/te_3d_texture.cpp
engines/tetraedge/te/te_3d_texture.h
engines/tetraedge/te/te_button_layout.cpp
engines/tetraedge/te/te_camera.cpp
engines/tetraedge/te/te_checkbox_layout.cpp
engines/tetraedge/te/te_curve_anim2.h
engines/tetraedge/te/te_font3.cpp
engines/tetraedge/te/te_font3.h
engines/tetraedge/te/te_image.cpp
engines/tetraedge/te/te_image.h
engines/tetraedge/te/te_layout.cpp
engines/tetraedge/te/te_layout.h
engines/tetraedge/te/te_lua_gui_lua_callbacks.cpp
engines/tetraedge/te/te_lua_thread.cpp
engines/tetraedge/te/te_model_vertex_animation.cpp
engines/tetraedge/te/te_renderer.cpp
engines/tetraedge/te/te_renderer.h
engines/tetraedge/te/te_scrolling_layout.cpp
engines/tetraedge/te/te_scrolling_layout.h
engines/tetraedge/te/te_sprite_layout.cpp
engines/tetraedge/te/te_text_base2.cpp
engines/tetraedge/te/te_tiled_surface.cpp
engines/tetraedge/te/te_tiled_texture.cpp
engines/tetraedge/te/te_vector3f32.h
engines/tetraedge/te/te_xml_gui.cpp
diff --git a/engines/tetraedge/game/application.cpp b/engines/tetraedge/game/application.cpp
index 37af6a70bc2..f9d0573a2fb 100644
--- a/engines/tetraedge/game/application.cpp
+++ b/engines/tetraedge/game/application.cpp
@@ -37,7 +37,8 @@
#include "tetraedge/te/te_renderer.h"
#include "tetraedge/te/te_font3.h"
#include "tetraedge/te/te_input_mgr.h"
-//#include "tetraedge/te/te_textbase2.h"
+
+//#define DUMP_LAYOUTS 1
namespace Tetraedge {
@@ -82,7 +83,7 @@ void Application::create() {
_mainWindowCamera->_orthNearVal = -2048.0f;
_mainWindowCamera->_orthFarVal = 2048.0f;
- _mainWindow.setSize(TeVector3f32(winWidth, winHeight, 100.0));
+ _mainWindow.setSize(TeVector3f32(winWidth, winHeight, 0.0));
_mainWindow.setSizeType(TeILayout::ABSOLUTE);
_mainWindow.setPositionType(TeILayout::ABSOLUTE);
@@ -162,7 +163,7 @@ void Application::create() {
_helpGui.load(helpMenuFilePath);
- debug("TODO: set TeCore flags here? Do they do anything?");
+ // TODO: set TeCore field 0x74 and 0x78 to true here? Do they do anything?");
// Game calls these here but does nothing with result?
//TeGetDeviceDPI();
@@ -385,6 +386,22 @@ void Application::drawFront() {
g_engine->getRenderer()->loadIdentityMatrix();
}
+#if DUMP_LAYOUTS
+static int renderCount = 0;
+static void dumpLayout(Te3DObject2 *layout, Common::String indent = "++") {
+ assert(layout);
+ if (!layout->worldVisible())
+ return;
+ debug("%s %s pos:%s worldPos:%s worldScale:%s size:%s col:%s", indent.c_str(), layout->name().c_str(),
+ layout->position().dump().c_str(), layout->worldPosition().dump().c_str(),
+ layout->worldScale().dump().c_str(), layout->size().dump().c_str(),
+ layout->color().dump().c_str());
+ for (auto & child: layout->childList()) {
+ dumpLayout(child, indent + "++");
+ }
+}
+#endif
+
void Application::performRender() {
Game *game = g_engine->getGame();
TeRenderer *renderer = g_engine->getRenderer();
@@ -422,6 +439,17 @@ void Application::performRender() {
renderer->renderTransparentMeshes();
game->scene().drawPath();
g_system->updateScreen();
+
+#if DUMP_LAYOUTS
+ renderCount++;
+ if (renderCount % 100 == 0) {
+ debug("\n--------------------\nFrame %d back layout: ", renderCount);
+ dumpLayout(&_backLayout);
+ debug("\n--------------------\nFrame %d front orientation layout: ", renderCount);
+ dumpLayout(&_frontOrientationLayout);
+ }
+#endif
+
}
//void Application::preloadTextrue(); does nothing..
diff --git a/engines/tetraedge/game/billboard.cpp b/engines/tetraedge/game/billboard.cpp
index 3e95616de21..2d2d99156a1 100644
--- a/engines/tetraedge/game/billboard.cpp
+++ b/engines/tetraedge/game/billboard.cpp
@@ -53,17 +53,18 @@ void Billboard::calcVertex() {
const TeMatrix4x4 camProjMatrix = currentCam->projectionMatrix();
TeMatrix4x4 camWorldInverse = currentCam->worldTransformationMatrix();
camWorldInverse.inverse();
-
+
const TeMatrix4x4 camTotalTransform = camProjMatrix * camWorldInverse;
TeMatrix4x4 camTotalInverse = camTotalTransform;
camTotalInverse.inverse();
+ camTotalInverse.scale(TeVector3f32(-1.0, -1.0, 1.0));
TeVector3f32 posvec(0.0f, 0.0f, _pos.z());
if (_hasPos2) {
posvec = _pos2;
}
posvec = camTotalTransform * posvec;
-
+
TeVector3f32 meshVertex;
float fx, fy;
@@ -81,7 +82,7 @@ void Billboard::calcVertex() {
fy = _pos.y();
meshVertex = camTotalInverse * TeVector3f32(fx + fx - 1.0f, fy + fy - 1.0f, posvec.z());
_model->_meshes[0].setVertex(2, meshVertex);
-
+
fx = _pos.x() + _size.getX();
fy = _pos.y() + _size.getY();
meshVertex = camTotalInverse * TeVector3f32(fx + fx - 1.0f, fy + fy - 1.0f, posvec.z());
diff --git a/engines/tetraedge/game/character.cpp b/engines/tetraedge/game/character.cpp
index 98299ae6323..b3d84b95cc9 100644
--- a/engines/tetraedge/game/character.cpp
+++ b/engines/tetraedge/game/character.cpp
@@ -91,12 +91,15 @@ Character::~Character() {
}
}
-void Character::addCallback(const Common::String &key, const Common::String &s2, float f1, float f2) {
+void Character::addCallback(const Common::String &animKey, const Common::String &fnName, float triggerFrame, float maxCalls) {
Callback *c = new Callback();
- c->_s = s2;
- c->_x = (int)f1;
- c->_y = (int)f2;
- c->_f = (f2 == -1.0 ? -NAN : 0.0f);
+ c->_luaFn = fnName;
+ c->_lastCheckFrame = 0;
+ c->_triggerFrame = (int)triggerFrame;
+ c->_maxCalls = (int)maxCalls;
+ // Slight difference here to orig (that sets -NAN) because of
+ // the way this gets used later, setting large negative is more correct.
+ c->_callsMade = (maxCalls == -1.0 ? -1e9 : 0.0f);
const Common::String animPath = _model->anim()->_loadedPath.toString();
if (_callbacks.contains(animPath)) {
@@ -104,7 +107,7 @@ void Character::addCallback(const Common::String &key, const Common::String &s2,
} else {
Common::Array<Callback *> callbacks;
callbacks.push_back(c);
- _callbacks.setVal(key, callbacks);
+ _callbacks.setVal(animKey, callbacks);
}
}
@@ -227,8 +230,31 @@ void Character::deleteAnim() {
_curModelAnim.release();
}
-void Character::deleteCallback(const Common::String &str1, const Common::String &str2, float f) {
- error("TODO: Implement Character::deleteCallback");
+void Character::deleteCallback(const Common::String &key, const Common::String &fnName, float f) {
+ _callbacksChanged = true;
+ assert(_model->anim());
+ Common::String animPath = _model->anim()->_loadedPath.toString();
+ if (!_callbacks.contains(animPath))
+ return;
+
+ Common::Array<Callback *> &cbs = _callbacks.getVal(animPath);
+ for (unsigned int i = 0; i < cbs.size(); i++) {
+ if (fnName.empty()) {
+ delete cbs[i];
+ // don't remove from array, clear at the end.
+ } else if (cbs[i]->_luaFn == fnName) {
+ if (f == -1 || cbs[i]->_triggerFrame == f) {
+ delete cbs[i];
+ cbs.remove_at(i);
+ i--;
+ }
+ }
+ }
+ if (fnName.empty())
+ cbs.clear();
+
+ if (cbs.empty())
+ _callbacks.erase(animPath);
}
//static bool deserialize(TiXmlElement *param_1, Walk *param_2);
@@ -480,7 +506,7 @@ bool Character::onBonesUpdate(const Common::String &boneName, TeMatrix4x4 &boneM
}
bool Character::onModelAnimationFinished() {
- const Common::Path &loadedPath = _model->anim()->_loadedPath;
+ const Common::Path loadedPath = _model->anim()->_loadedPath;
const Common::String animfile = loadedPath.getLastComponent().toString();
// TODO: Do something with _unrecalAnims here.
@@ -544,7 +570,42 @@ bool Character::onModelAnimationFinished() {
}
void Character::permanentUpdate() {
- error("TODO: Implement Character::permanentUpdate.");
+ assert(_model->anim());
+ const Common::String animPath = _model->anim()->_loadedPath.toString();
+ int curFrame = _model->anim()->curFrame2();
+ Game *game = g_engine->getGame();
+ _callbacksChanged = false;
+ if (_callbacks.contains(animPath)) {
+ Common::Array<Callback *> &cbs = _callbacks.getVal(animPath);
+ for (Callback *cb : cbs) {
+ if (cb->_triggerFrame > cb->_lastCheckFrame && curFrame >= cb->_triggerFrame){
+ int callsMade = cb->_callsMade;
+ cb->_callsMade++;
+ if (callsMade >= cb->_maxCalls)
+ continue;
+ cb->_lastCheckFrame = curFrame;
+ game->luaScript().execute(cb->_luaFn);
+ if (_callbacksChanged)
+ break;
+ }
+ cb->_lastCheckFrame = curFrame;
+ }
+ }
+
+ if (animPath.contains("ka_esc_h")) {
+ if (_lastAnimFrame < 7 && _model->anim()->curFrame2() > 6) {
+ game->playSound("sounds/SFX/PAS_F_PAVE1.ogg", 1, 1.0f);
+ } else if (_lastAnimFrame < 22 && _model->anim()->curFrame2() > 21) {
+ game->playSound("sounds/SFX/PAS_F_PAVE2.ogg", 1, 1.0f);
+ }
+ } else if (animPath.contains("ka_esc_b")) {
+ if (_lastAnimFrame < 12 && _model->anim()->curFrame2() > 11) {
+ game->playSound("sounds/SFX/PAS_F_PAVE1.ogg", 1, 1.0f);
+ } else if (_lastAnimFrame < 27 && _model->anim()->curFrame2() > 26) {
+ game->playSound("sounds/SFX/PAS_F_PAVE2.ogg", 1, 1.0f);
+ }
+ }
+ updateAnimFrame();
}
void Character::placeOnCurve(TeIntrusivePtr<TeBezierCurve> &curve) {
diff --git a/engines/tetraedge/game/character.h b/engines/tetraedge/game/character.h
index b8111e0cfdb..b524c8c8691 100644
--- a/engines/tetraedge/game/character.h
+++ b/engines/tetraedge/game/character.h
@@ -86,10 +86,11 @@ public:
};
struct Callback {
- int _x;
- Common::String _s;
- int _y;
- float _f;
+ Common::String _luaFn;
+ int _triggerFrame;
+ int _lastCheckFrame;
+ int _maxCalls;
+ float _callsMade;
};
void addCallback(const Common::String &s1, const Common::String &s2, float f1, float f2);
diff --git a/engines/tetraedge/game/dialog2.cpp b/engines/tetraedge/game/dialog2.cpp
index 5437c206270..d583e0f3400 100644
--- a/engines/tetraedge/game/dialog2.cpp
+++ b/engines/tetraedge/game/dialog2.cpp
@@ -96,13 +96,14 @@ void Dialog2::load() {
setSizeType(RELATIVE_TO_PARENT);
TeVector3f32 usersz = userSize();
setSize(TeVector3f32(1.0f, 1.0f, usersz.z()));
- size(); // refresh size.. seems to do nothing with result?
+ size(); // refresh size? seems to do nothing with result
_music.repeat(false);
_gui.load("menus/dialog.lua");
TeButtonLayout *dialogLockBtn = _gui.buttonLayoutChecked("dialogLockButton");
dialogLockBtn->setVisible(false);
addChild(dialogLockBtn);
+ size(); // refresh size? seems to do nothing with result again.
TeButtonLayout *dialogBtn = _gui.buttonLayoutChecked("dialog");
dialogBtn->onMouseClickValidated().add(this, &Dialog2::onSkipButton);
diff --git a/engines/tetraedge/game/dialog2.h b/engines/tetraedge/game/dialog2.h
index 5c21231e2b7..a1f98b3772a 100644
--- a/engines/tetraedge/game/dialog2.h
+++ b/engines/tetraedge/game/dialog2.h
@@ -59,6 +59,7 @@ public:
void unload();
TeLuaGUI &gui() { return _gui; }
+ TeSignal1Param<const Common::String &> &onAnimationDownFinishedSignal() { return _onAnimationDownFinishedSignal; }
private:
Common::Array<DialogData> _dialogs;
@@ -67,7 +68,7 @@ private:
TeLuaGUI _gui;
TeMusic _music;
-
+
DialogData _currentDialogData;
TeSignal1Param<const Common::String &> _onAnimationDownFinishedSignal;
diff --git a/engines/tetraedge/game/documents_browser.cpp b/engines/tetraedge/game/documents_browser.cpp
index 1e37a00fad6..57c288a7ea3 100644
--- a/engines/tetraedge/game/documents_browser.cpp
+++ b/engines/tetraedge/game/documents_browser.cpp
@@ -21,9 +21,16 @@
#include "tetraedge/game/documents_browser.h"
+#include "tetraedge/tetraedge.h"
+#include "tetraedge/game/application.h"
+#include "tetraedge/game/game.h"
+#include "tetraedge/te/te_core.h"
+#include "tetraedge/te/te_lua_thread.h"
+#include "tetraedge/te/te_scrolling_layout.h"
+
namespace Tetraedge {
-DocumentsBrowser::DocumentsBrowser() {
+DocumentsBrowser::DocumentsBrowser() : _startPage(0), _curPage(0), _zoomCount(0) {
_timer.alarmSignal().add(this, &DocumentsBrowser::onQuitDocumentDoubleClickTimer);
}
@@ -33,7 +40,35 @@ void DocumentsBrowser::enter() {
}
void DocumentsBrowser::hideDocument() {
- error("TODO: Implement DocumentsBrowser::hideDocument");
+ Common::String docName = _curDocName;
+ _curDocName.clear();
+ TeSpriteLayout *zoomedSprite = _gui1.spriteLayout("zoomedSprite");
+ if (!zoomedSprite)
+ return;
+ Application *app = g_engine->getApplication();
+ app->captureFade();
+ zoomedSprite->unload();
+ _gui1.buttonLayoutChecked("zoomed")->setVisible(false);
+ _gui2.unload();
+ Game *game = g_engine->getGame();
+
+ bool callFn = true;
+ Common::Array<Game::YieldedCallback> &yieldedcallbacks = game->yieldedCallbacks();
+ for (unsigned int i = 0; i < yieldedcallbacks.size(); i++) {
+ if (yieldedcallbacks[i]._luaFnName == "OnDocumentClosed" &&
+ yieldedcallbacks[i]._luaParam == docName) {
+ yieldedcallbacks.remove_at(i);
+ if (yieldedcallbacks[i]._luaThread) {
+ yieldedcallbacks[i]._luaThread->resume();
+ callFn = false;
+ }
+ break;
+ }
+ }
+ if (callFn)
+ game->luaScript().execute("OnDocumentClosed", docName);
+
+ app->fade();
}
void DocumentsBrowser::leave() {
@@ -49,19 +84,18 @@ void DocumentsBrowser::load() {
const TeVector3f32 userSz = TeLayout::userSize();
setSize(TeVector3f32(1.0f, 1.0f, userSz.z()));
- TeLuaGUI::load("DocumentsBrowser/DocumentsBrowser.lua");
+ _gui1.load("DocumentsBrowser/DocumentsBrowser.lua");
- TeLayout *docBrowser = TeLuaGUI::layout("documentBrowser");
+ TeLayout *docBrowser = _gui1.layout("documentBrowser");
if (docBrowser)
addChild(docBrowser);
- TeButtonLayout *button = buttonLayout("previousPage");
+ TeButtonLayout *button = _gui1.buttonLayout("previousPage");
button->onMouseClickValidated().add(this, &DocumentsBrowser::onPreviousPage);
- button = buttonLayout("nextPage");
+ button = _gui1.buttonLayout("nextPage");
button->onMouseClickValidated().add(this, &DocumentsBrowser::onNextPage);
- button = TeLuaGUI::buttonLayout("zoomed");
+ button = _gui1.buttonLayout("zoomed");
button->onMouseClickValidated().add(this, &DocumentsBrowser::onZoomedButton);
- button = TeLuaGUI::buttonLayout("zoomed");
button->setVisible(false);
// Game tries to load a file that doesn't exist..
@@ -73,28 +107,39 @@ void DocumentsBrowser::loadZoomed() {
_zoomedLayout.setSizeType(RELATIVE_TO_PARENT);
TeVector3f32 usersz = userSize();
_zoomedLayout.setSize(TeVector3f32(1.0f, 1.0f, usersz.z()));
- TeLayout *zoomedChild = layout("zoomed");
+ TeLayout *zoomedChild = _gui1.layout("zoomed");
_zoomedLayout.addChild(zoomedChild);
}
-void DocumentsBrowser::currentPage(long page) {
- const Common::String pageName = Common::String::format("page%ld", page);
- TeLayout *pageLayout = layout(pageName);
+void DocumentsBrowser::currentPage(long setPage) {
+ const Common::String setPageName = Common::String::format("page%ld", setPage);
+ TeLayout *pageLayout = _gui1.layout(setPageName);
if (!pageLayout)
return;
- _curPage = page;
-
- error("TODO: Implement DocumentsBrowser::currentPage");
+ _curPage = setPage;
+
+ int pageNo = 0;
+ while (true) {
+ const Common::String pageName = Common::String::format("page%d", pageNo);
+ pageLayout = _gui1.layout(pageName);
+ if (!pageLayout)
+ break;
+ pageLayout->setVisible(pageNo == setPage);
+ const Common::String diodeName = Common::String::format("diode%d", pageNo);
+ _gui1.buttonLayoutChecked(diodeName)->setEnable(pageNo == setPage);
+ pageNo++;
+ }
}
bool DocumentsBrowser::onQuitDocumentDoubleClickTimer() {
long time = _timer.getTimeFromStart();
_timer.stop();
- if (time >= 200000)
- error("TODO: Implement DocumentsBrowser::onQuitDocumentDoubleClickTimer");
- else
+ if (time >= 200000) {
+ showDocument(_curDocName, _startPage + 1);
+ } else {
hideDocument();
+ }
return false;
}
@@ -109,11 +154,61 @@ bool DocumentsBrowser::onPreviousPage() {
}
bool DocumentsBrowser::onZoomedButton() {
- error("TODO: Implement DocumentsBrowser::onZoomedButton");
+ int count = _zoomCount;
+ _zoomCount++;
+ if (count == 0) {
+ _timer.start();
+ _timer.setAlarmIn(200000);
+ } else {
+ onQuitDocumentDoubleClickTimer();
+ }
+ return false;
}
-void DocumentsBrowser::showDocument(const Common::String &str, long n) {
- error("TODO: Implement DocumentsBrowser::showDocument");
+void DocumentsBrowser::showDocument(const Common::String &docName, long startPage) {
+ _curPage = startPage;
+ _startPage = startPage;
+ _curDocName = docName;
+ _gui2.unload();
+ TeCore *core = g_engine->getCore();
+ const Common::Path docPathBase(Common::String::format("DocumentsBrowser/Documents/Documents/%s_zoomed_%d", docName.c_str(), (int)startPage));
+ Common::Path docPath = docPathBase.append(".png");
+ docPath = core->findFile(docPath);
+ if (!Common::File::exists(docPath)) {
+ docPath = docPathBase.append(".jpg");
+ docPath = core->findFile(docPath);
+ if (!Common::File::exists(docPath)) {
+ // Probably the end of the doc
+ if (startPage == 0)
+ warning("Can't find first page of doc named %s", docName.c_str());
+ hideDocument();
+ return;
+ }
+ }
+ Application *app = g_engine->getApplication();
+ app->captureFade();
+ TeSpriteLayout *sprite = _gui1.spriteLayoutChecked("zoomedSprite");
+ //sprite->setSizeType(ABSOLUTE);
+ sprite->load(docPath);
+ TeVector2s32 spriteSize = sprite->_tiledSurfacePtr->_tiledTexture->_totalSize;
+ sprite->setSizeType(RELATIVE_TO_PARENT);
+ TeVector3f32 winSize = app->getMainWindow().size();
+ sprite->setSize(TeVector3f32(1.0, (4.0 / (winSize.y() / winSize.x() * 4.0)) *
+ ((float)spriteSize._y / (float)spriteSize._x), 0.0));
+ TeScrollingLayout *scroll = _gui1.scrollingLayout("scroll");
+ if (!scroll)
+ error("DocumentsBrowser::showDocument Couldn't fetch scroll object");
+ scroll->resetScrollPosition();
+ scroll->playAutoScroll();
+ Common::Path luaPath = docPathBase.append(".lua");
+ luaPath = core->findFile(luaPath);
+ if (Common::File::exists(luaPath)) {
+ _gui2.load(luaPath);
+ error("Finish DocumentsBrowser::showDocument");
+ }
+ _gui1.layoutChecked("zoomed")->setVisible(true);
+ _zoomCount = 0;
+ app->fade();
}
void DocumentsBrowser::unload() {
diff --git a/engines/tetraedge/game/documents_browser.h b/engines/tetraedge/game/documents_browser.h
index f1d4818cb2d..c2a42943507 100644
--- a/engines/tetraedge/game/documents_browser.h
+++ b/engines/tetraedge/game/documents_browser.h
@@ -28,7 +28,7 @@
namespace Tetraedge {
-class DocumentsBrowser : public TeLuaGUI, public TeLayout {
+class DocumentsBrowser : public TeLayout {
public:
DocumentsBrowser();
@@ -79,15 +79,23 @@ public:
bool onShowedDocumentButton18();
bool onShowedDocumentButton19();
- void showDocument(const Common::String &str, long n);
+ void showDocument(const Common::String &str, long startPage);
void unload();
TeLayout &zoomedLayout() { return _zoomedLayout; }
+ TeLuaGUI &gui1() { return _gui1; }
+
private:
TeTimer _timer;
TeLayout _zoomedLayout;
unsigned long _curPage;
+ unsigned long _startPage;
+ int _zoomCount;
+ Common::String _curDocName;
+
+ TeLuaGUI _gui1;
+ TeLuaGUI _gui2;
// TiXmlDocument _xmldoc;
};
diff --git a/engines/tetraedge/game/game.cpp b/engines/tetraedge/game/game.cpp
index 407a7730b5b..d9bf03e1ccc 100644
--- a/engines/tetraedge/game/game.cpp
+++ b/engines/tetraedge/game/game.cpp
@@ -56,6 +56,8 @@ _firstInventory(true), _loadName("save.xml"), _randomSource("SyberiaGameRandom")
_objectsTakenBits[i] = false;
}
_randomSound = new RandomSound();
+ _dialog2.onAnimationDownFinishedSignal().add(this, &Game::onDialogFinished);
+ _question2.onAnswerSignal().add(this, &Game::onAnswered);
}
Game::~Game() {
@@ -81,13 +83,13 @@ bool Game::addAnimToSet(const Common::String &anim) {
const Common::String layoutName = parts[1];
const Common::String path = Common::String("scenes/") + parts[0] + "/" + parts[1] + "/Set" + parts[1];
- _gui2.load(path + ".lua");
+ _setAnimGui.load(path + ".lua");
// Note: game makes this here, but never uses it..
// it seems like a random memory leak??
// TeSpriteLayout *spritelayout = new TeSpriteLayout();
- TeSpriteLayout *spritelayout = findSpriteLayoutByName(_gui2.layoutChecked("root"), layoutName);
+ TeSpriteLayout *spritelayout = findSpriteLayoutByName(_setAnimGui.layoutChecked("root"), layoutName);
_scene.bgGui().layoutChecked("root")->addChild(spritelayout);
return true;
@@ -237,7 +239,7 @@ bool Game::changeWarp2(const Common::String &zone, const Common::String &scene,
_luaScript.unload();
}
- _gui3.unload();
+ _forGui.unload();
_prevSceneName = _currentScene;
if (fadeFlag)
g_engine->getApplication()->fade();
@@ -260,8 +262,8 @@ void Game::deleteNoScale() {
void Game::draw() {
if (_running) {
- _frameCounter++;
- _scene.draw();
+ _frameCounter++;
+ _scene.draw();
}
}
@@ -493,8 +495,8 @@ bool Game::initWarp(const Common::String &zone, const Common::String &scene, boo
_luaScript.load(logicLuaPath);
}
- if (_gui3.loaded())
- _gui3.unload();
+ if (_forGui.loaded())
+ _forGui.unload();
_scene.reset();
_scene.bgGui().unload();
@@ -507,8 +509,8 @@ bool Game::initWarp(const Common::String &zone, const Common::String &scene, boo
Application *app = g_engine->getApplication();
if (forLuaExists) {
- _gui3.load(forLuaPath);
- TeLayout *bg = _gui3.layout("background");
+ _forGui.load(forLuaPath);
+ TeLayout *bg = _forGui.layout("background");
bg->setRatioMode(TeILayout::RATIO_MODE_NONE);
app->_frontLayout.addChild(bg);
TeLayout *cellbg = _inventory.cellphone()->gui().buttonLayout("background");
@@ -595,7 +597,7 @@ bool Game::initWarp(const Common::String &zone, const Common::String &scene, boo
app->_backLayout.addChild(_scene.background());
if (markerLuaExists) {
- TeLayout *bg = _gui2.layout("background");
+ TeLayout *bg = _scene.markerGui().layout("background");
app->_frontLayout.addChild(bg);
}
@@ -641,7 +643,7 @@ bool Game::initWarp(const Common::String &zone, const Common::String &scene, boo
}
bool Game::isDocumentOpened() {
- return _documentsBrowser.layoutChecked("zoomed")->visible();
+ return _documentsBrowser.gui1().layoutChecked("zoomed")->visible();
}
bool Game::isMoviePlaying() {
@@ -674,7 +676,7 @@ bool Game::launchDialog(const Common::String &dname, uint param_2, const Common:
}
const Common::String sndfile = dname + ".ogg";
- _dialog2.pushDialog(*locdname, *locdname, sndfile, charname, animfile, param_5);
+ _dialog2.pushDialog(dname, *locdname, sndfile, charname, animfile, param_5);
return true;
}
@@ -695,13 +697,14 @@ void Game::leave(bool flag) {
_inventoryMenu.unload();
_gui1.unload();
_scene.close();
- _gui3.unload();
+ _forGui.unload();
if (_scene._character) {
_scene._character->deleteAllCallback();
_scene._character->stop();
_scene.unloadCharacter(_scene._character->_model->name());
}
- warning("TODO: Game::leave: clear game sounds");
+
+ warning("TODO: Game::leave: clear game sounds and randomsounds");
for (auto *hitobj : _gameHitObjects) {
delete hitobj;
@@ -718,6 +721,7 @@ void Game::leave(bool flag) {
_inGameGui.buttonLayoutChecked("inventoryButton")->onMouseClickValidated().remove(this, &Game::onInventoryButtonValidated);
_inGameGui.unload();
_playedTimer.stop();
+ _enteredFlag2 = false;
Application *app = g_engine->getApplication();
app->_lockCursorButton.setVisible(false);
@@ -808,8 +812,9 @@ bool Game::onCharacterAnimationPlayerFinished(const Common::String &anim) {
Character *character = scene()._character;
assert(character);
-
- const Common::String &curAnimName = character->curAnimName();
+ // Note: the above callbacks can change the anim,
+ // so we have to fetch this *after* them.
+ const Common::String curAnimName = character->curAnimName();
if (_currentScene == _someSceneName) {
if (curAnimName == character->walkAnim(Character::WalkPart_Start)
|| curAnimName == character->walkAnim(Character::WalkPart_Loop)
@@ -825,8 +830,10 @@ bool Game::onCharacterAnimationPlayerFinished(const Common::String &anim) {
|| curAnimName == character->walkAnim(Character::WalkPart_EndG)) {
character->updatePosition(1.0);
character->endMove();
- // Note: original checks walkAnim again.. is there a reason to do that?
- character->setAnimation(character->characterSettings()._idleAnimFileName, true);
+ // endMove can result in callbacks that change the animation. check again.
+ if (character->curAnimName() == character->walkAnim(Character::WalkPart_EndD)
+ || character->curAnimName() == character->walkAnim(Character::WalkPart_EndG))
+ character->setAnimation(character->characterSettings()._idleAnimFileName, true);
}
}
@@ -1352,7 +1359,7 @@ void Game::setCurrentObjectSprite(const Common::String &spritePath) {
}
bool Game::showMarkers(bool val) {
- TeLayout *bg = _gui3.layoutChecked("background");
+ TeLayout *bg = _forGui.layoutChecked("background");
for (unsigned int i = 0; i < bg->childCount(); i++) {
const InGameScene::TeMarker *marker = _scene.findMarker(bg->child(i)->name());
if (marker)
@@ -1446,7 +1453,7 @@ void Game::update() {
if (player) {
TeIntrusivePtr<TeModel> model = player->_model;
bool modelVisible = model->visible();
- if (!model->anim().get())
+ if (model->anim())
player->permanentUpdate();
if (modelVisible) {
if (player->needsSomeUpdate()) {
diff --git a/engines/tetraedge/game/game.h b/engines/tetraedge/game/game.h
index 610c7e2c87d..3481d25bf44 100644
--- a/engines/tetraedge/game/game.h
+++ b/engines/tetraedge/game/game.h
@@ -75,8 +75,9 @@ public:
struct YieldedCallback {
TeLuaThread *_luaThread;
Common::String _luaParam;
+ Common::String _luaParam2;
Common::String _luaFnName;
- // Note: original game has more String, long, and int fields.. seem unused.
+ // Note: original game long, and int fields.. unused?
};
//enum EGameScoreID {}; // Not needed?
@@ -183,7 +184,7 @@ public:
InGameScene &scene() { return _scene; }
Dialog2 &dialog2() { return _dialog2; }
Question2 &question2() { return _question2; }
- TeLuaGUI &gui3() { return _gui3; }
+ TeLuaGUI &forGui() { return _forGui; }
Objectif &objectif() { return _objectif; }
Common::Array<YieldedCallback> &yieldedCallbacks() { return _yieldedCallbacks; }
void setSaveRequested() { _saveRequested = true; }
@@ -199,9 +200,9 @@ private:
bool _entered;
bool _enteredFlag2;
- TeLuaGUI _gui1; // TODO: get better names for these.
- TeLuaGUI _gui2;
- TeLuaGUI _gui3;
+ TeLuaGUI _gui1; // TODO: Is this ever used?
+ TeLuaGUI _setAnimGui;
+ TeLuaGUI _forGui;
TeLuaGUI _inGameGui;
Inventory _inventory;
diff --git a/engines/tetraedge/game/in_game_scene.cpp b/engines/tetraedge/game/in_game_scene.cpp
index 7aabee33cfe..f61c87d348c 100644
--- a/engines/tetraedge/game/in_game_scene.cpp
+++ b/engines/tetraedge/game/in_game_scene.cpp
@@ -42,7 +42,7 @@
#include "tetraedge/te/te_lua_script.h"
#include "tetraedge/te/te_lua_thread.h"
-#define DEBUG_PATHFINDING 1
+//#define DEBUG_PATHFINDING 1
namespace Tetraedge {
@@ -124,7 +124,7 @@ bool InGameScene::addMarker(const Common::String &markerName, const Common::Stri
newMarker._name = markerName;
newMarker._val = markerVal;
_markers.push_back(newMarker);
- TeLayout *bg = game->gui3().layout("background");
+ TeLayout *bg = game->forGui().layout("background");
if (bg)
bg->addChild(markerSprite);
_sprites.push_back(markerSprite);
@@ -259,7 +259,7 @@ void InGameScene::deleteMarker(const Common::String &markerName) {
}
Game *game = g_engine->getGame();
- TeLayout *bg = game->gui3().layout("background");
+ TeLayout *bg = game->forGui().layout("background");
if (!bg)
return;
for (Te3DObject2 *child : bg->childList()) {
@@ -480,7 +480,7 @@ Common::String InGameScene::imagePathMarker(const Common::String &name) {
if (!isMarker(name))
return Common::String();
Game *game = g_engine->getGame();
- TeLayout *bg = game->gui3().layoutChecked("background");
+ TeLayout *bg = game->forGui().layoutChecked("background");
for (Te3DObject2 *child : bg->childList()) {
TeSpriteLayout *spritelayout = dynamic_cast<TeSpriteLayout *>(child);
if (spritelayout && spritelayout->name() == name) {
@@ -907,7 +907,7 @@ void InGameScene::setImagePathMarker(const Common::String &markerName, const Com
return;
Game *game = g_engine->getGame();
- TeLayout *bg = game->gui3().layoutChecked("background");
+ TeLayout *bg = game->forGui().layoutChecked("background");
for (Te3DObject2 *child : bg->childList()) {
if (child->name() == markerName) {
diff --git a/engines/tetraedge/game/inventory.cpp b/engines/tetraedge/game/inventory.cpp
index dc48f38fb07..2fcb923c5af 100644
--- a/engines/tetraedge/game/inventory.cpp
+++ b/engines/tetraedge/game/inventory.cpp
@@ -88,8 +88,9 @@ void Inventory::load() {
btn->setVisible(true);
btn->onMouseClickValidated().add(this, &Inventory::onQuitButton);
+ // FIXME: This is capturing mouse clicks.. should be set visible per original.
btn = _gui.buttonLayoutChecked("quitBackground");
- btn->setVisible(true);
+ btn->setVisible(false);
btn->onMouseClickValidated().add(this, &Inventory::onQuitButton);
btn = _gui.buttonLayoutChecked("mainMenuButton");
@@ -207,6 +208,7 @@ bool Inventory::addObject(InventoryObject *obj) {
c--;
}
}
+ slotno++;
}
pageno++;
}
@@ -234,7 +236,7 @@ bool Inventory::addObject(InventoryObject *obj) {
finished = true;
break;
}
-
+
TeTextLayout *newText = new TeTextLayout();
newText->setSizeType(CoordinatesType::RELATIVE_TO_PARENT);
newText->setPosition(TeVector3f32(1.0,1.0,0.0));
diff --git a/engines/tetraedge/game/lua_binds.cpp b/engines/tetraedge/game/lua_binds.cpp
index e8c74ffb3dd..514fd08bb0b 100644
--- a/engines/tetraedge/game/lua_binds.cpp
+++ b/engines/tetraedge/game/lua_binds.cpp
@@ -181,6 +181,21 @@ static int tolua_ExportedFunctions_AddNumber00(lua_State *L) {
error("#ferror in function 'AddNumber': %d %d %s", err.index, err.array, err.type);
}
+static void ShowDocument(const Common::String &name) {
+ Game *game = g_engine->getGame();
+ game->documentsBrowser().showDocument(name, 0);
+}
+
+static int tolua_ExportedFunctions_ShowDocument00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isnoobj(L, 2, &err)) {
+ Common::String s1(tolua_tostring(L, 1, nullptr));
+ ShowDocument(s1);
+ return 0;
+ }
+ error("#ferror in function 'ShowDocument': %d %d %s", err.index, err.array, err.type);
+}
+
static void AddUnrecalAnim(const Common::String &newanim) {
Application *app = g_engine->getApplication();
Common::Array<Common::String> &anims = app->unrecalAnims();
@@ -266,11 +281,11 @@ static int tolua_ExportedFunctions_MoveCharacterPlayerDisabled00(lua_State *L) {
error("#ferror in function 'MoveCharacterPlayerDisabled': %d %d %s", err.index, err.array, err.type);
}
-static void AddCallback(const Common::String &charName, const Common::String &key, const Common::String &s1, float f1, float f2) {
+static void AddCallback(const Common::String &charName, const Common::String &animName, const Common::String &fnName, float triggerFrame, float maxCalls) {
Game *game = g_engine->getGame();
Character *c = game->scene().character(charName);
if (c) {
- c->addCallback(key, s1, f1, f2);
+ c->addCallback(animName, fnName, triggerFrame, maxCalls);
} else {
warning("[AddCallback] Character's \"%s\" doesn't exist", charName.c_str());
}
@@ -283,9 +298,9 @@ static int tolua_ExportedFunctions_AddCallback00(lua_State *L) {
&& tolua_isnumber(L, 5, 1, &err) && tolua_isnoobj(L, 6, &err)) {
Common::String s1(tolua_tostring(L, 1, nullptr));
Common::String s2(tolua_tostring(L, 2, nullptr));
- Common::String s3(tolua_tostring(L, 2, nullptr));
- double n1 = tolua_tonumber(L, 3, 0.0);
- double n2 = tolua_tonumber(L, 4, -1.0);
+ Common::String s3(tolua_tostring(L, 3, nullptr));
+ double n1 = tolua_tonumber(L, 4, 0.0);
+ double n2 = tolua_tonumber(L, 5, -1.0);
AddCallback(s1, s2, s3, n1, n2);
return 0;
}
@@ -412,7 +427,7 @@ static void HideObject(const Common::String &objName) {
}
debug("[HideObject] \"Set\" Object 2D \"%s\" doesn't exist.", objName.c_str());
- layout = game->gui3().layout(objName);
+ layout = game->forGui().layout(objName);
if (layout) {
layout->setVisible(false);
return;
@@ -447,7 +462,7 @@ static void ShowObject(const Common::String &objName) {
}
debug("[ShowObject] \"Set\" Object 2D \"%s\" doesn't exist.", objName.c_str());
- layout = game->gui3().layout(objName);
+ layout = game->forGui().layout(objName);
if (layout) {
layout->setVisible(true);
return;
@@ -578,7 +593,7 @@ static int tolua_ExportedFunctions_SetCharacterOrientation00(lua_State *L) {
static void SetCharacterAnimation(const Common::String &charname, const Common::String &animname, bool repeat, bool b2, int i1, int i2) {
Game *game = g_engine->getGame();
Character *c = game->scene().character(charname);
- bool result = c->setAnimation(animname, repeat, b2, i1, i2);
+ bool result = c->setAnimation(animname, repeat, b2, true, i1, i2);
if (!result) {
warning("[SetCharacterAnimation] Character's animation \"%s\" doesn't exist for the character\"%s\" ",
animname.c_str(), charname.c_str());
@@ -603,6 +618,59 @@ static int tolua_ExportedFunctions_SetCharacterAnimation00(lua_State *L) {
error("#ferror in function 'SetCharacterAnimation': %d %d %s", err.index, err.array, err.type);
}
+static void BlendCharacterAnimation(const Common::String &charname, const Common::String &animname, float blendAmount, bool repeat, bool b2) {
+ Game *game = g_engine->getGame();
+ Character *c = game->scene().character(charname);
+ bool result = c->blendAnimation(animname, blendAmount, repeat, b2);
+ if (!result) {
+ warning("[BlendCharacterAnimation] Character's animation \"%s\" doesn't exist for the character\"%s\" ",
+ animname.c_str(), charname.c_str());
+ }
+}
+
+static int tolua_ExportedFunctions_BlendCharacterAnimation00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isstring(L, 2, 0, &err)
+ && tolua_isnumber(L, 3, 0, &err) && tolua_isboolean(L, 4, 1, &err)
+ && tolua_isboolean(L, 5, 1, &err) && tolua_isnoobj(L, 6, &err)) {
+ Common::String s1(tolua_tostring(L, 1, nullptr));
+ Common::String s2(tolua_tostring(L, 2, nullptr));
+ double f1 = tolua_tonumber(L, 3, 0.0);
+ bool b1 = tolua_toboolean(L, 4, 1);
+ bool b2 = tolua_toboolean(L, 5, 0);
+ BlendCharacterAnimation(s1, s2, f1, b1, b2);
+ return 0;
+ }
+ error("#ferror in function 'BlendCharacterAnimation': %d %d %s", err.index, err.array, err.type);
+}
+
+static int tolua_ExportedFunctions_BlendCharacterAnimationAndWaitForEnd00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isstring(L, 2, 0, &err)
+ && tolua_isnumber(L, 3, 0, &err) && tolua_isboolean(L, 4, 1, &err)
+ && tolua_isboolean(L, 5, 1, &err) && tolua_isnoobj(L, 6, &err)) {
+ Common::String s1(tolua_tostring(L, 1, nullptr));
+ Common::String s2(tolua_tostring(L, 2, nullptr));
+ double f1 = tolua_tonumber(L, 3, 0.0);
+ bool b1 = tolua_toboolean(L, 4, 1);
+ bool b2 = tolua_toboolean(L, 5, 0);
+ BlendCharacterAnimation(s1, s2, f1, b1, b2);
+
+ Game::YieldedCallback cb;
+ cb._luaFnName = "OnCharacterAnimationFinished";
+ cb._luaParam = s1;
+ cb._luaParam2 = s2;
+ cb._luaThread = TeLuaThread::threadFromState(L);
+ Game *game = g_engine->getGame();
+ for (const auto &gamecb : game->yieldedCallbacks()) {
+ if (gamecb._luaFnName == cb._luaFnName && gamecb._luaParam == s1 && gamecb._luaParam2 == s2)
+ error("BlendCharacterAnimationAndWaitForEnd: Reentrency error, your are already in a yielded/sync function call");
+ }
+ game->yieldedCallbacks().push_back(cb);
+ return cb._luaThread->yield();
+ }
+ error("#ferror in function 'BlendCharacterAnimationAndWaitForEnd': %d %d %s", err.index, err.array, err.type);
+}
static void SetCharacterPosition(const Common::String &charname, const Common::String &zonename, float f1, float f2, float f3) {
Game *game = g_engine->getGame();
@@ -869,6 +937,7 @@ static int tolua_ExportedFunctions_LaunchDialogAndWaitForEnd00(lua_State *L) {
error("LaunchDialogAndWaitForEnd: Reentrency error, your are already in a yielded/sync function call");
}
+ game->yieldedCallbacks().push_back(callback);
return callback._luaThread->yield();
}
error("#ferror in function 'LaunchDialogAndWaitForEnd': %d %d %s", err.index, err.array, err.type);
@@ -1196,7 +1265,7 @@ static int tolua_ExportedFunctions_PlayMusic00(lua_State *L) {
error("#ferror in function 'PlayMusic': %d %d %s", err.index, err.array, err.type);
}
-static void SetObjectOnCharacter(const Common::String &obj, const Common::String &charName, const Common::String &boneName) {
+static void SetObjectOnCharacter(const Common::String &charName, const Common::String &obj, const Common::String &boneName) {
Game *game = g_engine->getGame();
Object3D *obj3d = game->scene().object3D(obj);
if (!obj3d) {
@@ -1499,8 +1568,8 @@ void LuaOpenBinds(lua_State *L) {
tolua_function(L, "RemoveObject", tolua_ExportedFunctions_RemoveObject00);
tolua_function(L, "RemoveObject", tolua_ExportedFunctions_RemoveObject01);*/
tolua_function(L, "AddNumber", tolua_ExportedFunctions_AddNumber00);
- /*tolua_function(L, "ShowDocument", tolua_ExportedFunctions_ShowDocument00);
- tolua_function(L, "ShowDocumentAndWaitForEnd", tolua_ExportedFunctions_ShowDocumentAndWaitForEnd00);
+ tolua_function(L, "ShowDocument", tolua_ExportedFunctions_ShowDocument00);
+ /*tolua_function(L, "ShowDocumentAndWaitForEnd", tolua_ExportedFunctions_ShowDocumentAndWaitForEnd00);
tolua_function(L, "HideDocument", tolua_ExportedFunctions_HideDocument00);
tolua_function(L, "AddDocument", tolua_ExportedFunctions_AddDocument00);*/
tolua_function(L, "LoadCharacter", tolua_ExportedFunctions_LoadCharacter00);
@@ -1522,10 +1591,10 @@ void LuaOpenBinds(lua_State *L) {
tolua_function(L, "SetCharacterOrientation", tolua_ExportedFunctions_SetCharacterOrientation00);
tolua_function(L, "SetCharacterAnimation", tolua_ExportedFunctions_SetCharacterAnimation00);
/*tolua_function(L, "SetCharacterAnimationAndWaitForEnd",
- tolua_ExportedFunctions_SetCharacterAnimationAndWaitForEnd00);
+ tolua_ExportedFunctions_SetCharacterAnimationAndWaitForEnd00);*/
tolua_function(L, "BlendCharacterAnimation", tolua_ExportedFunctions_BlendCharacterAnimation00);
tolua_function(L, "BlendCharacterAnimationAndWaitForEnd",
- tolua_ExportedFunctions_BlendCharacterAnimationAndWaitForEnd00);*/
+ tolua_ExportedFunctions_BlendCharacterAnimationAndWaitForEnd00);
tolua_function(L, "CurrentCharacterAnimation", tolua_ExportedFunctions_CurrentCharacterAnimation00);
tolua_function(L, "SetCharacterPlayerVisible", tolua_ExportedFunctions_SetCharacterPlayerVisible00);
tolua_function(L, "MoveCharacterPlayerDisabled",
diff --git a/engines/tetraedge/game/question2.h b/engines/tetraedge/game/question2.h
index ca5ddd7ee6f..6468adafa8b 100644
--- a/engines/tetraedge/game/question2.h
+++ b/engines/tetraedge/game/question2.h
@@ -52,6 +52,7 @@ public:
void pushAnswer(const Common::String &name, const Common::String &unk, const Common::String &path);
void unload();
TeLuaGUI &gui() { return _gui; }
+ TeSignal1Param<const Common::String &> &onAnswerSignal() { return _onAnswerSignal; }
private:
TeLuaGUI _gui;
diff --git a/engines/tetraedge/te/te_3d_object2.cpp b/engines/tetraedge/te/te_3d_object2.cpp
index d4997914a24..f18a56b5e43 100644
--- a/engines/tetraedge/te/te_3d_object2.cpp
+++ b/engines/tetraedge/te/te_3d_object2.cpp
@@ -141,6 +141,11 @@ void Te3DObject2::removeChild(Te3DObject2 *child) {
_children[i]->setParent(nullptr);
_children.remove_at(i);
_childListChangedSignal.call();
+ } else {
+ Common::String cname("nullptr");
+ if (child)
+ cname = child->name();
+ warning("Request to remove child (%s) which is not a child of this (%s).", cname.c_str(), name().c_str());
}
}
@@ -196,6 +201,7 @@ void Te3DObject2::setPosition(const TeVector3f32 &pos) {
if (_position == pos)
return;
+ // FIXME: remove this debugging code.
if ((_position - pos).length() > 2.0f && name() == "Kate" && _position != TeVector3f32()) {
debug("Large position move %s %s -> %s", name().c_str(),
_position.dump().c_str(), pos.dump().c_str());
diff --git a/engines/tetraedge/te/te_3d_texture.cpp b/engines/tetraedge/te/te_3d_texture.cpp
index 54693085cb7..a129e438679 100644
--- a/engines/tetraedge/te/te_3d_texture.cpp
+++ b/engines/tetraedge/te/te_3d_texture.cpp
@@ -31,7 +31,7 @@ namespace Tetraedge {
static const uint NO_TEXTURE = 0xffffffff;
Te3DTexture::Te3DTexture() : _glTexture(NO_TEXTURE), _createdTexture(false),
-_numFrames(1), _frameRate(0), _format(TeImage::INVALID), _glPixelFormat(GL_INVALID_ENUM) {
+_numFrames(1), _frameRate(0), _format(TeImage::INVALID)/*, _glPixelFormat(GL_INVALID_ENUM)*/ {
create();
}
@@ -49,18 +49,17 @@ void Te3DTexture::bind() const {
}
void Te3DTexture::copyCurrentRender(uint xoffset, uint yoffset, uint x, uint y) {
- // TODO: Get some better variable names here.
_matrix.setToIdentity();
- const TeVector3f32 local_40((float)_width / _texWidth, (float)_height / _texHeight, 1.0);
- _matrix.scale(local_40);
- const TeVector3f32 local_50((float)_leftBorder / _width, (float)_btmBorder / _height, 0.0);
- _matrix.translate(local_50);
- const TeVector3f32 local_60(
+ const TeVector3f32 texScale((float)_width / _texWidth, (float)_height / _texHeight, 1.0);
+ _matrix.scale(texScale);
+ const TeVector3f32 offset((float)_leftBorder / _width, (float)_btmBorder / _height, 0.0);
+ _matrix.translate(offset);
+ const TeVector3f32 borderScale(
1.0 - (float)(_rightBorder + _leftBorder) /
(float)_width,
1.0 - (float)(_topBorder + _btmBorder) /
(float)_height, 1.0);
- _matrix.scale(local_60);
+ _matrix.scale(borderScale);
bind();
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, xoffset, yoffset, x, y, _texWidth, _texHeight);
}
diff --git a/engines/tetraedge/te/te_3d_texture.h b/engines/tetraedge/te/te_3d_texture.h
index f3a57e96041..1696cbaf2d1 100644
--- a/engines/tetraedge/te/te_3d_texture.h
+++ b/engines/tetraedge/te/te_3d_texture.h
@@ -69,7 +69,7 @@ private:
bool _createdTexture;
bool _loaded;
uint _glTexture;
- uint _glPixelFormat;
+ //uint _glPixelFormat;
TeMatrix4x4 _matrix;
uint _texWidth;
diff --git a/engines/tetraedge/te/te_button_layout.cpp b/engines/tetraedge/te/te_button_layout.cpp
index f0235e3492c..d06768c6bc5 100644
--- a/engines/tetraedge/te/te_button_layout.cpp
+++ b/engines/tetraedge/te/te_button_layout.cpp
@@ -220,7 +220,8 @@ void TeButtonLayout::setDisabledLayout(TeLayout *disabledLayout) {
_disabledLayout = disabledLayout;
if (_disabledLayout) {
addChild(_disabledLayout);
- _disabledLayout->setColor(TeColor(0, 0, 0, 0));
+ //_disabledLayout->setColor(TeColor(0, 0, 0, 0));
+ //_disabledLayout->setName(name() + "_disabledLayout");
}
setState(_currentState);
@@ -233,7 +234,8 @@ void TeButtonLayout::setHitZone(TeLayout *hitZoneLayout) {
_hitZoneLayout = hitZoneLayout;
if (_hitZoneLayout) {
addChild(_hitZoneLayout);
- _hitZoneLayout->setColor(TeColor(0, 0, 0xff, 0xff));
+ //_hitZoneLayout->setColor(TeColor(0, 0, 0xff, 0xff));
+ //_hitZoneLayout->setName(name() + "_hitZoneLayout");
}
}
@@ -251,8 +253,10 @@ void TeButtonLayout::setDownLayout(TeLayout *downLayout) {
setSize(_downLayout->size());
}
- if (_downLayout)
- _downLayout->setColor(TeColor(0, 0, 0, 0));
+ //if (_downLayout) {
+ // _downLayout->setColor(TeColor(0, 0, 0, 0));
+ //_downLayout->setName(name() + "_downLayout");
+ //}
setState(_currentState);
}
@@ -264,9 +268,14 @@ void TeButtonLayout::setRollOverLayout(TeLayout *rollOverLayout) {
_rolloverLayout = rollOverLayout;
if (_rolloverLayout) {
addChild(_rolloverLayout);
- _rolloverLayout->setColor(TeColor(0, 0, 0, 0));
+ //_rolloverLayout->setName(name() + "_rolloverLayout");
}
+ // This is not a copy paste error, or at least, not *my*
+ // copy paste error.. it's what the original game does.
+ //if (_disabledLayout)
+ // _disabledLayout->setColor(TeColor(0, 0, 0, 0));
+
setState(_currentState);
}
@@ -284,8 +293,10 @@ void TeButtonLayout::setUpLayout(TeLayout *upLayout) {
setSize(_upLayout->size());
}
- if (_upLayout)
- _upLayout->setColor(TeColor(0, 0, 0, 0));
+ if (_upLayout) {
+ //_upLayout->setColor(TeColor(0, 0, 0, 0));
+ //_upLayout->setName(name() + "_upLayout");
+ }
setState(_currentState);
}
@@ -338,7 +349,10 @@ void TeButtonLayout::setState(State newState) {
}
if (_upLayout)
- _upLayout->setVisible(_currentState == BUTTON_STATE_UP);
+ _upLayout->setVisible(_currentState == BUTTON_STATE_UP
+ || (_currentState == BUTTON_STATE_ROLLOVER && _rolloverLayout == nullptr)
+ || (_currentState == BUTTON_STATE_DOWN && _downLayout == nullptr)
+ || (_currentState == BUTTON_STATE_DISABLED && _disabledLayout == nullptr));
if (_downLayout)
_downLayout->setVisible(_currentState == BUTTON_STATE_DOWN);
if (_disabledLayout)
diff --git a/engines/tetraedge/te/te_camera.cpp b/engines/tetraedge/te/te_camera.cpp
index 430d9be686f..bb2eb7bf4dc 100644
--- a/engines/tetraedge/te/te_camera.cpp
+++ b/engines/tetraedge/te/te_camera.cpp
@@ -79,23 +79,23 @@ void TeCamera::buildOrthoMatrix() {
}
_projectionMatrix.setValue(0, 0, widthNorm * 2.0f);
- _projectionMatrix.setValue(0, 1, 0.0);
- _projectionMatrix.setValue(0, 2, 0.0);
- _projectionMatrix.setValue(0, 3, -((_orthogonalParamR + _orthogonalParamL) * widthNorm));
-
_projectionMatrix.setValue(1, 0, 0.0);
- _projectionMatrix.setValue(1, 1, heightNorm * 2.0f);
- _projectionMatrix.setValue(1, 2, 0.0);
- _projectionMatrix.setValue(1, 3, -((_orthogonalParamB + _orthogonalParamT) * heightNorm));
-
_projectionMatrix.setValue(2, 0, 0.0);
- _projectionMatrix.setValue(2, 1, 0.0);
- _projectionMatrix.setValue(2, 2, depthNorm * -2.0f);
- _projectionMatrix.setValue(2, 3, -((_orthFarVal + _orthNearVal) * depthNorm));
-
_projectionMatrix.setValue(3, 0, 0.0);
+
+ _projectionMatrix.setValue(0, 1, 0.0);
+ _projectionMatrix.setValue(1, 1, heightNorm * 2.0f);
+ _projectionMatrix.setValue(2, 1, 0.0);
_projectionMatrix.setValue(3, 1, 0.0);
+
+ _projectionMatrix.setValue(0, 2, 0.0);
+ _projectionMatrix.setValue(1, 2, 0.0);
+ _projectionMatrix.setValue(2, 2, depthNorm * -2.0f);
_projectionMatrix.setValue(3, 2, 0.0);
+
+ _projectionMatrix.setValue(0, 3, -((_orthogonalParamR + _orthogonalParamL) * widthNorm));
+ _projectionMatrix.setValue(1, 3, -((_orthogonalParamB + _orthogonalParamT) * heightNorm));
+ _projectionMatrix.setValue(2, 3, -((_orthFarVal + _orthNearVal) * depthNorm));
_projectionMatrix.setValue(3, 3, 1.0);
}
diff --git a/engines/tetraedge/te/te_checkbox_layout.cpp b/engines/tetraedge/te/te_checkbox_layout.cpp
index 05ad75eec21..0392205e0a7 100644
--- a/engines/tetraedge/te/te_checkbox_layout.cpp
+++ b/engines/tetraedge/te/te_checkbox_layout.cpp
@@ -71,7 +71,7 @@ void TeCheckboxLayout::setUnactiveLayout(TeLayout *layout) {
warning("TODO: Add extra code in TeCheckboxLayout::setUnactiveLayout.");
if (layout) {
addChild(layout);
- layout->setColor(TeColor(0, 0, 0, 0));
+ //layout->setColor(TeColor(0, 0, 0, 0));
}
setState(_state);
}
@@ -82,7 +82,7 @@ void TeCheckboxLayout::setActiveDisabledLayout(TeLayout *layout) {
_activeDisabledLayout = layout;
if (layout) {
addChild(layout);
- layout->setColor(TeColor(0, 0, 0, 0));
+ //layout->setColor(TeColor(0, 0, 0, 0));
}
setState(_state);
}
@@ -93,7 +93,7 @@ void TeCheckboxLayout::setUnactiveDisabledLayout(TeLayout *layout) {
_unactiveDisabledLayout = layout;
if (layout) {
addChild(layout);
- layout->setColor(TeColor(0, 0, 0, 0));
+ //layout->setColor(TeColor(0, 0, 0, 0));
}
setState(_state);
}
@@ -104,7 +104,7 @@ void TeCheckboxLayout::setActiveRollOverLayout(TeLayout *layout) {
_activeRollOverLayout = layout;
if (layout) {
addChild(layout);
- layout->setColor(TeColor(0, 0, 0, 0));
+ //layout->setColor(TeColor(0, 0, 0, 0));
}
setState(_state);
}
@@ -115,7 +115,7 @@ void TeCheckboxLayout::setUnactiveRollOverLayout(TeLayout *layout) {
_unactiveRollOverLayout = layout;
if (layout) {
addChild(layout);
- layout->setColor(TeColor(0, 0, 0, 0));
+ //layout->setColor(TeColor(0, 0, 0, 0));
}
setState(_state);
}
@@ -126,7 +126,7 @@ void TeCheckboxLayout::setHitZone(TeLayout *layout) {
_hitZone = layout;
if (layout) {
addChild(layout);
- layout->setColor(TeColor(0, 0, 0xff, 0xff));
+ //layout->setColor(TeColor(0, 0, 0xff, 0xff));
}
}
diff --git a/engines/tetraedge/te/te_curve_anim2.h b/engines/tetraedge/te/te_curve_anim2.h
index 29a30834186..f13bdae1fa2 100644
--- a/engines/tetraedge/te/te_curve_anim2.h
+++ b/engines/tetraedge/te/te_curve_anim2.h
@@ -28,6 +28,7 @@
namespace Tetraedge {
template<class T> static T linearInterpolation(T &obj1, T &obj2, double amount) {
+ amount = CLIP(amount, 0.0, 1.0);
return (obj1 * (1.0 - amount)) + (obj2 * amount);
}
diff --git a/engines/tetraedge/te/te_font3.cpp b/engines/tetraedge/te/te_font3.cpp
index 757d1050ca3..54367dea86d 100644
--- a/engines/tetraedge/te/te_font3.cpp
+++ b/engines/tetraedge/te/te_font3.cpp
@@ -118,6 +118,11 @@ Common::Rect TeFont3::getBoundingBox(const Common::String &str, int fontSize) {
return font->getBoundingBox(str);
}
+int TeFont3::getHeight(int fontSize) {
+ Graphics::Font *font = getAtSize(fontSize);
+ return font->getFontHeight();
+}
+
void TeFont3::draw(TeImage &destImage, const Common::String &str, int fontSize, int yoff, const TeColor &col, TeFont3::AlignStyle align) {
Graphics::Font *font = getAtSize(fontSize);
Graphics::TextAlign talign;
@@ -135,7 +140,10 @@ void TeFont3::draw(TeImage &destImage, const Common::String &str, int fontSize,
talign = Graphics::kTextAlignCenter;
break;
}
- uint32 uintcol = (col.r() << 24) | (col.r() << 16) | (col.r() << 8) | col.r();
+ const Graphics::PixelFormat &fmt = destImage.format;
+
+ uint32 uintcol = ((uint32)col.a() << fmt.aShift) | ((uint32)(col.r()) << fmt.rShift)
+ | ((uint32)(col.g()) << fmt.gShift) | ((uint32)(col.b()) << fmt.bShift);
font->drawString(&destImage, str, 0, yoff, destImage.w, uintcol, talign);
}
diff --git a/engines/tetraedge/te/te_font3.h b/engines/tetraedge/te/te_font3.h
index a17cdd0cb1a..7350d355049 100644
--- a/engines/tetraedge/te/te_font3.h
+++ b/engines/tetraedge/te/te_font3.h
@@ -79,6 +79,7 @@ public:
int wordWrapText(const Common::String &str, int fontSize, int maxWidth, Common::Array<Common::String> &lines);
Common::Rect getBoundingBox(const Common::String &str, int fontSize);
+ int getHeight(int fontSize);
void draw(TeImage &destImage, const Common::String &str, int fontSize, int yoff, const TeColor &col, AlignStyle alignMode);
diff --git a/engines/tetraedge/te/te_image.cpp b/engines/tetraedge/te/te_image.cpp
index b59155364c8..617b44779f5 100644
--- a/engines/tetraedge/te/te_image.cpp
+++ b/engines/tetraedge/te/te_image.cpp
@@ -55,7 +55,7 @@ void TeImage::create(uint xsize, uint ysize, Common::SharedPtr<TePalette> &pal,
Graphics::PixelFormat(3, 8, 8, 8, 0, 16, 8, 0, 0) : Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24));
Graphics::Surface::create(xsize, ysize, pxformat);
- Graphics::Surface::fillRect(Common::Rect(0, 0, xsize, ysize), 0xff883311);
+ Graphics::Surface::fillRect(Common::Rect(0, 0, xsize, ysize), 0);
}
void TeImage::deserialize(Common::ReadStream &stream) {
@@ -77,7 +77,8 @@ void TeImage::fill(byte val) {
void TeImage::fill(byte r, byte g, byte b, byte a) {
Common::Rect wholeSurf(0, 0, w, h);
- uint32 col = (r << 24) | (g << 16) | (b << 8) | a;
+
+ uint32 col = ((uint32)r << format.rShift) | ((uint32)g << format.gShift) | ((uint32)b << format.bShift) | (uint32)a << format.aShift;
Graphics::Surface::fillRect(wholeSurf, col);
}
diff --git a/engines/tetraedge/te/te_image.h b/engines/tetraedge/te/te_image.h
index 995e8be2f91..ae0aa47ffb5 100644
--- a/engines/tetraedge/te/te_image.h
+++ b/engines/tetraedge/te/te_image.h
@@ -83,7 +83,7 @@ public:
private:
- // TODO add private members
+ // No private members?
};
diff --git a/engines/tetraedge/te/te_layout.cpp b/engines/tetraedge/te/te_layout.cpp
index 733eb5ba5ac..be8ac7b36d2 100644
--- a/engines/tetraedge/te/te_layout.cpp
+++ b/engines/tetraedge/te/te_layout.cpp
@@ -27,14 +27,13 @@
namespace Tetraedge {
-TeLayout::TeLayout() : Te3DObject2(), _updatingZ(false), _updatingZSize(false),
- _updatingPosition(false), _updatingWorldMatrix(false), _updatingSize(false),
- _autoz(true), _childOrParentChanged(true), _childChanged(true),
- _sizeChanged(true), _positionChanged(true), _worldMatrixChanged(true),
+TeLayout::TeLayout() : Te3DObject2(), _autoz(true), _needZUpdate(true), _updatingZ(false),
+ _needZSizeUpdate(true), _updatingZSize(false), _sizeChanged(true), _updatingSize(false),
+ _positionChanged(true), _updatingPosition(false), _worldMatrixChanged(true),
+ _updatingWorldMatrix(false), _drawMode(TeILayout::DrawMode0),
_sizeType(CoordinatesType::ABSOLUTE), _userSize(1.0f, 1.0f, 1.0f),
- _anchor(0.5f, 0.5f, 0.5f), _ratio(1.0f), _drawMode(TeILayout::DrawMode0),
- _safeAreaRatio(1.3333334f), _ratioMode(RATIO_MODE_NONE),
- _positionType(CoordinatesType::RELATIVE_TO_PARENT)
+ _anchor(0.5f, 0.5f, 0.5f), _ratio(1.0f), _safeAreaRatio(1.3333334f),
+ _ratioMode(RATIO_MODE_NONE), _positionType(CoordinatesType::RELATIVE_TO_PARENT)
{
_userPosition = _position = TeVector3f32(0.5f, 0.5f, 0.5f);
_size = TeVector3f32(1.0f, 1.0f, 1.0f);
@@ -67,8 +66,8 @@ void TeLayout::addChild(Te3DObject2 *child) {
if (_onChildSizeChangedCallback) {
child->onSizeChanged().insert(_onChildSizeChangedCallback);
}
- _childChanged = true;
- _childOrParentChanged = true;
+ _needZSizeUpdate = true;
+ _needZUpdate = true;
updateZSize();
updateZ();
}
@@ -78,8 +77,8 @@ void TeLayout::addChildBefore(Te3DObject2 *child, const Te3DObject2 *ref) {
if (_onChildSizeChangedCallback) {
child->onSizeChanged().insert(_onChildSizeChangedCallback);
}
- _childChanged = true;
- _childOrParentChanged = true;
+ _needZSizeUpdate = true;
+ _needZUpdate = true;
updateZSize();
updateZ();
}
@@ -89,8 +88,8 @@ void TeLayout::removeChild(Te3DObject2 *child) {
child->onSizeChanged().remove(_onChildSizeChangedCallback);
}
Te3DObject2::removeChild(child);
- _childChanged = true;
- _childOrParentChanged = true;
+ _needZSizeUpdate = true;
+ _needZUpdate = true;
updateZSize();
updateZ();
}
@@ -138,8 +137,8 @@ TeILayout::DrawMode TeLayout::mode() {
}
bool TeLayout::onChildSizeChanged() {
- _childChanged = true;
- _childOrParentChanged = true;
+ _needZSizeUpdate = true;
+ _needZUpdate = true;
updateSize();
if (!_updatingZSize)
@@ -205,8 +204,9 @@ void TeLayout::setParent(Te3DObject2 *parent) {
oldParent->onWorldTransformationMatrixChanged().remove(_onParentWorldTransformationMatrixChangedCallback);
}
- //warning("TODO: remove callback from main window");
- //TeMainWindow *mainWindow = g_engine->getMainWindow();
+ //
+ TeLayout &mainWindowLayout = g_engine->getApplication()->getMainWindow();
+ mainWindowLayout.onSizeChanged().remove(_onMainWindowChangedCallback);
Te3DObject2::setParent(parent);
if (parent) {
@@ -214,10 +214,10 @@ void TeLayout::setParent(Te3DObject2 *parent) {
parent->onSizeChanged().insert(_onParentSizeChangedCallback);
if (_onParentWorldTransformationMatrixChangedCallback)
parent->onWorldTransformationMatrixChanged().insert(_onParentWorldTransformationMatrixChangedCallback);
- // TODO: add a new callback to the MainWindow.
- //warning("TODO: update signal on main window");
+ if (_onMainWindowChangedCallback)
+ mainWindowLayout.onSizeChanged().insert(_onMainWindowChangedCallback);
}
- _childOrParentChanged = true;
+ _needZUpdate = true;
_sizeChanged = true;
_positionChanged = true;
_worldMatrixChanged = true;
@@ -373,10 +373,9 @@ void TeLayout::updateSize() {
if (_sizeType == ABSOLUTE) {
TeVector3f32 newSize = _userSize;
- newSize.x() = abs(newSize.x());
- newSize.y() = abs(newSize.y());
- newSize.z() = abs(newSize.z());
- _size = newSize;
+ _size.x() = abs(newSize.x());
+ _size.y() = abs(newSize.y());
+ // don't set Z val.
} else if (_sizeType == RELATIVE_TO_PARENT) {
Te3DObject2 *parentObj = parent();
if (parentObj) {
@@ -400,9 +399,11 @@ void TeLayout::updateSize() {
}
}
- _size = newSize;
+ _size.x() = newSize.x();
+ _size.y() = newSize.y();
} else {
- _size = TeVector3f32(0.0f, 0.0f, 0.0f);
+ _size.x() = 0.0f;
+ _size.y() = 0.0f;
}
}
@@ -432,24 +433,25 @@ void TeLayout::updateWorldMatrix() {
}
void TeLayout::updateZ() {
- if (!_childOrParentChanged || !_autoz)
+ if (!_needZUpdate || !_autoz)
return;
- _childOrParentChanged = false;
+ _needZUpdate = false;
_updatingZ = true;
- /*float ztotal = 0.1f;*/
+ float ztotal = 0.1f;
for (auto &child : childList()) {
- /*ztotal += */child->zSize();
+ child->setZPosition(ztotal);
+ ztotal += child->zSize();
}
_updatingZ = false;
}
void TeLayout::updateZSize() {
- if (!_childChanged)
+ if (!_needZSizeUpdate)
return;
- _childChanged = false;
+ _needZSizeUpdate = false;
_updatingZSize = true;
const TeVector3f32 oldSize = _size;
_size.z() = 0.1f;
@@ -478,7 +480,7 @@ TeVector3f32 TeLayout::worldPosition() {
if (!parent()) {
return position();
} else {
- return parent()->position() + position();
+ return parent()->worldPosition() + position();
}
}
@@ -499,17 +501,17 @@ bool TeLayout::worldVisible() {
float TeLayout::xSize() {
updateSize();
- return size().x();
+ return _size.x();
}
float TeLayout::ySize() {
updateSize();
- return size().y();
+ return _size.y();
}
float TeLayout::zSize() {
updateZSize();
- return size().z();
+ return _size.z();
}
} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_layout.h b/engines/tetraedge/te/te_layout.h
index bfce5412e73..ec77facb3ba 100644
--- a/engines/tetraedge/te/te_layout.h
+++ b/engines/tetraedge/te/te_layout.h
@@ -111,8 +111,8 @@ private:
bool _autoz;
bool _positionChanged;
bool _worldMatrixChanged;
- bool _childChanged;
- bool _childOrParentChanged;
+ bool _needZSizeUpdate;
+ bool _needZUpdate;
bool _updatingZ;
bool _updatingZSize;
bool _updatingSize;
@@ -125,6 +125,7 @@ private:
TeICallback0ParamPtr _onChildSizeChangedCallback;
TeICallback0ParamPtr _onParentSizeChangedCallback;
TeICallback0ParamPtr _onParentWorldTransformationMatrixChangedCallback;
+ TeICallback0ParamPtr _onMainWindowChangedCallback;
};
} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_lua_gui_lua_callbacks.cpp b/engines/tetraedge/te/te_lua_gui_lua_callbacks.cpp
index 9d184739831..d78d734fb01 100644
--- a/engines/tetraedge/te/te_lua_gui_lua_callbacks.cpp
+++ b/engines/tetraedge/te/te_lua_gui_lua_callbacks.cpp
@@ -389,7 +389,7 @@ int spriteLayoutBindings(lua_State *L) {
lua_pushnil(L);
while (lua_next(L, -2) != 0) {
- if (lua_type(L, -2) == 3) {
+ if (lua_type(L, -2) == LUA_TNUMBER) {
Te3DObject2 *object = TeLuaTo<Te3DObject2*>(L, -1);
layout->addChild(object);
}
@@ -475,7 +475,7 @@ int buttonLayoutBindings(lua_State *L) {
lua_pushnil(L);
while (lua_next(L, -2) != 0) {
- if (lua_type(L, -2) == 3) {
+ if (lua_type(L, -2) == LUA_TNUMBER) {
Te3DObject2 *object = TeLuaTo<Te3DObject2*>(L, -1);
layout->addChild(object);
}
@@ -545,7 +545,7 @@ int checkboxLayoutBindings(lua_State *L) {
lua_pushnil(L);
while (lua_next(L, -2) != 0) {
- if (lua_type(L, -2) == 3) {
+ if (lua_type(L, -2) == LUA_TNUMBER) {
Te3DObject2 *object = TeLuaTo<Te3DObject2*>(L, -1);
layout->addChild(object);
}
diff --git a/engines/tetraedge/te/te_lua_thread.cpp b/engines/tetraedge/te/te_lua_thread.cpp
index b56aab1b937..54fe22956af 100644
--- a/engines/tetraedge/te/te_lua_thread.cpp
+++ b/engines/tetraedge/te/te_lua_thread.cpp
@@ -24,6 +24,7 @@
#include "tetraedge/te/te_variant.h"
#include "common/str.h"
+#include "common/debug.h"
#include "common/file.h"
#include "common/lua/lua.h"
#include "common/lua/lauxlib.h"
@@ -75,7 +76,7 @@ void TeLuaThread::execute(const Common::String &fname) {
_resume(0);
} else {
if (!fname.contains("Update"))
- warning("[TeLuaThread::Execute0] La fonction : \"%s\" n'existe pas.", fname.c_str());
+ debug("[TeLuaThread::Execute0] La fonction : \"%s\" n'existe pas.", fname.c_str());
lua_settop(_luaThread, -2);
}
}
@@ -90,7 +91,7 @@ void TeLuaThread::execute(const Common::String &fname, const TeVariant &p1) {
_resume(1);
} else {
if (!fname.contains("Update"))
- warning("[TeLuaThread::Execute1] La fonction : \"%s\" n'existe pas.", fname.c_str());
+ debug("[TeLuaThread::Execute1] La fonction : \"%s\" n'existe pas.", fname.c_str());
lua_settop(_luaThread, -2);
}
}
@@ -106,7 +107,7 @@ void TeLuaThread::execute(const Common::String &fname, const TeVariant &p1, cons
_resume(2);
} else {
if (!fname.contains("Update"))
- warning("[TeLuaThread::Execute2] La fonction : \"%s\" n'existe pas.", fname.c_str());
+ debug("[TeLuaThread::Execute2] La fonction : \"%s\" n'existe pas.", fname.c_str());
lua_settop(_luaThread, -2);
}
}
@@ -123,7 +124,7 @@ void TeLuaThread::execute(const Common::String &fname, const TeVariant &p1, cons
_resume(3);
} else {
if (!fname.contains("Update"))
- warning("[TeLuaThread::Execute3] La fonction : \"%s\" n'existe pas.", fname.c_str());
+ debug("[TeLuaThread::Execute3] La fonction : \"%s\" n'existe pas.", fname.c_str());
lua_settop(_luaThread, -4);
}
}
diff --git a/engines/tetraedge/te/te_model_vertex_animation.cpp b/engines/tetraedge/te/te_model_vertex_animation.cpp
index 2735fba1f80..5b90be781c3 100644
--- a/engines/tetraedge/te/te_model_vertex_animation.cpp
+++ b/engines/tetraedge/te/te_model_vertex_animation.cpp
@@ -20,13 +20,12 @@
*/
#include "tetraedge/te/te_model_vertex_animation.h"
+#include "common/math.h"
namespace Tetraedge {
-TeModelVertexAnimation::TeModelVertexAnimation() : _rot(1.0f, 0.0f, 0.0f, 0.0f),
-_lastMillis(0.0f), _modelAnim(nullptr) {
- // TODO: set some other things up here.
- _rot.fromAxisAndAngle(TeVector3f32(0.0f, 1.0f, 0.0f), -1.570796);
+TeModelVertexAnimation::TeModelVertexAnimation() : _lastMillis(0.0f), _modelAnim(nullptr) {
+ _rot.fromAxisAndAngle(TeVector3f32(0.0f, 1.0f, 0.0f), -M_PI_2);
}
void TeModelVertexAnimation::bind(TeIntrusivePtr<TeModel> &model) {
@@ -101,6 +100,4 @@ void TeModelVertexAnimation::update(double millis) {
_onFinishedSignal.call();
}
-
-
} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_renderer.cpp b/engines/tetraedge/te/te_renderer.cpp
index 9c8563934eb..ea5e0b0ee9d 100644
--- a/engines/tetraedge/te/te_renderer.cpp
+++ b/engines/tetraedge/te/te_renderer.cpp
@@ -282,8 +282,8 @@ void TeRenderer::loadMatrix(const TeMatrix4x4 &matrix) {
}
void TeRenderer::loadMatrixToGL(const TeMatrix4x4 &matrix) {
- int mmode;
- glGetIntegerv(GL_MATRIX_MODE, &mmode);
+ //int mmode;
+ //glGetIntegerv(GL_MATRIX_MODE, &mmode);
//debug("loadMatrixToGL[0x%x]: %s", mmode, matrix.toString().c_str());
glLoadMatrixf(matrix.getData());
}
@@ -308,22 +308,27 @@ void TeRenderer::multiplyMatrix(const TeMatrix4x4 &matrix) {
}
void TeRenderer::optimiseTransparentMeshProperties() {
- if (_transparentMeshProps.size() > 1) {
- for (unsigned int i = 0; i < _transparentMeshProps.size() - 1; i++) {
- if (_transparentMeshProps[i]._camera == _transparentMeshProps[i + 1]._camera
- && _transparentMeshProps[i]._material == _transparentMeshProps[i + 1]._material
- && _transparentMeshProps[i]._glTexEnvMode == _transparentMeshProps[i + 1]._glTexEnvMode
- && _transparentMeshProps[i]._matrix == _transparentMeshProps[i + 1]._matrix
- && _transparentMeshProps[i]._hasColor == _transparentMeshProps[i + 1]._hasColor
- && _transparentMeshProps[i]._scissorEnabled == _transparentMeshProps[i + 1]._scissorEnabled
- && _transparentMeshProps[i]._scissorX == _transparentMeshProps[i + 1]._scissorX
- && _transparentMeshProps[i]._scissorY == _transparentMeshProps[i + 1]._scissorY
- && _transparentMeshProps[i]._scissorWidth == _transparentMeshProps[i + 1]._scissorWidth
- && _transparentMeshProps[i]._scissorHeight == _transparentMeshProps[i + 1]._scissorHeight) {
- _transparentMeshProps[i]._vertexCount += _transparentMeshProps[i + 1]._vertexCount;
- _transparentMeshProps[i + 1]._shouldDraw = false;
- }
+ if (_transparentMeshProps.size() <= 1)
+ return;
+
+ unsigned int i = 0;
+ for (unsigned int other = 1; other < _transparentMeshProps.size(); other++) {
+ unsigned int nextI = other;
+ if (_transparentMeshProps[i]._camera == _transparentMeshProps[other]._camera
+ && _transparentMeshProps[i]._material == _transparentMeshProps[other]._material
+ && _transparentMeshProps[i]._glTexEnvMode == _transparentMeshProps[other]._glTexEnvMode
+ && _transparentMeshProps[i]._matrix == _transparentMeshProps[other]._matrix
+ && _transparentMeshProps[i]._hasColor == _transparentMeshProps[other]._hasColor
+ && _transparentMeshProps[i]._scissorEnabled == _transparentMeshProps[other]._scissorEnabled
+ && _transparentMeshProps[i]._scissorX == _transparentMeshProps[other]._scissorX
+ && _transparentMeshProps[i]._scissorY == _transparentMeshProps[other]._scissorY
+ && _transparentMeshProps[i]._scissorWidth == _transparentMeshProps[other]._scissorWidth
+ && _transparentMeshProps[i]._scissorHeight == _transparentMeshProps[other]._scissorHeight) {
+ _transparentMeshProps[i]._vertexCount += _transparentMeshProps[other]._vertexCount;
+ _transparentMeshProps[other]._shouldDraw = false;
+ nextI = i;
}
+ i = nextI;
}
}
@@ -340,18 +345,28 @@ Common::String TeRenderer::renderer() {
}
-static int compareTransparentMeshProperties(const TeRenderer::TransparentMeshProperties &p1,
+static bool compareTransparentMeshProperties(const TeRenderer::TransparentMeshProperties &p1,
const TeRenderer::TransparentMeshProperties &p2) {
- if (p1._zOrder > p2._zOrder)
- return 1;
- if (p1._zOrder == p2._zOrder)
- return 0;
- return -1;
+ return (p1._zOrder < p2._zOrder);
}
-void TeRenderer::dumpTransparentMeshes() const {
+void TeRenderer::dumpTransparentMeshProps() const {
+ debug("** Transparent MeshProps: num:%ld pending:%d **", _numTransparentMeshes, _pendingTransparentMeshProperties);
+ debug("draw? / nverts / source / transl / zorder");
+ for (unsigned int i = 0; i < _transparentMeshProps.size(); i++) {
+ debug("%s %d %d %s %f",
+ _transparentMeshProps[i]._shouldDraw ? "draw" : "nodr",
+ _transparentMeshProps[i]._vertexCount,
+ _transparentMeshProps[i]._sourceTransparentMesh,
+ _transparentMeshProps[i]._matrix.translation().dump().c_str(),
+ _transparentMeshProps[i]._zOrder
+ );
+ }
+}
+
+void TeRenderer::dumpTransparentMeshData() const {
debug("** Transparent Meshes: num:%ld pending:%d **", _numTransparentMeshes, _pendingTransparentMeshProperties);
- debug("vert / normal / coord / color / trianglenum");
+ debug("vert / normal / coord / color / vertNo");
for (unsigned int i = 0; i < _transparentMeshVertexes.size(); i++) {
debug("%s %s %s %s %d",
_transparentMeshVertexes[i].dump().c_str(),
@@ -368,6 +383,8 @@ void TeRenderer::renderTransparentMeshes() {
return;
glDepthMask(GL_FALSE);
+ //dumpTransparentMeshProps();
+
Common::sort(_transparentMeshProps.begin(), _transparentMeshProps.end(),
compareTransparentMeshProperties);
@@ -379,9 +396,11 @@ void TeRenderer::renderTransparentMeshes() {
vertsDrawn += vcount;
}
- //dumpTransparentMeshes();
-
optimiseTransparentMeshProperties();
+
+ //dumpTransparentMeshProps();
+ //dumpTransparentMeshData();
+
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
@@ -402,7 +421,7 @@ void TeRenderer::renderTransparentMeshes() {
continue;
const TeMaterial &material = meshProperties._material;
-
+
meshProperties._camera->applyProjection();
glMatrixMode(GL_MODELVIEW);
_matrixMode = MM_GL_MODELVIEW;
diff --git a/engines/tetraedge/te/te_renderer.h b/engines/tetraedge/te/te_renderer.h
index e211ebc3f58..03ccb7ed28b 100644
--- a/engines/tetraedge/te/te_renderer.h
+++ b/engines/tetraedge/te/te_renderer.h
@@ -48,7 +48,7 @@ public:
class TransparentMeshProperties {
public:
-
+ TransparentMeshProperties() : _camera(nullptr), _vertexCount(0), _shouldDraw(false), _scissorEnabled(false), _hasColor(false) {}
TeCamera *_camera;
int _vertexCount;
TeMatrix4x4 _matrix;
@@ -117,7 +117,8 @@ public:
void translate(float x, float y, float z);
Common::String vendor();
- void dumpTransparentMeshes() const;
+ void dumpTransparentMeshProps() const;
+ void dumpTransparentMeshData() const;
const TeColor ¤tColor() const { return _currentColor; }
private:
diff --git a/engines/tetraedge/te/te_scrolling_layout.cpp b/engines/tetraedge/te/te_scrolling_layout.cpp
index d4e3b334a22..9f027a624a9 100644
--- a/engines/tetraedge/te/te_scrolling_layout.cpp
+++ b/engines/tetraedge/te/te_scrolling_layout.cpp
@@ -38,6 +38,15 @@ void TeScrollingLayout::setContentLayout(TeLayout *layout) {
}
}
+void TeScrollingLayout::resetScrollPosition() {
+ if (!_contentLayout)
+ return;
+ warning("TODO: Implement TeScrollingLayout::resetScrollPosition");
+}
+
+void TeScrollingLayout::playAutoScroll() {
+ warning("TODO: Implement TeScrollingLayout::playAutoScroll");
+}
// TODO: Add more functions here.
diff --git a/engines/tetraedge/te/te_scrolling_layout.h b/engines/tetraedge/te/te_scrolling_layout.h
index 25d36471d89..ba64168cf57 100644
--- a/engines/tetraedge/te/te_scrolling_layout.h
+++ b/engines/tetraedge/te/te_scrolling_layout.h
@@ -80,6 +80,9 @@ public:
}
void setContentLayout(TeLayout *layout);
+ void resetScrollPosition();
+ void playAutoScroll();
+
private:
int _inertiaAnimationDuration;
Common::Array<float> _inertiaAnimationCurve;
diff --git a/engines/tetraedge/te/te_sprite_layout.cpp b/engines/tetraedge/te/te_sprite_layout.cpp
index 625603d8571..7cc19c754ca 100644
--- a/engines/tetraedge/te/te_sprite_layout.cpp
+++ b/engines/tetraedge/te/te_sprite_layout.cpp
@@ -28,6 +28,8 @@ namespace Tetraedge {
TeSpriteLayout::TeSpriteLayout() : _tiledSurfacePtr(new TeTiledSurface()), _sizeSet(false) {
_tiledSurfacePtr->setColor(TeColor(255, 255, 255, 255));
+ //_tiledSurfacePtr->_shouldDraw = true // should already be true..
+ // TODO: set some other flag in _tiledSurfacePtr?
updateMesh();
}
@@ -44,10 +46,11 @@ void TeSpriteLayout::draw() {
if (!worldVisible())
return;
- /*debug("Draw SpriteLayout %p (%s, surf %s, size %.01fx%.01f, surf %.01fx%.01f, %s)", this,
- name().empty() ? "no name" : name().c_str(), _tiledSurfacePtr->getAccessName().toString().c_str(),
- size().x(), size().y(),
- _tiledSurfacePtr->size().x(), _tiledSurfacePtr->size().y(), color().dump().c_str());*/
+ /*if (parent() && parent()->name() == "inventoryButton")
+ debug("Draw SpriteLayout %p (%s, surf %s, size %.01fx%.01f, surf %.01fx%.01f, %s)", this,
+ name().empty() ? "no name" : name().c_str(), _tiledSurfacePtr->getAccessName().toString().c_str(),
+ size().x(), size().y(),
+ _tiledSurfacePtr->size().x(), _tiledSurfacePtr->size().y(), color().dump().c_str());*/
TeMatrix4x4 matrix = worldTransformationMatrix();
if (sizeType() == ABSOLUTE) {
@@ -89,6 +92,8 @@ bool TeSpriteLayout::load(const Common::Path &path) {
setSize(TeVector3f32(texSize._x, texSize._y, 1.0));
}
updateMesh();
+ } else {
+ debug("Failed to load TeSpriteLayout %s", path.toString().c_str());
}
return true;
}
@@ -101,7 +106,7 @@ bool TeSpriteLayout::load(TeIntrusivePtr<Te3DTexture> &texture) {
if (tiledTexSize._y <= 0) {
setRatio(1.0);
} else {
- setRatio((float)tiledTexSize._y / tiledTexSize._x);
+ setRatio((float)tiledTexSize._x / tiledTexSize._y);
}
if (sizeType() == CoordinatesType::ABSOLUTE && !_sizeSet) {
@@ -109,6 +114,8 @@ bool TeSpriteLayout::load(TeIntrusivePtr<Te3DTexture> &texture) {
}
updateMesh();
return true;
+ } else {
+ debug("Failed to load TeSpriteLayout from texture %s", texture->getAccessName().toString().c_str());
}
return false;
}
@@ -121,7 +128,7 @@ bool TeSpriteLayout::load(TeImage &img) {
if (tiledTexSize._y <= 0) {
setRatio(1.0);
} else {
- setRatio((float)tiledTexSize._y / tiledTexSize._x);
+ setRatio((float)tiledTexSize._x / tiledTexSize._y);
}
if (sizeType() == CoordinatesType::ABSOLUTE && !_sizeSet) {
@@ -129,6 +136,8 @@ bool TeSpriteLayout::load(TeImage &img) {
}
updateMesh();
return true;
+ } else {
+ debug("Failed to load TeSpriteLayout from texture %s", img.getAccessName().toString().c_str());
}
return false;
}
diff --git a/engines/tetraedge/te/te_text_base2.cpp b/engines/tetraedge/te/te_text_base2.cpp
index d03f3b4034a..114012dfca7 100644
--- a/engines/tetraedge/te/te_text_base2.cpp
+++ b/engines/tetraedge/te/te_text_base2.cpp
@@ -56,6 +56,7 @@ void TeTextBase2::build() {
font->wordWrapText(_text, _fontSize, _drawRect._x, _wrappedLines);
Common::Array<float> lineoffsets;
+ float lineHeight = font->getHeight(_fontSize);
float height = 0;
for (const Common::String &line : _wrappedLines) {
if (_alignStyle == TeFont3::AlignJustify) {
@@ -67,7 +68,7 @@ void TeTextBase2::build() {
_size._x = lineSize.right;
lineoffsets.push_back(height);
- height += lineSize.bottom + _interLine;
+ height += lineHeight + _interLine;
}
_size._y = (int)ceilf(height);
@@ -92,7 +93,8 @@ void TeTextBase2::build() {
_mesh.setConf(4, 4, TeMesh::MeshMode_TriangleStrip, 0, 0);
_mesh.defaultMaterial(texture);
-
+ // FIXME: Original uses BLEND, but we need MODULATE to get right colors?
+ _mesh.setglTexEnv(GL_MODULATE);
_mesh.setShouldDraw(true);
_mesh.setColor(_globalColor);
_mesh.setVertex(0, TeVector3f32(_size._x * -0.5f, _size._y * -0.5f, 0.0f));
@@ -245,8 +247,6 @@ void TeTextBase2::setFont(unsigned int offset, const TeIntrusivePtr<TeFont3> &ne
}
void TeTextBase2::setFontSize(unsigned long newSize) {
- // Bit of a hack here to get the right font size.
- newSize *= 1.2;
if (_fontSize != newSize) {
_fontSize = newSize;
_valueWasSet = true;
diff --git a/engines/tetraedge/te/te_tiled_surface.cpp b/engines/tetraedge/te/te_tiled_surface.cpp
index fc087c10ccf..1e4245b803a 100644
--- a/engines/tetraedge/te/te_tiled_surface.cpp
+++ b/engines/tetraedge/te/te_tiled_surface.cpp
@@ -57,6 +57,8 @@ bool TeTiledSurface::load(const Common::Path &path) {
_path = path;
TeIntrusivePtr<TeTiledTexture> texture;
+ if (path.toString() == "menus/inGame/Inventory.png")
+ debug("loading inventory from path");
if (resmgr->exists(path.append(".tt"))) {
texture = resmgr->getResourceNoSearch<TeTiledTexture>(path.append(".tt"));
// we don't own this one..
@@ -73,7 +75,7 @@ bool TeTiledSurface::load(const Common::Path &path) {
texture = new TeTiledTexture();
if (_codec->load(foundPath)) {
- texture->setAccessName(path);
+ texture->setAccessName(path.append(".tt"));
resmgr->addResource(texture.get());
_imgFormat = _codec->imageFormat();
@@ -93,7 +95,7 @@ bool TeTiledSurface::load(const Common::Path &path) {
}
Common::SharedPtr<TePalette> nullpal;
- img.create(_codec->width(), _codec->height(), nullpal, (TeImage::Format)_imgFormat, bufx, bufy);
+ img.create(_codec->width(), _codec->height(), nullpal, _imgFormat, bufx, bufy);
if (_codec->update(0, img)) {
texture->load(img);
@@ -118,6 +120,8 @@ bool TeTiledSurface::load(const TeIntrusivePtr<Te3DTexture> &texture) {
TeIntrusivePtr<TeTiledTexture> tiledTexture;
const Common::Path ttPath = texture->getAccessName().append(".tt");
+ if (ttPath.toString() == "menus/inGame/Inventory.png.tt")
+ debug("loading inventory from texture");
if (resmgr->exists(ttPath)) {
tiledTexture = resmgr->getResourceNoSearch<TeTiledTexture>(ttPath);
@@ -233,7 +237,7 @@ void TeTiledSurface::updateSurface() {
TeTiledTexture::Tile *tile = _tiledTexture->tile(TeVector2s32(col, row));
mesh.defaultMaterial(tile->_texture);
- const TeColor meshcol = color();
+ TeColor meshcol = color();
float left, right, top, bottom;
getRangeIntersection(_leftCrop, 1.0 - _rightCrop, tile->_vec1.x(), tile->_vec2.x() + tile->_vec1.x(), &left, &right);
diff --git a/engines/tetraedge/te/te_tiled_texture.cpp b/engines/tetraedge/te/te_tiled_texture.cpp
index 6ae69f9dcc3..d07804297e0 100644
--- a/engines/tetraedge/te/te_tiled_texture.cpp
+++ b/engines/tetraedge/te/te_tiled_texture.cpp
@@ -117,6 +117,8 @@ bool TeTiledTexture::load(const TeImage &img) {
if (rows)
_somethingSize._y = _somethingSize._y / rows;
setAccessName(img.getAccessName().append(".tt"));
+ if (img.getAccessName().toString() == "menus/inGame/Inventory.png")
+ debug("loading inventory tiled texture");
return true;
}
@@ -131,6 +133,8 @@ bool TeTiledTexture::load(const TeIntrusivePtr<Te3DTexture> &texture) {
tileData->_vec2 = TeVector3f32(1.0, 1.0, 0.0);
tileData->_vec1 = TeVector3f32(0.0, 0.0, 0.0);
setAccessName(texture->getAccessName().append(".tt"));
+ if (texture->getAccessName().toString() == "menus/inGame/Inventory.png")
+ debug("loading inventory tiled texture from texture");
return true;
}
diff --git a/engines/tetraedge/te/te_vector3f32.h b/engines/tetraedge/te/te_vector3f32.h
index 668328aa7aa..951fe0157d3 100644
--- a/engines/tetraedge/te/te_vector3f32.h
+++ b/engines/tetraedge/te/te_vector3f32.h
@@ -72,7 +72,7 @@ public:
bool parse(const Common::String &val);
Common::String dump() const {
- return Common::String::format("TeVec3f32(%.02f %.02f %.02f)", x(), y(), z());
+ return Common::String::format("Vec3f(%.02f %.02f %.02f)", x(), y(), z());
}
void rotate(const TeQuaternion &rot);
diff --git a/engines/tetraedge/te/te_xml_gui.cpp b/engines/tetraedge/te/te_xml_gui.cpp
index e9ba7c0bd62..8d14949bf83 100644
--- a/engines/tetraedge/te/te_xml_gui.cpp
+++ b/engines/tetraedge/te/te_xml_gui.cpp
@@ -19,6 +19,7 @@
*
*/
+#include "common/debug.h"
#include "common/hash-str.h"
#include "common/textconsole.h"
#include "tetraedge/te/te_xml_gui.h"
@@ -47,7 +48,7 @@ void TeXmlGui::load(const Common::Path &path) {
void TeXmlGui::clear() {
_map.clear();
- // TODO: probably more here.
+ debug("TODO: Finish TeXmlGui.clear()");
}
} // end namespace Tetraedge
Commit: 501b00ebe79d75682db0c43770a7ec15c831e070
https://github.com/scummvm/scummvm/commit/501b00ebe79d75682db0c43770a7ec15c831e070
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2023-01-16T17:36:43+01:00
Commit Message:
TETRAEDGE: WIP. Fixed some callbacks, more bits of the game working.
Changed paths:
engines/tetraedge/game/application.cpp
engines/tetraedge/game/billboard.cpp
engines/tetraedge/game/character.cpp
engines/tetraedge/game/character.h
engines/tetraedge/game/document.h
engines/tetraedge/game/documents_browser.cpp
engines/tetraedge/game/game.cpp
engines/tetraedge/game/game.h
engines/tetraedge/game/in_game_scene.cpp
engines/tetraedge/game/in_game_scene.h
engines/tetraedge/game/lua_binds.cpp
engines/tetraedge/game/object3d.cpp
engines/tetraedge/game/question2.cpp
engines/tetraedge/te/te_button_layout.cpp
engines/tetraedge/te/te_button_layout.h
engines/tetraedge/te/te_free_move_zone.h
engines/tetraedge/te/te_image.cpp
engines/tetraedge/te/te_model.cpp
engines/tetraedge/te/te_music.cpp
engines/tetraedge/te/te_music.h
engines/tetraedge/te/te_sound_manager.cpp
engines/tetraedge/te/te_sound_manager.h
engines/tetraedge/te/te_text_base2.cpp
engines/tetraedge/te/te_tiled_texture.cpp
engines/tetraedge/to_lua.cpp
engines/tetraedge/to_lua.h
diff --git a/engines/tetraedge/game/application.cpp b/engines/tetraedge/game/application.cpp
index f9d0573a2fb..dfd1386998f 100644
--- a/engines/tetraedge/game/application.cpp
+++ b/engines/tetraedge/game/application.cpp
@@ -37,6 +37,7 @@
#include "tetraedge/te/te_renderer.h"
#include "tetraedge/te/te_font3.h"
#include "tetraedge/te/te_input_mgr.h"
+#include "tetraedge/te/te_sound_manager.h"
//#define DUMP_LAYOUTS 1
@@ -312,7 +313,7 @@ bool Application::run() {
renderer->reset();
game->update();
- //_soundManager->update(soundmgr);
+ g_engine->getSoundManager()->update();
performRender();
if (game->_returnToMainMenu) {
game->leave(true);
diff --git a/engines/tetraedge/game/billboard.cpp b/engines/tetraedge/game/billboard.cpp
index 2d2d99156a1..0d37ac6dcec 100644
--- a/engines/tetraedge/game/billboard.cpp
+++ b/engines/tetraedge/game/billboard.cpp
@@ -57,7 +57,6 @@ void Billboard::calcVertex() {
const TeMatrix4x4 camTotalTransform = camProjMatrix * camWorldInverse;
TeMatrix4x4 camTotalInverse = camTotalTransform;
camTotalInverse.inverse();
- camTotalInverse.scale(TeVector3f32(-1.0, -1.0, 1.0));
TeVector3f32 posvec(0.0f, 0.0f, _pos.z());
if (_hasPos2) {
diff --git a/engines/tetraedge/game/character.cpp b/engines/tetraedge/game/character.cpp
index b3d84b95cc9..8ef4dac0efa 100644
--- a/engines/tetraedge/game/character.cpp
+++ b/engines/tetraedge/game/character.cpp
@@ -489,16 +489,20 @@ bool Character::onBonesUpdate(const Common::String &boneName, TeMatrix4x4 &boneM
// Move any objects attached to the bone
for (Object3D *obj : game->scene().object3Ds()) {
if (obj->_onCharName == _model->name() && boneName == obj->_onCharBone) {
- obj->model()->setVisible(true);
- TeMatrix4x4 objmatrix = boneMatrix;
- objmatrix.scale(obj->_objScale);
- objmatrix.rotate(obj->_objRotation);
- objmatrix.scale(obj->_objScale);
- objmatrix.translate(obj->_objTranslation);
- obj->model()->forceMatrix(objmatrix);
- obj->model()->setPosition(_model->position());
- obj->model()->setRotation(_model->rotation());
- obj->model()->setScale(_model->scale());
+ if (_model->anim()->curFrame2() >= obj->_startFrame
+ && _model->anim()->curFrame2() <= obj->_endFrame) {
+ obj->model()->setVisible(true);
+ TeMatrix4x4 objmatrix = boneMatrix;
+ objmatrix.scale(obj->_objScale);
+ objmatrix.rotate(obj->_objRotation);
+ objmatrix.translate(obj->_objTranslation);
+ obj->model()->forceMatrix(objmatrix);
+ obj->model()->setRotation(_model->rotation());
+ obj->model()->setPosition(_model->position());
+ obj->model()->setScale(_model->scale());
+ } else {
+ obj->model()->setVisible(false);
+ }
}
}
diff --git a/engines/tetraedge/game/character.h b/engines/tetraedge/game/character.h
index b524c8c8691..e403bbfd098 100644
--- a/engines/tetraedge/game/character.h
+++ b/engines/tetraedge/game/character.h
@@ -173,6 +173,7 @@ public:
bool lookingAtTallThing() const { return _lookingAtTallThing; }
void setLookingAtTallThing(bool val) { _lookingAtTallThing = val; }
TeIntrusivePtr<TeBezierCurve> curve() { return _curve; }
+ void setRecallageY(bool val) { _recallageY = val; }
private:
float _walkCurveStart;
diff --git a/engines/tetraedge/game/document.h b/engines/tetraedge/game/document.h
index 33647fe574c..688fb029381 100644
--- a/engines/tetraedge/game/document.h
+++ b/engines/tetraedge/game/document.h
@@ -37,7 +37,8 @@ public:
~Document() {
unload();
if (parent()) {
- // TODO: do something with parent here.
+ parent()->removeChild(this);
+ setParent(nullptr);
}
}
diff --git a/engines/tetraedge/game/documents_browser.cpp b/engines/tetraedge/game/documents_browser.cpp
index 57c288a7ea3..73e2881e1e8 100644
--- a/engines/tetraedge/game/documents_browser.cpp
+++ b/engines/tetraedge/game/documents_browser.cpp
@@ -213,7 +213,29 @@ void DocumentsBrowser::showDocument(const Common::String &docName, long startPag
void DocumentsBrowser::unload() {
hideDocument();
- error("TODO: Implement DocumentsBrowser::unload");
+ int pageno = 0;
+ while (true) {
+ Common::String pageName = Common::String::format("page%d", pageno);
+ TeLayout *page = _gui1.layout(pageName);
+ if (!page)
+ break;
+ int slotno = 0;
+ while (true) {
+ Common::String pageSlotName = Common::String::format("page%dSlot%d", pageno, slotno);
+ TeLayout *slot = _gui1.layout(pageSlotName);
+ if (!slot)
+ break;
+ for (unsigned int i = 0; i < slot->childCount(); i++) {
+ Te3DObject2 *child = slot->child(i);
+ Document *doc = dynamic_cast<Document *>(child);
+ if (doc)
+ delete doc;
+ }
+ slotno++;
+ }
+ pageno++;
+ }
+ _gui1.unload();
}
} // end namespace Tetraedge
diff --git a/engines/tetraedge/game/game.cpp b/engines/tetraedge/game/game.cpp
index d9bf03e1ccc..34c06024136 100644
--- a/engines/tetraedge/game/game.cpp
+++ b/engines/tetraedge/game/game.cpp
@@ -274,10 +274,11 @@ void Game::enter(bool newgame) {
_score = 0;
Application *app = g_engine->getApplication();
app->visualFade().init();
- Common::SharedPtr<TeCallback1Param<Game, const Common::Point &>> callbackptr(new TeCallback1Param<Game, const Common::Point &>(this, &Game::onMouseClick, -1000.0f));
+ Common::SharedPtr<TeCallback1Param<Game, const Common::Point &>> callbackptr(new TeCallback1Param<Game, const Common::Point &>(this, &Game::onMouseClick, -10000.0f));
g_engine->getInputMgr()->_mouseLUpSignal.insert(callbackptr);
_movePlayerCharacterDisabled = false;
- warning("TODO: Game::enter set some other field here");
+ // TODO? Set character mouse move event no to -1
+ _isCharacterIdle = true;
_sceneCharacterVisibleFromLoad = false;
Character::loadSettings("models/ModelsSettings.xml");
Object3D::loadSettings("objects/ObjectsSettings.xml");
diff --git a/engines/tetraedge/game/game.h b/engines/tetraedge/game/game.h
index 3481d25bf44..7d19600e196 100644
--- a/engines/tetraedge/game/game.h
+++ b/engines/tetraedge/game/game.h
@@ -193,6 +193,7 @@ public:
void setPosPlayer(const TeVector3f32 &pos) { _posPlayer = pos; }
TeTimer &walkTimer() { return _walkTimer; }
void setExitZone(const Common::String &zone) { _exitZone = zone; }
+ Common::RandomSource &randomSource() { return _randomSource; }
private:
bool _luaShowOwnerError;
diff --git a/engines/tetraedge/game/in_game_scene.cpp b/engines/tetraedge/game/in_game_scene.cpp
index f61c87d348c..bfd7d0251ab 100644
--- a/engines/tetraedge/game/in_game_scene.cpp
+++ b/engines/tetraedge/game/in_game_scene.cpp
@@ -774,7 +774,7 @@ void InGameScene::loadBlockers() {
_blockers[i]._s = Te3DObject2::deserializeString(blockersfile);
TeVector2f32::deserialize(blockersfile, _blockers[i]._pts[0]);
TeVector2f32::deserialize(blockersfile, _blockers[i]._pts[1]);
- _blockers[i]._x = 1;
+ _blockers[i]._enabled = true;
}
if (hasHeader) {
@@ -787,7 +787,7 @@ void InGameScene::loadBlockers() {
for (unsigned int j = 0; j < 4l; j++) {
TeVector2f32::deserialize(blockersfile, _rectBlockers[i]._pts[j]);
}
- _rectBlockers[i]._x = 1;
+ _rectBlockers[i]._enabled = true;
}
}
}
@@ -990,6 +990,13 @@ void InGameScene::unloadCharacter(const Common::String &name) {
void InGameScene::unloadObject(const Common::String &name) {
for (unsigned int i = 0; i < _object3Ds.size(); i++) {
if (_object3Ds[i]->model()->name() == name) {
+ // Remove from the scene models.
+ for (unsigned int j = 0; j < models().size(); j++) {
+ if (models()[j] == _object3Ds[i]->model()) {
+ models().remove_at(j);
+ break;
+ }
+ }
_object3Ds[i]->deleteLater();
_object3Ds.remove_at(i);
break;
diff --git a/engines/tetraedge/game/in_game_scene.h b/engines/tetraedge/game/in_game_scene.h
index 690e76ec861..c70f0e8c57e 100644
--- a/engines/tetraedge/game/in_game_scene.h
+++ b/engines/tetraedge/game/in_game_scene.h
@@ -193,6 +193,7 @@ public:
void setCurve(TeIntrusivePtr<TeBezierCurve> &c) { _curve = c; }
Common::Array<TeIntrusivePtr<TeModel>> &zoneModels() { return _zoneModels; }
Common::Array<TeRectBlocker> &rectBlockers() { return _rectBlockers; }
+ Common::Array<TeBlocker> &blockers() { return _blockers; }
Common::Array<Object3D *> object3Ds() { return _object3Ds; }
private:
diff --git a/engines/tetraedge/game/lua_binds.cpp b/engines/tetraedge/game/lua_binds.cpp
index 514fd08bb0b..2346da3cf25 100644
--- a/engines/tetraedge/game/lua_binds.cpp
+++ b/engines/tetraedge/game/lua_binds.cpp
@@ -618,6 +618,35 @@ static int tolua_ExportedFunctions_SetCharacterAnimation00(lua_State *L) {
error("#ferror in function 'SetCharacterAnimation': %d %d %s", err.index, err.array, err.type);
}
+static int tolua_ExportedFunctions_SetCharacterAnimationAndWaitForEnd00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isstring(L, 2, 0, &err)
+ && tolua_isboolean(L, 3, 1, &err) && tolua_isboolean(L, 4, 1, &err)
+ && tolua_isnumber(L, 5, 1, &err) && tolua_isnumber(L, 6, 1, &err)
+ && tolua_isnoobj(L, 7, &err)) {
+ Common::String s1(tolua_tostring(L, 1, nullptr));
+ Common::String s2(tolua_tostring(L, 2, nullptr));
+ bool b1 = tolua_toboolean(L, 3, 1);
+ bool b2 = tolua_toboolean(L, 4, 0);
+ double f3 = tolua_tonumber(L, 5, -1.0);
+ double f4 = tolua_tonumber(L, 6, 9999.0);
+ SetCharacterAnimation(s1, s2, b1, b2, (int)f3, (int)f4);
+ Game::YieldedCallback cb;
+ cb._luaFnName = "OnCharacterAnimationFinished";
+ cb._luaParam = s1;
+ cb._luaParam2 = s2;
+ cb._luaThread = TeLuaThread::threadFromState(L);
+ Game *game = g_engine->getGame();
+ for (const auto &gamecb : game->yieldedCallbacks()) {
+ if (gamecb._luaFnName == cb._luaFnName && gamecb._luaParam == s1 && gamecb._luaParam2 == s2)
+ error("SetCharacterAnimationAndWaitForEnd: Reentrency error, your are already in a yielded/sync function call");
+ }
+ game->yieldedCallbacks().push_back(cb);
+ return cb._luaThread->yield();
+ }
+ error("#ferror in function 'SetCharacterAnimationAndWaitForEnd': %d %d %s", err.index, err.array, err.type);
+}
+
static void BlendCharacterAnimation(const Common::String &charname, const Common::String &animname, float blendAmount, bool repeat, bool b2) {
Game *game = g_engine->getGame();
Character *c = game->scene().character(charname);
@@ -1048,7 +1077,7 @@ static void EnableRectBlocker(uint offset, bool enabled) {
if (game->scene().rectBlockers().size() < offset)
error("invalid rectblocker offset %d", offset);
- game->scene().rectBlockers()[offset]._x = enabled;
+ game->scene().rectBlockers()[offset]._enabled = enabled;
}
static int tolua_ExportedFunctions_EnableRectBlocker00(lua_State *L) {
@@ -1062,6 +1091,26 @@ static int tolua_ExportedFunctions_EnableRectBlocker00(lua_State *L) {
error("#ferror in function 'EnableRectBlocker': %d %d %s", err.index, err.array, err.type);
}
+static void EnableBlocker(uint offset, bool enabled) {
+ Game *game = g_engine->getGame();
+ if (game->scene().blockers().size() < offset)
+ error("invalid blocker offset %d", offset);
+
+ game->scene().blockers()[offset]._enabled = enabled;
+}
+
+static int tolua_ExportedFunctions_EnableBlocker00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isnumber(L, 1, 0, &err) && tolua_isboolean(L, 2, 0, &err) && tolua_isnoobj(L, 3, &err)) {
+ double d1 = tolua_tonumber(L, 1, 0.0f);
+ bool b1 = tolua_toboolean(L, 2, 0);
+ EnableBlocker((uint)d1, b1);
+ return 0;
+ }
+ error("#ferror in function 'EnableBlocker': %d %d %s", err.index, err.array, err.type);
+}
+
+
static void AddAnchorZone(const Common::String &s1, const Common::String &s2, float f1) {
if (s1.empty())
return;
@@ -1144,6 +1193,62 @@ static int tolua_ExportedFunctions_SetCharacterLookChar00(lua_State *L) {
error("#ferror in function 'SetCharacterLookChar': %d %d %s", err.index, err.array, err.type);
}
+static uint Random(uint max) {
+ return g_engine->getGame()->randomSource().getRandomNumber(max);
+}
+
+static int tolua_ExportedFunctions_Random00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isnumber(L, 1, 0, &err) && tolua_isnoobj(L, 2, &err)) {
+ double d1 = tolua_tonumber(L, 1, 0.0);
+ unsigned int result = Random(d1);
+ tolua_pushnumber(L, result);
+ return 1;
+ }
+ error("#ferror in function 'Random': %d %d %s", err.index, err.array, err.type);
+}
+
+static void SetCharacterMeshVisible(const Common::String &charName, const Common::String &meshName, bool val) {
+ Character *character = g_engine->getGame()->scene().character(charName);
+ if (character) {
+ character->_model->setVisibleByName(meshName, val);
+ } else {
+ error("[SetCharacterMeshVisible] Character not found %s", charName.c_str());
+ }
+}
+
+static int tolua_ExportedFunctions_SetCharacterMeshVisible00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isboolean(L, 2, 1, &err) && tolua_isnoobj(L, 3, &err)) {
+ Common::String s1(tolua_tostring(L, 1, nullptr));
+ Common::String s2(tolua_tostring(L, 2, nullptr));
+ bool b = tolua_toboolean(L, 3, 0);
+ SetCharacterMeshVisible(s1, s2, b);
+ return 0;
+ }
+ error("#ferror in function 'SetRecallageY': %d %d %s", err.index, err.array, err.type);
+}
+
+static void SetRecallageY(const Common::String &charName, bool val) {
+ Character *character = g_engine->getGame()->scene().character(charName);
+ if (character) {
+ character->setRecallageY(val);
+ } else {
+ error("[SetRecallageY] Character not found %s", charName.c_str());
+ }
+}
+
+static int tolua_ExportedFunctions_SetRecallageY00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isboolean(L, 2, 1, &err) && tolua_isnoobj(L, 3, &err)) {
+ Common::String s(tolua_tostring(L, 1, nullptr));
+ bool b = tolua_toboolean(L, 2, 0);
+ SetRecallageY(s, b);
+ return 0;
+ }
+ error("#ferror in function 'SetRecallageY': %d %d %s", err.index, err.array, err.type);
+}
+
static void DisabledZone(const Common::String &s1, bool b) {
Game *game = g_engine->getGame();
if (!game->scene().markerGui().loaded())
@@ -1525,8 +1630,8 @@ void LuaOpenBinds(lua_State *L) {
tolua_function(L, "ShowObject", tolua_ExportedFunctions_ShowObject00);
// tolua_function(L, "ShowAllObjects", tolua_ExportedFunctions_ShowAllObjects00); // Never used
tolua_function(L, "SetBackground", tolua_ExportedFunctions_SetBackground00);
- //tolua_function(L, "AddBlockingObject", tolua_ExportedFunctions_AddBlockingObject00); // Never used
- //tolua_function(L, "RemoveBlockingObject", tolua_ExportedFunctions_RemoveBlockingObject00); // Never used
+ // tolua_function(L, "AddBlockingObject", tolua_ExportedFunctions_AddBlockingObject00); // Never used
+ // tolua_function(L, "RemoveBlockingObject", tolua_ExportedFunctions_RemoveBlockingObject00); // Never used
tolua_function(L, "ChangeWarp", tolua_ExportedFunctions_ChangeWarp00);
tolua_function(L, "PlayMovie", tolua_ExportedFunctions_PlayMovie00);
/*tolua_function(L, "PlayMovieAndWaitForEnd", tolua_ExportedFunctions_PlayMovieAndWaitForEnd00);
@@ -1590,8 +1695,8 @@ void LuaOpenBinds(lua_State *L) {
tolua_function(L, "SetCharacterRotation", tolua_ExportedFunctions_SetCharacterRotation00);
tolua_function(L, "SetCharacterOrientation", tolua_ExportedFunctions_SetCharacterOrientation00);
tolua_function(L, "SetCharacterAnimation", tolua_ExportedFunctions_SetCharacterAnimation00);
- /*tolua_function(L, "SetCharacterAnimationAndWaitForEnd",
- tolua_ExportedFunctions_SetCharacterAnimationAndWaitForEnd00);*/
+ tolua_function(L, "SetCharacterAnimationAndWaitForEnd",
+ tolua_ExportedFunctions_SetCharacterAnimationAndWaitForEnd00);
tolua_function(L, "BlendCharacterAnimation", tolua_ExportedFunctions_BlendCharacterAnimation00);
tolua_function(L, "BlendCharacterAnimationAndWaitForEnd",
tolua_ExportedFunctions_BlendCharacterAnimationAndWaitForEnd00);
@@ -1637,25 +1742,25 @@ void LuaOpenBinds(lua_State *L) {
tolua_function(L, "Save", tolua_ExportedFunctions_Save00);
tolua_function(L, "Wait", tolua_ExportedFunctions_Wait00);
tolua_function(L, "WaitAndWaitForEnd", tolua_ExportedFunctions_WaitAndWaitForEnd00);
- tolua_function(L, "OpenFinalURL", tolua_ExportedFunctions_OpenFinalURL00);
+ tolua_function(L, "OpenFinalURL", tolua_ExportedFunctions_OpenFinalURL00); // Unused
tolua_function(L, "FinishGame", tolua_ExportedFunctions_FinishGame00);
- tolua_function(L, "RequestMainMenu", tolua_ExportedFunctions_RequestMainMenu00);
- tolua_function(L, "BFGRateImmediately", tolua_ExportedFunctions_BFGRateImmediately00);
- tolua_function(L, "BFGReportEvent", tolua_ExportedFunctions_BFGReportEvent00);
- tolua_function(L, "BFGReportEventWithValue", tolua_ExportedFunctions_BFGReportEventWithValue00);
- tolua_function(L, "BFGReachedFreemiumLimit", tolua_ExportedFunctions_BFGReachedFreemiumLimit00);*/
+ tolua_function(L, "RequestMainMenu", tolua_ExportedFunctions_RequestMainMenu00);*/
+ // tolua_function(L, "BFGRateImmediately", tolua_ExportedFunctions_BFGRateImmediately00); // Unused
+ // tolua_function(L, "BFGReportEvent", tolua_ExportedFunctions_BFGReportEvent00); // Unused
+ // tolua_function(L, "BFGReportEventWithValue", tolua_ExportedFunctions_BFGReportEventWithValue00); // Unused
+ // tolua_function(L, "BFGReachedFreemiumLimit", tolua_ExportedFunctions_BFGReachedFreemiumLimit00); // Unused
tolua_function(L, "TestFileFlagSystemFlag", tolua_ExportedFunctions_TestFileFlagSystemFlag00);
// tolua_function(L, "PrintDebugMessage", tolua_ExportedFunctions_PrintDebugMessage00); // Unused
tolua_function(L, "ExitZone", tolua_ExportedFunctions_ExitZone00);
tolua_function(L, "EnableRectBlocker", tolua_ExportedFunctions_EnableRectBlocker00);
- /*tolua_function(L, "EnableBlocker", tolua_ExportedFunctions_EnableBlocker00);*/
+ tolua_function(L, "EnableBlocker", tolua_ExportedFunctions_EnableBlocker00);
tolua_function(L, "AddAnchorZone", tolua_ExportedFunctions_AddAnchorZone00);
tolua_function(L, "ActivateAnchorZone", tolua_ExportedFunctions_ActivateAnchorZone00);
//tolua_function(L, "SetCharacterAnchor", tolua_ExportedFunctions_SetCharacterAnchor00); // Unused
tolua_function(L, "SetCharacterLookChar", tolua_ExportedFunctions_SetCharacterLookChar00);
- /*tolua_function(L, "Random", tolua_ExportedFunctions_Random00);
+ tolua_function(L, "Random", tolua_ExportedFunctions_Random00);
tolua_function(L, "SetCharacterMeshVisible", tolua_ExportedFunctions_SetCharacterMeshVisible00);
- tolua_function(L, "SetRecallageY", tolua_ExportedFunctions_SetRecallageY00);*/
+ tolua_function(L, "SetRecallageY", tolua_ExportedFunctions_SetRecallageY00);
// tolua_function(L, "IsFreemiumUnlocked", tolua_ExportedFunctions_IsFreemiumUnlocked00); // Unused
// tolua_function(L, "ReachedFreemiumLimit", tolua_ExportedFunctions_ReachedFreemiumLimit00); // Unused
tolua_function(L, "AddUnrecalAnim", tolua_ExportedFunctions_AddUnrecalAnim00);
diff --git a/engines/tetraedge/game/object3d.cpp b/engines/tetraedge/game/object3d.cpp
index 23609ec05cd..4f3b46ec179 100644
--- a/engines/tetraedge/game/object3d.cpp
+++ b/engines/tetraedge/game/object3d.cpp
@@ -28,7 +28,10 @@ namespace Tetraedge {
/*static*/ Common::HashMap<Common::String, Object3D::ObjectSettings> *Object3D::_objectSettings = nullptr;
-Object3D::Object3D() : _translateTime(-1), _rotateTime(-1), _objScale(1.0f, 1.0f, 1.0f) {
+// start and end frames not initialized in original, but to guarantee we don't use
+// uninitialized values we set it here.
+Object3D::Object3D() : _translateTime(-1), _rotateTime(-1), _objScale(1.0f, 1.0f, 1.0f),
+_startFrame(-1), _endFrame(9999) {
}
bool Object3D::loadModel(const Common::String &name) {
diff --git a/engines/tetraedge/game/question2.cpp b/engines/tetraedge/game/question2.cpp
index 1e86f08ca1d..839fe5e5ddc 100644
--- a/engines/tetraedge/game/question2.cpp
+++ b/engines/tetraedge/game/question2.cpp
@@ -140,7 +140,7 @@ void Question2::Answer::load(const Common::String &name, const Common::String &l
TeButtonLayout *answerButton = _gui.buttonLayout("answer");
if (answerButton) {
answerButton->onMouseClickValidated().add(this, &Question2::Answer::onButtonValidated);
- answerButton->_someClickFlag = false;
+ answerButton->_ignoreMouseEvents = false;
}
}
diff --git a/engines/tetraedge/te/te_button_layout.cpp b/engines/tetraedge/te/te_button_layout.cpp
index d06768c6bc5..68760a98069 100644
--- a/engines/tetraedge/te/te_button_layout.cpp
+++ b/engines/tetraedge/te/te_button_layout.cpp
@@ -41,7 +41,7 @@ namespace Tetraedge {
TeButtonLayout::TeButtonLayout() :
_currentState(BUTTON_STATE_UP), _clickPassThrough(false), _validationSoundVolume(1.0),
-_someClickFlag(false), _doubleValidationProtectionEnabled(true), _upLayout(nullptr),
+_ignoreMouseEvents(false), _doubleValidationProtectionEnabled(true), _upLayout(nullptr),
_downLayout(nullptr), _rolloverLayout(nullptr), _disabledLayout(nullptr),
_hitZoneLayout(nullptr)
{
@@ -71,7 +71,6 @@ TeButtonLayout::~TeButtonLayout() {
inputmgr->_mouseLDownSignal.remove(_onMouseLeftDownCallback);
inputmgr->_mouseLUpSignal.remove(_onMouseLeftUpCallback);
inputmgr->_mouseLUpSignal.remove(_onMouseLeftUpMaxPriorityCallback);
-
}
bool TeButtonLayout::isMouseIn(const TeVector2s32 &mouseloc) {
@@ -83,7 +82,7 @@ bool TeButtonLayout::isMouseIn(const TeVector2s32 &mouseloc) {
}
bool TeButtonLayout::onMouseLeftDown(const Common::Point &pt) {
- if (!worldVisible() || _currentState == BUTTON_STATE_DISABLED)
+ if (!worldVisible() || _currentState == BUTTON_STATE_DISABLED || _ignoreMouseEvents)
return false;
// Note: This doesn't exactly reproduce the original behavior, it's
@@ -95,9 +94,10 @@ bool TeButtonLayout::onMouseLeftDown(const Common::Point &pt) {
enum State newState = _currentState;
switch (_currentState) {
- break;
case BUTTON_STATE_DOWN:
newState = BUTTON_STATE_UP;
+ /*
+ // TODO: should this be a click?
if (mouseIn) {
debug("mouse clicked button '%s' (from leftdown)", name().c_str());
if (!_validationSound.empty()) {
@@ -107,11 +107,12 @@ bool TeButtonLayout::onMouseLeftDown(const Common::Point &pt) {
setState(newState);
_onMouseClickValidatedSignal.call();
return !_clickPassThrough;
- }
+ }*/
break;
case BUTTON_STATE_ROLLOVER:
case BUTTON_STATE_UP:
- newState = BUTTON_STATE_DOWN;
+ if (mouseIn)
+ newState = BUTTON_STATE_DOWN;
break;
case BUTTON_STATE_DISABLED:
break;
@@ -137,7 +138,6 @@ bool TeButtonLayout::onMouseLeftUp(const Common::Point &pt) {
enum State newState = _currentState;
switch (_currentState) {
- break;
case BUTTON_STATE_DOWN:
newState = BUTTON_STATE_UP;
if (mouseIn) {
@@ -165,7 +165,7 @@ bool TeButtonLayout::onMouseLeftUp(const Common::Point &pt) {
}
bool TeButtonLayout::onMousePositionChanged(const Common::Point &pt) {
- if (!worldVisible() || _someClickFlag)
+ if (!worldVisible() || _ignoreMouseEvents)
return false;
// Note: This doesn't exactly reproduce the original behavior, it's
@@ -176,14 +176,12 @@ bool TeButtonLayout::onMousePositionChanged(const Common::Point &pt) {
switch (_currentState) {
case BUTTON_STATE_UP:
if (mouseIn) {
- //debug("mouse entered button '%s'", name().c_str());
newState = BUTTON_STATE_ROLLOVER;
}
break;
case BUTTON_STATE_DOWN:
case BUTTON_STATE_ROLLOVER:
if (!mouseIn) {
- //debug("mouse exit button '%s'", name().c_str());
newState = BUTTON_STATE_UP;
}
break;
@@ -324,7 +322,7 @@ void TeButtonLayout::setPosition(const TeVector3f32 &pos) {
// probably not needed as we reimplememted how this works.
error("TODO: Implement setPosition logic for up/down state");
}
- if (_someClickFlag) {
+ if (!_ignoreMouseEvents) {
setState(somethingCount ? BUTTON_STATE_DOWN : BUTTON_STATE_UP);
}
}
diff --git a/engines/tetraedge/te/te_button_layout.h b/engines/tetraedge/te/te_button_layout.h
index ebeaab28ae0..908e73ff1ab 100644
--- a/engines/tetraedge/te/te_button_layout.h
+++ b/engines/tetraedge/te/te_button_layout.h
@@ -92,7 +92,7 @@ public:
TeSignal0Param &onButtonChangedToStateDownSignal() { return _onButtonChangedToStateDownSignal; };
TeSignal0Param &onButtonChangedToStateRolloverSignal() { return _onButtonChangedToStateRolloverSignal; };
- bool _someClickFlag;
+ bool _ignoreMouseEvents;
TeLayout *_upLayout;
TeLayout *_downLayout;
diff --git a/engines/tetraedge/te/te_free_move_zone.h b/engines/tetraedge/te/te_free_move_zone.h
index f98231f7a4a..4e3efb5fbc9 100644
--- a/engines/tetraedge/te/te_free_move_zone.h
+++ b/engines/tetraedge/te/te_free_move_zone.h
@@ -43,13 +43,13 @@ namespace micropather {
struct TeBlocker {
Common::String _s;
TeVector2f32 _pts[2];
- long _x;
+ bool _enabled;
};
struct TeRectBlocker {
Common::String _s;
TeVector2f32 _pts[4];
- long _x;
+ bool _enabled;
};
class TeFreeMoveZoneGraph;
diff --git a/engines/tetraedge/te/te_image.cpp b/engines/tetraedge/te/te_image.cpp
index 617b44779f5..e834c50304d 100644
--- a/engines/tetraedge/te/te_image.cpp
+++ b/engines/tetraedge/te/te_image.cpp
@@ -78,7 +78,7 @@ void TeImage::fill(byte val) {
void TeImage::fill(byte r, byte g, byte b, byte a) {
Common::Rect wholeSurf(0, 0, w, h);
- uint32 col = ((uint32)r << format.rShift) | ((uint32)g << format.gShift) | ((uint32)b << format.bShift) | (uint32)a << format.aShift;
+ uint32 col = ((uint32)r << format.rShift) | ((uint32)g << format.gShift) | ((uint32)b << format.bShift) | ((uint32)a << format.aShift);
Graphics::Surface::fillRect(wholeSurf, col);
}
diff --git a/engines/tetraedge/te/te_model.cpp b/engines/tetraedge/te/te_model.cpp
index 4c8bfdbb9f1..111775b8e15 100644
--- a/engines/tetraedge/te/te_model.cpp
+++ b/engines/tetraedge/te/te_model.cpp
@@ -552,11 +552,11 @@ void TeModel::setQuad(const TeIntrusivePtr<Te3DTexture> &tex, const Common::Arra
mesh.defaultMaterial(tex);
for (int i = 0; i < 2; i++) {
- float f = (i == 0 ? 1.0f : 0.0f);
+ float f = (i == 0 ? 0.0f : 1.0f);
for (int j = 0; j < 2; j++) {
int index = i * 2 + j;
mesh.setVertex(index, verts[i * 2 + j]);
- mesh.setTextureUV(index, TeVector2f32(f, (j == 0 ? 1.0f : 0.0f)));
+ mesh.setTextureUV(index, TeVector2f32(f, (j == 0 ? 0.0f : 1.0f)));
mesh.setIndex(index, index);
if (col.a() != 0)
mesh.setColor(index, col);
diff --git a/engines/tetraedge/te/te_music.cpp b/engines/tetraedge/te/te_music.cpp
index 41fb9eb2f36..3f2e0e07875 100644
--- a/engines/tetraedge/te/te_music.cpp
+++ b/engines/tetraedge/te/te_music.cpp
@@ -24,6 +24,7 @@
#include "audio/mixer.h"
#include "audio/decoders/vorbis.h"
#include "tetraedge/tetraedge.h"
+#include "tetraedge/te/te_sound_manager.h"
#include "tetraedge/te/te_music.h"
#include "tetraedge/te/te_core.h"
@@ -31,6 +32,18 @@ namespace Tetraedge {
TeMusic::TeMusic() : _repeat(true), _isPlaying(false), _currentData(0),
_volume(1.0), _isPaused(true), _channelName("music"), _sndHandleValid(false) {
+ g_engine->getSoundManager()->musics().push_back(this);
+}
+
+TeMusic::~TeMusic() {
+ close();
+ Common::Array<TeMusic *> &m = g_engine->getSoundManager()->musics();
+ for (unsigned int i = 0; i < m.size(); i++) {
+ if (m[i] == this) {
+ m.remove_at(i);
+ break;
+ }
+ }
}
void TeMusic::pause() {
@@ -54,13 +67,14 @@ bool TeMusic::play() {
delete streamfile;
return false;
}
-
Audio::AudioStream *stream = Audio::makeVorbisStream(streamfile, DisposeAfterUse::YES);
byte vol = round(_volume * 255.0);
int channelId = _channelName.hash();
Audio::Mixer *mixer = g_system->getMixer();
mixer->playStream(Audio::Mixer::kMusicSoundType, &_sndHandle, stream, channelId, vol);
_sndHandleValid = true;
+ _isPaused = false;
+ _isPlaying = true;
if (_repeat)
mixer->loopChannel(_sndHandle);
return true;
@@ -98,7 +112,8 @@ void TeMusic::resume() {
void TeMusic::stop() {
_mutex.lock();
- _isStopped = true;
+ _isPlaying = false;
+ _isPaused = false;
_mutex.unlock();
/* original does this here.. probably not needed as mixer
does it for us.
@@ -130,7 +145,7 @@ void TeMusic::entry() {
bool TeMusic::isPlaying() {
_mutex.lock();
- bool retval = _isPlaying;
+ bool retval = _isPlaying && !_isPaused;
_mutex.unlock();
return retval;
}
@@ -170,8 +185,22 @@ void TeMusic::setFilePath(const Common::String &name) {
}
void TeMusic::update() {
- /* Probably not needed in ScummVM? Handled by the mixer. */
- error("TODO: Implement me");
+ /* Do callback and update flags when sounds stop */
+ bool hasStopped = false;
+ _mutex.lock();
+ if (_isPlaying && !_isPaused && _sndHandleValid && !g_system->getMixer()->isSoundHandleActive(_sndHandle))
+ hasStopped = true;
+
+ if (hasStopped) {
+ _isPaused = false;
+ _isPlaying = false;
+ _sndHandleValid = false;
+ }
+ _mutex.unlock();
+
+ if (hasStopped) {
+ _onStopSignal.call();
+ }
}
void TeMusic::volume(float vol) {
diff --git a/engines/tetraedge/te/te_music.h b/engines/tetraedge/te/te_music.h
index 68482da2bb1..cfa0e620b0f 100644
--- a/engines/tetraedge/te/te_music.h
+++ b/engines/tetraedge/te/te_music.h
@@ -35,6 +35,7 @@ namespace Tetraedge {
class TeMusic : public TeResource {
public:
TeMusic();
+ ~TeMusic();
void close() {
stop();
@@ -72,9 +73,10 @@ private:
bool _repeat;
byte _currentData;
+
bool _isPlaying;
bool _isPaused;
- bool _isStopped;
+
float _volume;
Audio::SoundHandle _sndHandle;
diff --git a/engines/tetraedge/te/te_sound_manager.cpp b/engines/tetraedge/te/te_sound_manager.cpp
index 42588e7ed45..2f30ef256c3 100644
--- a/engines/tetraedge/te/te_sound_manager.cpp
+++ b/engines/tetraedge/te/te_sound_manager.cpp
@@ -29,13 +29,13 @@
#include "tetraedge/tetraedge.h"
#include "tetraedge/te/te_core.h"
#include "tetraedge/te/te_sound_manager.h"
+#include "tetraedge/te/te_music.h"
namespace Tetraedge {
TeSoundManager::TeSoundManager() {
}
-
void TeSoundManager::playFreeSound(const Common::Path &path, float vol, const Common::String &channel) {
TeCore *core = g_engine->getCore();
Common::Path modPath = core->findFile(path);
@@ -75,5 +75,10 @@ void TeSoundManager::stopFreeSound(const Common::String &name) {
_handles.erase(name);
}
+void TeSoundManager::update() {
+ for (auto &m : _musics)
+ m->update();
+}
+
} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_sound_manager.h b/engines/tetraedge/te/te_sound_manager.h
index dbce36199cd..227a7ce29d4 100644
--- a/engines/tetraedge/te/te_sound_manager.h
+++ b/engines/tetraedge/te/te_sound_manager.h
@@ -28,6 +28,8 @@
namespace Tetraedge {
+class TeMusic;
+
class TeSoundManager {
public:
TeSoundManager();
@@ -35,8 +37,14 @@ public:
void playFreeSound(const Common::Path &path, float vol, const Common::String &channel);
void stopFreeSound(const Common::String &channel);
+ void update();
+
+ Common::Array<TeMusic *> &musics() { return _musics; }
+
private:
Common::HashMap<Common::String, Audio::SoundHandle> _handles;
+
+ Common::Array<TeMusic *> _musics;
};
} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_text_base2.cpp b/engines/tetraedge/te/te_text_base2.cpp
index 114012dfca7..a8da12c91ca 100644
--- a/engines/tetraedge/te/te_text_base2.cpp
+++ b/engines/tetraedge/te/te_text_base2.cpp
@@ -75,7 +75,7 @@ void TeTextBase2::build() {
TeImage img;
Common::SharedPtr<TePalette> nullpal;
img.create(_size._x, _size._y, nullpal, TeImage::RGBA8);
- img.fill(0, 0, 0, 0);
+ img.fill(_globalColor.r(), _globalColor.g(), _globalColor.b(), 0);
for (unsigned int i = 0; i < _wrappedLines.size(); i++) {
drawLine(img, _wrappedLines[i], lineoffsets[i]);
@@ -94,7 +94,7 @@ void TeTextBase2::build() {
_mesh.setConf(4, 4, TeMesh::MeshMode_TriangleStrip, 0, 0);
_mesh.defaultMaterial(texture);
// FIXME: Original uses BLEND, but we need MODULATE to get right colors?
- _mesh.setglTexEnv(GL_MODULATE);
+ //_mesh.setglTexEnv(GL_MODULATE);
_mesh.setShouldDraw(true);
_mesh.setColor(_globalColor);
_mesh.setVertex(0, TeVector3f32(_size._x * -0.5f, _size._y * -0.5f, 0.0f));
@@ -197,8 +197,10 @@ void TeTextBase2::drawEmptyChar(unsigned int offset) {
void TeTextBase2::drawLine(TeImage &img, const Common::String &str, int yoffset) {
TeIntrusivePtr<TeFont3> font = _fonts[0];
- // TODO: Add multi-color support if needed.
- font->draw(img, str, _fontSize, yoffset, _globalColor, _alignStyle);
+ // TODO: Add multi-color support if needed?
+ // We set black here as the color is set on the mesh and we use
+ // MODULATE blend in build()
+ font->draw(img, str, _fontSize, yoffset, TeColor(0, 0, 0, 255), _alignStyle);
}
unsigned int TeTextBase2::endOfWord(unsigned int offset) const {
diff --git a/engines/tetraedge/te/te_tiled_texture.cpp b/engines/tetraedge/te/te_tiled_texture.cpp
index d07804297e0..593055a2ff1 100644
--- a/engines/tetraedge/te/te_tiled_texture.cpp
+++ b/engines/tetraedge/te/te_tiled_texture.cpp
@@ -176,11 +176,12 @@ TeTiledTexture::Tile *TeTiledTexture::tile(const TeVector2s32 &loc) {
}
void TeTiledTexture::update(const TeImage &image) {
- //if (image.w == _totalSize._x && image.h == _totalSize._y) {
- // error("FIXME: Implement fast path of TeTiledTexture::update");
- //} else {
+ if (image.w == _totalSize._x && image.h == _totalSize._y) {
+ // TODO: Implement fast path of TeTiledTexture::update
load(image);
- //}
+ } else {
+ load(image);
+ }
}
} // end namespace Tetraedge
diff --git a/engines/tetraedge/to_lua.cpp b/engines/tetraedge/to_lua.cpp
index 31280d99aaf..979732d03d4 100644
--- a/engines/tetraedge/to_lua.cpp
+++ b/engines/tetraedge/to_lua.cpp
@@ -438,6 +438,10 @@ void tolua_pushboolean(lua_State *L, bool val) {
lua_pushboolean(L, val);
}
+void tolua_pushnumber(lua_State *L, double val) {
+ lua_pushnumber(L, val);
+}
+
} // end namespace ToLua
} // end namespace Tetraedge
diff --git a/engines/tetraedge/to_lua.h b/engines/tetraedge/to_lua.h
index 0cee065adbf..bd8d8982d2a 100644
--- a/engines/tetraedge/to_lua.h
+++ b/engines/tetraedge/to_lua.h
@@ -68,6 +68,7 @@ void* tolua_tousertype(lua_State *L, int narg, void *def);
int tolua_toboolean(lua_State *L, int narg, int def);
void tolua_pushboolean(lua_State *L, bool val);
+void tolua_pushnumber(lua_State *L, double val);
} // end namespace ToLua
Commit: 791575b0c22eb0f17df9c95d6bc30073ce80d46c
https://github.com/scummvm/scummvm/commit/791575b0c22eb0f17df9c95d6bc30073ce80d46c
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2023-01-16T17:36:43+01:00
Commit Message:
TETRAEDGE: WIP: Fix more interactions
Changed paths:
engines/tetraedge/game/application.cpp
engines/tetraedge/game/character.cpp
engines/tetraedge/game/game.cpp
engines/tetraedge/game/lua_binds.cpp
engines/tetraedge/game/object3d.cpp
engines/tetraedge/game/object_settings_xml_parser.cpp
engines/tetraedge/game/question2.cpp
engines/tetraedge/te/te_3d_object2.cpp
engines/tetraedge/te/te_core.cpp
engines/tetraedge/te/te_lua_context.cpp
engines/tetraedge/te/te_lua_gui_lua_callbacks.cpp
engines/tetraedge/te/te_lua_thread.cpp
engines/tetraedge/te/te_matrix4x4.cpp
engines/tetraedge/te/te_mesh.cpp
engines/tetraedge/te/te_mesh.h
engines/tetraedge/te/te_model.cpp
engines/tetraedge/te/te_model.h
engines/tetraedge/te/te_music.cpp
engines/tetraedge/te/te_music.h
engines/tetraedge/te/te_sound_manager.cpp
engines/tetraedge/te/te_sound_manager.h
diff --git a/engines/tetraedge/game/application.cpp b/engines/tetraedge/game/application.cpp
index dfd1386998f..eb7000ea85b 100644
--- a/engines/tetraedge/game/application.cpp
+++ b/engines/tetraedge/game/application.cpp
@@ -62,7 +62,11 @@ _drawShadows(true) {
_firstZone = tempGui.value("firstZone").toString();
_firstScene = tempGui.value("firstScene").toString();
- // TODO: Configure sound manager here?
+ TeSoundManager *soundmgr = g_engine->getSoundManager();
+ soundmgr->setChannelVolume("sfx", 0.7);
+ soundmgr->setChannelVolume("music", 0.7);
+ soundmgr->setChannelVolume("dialog", 0.7);
+ soundmgr->setChannelVolume("video", 0.7);
// TODO: Configure freemium things here?
// Note: original has an app run timer, but it's never used?
diff --git a/engines/tetraedge/game/character.cpp b/engines/tetraedge/game/character.cpp
index 8ef4dac0efa..a3cf7ab5da8 100644
--- a/engines/tetraedge/game/character.cpp
+++ b/engines/tetraedge/game/character.cpp
@@ -30,6 +30,7 @@
#include "tetraedge/game/game.h"
#include "tetraedge/game/character_settings_xml_parser.h"
#include "tetraedge/te/te_model_animation.h"
+#include "tetraedge/te/te_core.h"
namespace Tetraedge {
@@ -130,8 +131,9 @@ void Character::addCallback(const Common::String &animKey, const Common::String
return _cache.getVal(pathStr);
TeIntrusivePtr<TeModelAnimation> modelAnim = new TeModelAnimation();
- if (!modelAnim->load(path)) {
- warning("Failed to load anim %s", path.toString().c_str());
+ Common::Path foundPath = g_engine->getCore()->findFile(path);
+ if (!modelAnim->load(foundPath)) {
+ warning("Failed to load anim %s", foundPath.toString().c_str());
}
_cache.setVal(pathStr, modelAnim);
@@ -362,7 +364,8 @@ bool Character::loadModel(const Common::String &mname, bool unused) {
return true;
}
-/*static*/ bool Character::loadSettings(const Common::String &path) {
+/*static*/
+bool Character::loadSettings(const Common::String &path) {
CharacterSettingsXmlParser parser;
parser.setAllowText();
if (_globalCharacterSettings)
@@ -405,7 +408,7 @@ bool Character::loadModel(const Common::String &mname, bool unused) {
if (!parser.parse())
error("Character::loadSettings: Can't parse %s", path.c_str());
- return false;
+ return true;
}
bool Character::onBonesUpdate(const Common::String &boneName, TeMatrix4x4 &boneMatrix) {
diff --git a/engines/tetraedge/game/game.cpp b/engines/tetraedge/game/game.cpp
index 34c06024136..8180c981bff 100644
--- a/engines/tetraedge/game/game.cpp
+++ b/engines/tetraedge/game/game.cpp
@@ -485,8 +485,9 @@ bool Game::initWarp(const Common::String &zone, const Common::String &scene, boo
return false;
}
- if (!_gameSounds.empty())
- warning("TODO: Game::initWarp: stop game sounds");
+ for (auto &sound : _gameSounds) {
+ sound->setRetain(false);
+ }
if (logicLuaExists) {
_luaContext.addBindings(LuaBinds::LuaOpenBinds);
@@ -567,7 +568,7 @@ bool Game::initWarp(const Common::String &zone, const Common::String &scene, boo
}
TeCheckboxLayout *markersCheckbox = _inGameGui.checkboxLayout("markersVisibleButton");
- markersCheckbox->setVisible(!_markersVisible);
+ markersCheckbox->setState(_markersVisible? TeCheckboxLayout::CheckboxStateActive : TeCheckboxLayout::CheckboxStateUnactive);
markersCheckbox->onStateChangedSignal().add(this, &Game::onMarkersVisible);
initNoScale();
@@ -625,9 +626,14 @@ bool Game::initWarp(const Common::String &zone, const Common::String &scene, boo
_luaScript.execute("OnSelectedObject", _inventory.selectedObject());
}
- for (GameSound *sound : _gameSounds) {
- sound->stop();
- sound->deleteLater();
+
+ for (unsigned int i = 0; i < _gameSounds.size(); i++) {
+ if (_gameSounds[i]->retain())
+ continue;
+ _gameSounds[i]->stop();
+ _gameSounds[i]->deleteLater();
+ _gameSounds.remove_at(i);
+ i--;
}
_gameSounds.clear();
@@ -785,7 +791,20 @@ bool Game::onCharacterAnimationFinished(const Common::String &val) {
if (!_scene._character)
return false;
- error("TODO: Implemet Game::onCharacterAnimationFinished %s", val.c_str());
+ for (unsigned int i = 0; i < _yieldedCallbacks.size(); i++) {
+ YieldedCallback &cb = _yieldedCallbacks[i];
+ if (cb._luaFnName == "OnCharacterAnimationFinished" && cb._luaParam == val) {
+ TeLuaThread *lua = cb._luaThread;
+ _yieldedCallbacks.remove_at(i);
+ if (lua) {
+ lua->resume();
+ return false;
+ }
+ break;
+ }
+ }
+ _luaScript.execute("OnCharacterAnimationFinished", val);
+ return false;
}
bool Game::onCharacterAnimationPlayerFinished(const Common::String &anim) {
@@ -801,7 +820,6 @@ bool Game::onCharacterAnimationPlayerFinished(const Common::String &anim) {
if (lua) {
lua->resume();
callScripts = false;
- return false;
}
break;
}
@@ -1266,13 +1284,13 @@ void Game::playSound(const Common::String &name, int repeats, float volume) {
// TODO: original seems to leak sound here??
} else {
sound->onStopSignal().add(sound, &GameSound::onSoundStopped);
- // TODO: set snd->field_0x201
+ sound->setRetain(true);
_gameSounds.push_back(sound);
}
} else if (repeats == -1) {
for (GameSound *snd : _gameSounds) {
if (snd->getAccessName() == name) {
- // TODO: set snd->field_0x201
+ snd->setRetain(true);
return;
}
}
@@ -1286,7 +1304,7 @@ void Game::playSound(const Common::String &name, int repeats, float volume) {
game->luaScript().execute("OnCellFreeSoundFinished", name);
delete sound;
} else {
- // TODO: set snd->field_0x201
+ sound->setRetain(true);
_gameSounds.push_back(sound);
}
}
diff --git a/engines/tetraedge/game/lua_binds.cpp b/engines/tetraedge/game/lua_binds.cpp
index 2346da3cf25..bd15a0e3128 100644
--- a/engines/tetraedge/game/lua_binds.cpp
+++ b/engines/tetraedge/game/lua_binds.cpp
@@ -593,7 +593,8 @@ static int tolua_ExportedFunctions_SetCharacterOrientation00(lua_State *L) {
static void SetCharacterAnimation(const Common::String &charname, const Common::String &animname, bool repeat, bool b2, int i1, int i2) {
Game *game = g_engine->getGame();
Character *c = game->scene().character(charname);
- bool result = c->setAnimation(animname, repeat, b2, true, i1, i2);
+ assert(c);
+ bool result = c->setAnimation(animname, repeat, b2, false, i1, i2);
if (!result) {
warning("[SetCharacterAnimation] Character's animation \"%s\" doesn't exist for the character\"%s\" ",
animname.c_str(), charname.c_str());
@@ -1039,6 +1040,21 @@ static int tolua_ExportedFunctions_DeleteTask00(lua_State *L) {
error("#ferror in function 'DeleteTask': %d %d %s", err.index, err.array, err.type);
}
+static void SetVisibleButtonHelp(bool val) {
+ Game *game = g_engine->getGame();
+ game->objectif().setVisibleButtonHelp(val);
+}
+
+static int tolua_ExportedFunctions_SetVisibleButtonHelp00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isboolean(L, 1, 0, &err) && tolua_isnoobj(L, 3, &err)) {
+ bool b1 = tolua_toboolean(L, 1, 0);
+ SetVisibleButtonHelp(b1);
+ return 0;
+ }
+ error("#ferror in function 'SetVisibleButtonHelp': %d %d %s", err.index, err.array, err.type);
+}
+
static bool TestFileFlagSystemFlag(const Common::String &flagname, const Common::String &val) {
if (flagname == "platform" && val == "Android")
return true;
@@ -1322,6 +1338,28 @@ static int tolua_ExportedFunctions_PlaySound00(lua_State *L) {
error("#ferror in function 'PlaySound': %d %d %s", err.index, err.array, err.type);
}
+static int tolua_ExportedFunctions_PlaySoundAndWaitForEnd00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isnumber(L, 2, 1, &err) && tolua_isnumber(L, 3, 1, &err) && tolua_isnoobj(L, 4, &err)) {
+ Common::String s1(tolua_tostring(L, 1, nullptr));
+ double d1 = tolua_tonumber(L, 2, -1.0);
+ double d2 = tolua_tonumber(L, 3, 1.0);
+ PlaySound(s1, d1, d2);
+ Game::YieldedCallback cb;
+ cb._luaFnName = "OnFreeSoundFinished";
+ cb._luaParam = s1;
+ cb._luaThread = TeLuaThread::threadFromState(L);
+ Game *game = g_engine->getGame();
+ for (const auto &gamecb : game->yieldedCallbacks()) {
+ if (gamecb._luaFnName == cb._luaFnName && gamecb._luaParam == s1)
+ error("PlaySoundAndWaitForEnd: Reentrency error, your are already in a yielded/sync function call");
+ }
+ game->yieldedCallbacks().push_back(cb);
+ return cb._luaThread->yield();
+ }
+ error("#ferror in function 'PlaySoundAndWaitForEnd': %d %d %s", err.index, err.array, err.type);
+}
+
static void StopSound(const Common::String &name) {
Game *game = g_engine->getGame();
game->stopSound(name);
@@ -1559,6 +1597,30 @@ static int tolua_ExportedFunctions_MoveCharacterTo00(lua_State *L) {
error("#ferror in function 'MoveCharacterTo': %d %d %s", err.index, err.array, err.type);
}
+static int tolua_ExportedFunctions_MoveCharacterToAndWaitForEnd00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isstring(L, 2, 0, &err)
+ && tolua_isstring(L, 3, 0, &err) && tolua_isstring(L, 4, 0, &err)
+ && tolua_isnoobj(L, 5, &err)) {
+ Common::String s1(tolua_tostring(L, 1, nullptr));
+ Common::String s2(tolua_tostring(L, 2, nullptr));
+ float f1 = tolua_tonumber(L, 3, 0.0);
+ float f2 = tolua_tonumber(L, 4, 0.0);
+ MoveCharacterTo(s1, s2, f1, f2);
+ Game::YieldedCallback cb;
+ cb._luaFnName = "OnDisplacementFinished";
+ cb._luaThread = TeLuaThread::threadFromState(L);
+ Game *game = g_engine->getGame();
+ for (const auto &gamecb : game->yieldedCallbacks()) {
+ if (gamecb._luaFnName == cb._luaFnName)
+ error("MoveCharacterToAndWaitForEnd: Reentrency error, your are already in a yielded/sync function call");
+ }
+ game->yieldedCallbacks().push_back(cb);
+ return cb._luaThread->yield();
+ }
+ error("#ferror in function 'MoveCharacterToAndWaitForEnd': %d %d %s", err.index, err.array, err.type);
+}
+
static void MoveCharacterPlayerTo(float x, float y, float z, bool walkFlag) {
Game *game = g_engine->getGame();
if (game->_movePlayerCharacterDisabled)
@@ -1628,18 +1690,18 @@ void LuaOpenBinds(lua_State *L) {
tolua_function(L, "LoadObjectMaterials", tolua_ExportedFunctions_LoadObjectMaterials01);
tolua_function(L, "HideObject", tolua_ExportedFunctions_HideObject00);
tolua_function(L, "ShowObject", tolua_ExportedFunctions_ShowObject00);
- // tolua_function(L, "ShowAllObjects", tolua_ExportedFunctions_ShowAllObjects00); // Never used
+ // tolua_function(L, "ShowAllObjects", tolua_ExportedFunctions_ShowAllObjects00); // Unused
tolua_function(L, "SetBackground", tolua_ExportedFunctions_SetBackground00);
- // tolua_function(L, "AddBlockingObject", tolua_ExportedFunctions_AddBlockingObject00); // Never used
- // tolua_function(L, "RemoveBlockingObject", tolua_ExportedFunctions_RemoveBlockingObject00); // Never used
+ // tolua_function(L, "AddBlockingObject", tolua_ExportedFunctions_AddBlockingObject00); // Unused
+ // tolua_function(L, "RemoveBlockingObject", tolua_ExportedFunctions_RemoveBlockingObject00); // Unused
tolua_function(L, "ChangeWarp", tolua_ExportedFunctions_ChangeWarp00);
tolua_function(L, "PlayMovie", tolua_ExportedFunctions_PlayMovie00);
- /*tolua_function(L, "PlayMovieAndWaitForEnd", tolua_ExportedFunctions_PlayMovieAndWaitForEnd00);
- tolua_function(L, "StartAnimationPart", tolua_ExportedFunctions_StartAnimationPart00);*/
+ /*tolua_function(L, "PlayMovieAndWaitForEnd", tolua_ExportedFunctions_PlayMovieAndWaitForEnd00);*/
+ // tolua_function(L, "StartAnimationPart", tolua_ExportedFunctions_StartAnimationPart00); // Unused
tolua_function(L, "StartAnimation", tolua_ExportedFunctions_StartAnimation00);
/*tolua_function(L, "StartAnimationAndWaitForEnd",
- tolua_ExportedFunctions_StartAnimationAndWaitForEnd00);
- tolua_function(L, "AddAnimToSet", tolua_ExportedFunctions_AddAnimToSet00); */
+ tolua_ExportedFunctions_StartAnimationAndWaitForEnd00); */
+ // tolua_function(L, "AddAnimToSet", tolua_ExportedFunctions_AddAnimToSet00); // Unused
tolua_function(L, "RequestAutoSave", tolua_ExportedFunctions_RequestAutoSave00);
/*tolua_function(L, "SetVisibleButtonZoomed", tolua_ExportedFunctions_SetVisibleButtonZoomed00);*/
tolua_function(L, "AddMarker", tolua_ExportedFunctions_AddMarker00);
@@ -1649,19 +1711,19 @@ void LuaOpenBinds(lua_State *L) {
tolua_function(L, "DisabledZone", tolua_ExportedFunctions_DisabledZone00);
tolua_function(L, "DisabledInt", tolua_ExportedFunctions_DisabledInt00);
tolua_function(L, "LockCursor", tolua_ExportedFunctions_LockCursor00);
- /*tolua_function(L, "SetCondition", tolua_ExportedFunctions_SetCondition00);
- tolua_function(L, "UnsetCondition", tolua_ExportedFunctions_UnsetCondition00);
- tolua_function(L, "TutoActive", tolua_ExportedFunctions_TutoActive00);*/
+ // tolua_function(L, "SetCondition", tolua_ExportedFunctions_SetCondition00); // Unused
+ // tolua_function(L, "UnsetCondition", tolua_ExportedFunctions_UnsetCondition00); // Unused
+ // tolua_function(L, "TutoActive", tolua_ExportedFunctions_TutoActive00); // Unused
tolua_function(L, "LaunchDialog", tolua_ExportedFunctions_LaunchDialog00);
tolua_function(L, "LaunchDialogAndWaitForEnd", tolua_ExportedFunctions_LaunchDialogAndWaitForEnd00);
tolua_function(L, "PushAnswer", tolua_ExportedFunctions_PushAnswer00);
tolua_function(L, "HideAnswers", tolua_ExportedFunctions_HideAnswers00);
tolua_function(L, "PushTask", tolua_ExportedFunctions_PushTask00);
tolua_function(L, "DeleteTask", tolua_ExportedFunctions_DeleteTask00);
- /*tolua_function(L, "SetVisibleButtonHelp", tolua_ExportedFunctions_SetVisibleButtonHelp00);*/
+ tolua_function(L, "SetVisibleButtonHelp", tolua_ExportedFunctions_SetVisibleButtonHelp00);
// tolua_function(L, "HideTasks", tolua_ExportedFunctions_HideTasks00); Not used.
tolua_function(L, "PlaySound", tolua_ExportedFunctions_PlaySound00);
- /*tolua_function(L, "PlaySoundAndWaitForEnd", tolua_ExportedFunctions_PlaySoundAndWaitForEnd00);*/
+ tolua_function(L, "PlaySoundAndWaitForEnd", tolua_ExportedFunctions_PlaySoundAndWaitForEnd00);
tolua_function(L, "StopSound", tolua_ExportedFunctions_StopSound00);
tolua_function(L, "AddRandomSound", tolua_ExportedFunctions_AddRandomSound00);
tolua_function(L, "PlayRandomSound", tolua_ExportedFunctions_PlayRandomSound00);
@@ -1669,14 +1731,14 @@ void LuaOpenBinds(lua_State *L) {
tolua_function(L, "SetSoundStep", tolua_ExportedFunctions_SetSoundStep00);
tolua_function(L, "Selected", tolua_ExportedFunctions_Selected00);
tolua_function(L, "TakeObject", tolua_ExportedFunctions_TakeObject00);
- /*tolua_function(L, "TakeObjectInHand", tolua_ExportedFunctions_TakeObjectInHand00);
- tolua_function(L, "RemoveObject", tolua_ExportedFunctions_RemoveObject00);
+ // tolua_function(L, "TakeObjectInHand", tolua_ExportedFunctions_TakeObjectInHand00); // Unused
+ /*tolua_function(L, "RemoveObject", tolua_ExportedFunctions_RemoveObject00);
tolua_function(L, "RemoveObject", tolua_ExportedFunctions_RemoveObject01);*/
tolua_function(L, "AddNumber", tolua_ExportedFunctions_AddNumber00);
tolua_function(L, "ShowDocument", tolua_ExportedFunctions_ShowDocument00);
- /*tolua_function(L, "ShowDocumentAndWaitForEnd", tolua_ExportedFunctions_ShowDocumentAndWaitForEnd00);
- tolua_function(L, "HideDocument", tolua_ExportedFunctions_HideDocument00);
- tolua_function(L, "AddDocument", tolua_ExportedFunctions_AddDocument00);*/
+ // tolua_function(L, "ShowDocumentAndWaitForEnd", tolua_ExportedFunctions_ShowDocumentAndWaitForEnd00); // Unused
+ // tolua_function(L, "HideDocument", tolua_ExportedFunctions_HideDocument00); // Unused
+ // tolua_function(L, "AddDocument", tolua_ExportedFunctions_AddDocument00); // Unused
tolua_function(L, "LoadCharacter", tolua_ExportedFunctions_LoadCharacter00);
tolua_function(L, "UnloadCharacter", tolua_ExportedFunctions_UnloadCharacter00);
// tolua_function(L, "GetRotationCharacter", tolua_ExportedFunctions_GetRotationCharacter00); // Unused
@@ -1684,12 +1746,12 @@ void LuaOpenBinds(lua_State *L) {
// tolua_function(L, "GetYPositionCharacter", tolua_ExportedFunctions_GetYPositionCharacter00); // Unused
// tolua_function(L, "GetZPositionCharacter", tolua_ExportedFunctions_GetZPositionCharacter00); // Unused
tolua_function(L, "MoveCharacterTo", tolua_ExportedFunctions_MoveCharacterTo00);
- /*tolua_function(L, "MoveCharacterToAndWaitForEnd",
- tolua_ExportedFunctions_MoveCharacterToAndWaitForEnd00);*/
+ tolua_function(L, "MoveCharacterToAndWaitForEnd",
+ tolua_ExportedFunctions_MoveCharacterToAndWaitForEnd00);
tolua_function(L, "MoveCharacterPlayerTo", tolua_ExportedFunctions_MoveCharacterPlayerTo00);
- /*tolua_function(L, "MoveCharacterPlayerToAndWaitForEnd",
- tolua_ExportedFunctions_MoveCharacterPlayerToAndWaitForEnd00);
- tolua_function(L, "MoveCharacterPlayerAtTo", tolua_ExportedFunctions_MoveCharacterPlayerAtTo00);*/
+ // tolua_function(L, "MoveCharacterPlayerToAndWaitForEnd",
+ // tolua_ExportedFunctions_MoveCharacterPlayerToAndWaitForEnd00); // Unused
+ // tolua_function(L, "MoveCharacterPlayerAtTo", tolua_ExportedFunctions_MoveCharacterPlayerAtTo00); // Unused
tolua_function(L, "SetCharacterPosition", tolua_ExportedFunctions_SetCharacterPosition00);
tolua_function(L, "PlaceCharacterOnDummy", tolua_ExportedFunctions_PlaceCharacterOnDummy00);
tolua_function(L, "SetCharacterRotation", tolua_ExportedFunctions_SetCharacterRotation00);
@@ -1705,16 +1767,16 @@ void LuaOpenBinds(lua_State *L) {
tolua_function(L, "MoveCharacterPlayerDisabled",
tolua_ExportedFunctions_MoveCharacterPlayerDisabled00);
/*tolua_function(L, "SetRunMode", tolua_ExportedFunctions_SetRunMode00);
- tolua_function(L, "SetRunMode2", tolua_ExportedFunctions_SetRunMode200);
- tolua_function(L, "SetCharacterColor", tolua_ExportedFunctions_SetCharacterColor00);
- tolua_function(L, "SetCharacterSound", tolua_ExportedFunctions_SetCharacterSound00);
- tolua_function(L, "SetCharacterShadow", tolua_ExportedFunctions_SetCharacterShadow00);*/
+ tolua_function(L, "SetRunMode2", tolua_ExportedFunctions_SetRunMode200); */
+ // tolua_function(L, "SetCharacterColor", tolua_ExportedFunctions_SetCharacterColor00); // Unused
+ // tolua_function(L, "SetCharacterSound", tolua_ExportedFunctions_SetCharacterSound00); // Unused
+ /*tolua_function(L, "SetCharacterShadow", tolua_ExportedFunctions_SetCharacterShadow00);*/
tolua_function(L, "AddCallback", tolua_ExportedFunctions_AddCallback00);
- /*tolua_function(L, "AddCallbackPlayer", tolua_ExportedFunctions_AddCallbackPlayer00);
- tolua_function(L, "AddCallbackAnimation2D", tolua_ExportedFunctions_AddCallbackAnimation2D00);
- tolua_function(L, "DeleteCallback", tolua_ExportedFunctions_DeleteCallback00);
- tolua_function(L, "DeleteCallbackPlayer", tolua_ExportedFunctions_DeleteCallbackPlayer00);
- tolua_function(L, "DeleteCallbackAnimation2D", tolua_ExportedFunctions_DeleteCallbackAnimation2D00);*/
+ /*tolua_function(L, "AddCallbackPlayer", tolua_ExportedFunctions_AddCallbackPlayer00); */
+ // tolua_function(L, "AddCallbackAnimation2D", tolua_ExportedFunctions_AddCallbackAnimation2D00); // Unused
+ // tolua_function(L, "DeleteCallback", tolua_ExportedFunctions_DeleteCallback00); // Unused
+ // tolua_function(L, "DeleteCallbackPlayer", tolua_ExportedFunctions_DeleteCallbackPlayer00); // Unused
+ // tolua_function(L, "DeleteCallbackAnimation2D", tolua_ExportedFunctions_DeleteCallbackAnimation2D00); // Unused
tolua_function(L, "SetObjectOnCharacter", tolua_ExportedFunctions_SetObjectOnCharacter00);
tolua_function(L, "SetObjectRotation", tolua_ExportedFunctions_SetObjectRotation00);
tolua_function(L, "SetObjectTranslation", tolua_ExportedFunctions_SetObjectTranslation00);
@@ -1724,14 +1786,14 @@ void LuaOpenBinds(lua_State *L) {
tolua_function(L, "UnloadObject", tolua_ExportedFunctions_UnloadObject00);
tolua_function(L, "SetGroundObjectPosition", tolua_ExportedFunctions_SetGroundObjectPosition00);
tolua_function(L, "SetGroundObjectRotation", tolua_ExportedFunctions_SetGroundObjectRotation00);
- /*tolua_function(L, "TranslateGroundObject", tolua_ExportedFunctions_TranslateGroundObject00);
- tolua_function(L, "RotateGroundObject", tolua_ExportedFunctions_RotateGroundObject00);
- tolua_function(L, "SetLightPlayerCharacter", tolua_ExportedFunctions_SetLightPlayerCharacter00);
- tolua_function(L, "SetLightPos", tolua_ExportedFunctions_SetLightPos00);
- tolua_function(L, "EnableLight", tolua_ExportedFunctions_EnableLight00);
- tolua_function(L, "SetLightDiffuse", tolua_ExportedFunctions_SetLightDiffuse00);
- tolua_function(L, "SetLightAmbient", tolua_ExportedFunctions_SetLightAmbient00);
- tolua_function(L, "SetLightSpecular", tolua_ExportedFunctions_SetLightSpecular00);*/
+ /*tolua_function(L, "TranslateGroundObject", tolua_ExportedFunctions_TranslateGroundObject00); */
+ // tolua_function(L, "RotateGroundObject", tolua_ExportedFunctions_RotateGroundObject00); // Unused
+ // tolua_function(L, "SetLightPlayerCharacter", tolua_ExportedFunctions_SetLightPlayerCharacter00); // Unused
+ // tolua_function(L, "SetLightPos", tolua_ExportedFunctions_SetLightPos00); // Unused
+ /*tolua_function(L, "EnableLight", tolua_ExportedFunctions_EnableLight00); */
+ // tolua_function(L, "SetLightDiffuse", tolua_ExportedFunctions_SetLightDiffuse00); // Unused
+ // tolua_function(L, "SetLightAmbient", tolua_ExportedFunctions_SetLightAmbient00); // Unused
+ // tolua_function(L, "SetLightSpecular", tolua_ExportedFunctions_SetLightSpecular00); // Unused
tolua_function(L, "LoadBillBoard", tolua_ExportedFunctions_LoadBillBoard00);
tolua_function(L, "SetBillboardPosition", tolua_ExportedFunctions_SetBillboardPosition00);
tolua_function(L, "SetBillboardPosition2", tolua_ExportedFunctions_SetBillboardPosition200);
@@ -1741,9 +1803,9 @@ void LuaOpenBinds(lua_State *L) {
/*tolua_function(L, "UnlockAchievement", tolua_ExportedFunctions_UnlockAchievement00);
tolua_function(L, "Save", tolua_ExportedFunctions_Save00);
tolua_function(L, "Wait", tolua_ExportedFunctions_Wait00);
- tolua_function(L, "WaitAndWaitForEnd", tolua_ExportedFunctions_WaitAndWaitForEnd00);
- tolua_function(L, "OpenFinalURL", tolua_ExportedFunctions_OpenFinalURL00); // Unused
- tolua_function(L, "FinishGame", tolua_ExportedFunctions_FinishGame00);
+ tolua_function(L, "WaitAndWaitForEnd", tolua_ExportedFunctions_WaitAndWaitForEnd00); */
+ // tolua_function(L, "OpenFinalURL", tolua_ExportedFunctions_OpenFinalURL00); // Unused
+ /*tolua_function(L, "FinishGame", tolua_ExportedFunctions_FinishGame00);
tolua_function(L, "RequestMainMenu", tolua_ExportedFunctions_RequestMainMenu00);*/
// tolua_function(L, "BFGRateImmediately", tolua_ExportedFunctions_BFGRateImmediately00); // Unused
// tolua_function(L, "BFGReportEvent", tolua_ExportedFunctions_BFGReportEvent00); // Unused
@@ -1756,7 +1818,7 @@ void LuaOpenBinds(lua_State *L) {
tolua_function(L, "EnableBlocker", tolua_ExportedFunctions_EnableBlocker00);
tolua_function(L, "AddAnchorZone", tolua_ExportedFunctions_AddAnchorZone00);
tolua_function(L, "ActivateAnchorZone", tolua_ExportedFunctions_ActivateAnchorZone00);
- //tolua_function(L, "SetCharacterAnchor", tolua_ExportedFunctions_SetCharacterAnchor00); // Unused
+ // tolua_function(L, "SetCharacterAnchor", tolua_ExportedFunctions_SetCharacterAnchor00); // Unused
tolua_function(L, "SetCharacterLookChar", tolua_ExportedFunctions_SetCharacterLookChar00);
tolua_function(L, "Random", tolua_ExportedFunctions_Random00);
tolua_function(L, "SetCharacterMeshVisible", tolua_ExportedFunctions_SetCharacterMeshVisible00);
diff --git a/engines/tetraedge/game/object3d.cpp b/engines/tetraedge/game/object3d.cpp
index 4f3b46ec179..9b676a57ee0 100644
--- a/engines/tetraedge/game/object3d.cpp
+++ b/engines/tetraedge/game/object3d.cpp
@@ -25,7 +25,8 @@
namespace Tetraedge {
-/*static*/ Common::HashMap<Common::String, Object3D::ObjectSettings> *Object3D::_objectSettings = nullptr;
+/*static*/
+Common::HashMap<Common::String, Object3D::ObjectSettings> *Object3D::_objectSettings = nullptr;
// start and end frames not initialized in original, but to guarantee we don't use
@@ -51,7 +52,8 @@ bool Object3D::loadModel(const Common::String &name) {
return false;
}
-/*static*/ bool Object3D::loadSettings(const Common::String &path) {
+/*static*/
+bool Object3D::loadSettings(const Common::String &path) {
ObjectSettingsXmlParser parser;
parser.setAllowText();
@@ -65,7 +67,7 @@ bool Object3D::loadModel(const Common::String &name) {
if (!parser.parse())
error("Object3D::loadSettings: Can't parse %s", path.c_str());
- return false;
+ return true;
}
void Object3D::ObjectSettings::clear() {
diff --git a/engines/tetraedge/game/object_settings_xml_parser.cpp b/engines/tetraedge/game/object_settings_xml_parser.cpp
index 906978068a1..88259dc3d14 100644
--- a/engines/tetraedge/game/object_settings_xml_parser.cpp
+++ b/engines/tetraedge/game/object_settings_xml_parser.cpp
@@ -52,8 +52,12 @@ bool ObjectSettingsXmlParser::textCallback(const Common::String &val) {
_curObject._modelFileName = val;
break;
case TagDefaultScale:
- _curObject._defaultScale.parse(val);
+ {
+ bool result = _curObject._defaultScale.parse(val);
+ if (!result)
+ warning("Failed to parse Object defaultScale from %s", val.c_str());
break;
+ }
default:
error("should only see text for model file name or scale");
}
diff --git a/engines/tetraedge/game/question2.cpp b/engines/tetraedge/game/question2.cpp
index 839fe5e5ddc..356e3df2f88 100644
--- a/engines/tetraedge/game/question2.cpp
+++ b/engines/tetraedge/game/question2.cpp
@@ -37,9 +37,8 @@ Question2::~Question2() {
}
void Question2::enter() {
- TeButtonLayout *backgroundButton = _gui.buttonLayout("background");
- if (backgroundButton)
- backgroundButton->setVisible(true);
+ TeButtonLayout *backgroundButton = _gui.buttonLayoutChecked("background");
+ backgroundButton->setVisible(true);
g_engine->getGame()->showMarkers(true);
}
@@ -120,7 +119,7 @@ void Question2::pushAnswer(const Common::String &name, const Common::String &loc
TeSpriteLayout *calepinLayout = _gui.spriteLayout("Calepin");
if (calepinLayout)
- calepinLayout->setParent(alayout);
+ calepinLayout->addChild(alayout);
enter();
}
diff --git a/engines/tetraedge/te/te_3d_object2.cpp b/engines/tetraedge/te/te_3d_object2.cpp
index f18a56b5e43..9ea9e9c5b7b 100644
--- a/engines/tetraedge/te/te_3d_object2.cpp
+++ b/engines/tetraedge/te/te_3d_object2.cpp
@@ -145,7 +145,7 @@ void Te3DObject2::removeChild(Te3DObject2 *child) {
Common::String cname("nullptr");
if (child)
cname = child->name();
- warning("Request to remove child (%s) which is not a child of this (%s).", cname.c_str(), name().c_str());
+ debug("Request to remove child (%s) which is not a child of this (%s).", cname.c_str(), name().c_str());
}
}
diff --git a/engines/tetraedge/te/te_core.cpp b/engines/tetraedge/te/te_core.cpp
index 0b2ed30ef1b..a85315b77f0 100644
--- a/engines/tetraedge/te/te_core.cpp
+++ b/engines/tetraedge/te/te_core.cpp
@@ -50,7 +50,7 @@ void TeCore::create() {
language("en");
_coreNotReady = false;
_activityTrackingTimer.alarmSignal().add<TeCore>(this, &TeCore::onActivityTrackingAlarm);
- warning("TeCore::create: Finish implementing me.");
+ warning("TODO: TeCore::create: Finish implementing me.");
}
TeICodec *TeCore::createVideoCodec(const Common::Path &path) {
@@ -133,6 +133,9 @@ Common::Path TeCore::findFile(const Common::Path &path) {
"PC-MacOSX-PS3-Xbox360",
"PC-MacOSX-Xbox360-PS3/PC-MacOSX",
"Full",
+ "Part1-Full",
+ "Part2-Full-Part1",
+ "Part3-Full-Part1",
"HD",
"HD/PC-MacOSX-Xbox360-PS3"
};
diff --git a/engines/tetraedge/te/te_lua_context.cpp b/engines/tetraedge/te/te_lua_context.cpp
index f2df4bda2ba..dff65386901 100644
--- a/engines/tetraedge/te/te_lua_context.cpp
+++ b/engines/tetraedge/te/te_lua_context.cpp
@@ -19,6 +19,7 @@
*
*/
+#include "common/debug.h"
#include "common/textconsole.h"
#include "common/lua/lua.h"
#include "common/lua/lualib.h"
@@ -75,7 +76,10 @@ TeVariant TeLuaContext::global(const Common::String &name) {
lua_settop(_luaState, -2);
return TeVariant(str);
}
- warning("TeLuaContext::global: Unexpected type %d for global %s", type, name.c_str());
+ if (type != LUA_TNIL)
+ warning("TeLuaContext::global: Unexpected type %d for global %s", type, name.c_str());
+ else
+ debug("TeLuaContext::global: Request for nil global %s", name.c_str());
return TeVariant();
}
diff --git a/engines/tetraedge/te/te_lua_gui_lua_callbacks.cpp b/engines/tetraedge/te/te_lua_gui_lua_callbacks.cpp
index d78d734fb01..e8d8c93ad04 100644
--- a/engines/tetraedge/te/te_lua_gui_lua_callbacks.cpp
+++ b/engines/tetraedge/te/te_lua_gui_lua_callbacks.cpp
@@ -431,7 +431,7 @@ int spriteLayoutBindings(lua_State *L) {
int buttonLayoutBindings(lua_State *L) {
if (lua_type(L, -1) != LUA_TTABLE) {
- warning("buttonLayoutBindings:: the lua value is not a table\n");
+ warning("buttonLayoutBindings:: the lua value is not a table");
return 0;
}
@@ -467,7 +467,7 @@ int buttonLayoutBindings(lua_State *L) {
layout->setScale(TeVector3f32(0.7500001,1.0,1.0));
}
} else {
- warning("[TeLuaGUI.buttonLayoutBindings] Unreconized attribute : %s\n", s);
+ warning("[TeLuaGUI.buttonLayoutBindings] Unreconized attribute : %s", s);
}
}
lua_settop(L, -2);
@@ -491,7 +491,7 @@ int buttonLayoutBindings(lua_State *L) {
lua_pushlightuserdata(L, static_cast<Te3DObject2*>(layout));
return true;
} else {
- warning("buttonLayoutBindings:: multiple objects with name %s\n", layout->name().c_str());
+ warning("buttonLayoutBindings:: multiple objects with name %s", layout->name().c_str());
delete layout;
return false;
}
@@ -537,7 +537,7 @@ int checkboxLayoutBindings(lua_State *L) {
layout->setScale(TeVector3f32(0.7500001,1.0,1.0));
}
} else {
- warning("[TeLuaGUI.buttonLayoutBindings] Unreconized attribute : %s\n", s);
+ warning("[TeLuaGUI.checkboxLayoutBindings] Unreconized attribute : %s", s);
}
}
lua_settop(L, -2);
@@ -561,7 +561,7 @@ int checkboxLayoutBindings(lua_State *L) {
lua_pushlightuserdata(L, static_cast<Te3DObject2*>(layout));
return true;
} else {
- warning("buttonLayoutBindings:: multiple objects with name %s\n", layout->name().c_str());
+ warning("checkboxLayoutBindings:: multiple objects with name %s", layout->name().c_str());
delete layout;
return false;
}
diff --git a/engines/tetraedge/te/te_lua_thread.cpp b/engines/tetraedge/te/te_lua_thread.cpp
index 54fe22956af..9b32db5908a 100644
--- a/engines/tetraedge/te/te_lua_thread.cpp
+++ b/engines/tetraedge/te/te_lua_thread.cpp
@@ -62,7 +62,7 @@ void TeLuaThread::_resume(int nargs) {
warning("TeLuaThread::_resume: %s", msg);
}
if (_lastResumeResult != 1 && _released) {
- warning("TeLuaThread:: deleting this.");
+ debug("TeLuaThread:: deleting this?");
delete this;
}
}
@@ -192,7 +192,7 @@ void TeLuaThread::pushValue(const TeVariant &val) {
void TeLuaThread::release() {
_released = true;
if (_lastResumeResult != 1) {
- //warning("TeLuaThread:: deleting this??");
+ //debug("TeLuaThread:: deleting this?");
delete this;
}
}
diff --git a/engines/tetraedge/te/te_matrix4x4.cpp b/engines/tetraedge/te/te_matrix4x4.cpp
index a26a2fad065..db6440047a5 100644
--- a/engines/tetraedge/te/te_matrix4x4.cpp
+++ b/engines/tetraedge/te/te_matrix4x4.cpp
@@ -86,6 +86,7 @@ void TeMatrix4x4::scale(const TeVector3f32 &vec) {
scaleMatrix(0, 0) = vec.x();
scaleMatrix(1, 1) = vec.y();
scaleMatrix(2, 2) = vec.z();
+ //scaleMatrix(3, 3) = 1.0; // default.
*this = (*this * scaleMatrix);
}
diff --git a/engines/tetraedge/te/te_mesh.cpp b/engines/tetraedge/te/te_mesh.cpp
index 3b404627c4f..51959d1fcfa 100644
--- a/engines/tetraedge/te/te_mesh.cpp
+++ b/engines/tetraedge/te/te_mesh.cpp
@@ -73,7 +73,7 @@ void TeMesh::draw() {
TeRenderer *renderer = g_engine->getRenderer();
renderer->pushMatrix();
if (_matrixForced)
- renderer->multiplyMatrix(_forceMatrix);
+ renderer->multiplyMatrix(_forcedMatrix);
else
renderer->multiplyMatrix(worldTransformationMatrix());
diff --git a/engines/tetraedge/te/te_mesh.h b/engines/tetraedge/te/te_mesh.h
index 8d6e5cd442d..f09fb8bdb10 100644
--- a/engines/tetraedge/te/te_mesh.h
+++ b/engines/tetraedge/te/te_mesh.h
@@ -137,7 +137,7 @@ private:
unsigned int _glMeshMode;
bool _matrixForced;
- TeMatrix4x4 _forceMatrix;
+ TeMatrix4x4 _forcedMatrix;
bool _hasAlpha;
uint _initialMaterialIndexCount;
bool _drawWires;
diff --git a/engines/tetraedge/te/te_model.cpp b/engines/tetraedge/te/te_model.cpp
index 111775b8e15..ebafd7b232e 100644
--- a/engines/tetraedge/te/te_model.cpp
+++ b/engines/tetraedge/te/te_model.cpp
@@ -175,10 +175,10 @@ void TeModel::update() {
for (unsigned int i = 0; i < _bones.size(); i++) {
const bone &b = _bones[i];
const TeMatrix4x4 matrix = TeMatrix4x4::fromTRS(b._trs);
- if (b._x == -1 || _bones.size() < 2) {
+ if (b._parentBone == -1 || _bones.size() < 2) {
matricies[0] = matrix;
} else {
- matricies[i] = matricies[b._x] * matrix;
+ matricies[i] = matricies[b._parentBone] * matrix;
}
}
@@ -202,18 +202,20 @@ void TeModel::update() {
trs = trs.lerp(endTRS, complete);
}
}
- TeMatrix4x4 matrix;
+
+ TeMatrix4x4 newBoneMatrix;
if (!_matrixForced) {
- matrix = TeMatrix4x4::fromTRS(trs);
+ newBoneMatrix = TeMatrix4x4::fromTRS(trs);
} else {
- matrix = invertx * _forcedMatrix;
+ newBoneMatrix = invertx * _forcedMatrix;
_matrixForced = false;
}
- if (_bones.size() < 2 || _bones[b]._x == -1) {
- _boneMatricies[b] = matrix;
+
+ if (_bones.size() < 2 || _bones[b]._parentBone == -1) {
+ _boneMatricies[b] = newBoneMatrix;
_boneMatricies[b].rotate(_boneRotation);
} else {
- _boneMatricies[b] = (invertx * _boneMatricies[_bones[b]._x]) * matrix;
+ _boneMatricies[b] = (invertx * _boneMatricies[_bones[b]._parentBone]) * newBoneMatrix;
}
_boneMatricies[b] = invertx * _boneMatricies[b];
_bonesUpdatedSignal.call(_bones[b]._name, _boneMatricies[b]);
@@ -284,6 +286,7 @@ void TeModel::update() {
for (MeshBlender *mb : _meshBlenders) {
if (mesh.name().contains(mb->_name)) {
+ error("TODO: Finish meshblend part of model::update");
// TODO: Finish TeModel::update. (disasm 585 ~ 644), LAB_doMeshBlends
//float blendamount = MIN(mb->_timer.getTimeFromStart() / 1000000.0f, 1.0f);
@@ -372,7 +375,7 @@ bool TeModel::load(Common::SeekableReadStream &stream) {
for (unsigned int i = 0; i < _bones.size(); i++) {
_bones[i]._name = Te3DObject2::deserializeString(stream);
loadAlign(stream);
- _bones[i]._x = stream.readUint32LE();
+ _bones[i]._parentBone = stream.readUint32LE();
TeTRS::deserialize(stream, _bones[i]._trs);
if (!_skipSkinOffsets) {
_skinOffsets[i].deserialize(stream);
diff --git a/engines/tetraedge/te/te_model.h b/engines/tetraedge/te/te_model.h
index d9fa712e01b..ab27bb06384 100644
--- a/engines/tetraedge/te/te_model.h
+++ b/engines/tetraedge/te/te_model.h
@@ -64,7 +64,7 @@ public:
struct bone {
Common::String _name;
- short _x;
+ short _parentBone;
TeTRS _trs;
};
diff --git a/engines/tetraedge/te/te_music.cpp b/engines/tetraedge/te/te_music.cpp
index 3f2e0e07875..6651f8727ed 100644
--- a/engines/tetraedge/te/te_music.cpp
+++ b/engines/tetraedge/te/te_music.cpp
@@ -31,7 +31,8 @@
namespace Tetraedge {
TeMusic::TeMusic() : _repeat(true), _isPlaying(false), _currentData(0),
-_volume(1.0), _isPaused(true), _channelName("music"), _sndHandleValid(false) {
+_volume(1.0), _isPaused(false), _channelName("music"), _sndHandleValid(false),
+_retain(false) {
g_engine->getSoundManager()->musics().push_back(this);
}
@@ -70,8 +71,19 @@ bool TeMusic::play() {
Audio::AudioStream *stream = Audio::makeVorbisStream(streamfile, DisposeAfterUse::YES);
byte vol = round(_volume * 255.0);
int channelId = _channelName.hash();
+
Audio::Mixer *mixer = g_system->getMixer();
- mixer->playStream(Audio::Mixer::kMusicSoundType, &_sndHandle, stream, channelId, vol);
+ Audio::Mixer::SoundType soundType = Audio::Mixer::kPlainSoundType;
+ if (_channelName == "sfx") {
+ soundType = Audio::Mixer::kSFXSoundType;
+ } else if (_channelName == "dialog") {
+ soundType = Audio::Mixer::kSpeechSoundType;
+ } else if (_channelName == "music") {
+ soundType = Audio::Mixer::kMusicSoundType;
+ }
+
+ debug("playing %s on channel %s at vol %d", _actualPath.toString().c_str(), _channelName.c_str(), vol);
+ mixer->playStream(soundType, &_sndHandle, stream, -1, vol);
_sndHandleValid = true;
_isPaused = false;
_isPlaying = true;
diff --git a/engines/tetraedge/te/te_music.h b/engines/tetraedge/te/te_music.h
index cfa0e620b0f..4180f6370de 100644
--- a/engines/tetraedge/te/te_music.h
+++ b/engines/tetraedge/te/te_music.h
@@ -65,6 +65,9 @@ public:
float volume();
TeSignal0Param &onStopSignal() { return _onStopSignal; }
+
+ void setRetain(bool retain) { _retain = retain; }
+ bool retain() const { return _retain; }
private:
Common::String _rawPath; // Plain name of file requested
@@ -76,6 +79,7 @@ private:
bool _isPlaying;
bool _isPaused;
+ bool _retain;
float _volume;
diff --git a/engines/tetraedge/te/te_sound_manager.cpp b/engines/tetraedge/te/te_sound_manager.cpp
index 2f30ef256c3..e10ce8d495a 100644
--- a/engines/tetraedge/te/te_sound_manager.cpp
+++ b/engines/tetraedge/te/te_sound_manager.cpp
@@ -75,6 +75,13 @@ void TeSoundManager::stopFreeSound(const Common::String &name) {
_handles.erase(name);
}
+void TeSoundManager::setChannelVolume(const Common::String &channel, float vol) {
+ //int channelId = channel.hash();
+ //Audio::Mixer *mixer = g_system->getMixer();
+ //mixer->setChannelVolume(handle, vol * 255);
+ // TODO: store channel volume here.
+}
+
void TeSoundManager::update() {
for (auto &m : _musics)
m->update();
diff --git a/engines/tetraedge/te/te_sound_manager.h b/engines/tetraedge/te/te_sound_manager.h
index 227a7ce29d4..75288ca7c51 100644
--- a/engines/tetraedge/te/te_sound_manager.h
+++ b/engines/tetraedge/te/te_sound_manager.h
@@ -37,6 +37,7 @@ public:
void playFreeSound(const Common::Path &path, float vol, const Common::String &channel);
void stopFreeSound(const Common::String &channel);
+ void setChannelVolume(const Common::String &channel, float vol);
void update();
Common::Array<TeMusic *> &musics() { return _musics; }
Commit: 531b53f66a522a24c612bd0230de0cf871357188
https://github.com/scummvm/scummvm/commit/531b53f66a522a24c612bd0230de0cf871357188
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2023-01-16T17:36:43+01:00
Commit Message:
TETRAEDGE: Switch button priority to z-order
Changed paths:
engines/tetraedge/game/game.cpp
engines/tetraedge/game/inventory.cpp
engines/tetraedge/te/te_3d_object2.cpp
engines/tetraedge/te/te_button_layout.cpp
engines/tetraedge/te/te_checkbox_layout.cpp
engines/tetraedge/te/te_layout.cpp
engines/tetraedge/te/te_signal.h
diff --git a/engines/tetraedge/game/game.cpp b/engines/tetraedge/game/game.cpp
index 8180c981bff..1eda0a2f4d5 100644
--- a/engines/tetraedge/game/game.cpp
+++ b/engines/tetraedge/game/game.cpp
@@ -275,7 +275,7 @@ void Game::enter(bool newgame) {
Application *app = g_engine->getApplication();
app->visualFade().init();
Common::SharedPtr<TeCallback1Param<Game, const Common::Point &>> callbackptr(new TeCallback1Param<Game, const Common::Point &>(this, &Game::onMouseClick, -10000.0f));
- g_engine->getInputMgr()->_mouseLUpSignal.insert(callbackptr);
+ g_engine->getInputMgr()->_mouseLUpSignal.push_back(callbackptr);
_movePlayerCharacterDisabled = false;
// TODO? Set character mouse move event no to -1
_isCharacterIdle = true;
diff --git a/engines/tetraedge/game/inventory.cpp b/engines/tetraedge/game/inventory.cpp
index 2fcb923c5af..292360c9e0e 100644
--- a/engines/tetraedge/game/inventory.cpp
+++ b/engines/tetraedge/game/inventory.cpp
@@ -88,9 +88,8 @@ void Inventory::load() {
btn->setVisible(true);
btn->onMouseClickValidated().add(this, &Inventory::onQuitButton);
- // FIXME: This is capturing mouse clicks.. should be set visible per original.
btn = _gui.buttonLayoutChecked("quitBackground");
- btn->setVisible(false);
+ btn->setVisible(true);
btn->onMouseClickValidated().add(this, &Inventory::onQuitButton);
btn = _gui.buttonLayoutChecked("mainMenuButton");
diff --git a/engines/tetraedge/te/te_3d_object2.cpp b/engines/tetraedge/te/te_3d_object2.cpp
index 9ea9e9c5b7b..7519441900e 100644
--- a/engines/tetraedge/te/te_3d_object2.cpp
+++ b/engines/tetraedge/te/te_3d_object2.cpp
@@ -185,11 +185,11 @@ void Te3DObject2::setParent(Te3DObject2 *newparent) {
_parent = newparent;
if (newparent) {
if (_onWorldVisibleChangedParentCallback)
- _parent->onWorldVisibleChanged().insert(_onWorldVisibleChangedParentCallback);
+ _parent->onWorldVisibleChanged().push_back(_onWorldVisibleChangedParentCallback);
if (_onWorldTransformationMatrixChangedParentCallback)
- _parent->onWorldTransformationMatrixChanged().insert(_onWorldTransformationMatrixChangedParentCallback);
+ _parent->onWorldTransformationMatrixChanged().push_back(_onWorldTransformationMatrixChangedParentCallback);
if (_onWorldColorChangedParentCallback)
- _parent->onWorldColorChanged().insert(_onWorldColorChangedParentCallback);
+ _parent->onWorldColorChanged().push_back(_onWorldColorChangedParentCallback);
_onWorldVisibleChangedSlotSignal.call();
_onParentWorldTransformationMatrixChangedSignal.call();
diff --git a/engines/tetraedge/te/te_button_layout.cpp b/engines/tetraedge/te/te_button_layout.cpp
index 68760a98069..ecc10794d76 100644
--- a/engines/tetraedge/te/te_button_layout.cpp
+++ b/engines/tetraedge/te/te_button_layout.cpp
@@ -29,6 +29,16 @@
namespace Tetraedge {
+class TeZPriorityMouseCallback : public TeCallback1Param<TeButtonLayout, const Common::Point &> {
+public:
+ TeZPriorityMouseCallback(TeButtonLayout *layout, TMethod method) : TeCallback1Param<TeButtonLayout, const Common::Point &>(layout, method), _pri(0.0) {}
+ virtual float &priority() override {
+ _pri =_object->position().z();
+ return _pri;
+ }
+ float _pri;
+};
+
/*static*/ bool TeButtonLayout::_mousePositionChangedCatched = false;
/*static*/ TeTimer *TeButtonLayout::_doubleValidationProtectionTimer = nullptr;
@@ -47,17 +57,17 @@ _hitZoneLayout(nullptr)
{
_onMousePositionChangedMaxPriorityCallback.reset(new TeCallback1Param<TeButtonLayout, const Common::Point &>(this, &TeButtonLayout::onMousePositionChangedMaxPriority, FLT_MAX));
- _onMousePositionChangedCallback.reset(new TeCallback1Param<TeButtonLayout, const Common::Point &>(this, &TeButtonLayout::onMousePositionChanged));
- _onMouseLeftDownCallback.reset(new TeCallback1Param<TeButtonLayout, const Common::Point &>(this, &TeButtonLayout::onMouseLeftDown));
+ _onMousePositionChangedCallback.reset(new TeZPriorityMouseCallback(this, &TeButtonLayout::onMousePositionChanged));
+ _onMouseLeftDownCallback.reset(new TeZPriorityMouseCallback(this, &TeButtonLayout::onMouseLeftDown));
_onMouseLeftUpMaxPriorityCallback.reset(new TeCallback1Param<TeButtonLayout, const Common::Point &>(this, &TeButtonLayout::onMouseLeftUpMaxPriority, FLT_MAX));
- _onMouseLeftUpCallback.reset(new TeCallback1Param<TeButtonLayout, const Common::Point &>(this, &TeButtonLayout::onMouseLeftUp));
+ _onMouseLeftUpCallback.reset(new TeZPriorityMouseCallback(this, &TeButtonLayout::onMouseLeftUp));
TeInputMgr *inputmgr = g_engine->getInputMgr();
- inputmgr->_mouseMoveSignal.insert(_onMousePositionChangedCallback);
- inputmgr->_mouseMoveSignal.insert(_onMousePositionChangedMaxPriorityCallback);
- inputmgr->_mouseLDownSignal.insert(_onMouseLeftDownCallback);
- inputmgr->_mouseLUpSignal.insert(_onMouseLeftUpCallback);
- inputmgr->_mouseLUpSignal.insert(_onMouseLeftUpMaxPriorityCallback);
+ inputmgr->_mouseMoveSignal.push_back(_onMousePositionChangedCallback);
+ inputmgr->_mouseMoveSignal.push_back(_onMousePositionChangedMaxPriorityCallback);
+ inputmgr->_mouseLDownSignal.push_back(_onMouseLeftDownCallback);
+ inputmgr->_mouseLUpSignal.push_back(_onMouseLeftUpCallback);
+ inputmgr->_mouseLUpSignal.push_back(_onMouseLeftUpMaxPriorityCallback);
setEditionColor(TeColor(128, 128, 128, 255));
if (!getDoubleValidationProtectionTimer()->running())
diff --git a/engines/tetraedge/te/te_checkbox_layout.cpp b/engines/tetraedge/te/te_checkbox_layout.cpp
index 0392205e0a7..0e1eed8682b 100644
--- a/engines/tetraedge/te/te_checkbox_layout.cpp
+++ b/engines/tetraedge/te/te_checkbox_layout.cpp
@@ -39,10 +39,10 @@ _clickPassThrough(false), _state(CheckboxState6)
_onMousePositionChangedCallback.reset(new TeCallback1Param<TeCheckboxLayout, const Common::Point &>(this, &TeCheckboxLayout::onMousePositionChanged));
TeInputMgr *inputmgr = g_engine->getInputMgr();
- inputmgr->_mouseMoveSignal.insert(_onMousePositionChangedCallback);
- inputmgr->_mouseLDownSignal.insert(_onMouseLeftDownCallback);
- inputmgr->_mouseLUpSignal.insert(_onMouseLeftUpCallback);
- inputmgr->_mouseLUpSignal.insert(_onMouseLeftUpMaxPriorityCallback);
+ inputmgr->_mouseMoveSignal.push_back(_onMousePositionChangedCallback);
+ inputmgr->_mouseLDownSignal.push_back(_onMouseLeftDownCallback);
+ inputmgr->_mouseLUpSignal.push_back(_onMouseLeftUpCallback);
+ inputmgr->_mouseLUpSignal.push_back(_onMouseLeftUpMaxPriorityCallback);
}
TeCheckboxLayout::~TeCheckboxLayout() {
diff --git a/engines/tetraedge/te/te_layout.cpp b/engines/tetraedge/te/te_layout.cpp
index be8ac7b36d2..f8e4e406e8b 100644
--- a/engines/tetraedge/te/te_layout.cpp
+++ b/engines/tetraedge/te/te_layout.cpp
@@ -64,7 +64,7 @@ TeLayout::~TeLayout() {
void TeLayout::addChild(Te3DObject2 *child) {
Te3DObject2::addChild(child);
if (_onChildSizeChangedCallback) {
- child->onSizeChanged().insert(_onChildSizeChangedCallback);
+ child->onSizeChanged().push_back(_onChildSizeChangedCallback);
}
_needZSizeUpdate = true;
_needZUpdate = true;
@@ -75,7 +75,7 @@ void TeLayout::addChild(Te3DObject2 *child) {
void TeLayout::addChildBefore(Te3DObject2 *child, const Te3DObject2 *ref) {
Te3DObject2::addChildBefore(child, ref);
if (_onChildSizeChangedCallback) {
- child->onSizeChanged().insert(_onChildSizeChangedCallback);
+ child->onSizeChanged().push_back(_onChildSizeChangedCallback);
}
_needZSizeUpdate = true;
_needZUpdate = true;
@@ -211,11 +211,11 @@ void TeLayout::setParent(Te3DObject2 *parent) {
Te3DObject2::setParent(parent);
if (parent) {
if (_onParentSizeChangedCallback)
- parent->onSizeChanged().insert(_onParentSizeChangedCallback);
+ parent->onSizeChanged().push_back(_onParentSizeChangedCallback);
if (_onParentWorldTransformationMatrixChangedCallback)
- parent->onWorldTransformationMatrixChanged().insert(_onParentWorldTransformationMatrixChangedCallback);
+ parent->onWorldTransformationMatrixChanged().push_back(_onParentWorldTransformationMatrixChangedCallback);
if (_onMainWindowChangedCallback)
- mainWindowLayout.onSizeChanged().insert(_onMainWindowChangedCallback);
+ mainWindowLayout.onSizeChanged().push_back(_onMainWindowChangedCallback);
}
_needZUpdate = true;
_sizeChanged = true;
diff --git a/engines/tetraedge/te/te_signal.h b/engines/tetraedge/te/te_signal.h
index 105c42b3199..ebad199faa3 100644
--- a/engines/tetraedge/te/te_signal.h
+++ b/engines/tetraedge/te/te_signal.h
@@ -28,23 +28,21 @@
namespace Tetraedge {
-template<class C> int _teCallbackSorter(const C &c1, const C &c2) {
+template<class C> bool _teCallbackSorter(const C &c1, const C &c2) {
+ // sort in *descending* priority.
float p1 = c1->priority();
float p2 = c2->priority();
- if (p1 < p2)
- return 1;
- else if (p1 == p2)
- return 0;
- return -1;
+ return p2 < p1;
}
typedef Common::SharedPtr<TeICallback0Param> TeICallback0ParamPtr;
-class TeSignal0Param : public Common::SortedArray<TeICallback0ParamPtr, const TeICallback0ParamPtr &> {
+class TeSignal0Param : public Common::Array<TeICallback0ParamPtr> {
public:
- TeSignal0Param() : Common::SortedArray<TeICallback0ParamPtr, const TeICallback0ParamPtr &>(_teCallbackSorter) {};
+ TeSignal0Param() : Common::Array<TeICallback0ParamPtr>() {};
bool call() {
+ Common::sort(this->begin(), this->end(), _teCallbackSorter<TeICallback0ParamPtr>);
typename Common::Array<TeICallback0ParamPtr>::iterator i = this->begin();
typename Common::Array<TeICallback0ParamPtr>::iterator end_ = this->end();
for (; i < end_; i++) {
@@ -66,7 +64,7 @@ public:
}
template<class T> void add(T *obj, typename TeCallback0Param<T>::TMethod method) {
- this->insert(TeICallback0ParamPtr(new TeCallback0Param<T>(obj, method)));
+ this->push_back(TeICallback0ParamPtr(new TeCallback0Param<T>(obj, method)));
}
template<class T> void remove(T *obj, typename TeCallback0Param<T>::TMethod method) {
@@ -80,11 +78,12 @@ public:
template<class T> using TeICallback1ParamPtr = Common::SharedPtr<TeICallback1Param<T>>;
/* Array of callbacks with a single parameter of type T */
-template<class T> class TeSignal1Param : public Common::SortedArray<TeICallback1ParamPtr<T>, const TeICallback1ParamPtr<T> &> {
+template<class T> class TeSignal1Param : public Common::Array<TeICallback1ParamPtr<T>> {
public:
- TeSignal1Param() : Common::SortedArray<TeICallback1ParamPtr<T>, const TeICallback1ParamPtr<T> &>(_teCallbackSorter) {};
+ TeSignal1Param() : Common::Array<TeICallback1ParamPtr<T>>() {};
bool call(T t) {
+ Common::sort(this->begin(), this->end(), _teCallbackSorter<TeICallback1ParamPtr<T>>);
typename Common::Array<TeICallback1ParamPtr<T>>::iterator i = this->begin();
typename Common::Array<TeICallback1ParamPtr<T>>::iterator end_ = this->end();
for (; i < end_; i++) {
@@ -106,7 +105,7 @@ public:
}
template<class S> void add(S *obj, typename TeCallback1Param<S, T>::TMethod method) {
- this->insert(TeICallback1ParamPtr<T>(new TeCallback1Param<S, T>(obj, method)));
+ this->push_back(TeICallback1ParamPtr<T>(new TeCallback1Param<S, T>(obj, method)));
}
template<class S> void remove(S *obj, typename TeCallback1Param<S, T>::TMethod method) {
@@ -119,11 +118,12 @@ public:
template<class S, class T> using TeICallback2ParamPtr = Common::SharedPtr<TeICallback2Param<S, T>>;
/* Array of callbacks with a two parameters of type T */
-template<class S, class T> class TeSignal2Param : public Common::SortedArray<TeICallback2ParamPtr<S, T>, const TeICallback2ParamPtr<S, T> &> {
+template<class S, class T> class TeSignal2Param : public Common::Array<TeICallback2ParamPtr<S, T>> {
public:
- TeSignal2Param() : Common::SortedArray<TeICallback2ParamPtr<S, T>, const TeICallback2ParamPtr<S, T> &>(_teCallbackSorter) {};
+ TeSignal2Param() : Common::Array<TeICallback2ParamPtr<S, T>>() {};
bool call(S s, T t) {
+ Common::sort(this->begin(), this->end(), _teCallbackSorter<TeICallback2ParamPtr<S, T>>);
typename Common::Array<TeICallback2ParamPtr<S, T>>::iterator i = this->begin();
typename Common::Array<TeICallback2ParamPtr<S, T>>::iterator end_ = this->end();
for (; i < end_; i++) {
@@ -145,7 +145,7 @@ public:
}
template<class C> void add(C *obj, typename TeCallback2Param<C, S, T>::TMethod method) {
- this->insert(TeICallback2ParamPtr<S, T>(new TeCallback2Param<C, S, T>(obj, method)));
+ this->push_back(TeICallback2ParamPtr<S, T>(new TeCallback2Param<C, S, T>(obj, method)));
}
template<class C> void remove(C *obj, typename TeCallback2Param<C, S, T>::TMethod method) {
Commit: a3eb8b9c1c3ca9d7143c7e72bd6d9d0341470080
https://github.com/scummvm/scummvm/commit/a3eb8b9c1c3ca9d7143c7e72bd6d9d0341470080
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2023-01-16T17:36:43+01:00
Commit Message:
TETRAEDGE: Fix inventory and other interactions
Changed paths:
engines/tetraedge/game/application.cpp
engines/tetraedge/game/character.cpp
engines/tetraedge/game/character.h
engines/tetraedge/game/dialog2.cpp
engines/tetraedge/game/game.cpp
engines/tetraedge/game/game.h
engines/tetraedge/game/in_game_scene.cpp
engines/tetraedge/game/in_game_scene.h
engines/tetraedge/game/inventory.cpp
engines/tetraedge/game/inventory.h
engines/tetraedge/game/lua_binds.cpp
engines/tetraedge/game/question2.cpp
engines/tetraedge/te/te_button_layout.cpp
engines/tetraedge/te/te_music.cpp
engines/tetraedge/te/te_music.h
diff --git a/engines/tetraedge/game/application.cpp b/engines/tetraedge/game/application.cpp
index eb7000ea85b..9055246d13e 100644
--- a/engines/tetraedge/game/application.cpp
+++ b/engines/tetraedge/game/application.cpp
@@ -393,16 +393,18 @@ void Application::drawFront() {
#if DUMP_LAYOUTS
static int renderCount = 0;
-static void dumpLayout(Te3DObject2 *layout, Common::String indent = "++") {
+static void dumpLayout(TeLayout *layout, Common::String indent = "++") {
assert(layout);
if (!layout->worldVisible())
return;
- debug("%s %s pos:%s worldPos:%s worldScale:%s size:%s col:%s", indent.c_str(), layout->name().c_str(),
- layout->position().dump().c_str(), layout->worldPosition().dump().c_str(),
- layout->worldScale().dump().c_str(), layout->size().dump().c_str(),
+ debug("%s %s pos:%s worldScale:%s userSize:%s size:%s col:%s", indent.c_str(), layout->name().c_str(),
+ layout->position().dump().c_str(), layout->worldScale().dump().c_str(),
+ layout->userSize().dump().c_str(), layout->size().dump().c_str(),
layout->color().dump().c_str());
for (auto & child: layout->childList()) {
- dumpLayout(child, indent + "++");
+ TeLayout *childLayout = dynamic_cast<TeLayout *>(child);
+ if (childLayout)
+ dumpLayout(childLayout, indent + "++");
}
}
#endif
@@ -523,11 +525,11 @@ void Application::lockCursorFromAction(bool lock) {
void Application::loadOptions(const Common::String &fname) {
// TODO: Maybe load options here - original uses an
// xml file but we would want confman.
- warning("TODO: Implement Application::loadOptions %s", fname.c_str());
+ debug("TODO: Implement Application::loadOptions %s", fname.c_str());
}
void Application::saveOptions(const Common::String &fname) {
- warning("TODO: Implement Application::saveOptions %s", fname.c_str());
+ debug("TODO: Implement Application::saveOptions %s", fname.c_str());
}
Common::String Application::getHelpText(const Common::String &key) {
diff --git a/engines/tetraedge/game/character.cpp b/engines/tetraedge/game/character.cpp
index a3cf7ab5da8..0b458c40f3a 100644
--- a/engines/tetraedge/game/character.cpp
+++ b/engines/tetraedge/game/character.cpp
@@ -59,7 +59,7 @@ void Character::WalkSettings::clear() {
}
Character::Character() : _walkCurveStart(0), _lastFrame(-1), _callbacksChanged(false),
-_notWalkAnim(false), _someRepeatFlag(false), _walkModeStr("Walk"),
+_notWalkAnim(false), _returnToIdleAnim(false), _walkModeStr("Walk"),
_needsSomeUpdate(false), _positionFlag(false), _lookingAtTallThing(false),
_stepSound1("sounds/SFX/PAS_H_BOIS1.ogg"), _stepSound2("sounds/SFX/PAS_H_BOIS2.ogg"),
_freeMoveZone(nullptr), _animSoundOffset(0), _lastAnimFrame(0), _charLookingAt(nullptr),
@@ -173,7 +173,7 @@ float Character::animLengthFromFile(const Common::String &animname, uint *pframe
return animLen * _model->scale().z();
}
-bool Character::blendAnimation(const Common::String &animname, float amount, bool repeat, bool param_4) {
+bool Character::blendAnimation(const Common::String &animname, float amount, bool repeat, bool returnToIdle) {
Common::Path animpath("models/Anims");
animpath.joinInPlace(animname);
@@ -197,7 +197,7 @@ bool Character::blendAnimation(const Common::String &animname, float amount, boo
_lastFrame = -1;
_curModelAnim->play();
_curAnimName = animname;
- _someRepeatFlag = !(repeat | !param_4);
+ _returnToIdleAnim = !repeat && returnToIdle;
return true;
}
@@ -567,9 +567,12 @@ bool Character::onModelAnimationFinished() {
_onCharacterAnimFinishedSignal.call(_model->name());
}
- if (_someRepeatFlag && loadedPath.toString().contains(_setAnimName)) {
+ Common::Path setAnimNamePath = _setAnimName;
+ Common::String setAnimNameFile = setAnimNamePath.getLastComponent().toString();
+ Common::String loadedPathFile = loadedPath.getLastComponent().toString();
+ if (_returnToIdleAnim && loadedPathFile.contains(setAnimNameFile)) {
_notWalkAnim = false;
- _someRepeatFlag = false;
+ _returnToIdleAnim = false;
setAnimation(_characterSettings._idleAnimFileName, true);
}
@@ -635,7 +638,7 @@ void Character::removeFromCurve() {
_curve.release();
}
-bool Character::setAnimation(const Common::String &aname, bool repeat, bool param_3, bool unused, int startFrame, int endFrame) {
+bool Character::setAnimation(const Common::String &aname, bool repeat, bool returnToIdle, bool unused, int startFrame, int endFrame) {
if (aname.empty())
return false;
@@ -663,7 +666,7 @@ bool Character::setAnimation(const Common::String &aname, bool repeat, bool para
_curModelAnim->play();
_setAnimName = aname;
_curAnimName = aname;
- _someRepeatFlag = !(repeat | !param_3);
+ _returnToIdleAnim = !repeat && returnToIdle;
return true;
}
diff --git a/engines/tetraedge/game/character.h b/engines/tetraedge/game/character.h
index e403bbfd098..19384586a7e 100644
--- a/engines/tetraedge/game/character.h
+++ b/engines/tetraedge/game/character.h
@@ -101,7 +101,7 @@ public:
float animLength(const TeModelAnimation &modelanim, long bone, long lastframe);
float animLengthFromFile(const Common::String &animname, uint *pframeCount, uint lastframe = 9999);
- bool blendAnimation(const Common::String &animname, float amount, bool repeat, bool param_4);
+ bool blendAnimation(const Common::String &animname, float amount, bool repeat, bool returnToIdle);
TeVector3f32 correctPosition(const TeVector3f32 &pos);
float curveOffset();
void deleteAllCallback();
@@ -127,7 +127,7 @@ public:
void removeFromCurve();
static Common::String rootBone() { return "Pere"; }
- bool setAnimation(const Common::String &name, bool repeat, bool param_3 = false, bool param_4 = false, int startFrame = -1, int endFrame = 9999);
+ bool setAnimation(const Common::String &name, bool repeat, bool returnToIdle = false, bool unused = false, int startFrame = -1, int endFrame = 9999);
void setAnimationSound(const Common::String &name, uint offset);
void setCurveOffset(float offset);
void setFreeMoveZone(TeFreeMoveZone *zone);
@@ -169,6 +169,7 @@ public:
const TeVector2f32 &headRotation() const { return _headRotation; }
void setHeadRotation(const TeVector2f32 &val) { _headRotation = val; }
void setLastHeadRotation(const TeVector2f32 &val) { _lastHeadRotation = val; }
+ const TeVector3f32 &lastHeadBoneTrans() const { return _lastHeadBoneTrans; }
Character *charLookingAt() { return _charLookingAt; }
bool lookingAtTallThing() const { return _lookingAtTallThing; }
void setLookingAtTallThing(bool val) { _lookingAtTallThing = val; }
@@ -215,7 +216,7 @@ private:
int _lastFrame;
int _lastAnimFrame;
bool _notWalkAnim;
- bool _someRepeatFlag; // TODO: what is this?
+ bool _returnToIdleAnim;
bool _callbacksChanged;
bool _needsSomeUpdate;
bool _positionFlag;
diff --git a/engines/tetraedge/game/dialog2.cpp b/engines/tetraedge/game/dialog2.cpp
index d583e0f3400..e0340bc0e59 100644
--- a/engines/tetraedge/game/dialog2.cpp
+++ b/engines/tetraedge/game/dialog2.cpp
@@ -99,6 +99,7 @@ void Dialog2::load() {
size(); // refresh size? seems to do nothing with result
_music.repeat(false);
_gui.load("menus/dialog.lua");
+ size(); // refresh size? seems to do nothing with result
TeButtonLayout *dialogLockBtn = _gui.buttonLayoutChecked("dialogLockButton");
dialogLockBtn->setVisible(false);
@@ -149,7 +150,7 @@ bool Dialog2::onMinimumTimeTimer() {
bool Dialog2::onSkipButton() {
const TeCurveAnim2<TeLayout,TeVector3f32> *dialogAnimUp = _gui.layoutAnchorLinearAnimation("dialogAnimationUp");
- if (dialogAnimUp->_runTimer.running()) {
+ if (!dialogAnimUp->_runTimer.running()) {
const TeCurveAnim2<TeLayout,TeVector3f32> *dialogAnimDown = _gui.layoutAnchorLinearAnimation("dialogAnimationDown");
if (!dialogAnimDown->_runTimer.running()) {
startDownAnimation();
diff --git a/engines/tetraedge/game/game.cpp b/engines/tetraedge/game/game.cpp
index 1eda0a2f4d5..ff4faee4042 100644
--- a/engines/tetraedge/game/game.cpp
+++ b/engines/tetraedge/game/game.cpp
@@ -515,6 +515,8 @@ bool Game::initWarp(const Common::String &zone, const Common::String &scene, boo
TeLayout *bg = _forGui.layout("background");
bg->setRatioMode(TeILayout::RATIO_MODE_NONE);
app->_frontLayout.addChild(bg);
+ // Note: Game also adds cellphone to both frontLayout *and* noScaleLayout2,
+ // so we reproduce the broken behavior exactly.
TeLayout *cellbg = _inventory.cellphone()->gui().buttonLayout("background");
app->_frontLayout.removeChild(cellbg);
app->_frontLayout.addChild(cellbg);
@@ -587,7 +589,7 @@ bool Game::initWarp(const Common::String &zone, const Common::String &scene, boo
addNoScale2Children();
if (!fadeFlag) {
if (_inventory.selectedObject().size()) {
- _inventory.selectedObject(*_inventory.selectedInventoryObject());
+ _inventory.selectedObject(_inventory.selectedInventoryObject());
}
_inventory.setVisible(false);
_objectif.setVisibleObjectif(false);
@@ -626,7 +628,6 @@ bool Game::initWarp(const Common::String &zone, const Common::String &scene, boo
_luaScript.execute("OnSelectedObject", _inventory.selectedObject());
}
-
for (unsigned int i = 0; i < _gameSounds.size(); i++) {
if (_gameSounds[i]->retain())
continue;
@@ -1366,10 +1367,10 @@ bool Game::setBackground(const Common::String &name) {
return _scene.changeBackground(name);
}
-void Game::setCurrentObjectSprite(const Common::String &spritePath) {
+void Game::setCurrentObjectSprite(const Common::Path &spritePath) {
TeSpriteLayout *currentSprite = _inGameGui.spriteLayout("currentObjectSprite");
if (currentSprite) {
- if (!spritePath.empty()) {
+ if (spritePath.empty()) {
currentSprite->unload();
} else {
currentSprite->load(spritePath);
diff --git a/engines/tetraedge/game/game.h b/engines/tetraedge/game/game.h
index 7d19600e196..866bebb30c8 100644
--- a/engines/tetraedge/game/game.h
+++ b/engines/tetraedge/game/game.h
@@ -152,7 +152,7 @@ public:
void resumeSounds() {}; // does nothing?
void saveBackup(const Common::String &saveName);
bool setBackground(const Common::String &name);
- void setCurrentObjectSprite(const Common::String &spritePath);
+ void setCurrentObjectSprite(const Common::Path &spritePath);
bool showMarkers(bool val);
bool startAnimation(const Common::String &animName, int loopcount, bool reversed);
void startAnimationPart(const Common::String ¶m_1, int param_2, int param_3, int param_4, bool param_5) {};
@@ -185,6 +185,7 @@ public:
Dialog2 &dialog2() { return _dialog2; }
Question2 &question2() { return _question2; }
TeLuaGUI &forGui() { return _forGui; }
+ TeLuaGUI &inGameGui() { return _inGameGui; }
Objectif &objectif() { return _objectif; }
Common::Array<YieldedCallback> &yieldedCallbacks() { return _yieldedCallbacks; }
void setSaveRequested() { _saveRequested = true; }
diff --git a/engines/tetraedge/game/in_game_scene.cpp b/engines/tetraedge/game/in_game_scene.cpp
index bfd7d0251ab..2db2f4e6e3e 100644
--- a/engines/tetraedge/game/in_game_scene.cpp
+++ b/engines/tetraedge/game/in_game_scene.cpp
@@ -467,13 +467,25 @@ void InGameScene::freeSceneObjects() {
}
float InGameScene::getHeadHorizontalRotation(Character *cter, const TeVector3f32 &vec) {
- //TeVector3f32 pos = cter->_model->position() - vec;
- error("TODO: Implement InGameScene::getHeadHorizontalRotation");
+ TeVector3f32 pos = vec - cter->_model->position();
+ TeVector3f32 zvec = TeVector3f32(0, 0, 1.0f);
+ zvec.rotate(cter->_model->rotation());
+ float angle = atan2f(-pos.x(), pos.z()) - atan2f(-zvec.x(), zvec.z());
+ if (angle < -M_PI)
+ angle += (M_PI * 2);
+ else if (angle > M_PI)
+ angle -= (M_PI * 2);
+ return angle;
}
float InGameScene::getHeadVerticalRotation(Character *cter, const TeVector3f32 &vec) {
- //TeVector3f32 pos = cter->_model->position() - vec;
- error("TODO: Implement InGameScene::getHeadVerticalRotation");
+ TeVector3f32 modelPos = cter->_model->position();
+ TeVector3f32 headWorldTrans = cter->_model->worldTransformationMatrix() * cter->lastHeadBoneTrans();
+ modelPos.y() = headWorldTrans.y();
+ TeVector3f32 offsetPos = vec - modelPos;
+ currentCamera()->apply();
+ float angle = atan2f(offsetPos.y(), TeVector2f32(offsetPos.x(), offsetPos.z()).length());
+ return angle;
}
Common::String InGameScene::imagePathMarker(const Common::String &name) {
@@ -948,7 +960,7 @@ void InGameScene::setPositionCharacter(const Common::String &charName, const Com
const TeVector3f32 corrected = zone->correctCharacterPosition(position, &correctFlag, true);
c->_model->setPosition(corrected);
if (!correctFlag)
- error("[SetCharacterPosition] Warning : The character is not above the ground %s", charName.c_str());
+ warning("[SetCharacterPosition] Warning : The character is not above the ground %s", charName.c_str());
}
}
@@ -1038,9 +1050,9 @@ void InGameScene::update() {
TeVector2f32 headRot(getHeadHorizontalRotation(_character, targetpos),
getHeadVerticalRotation(_character, targetpos));
float hangle = headRot.getX() * 180.0 / M_PI;
- if (hangle > 90)
+ if (hangle > 90.0f)
headRot.setX(M_PI_2);
- else if (hangle < -90)
+ else if (hangle < -90.0f)
headRot.setX(-M_PI_2);
_character->setHeadRotation(headRot);
_character->setHasAnchor(true);
@@ -1101,7 +1113,21 @@ void InGameScene::update() {
bool InGameScene::AnimObject::onFinished() {
- error("TODO: Implement InGameScene::AnimObject::onFinished");
+ Game *game = g_engine->getGame();
+ for (unsigned int i = 0; i < game->yieldedCallbacks().size(); i++) {
+ Game::YieldedCallback &yc = game->yieldedCallbacks()[i];
+ if (yc._luaFnName == "OnFinishedAnim" && yc._luaParam == _name) {
+ TeLuaThread *thread = yc._luaThread;
+ game->yieldedCallbacks().remove_at(i);
+ if (thread) {
+ thread->resume();
+ return false;
+ }
+ break;
+ }
+ }
+ game->luaScript().execute("OnFinishedAnim", _name);
+ return false;
}
} // end namespace Tetraedge
diff --git a/engines/tetraedge/game/in_game_scene.h b/engines/tetraedge/game/in_game_scene.h
index c70f0e8c57e..a9527ce74cd 100644
--- a/engines/tetraedge/game/in_game_scene.h
+++ b/engines/tetraedge/game/in_game_scene.h
@@ -195,6 +195,8 @@ public:
Common::Array<TeRectBlocker> &rectBlockers() { return _rectBlockers; }
Common::Array<TeBlocker> &blockers() { return _blockers; }
Common::Array<Object3D *> object3Ds() { return _object3Ds; }
+ void setWaitTime(float usecs) { _waitTime = usecs; }
+ TeTimer &waitTimeTimer() { return _waitTimeTimer; }
private:
TeColor _shadowColor;
diff --git a/engines/tetraedge/game/inventory.cpp b/engines/tetraedge/game/inventory.cpp
index 292360c9e0e..a342b2749c7 100644
--- a/engines/tetraedge/game/inventory.cpp
+++ b/engines/tetraedge/game/inventory.cpp
@@ -52,7 +52,7 @@ void Inventory::enter() {
}
if (_selectedObject)
- selectedObject(*_selectedObject);
+ selectedObject(_selectedObject);
}
void Inventory::leave() {
@@ -149,19 +149,18 @@ void Inventory::unload() {
while (true) {
const Common::String slotStr = Common::String::format("page%dSlot%d", pageNo, slotNo);
TeLayout *slotLayout = _gui.layout(slotStr);
- if (slotLayout) {
- // Take a copy of the list as we may be deleting some
- // and that removes them from the parent.
- Common::Array<Te3DObject2 *> children = slotLayout->childList();
- for (Te3DObject2 *child : children) {
- InventoryObject *invObj = dynamic_cast<InventoryObject *>(child);
- if (invObj)
- delete invObj;
- }
- slotNo++;
- } else {
+ if (!slotLayout)
break;
+
+ // Take a copy of the list as we may be deleting some
+ // and that removes them from the parent.
+ Common::Array<Te3DObject2 *> children = slotLayout->childList();
+ for (Te3DObject2 *child : children) {
+ InventoryObject *invObj = dynamic_cast<InventoryObject *>(child);
+ if (invObj)
+ delete invObj;
}
+ slotNo++;
}
pageNo++;
} else {
@@ -189,14 +188,14 @@ bool Inventory::addObject(InventoryObject *obj) {
_invObjects.push_front(obj);
obj->selectedSignal().add(this, &Inventory::onObjectSelected);
if (_invObjects.size() > 1) {
- int pageno = 0;
+ int pageNo = 0;
while (true) {
- TeLayout *page = _gui.layout(Common::String::format("page%d", pageno));
- int slotno = 0;
+ TeLayout *page = _gui.layout(Common::String::format("page%d", pageNo));
+ int slotNo = 0;
if (!page)
break;
while (true) {
- TeLayout *slot = _gui.layout(Common::String::format("page%dSlot%d", pageno, slotno));
+ TeLayout *slot = _gui.layout(Common::String::format("page%dSlot%d", pageNo, slotNo));
if (!slot)
break;
for (unsigned int c = 0; c < slot->childCount(); c++) {
@@ -207,9 +206,9 @@ bool Inventory::addObject(InventoryObject *obj) {
c--;
}
}
- slotno++;
+ slotNo++;
}
- pageno++;
+ pageNo++;
}
}
@@ -242,7 +241,7 @@ bool Inventory::addObject(InventoryObject *obj) {
newText->setSize(TeVector3f32(1.0,1.0,0.0));
newText->setTextSizeType(1);
newText->setTextSizeProportionalToWidth(200);
- newText->setText(_gui.value("textAttributs").toString() + (*invObjIter)->name());
+ newText->setText(_gui.value("textAttributs").toString() + objectName((*invObjIter)->name()));
newText->setName((*invObjIter)->name());
newText->setVisible(false);
@@ -294,7 +293,7 @@ bool Inventory::onMainMenuButton() {
}
bool Inventory::onObjectSelected(InventoryObject &obj) {
- selectedObject(obj);
+ selectedObject(&obj);
if (_selectedTimer.running()) {
if (_selectedTimer.timeElapsed() < 300000)
g_engine->getGame()->inventoryMenu().leave();
@@ -350,11 +349,48 @@ void Inventory::unPauseAnims() {
}
void Inventory::removeObject(const Common::String &objname) {
- error("TODO: implement Inventory::removeObject");
+ int pageNo = 0;
+ bool retval;
+ bool finished = false;
+ while (!finished) {
+ TeLayout *page = _gui.layout(Common::String::format("page%d", pageNo));
+ retval = false;
+ if (!page)
+ break;
+ int slotNo = 0;
+ while (true) {
+ const Common::String slotStr = Common::String::format("page%dSlot%d", pageNo, slotNo);
+ TeLayout *slotLayout = _gui.layout(slotStr);
+ if (!slotLayout)
+ break;
+
+ for (Te3DObject2 *child : slotLayout->childList()) {
+ InventoryObject *childObj = dynamic_cast<InventoryObject *>(child);
+ if (childObj && childObj->name() == objname) {
+ if (_selectedObject == childObj)
+ selectedObject(nullptr);
+ for (auto &invObj : _invObjects) {
+ if (invObj->name() == objname) {
+ _invObjects.remove(invObj);
+ break;
+ }
+ }
+ delete childObj;
+ updateLayout();
+ return;
+ }
+ }
+ slotNo++;
+ }
+ pageNo++;
+ }
}
void Inventory::removeSelectedObject() {
- error("TODO: implement Inventory::removeSelectedObject");
+ if (_selectedObject) {
+ removeObject(_selectedObject->name());
+ selectedObject(nullptr);
+ }
}
InventoryObject *Inventory::selectedInventoryObject() {
@@ -362,11 +398,45 @@ InventoryObject *Inventory::selectedInventoryObject() {
}
void Inventory::selectedObject(const Common::String &objname) {
- error("TODO: implement Inventory::selectedObject");
+ error("TODO: implement Inventory::selectedObject('%s')", objname.c_str());
}
-void Inventory::selectedObject(InventoryObject &obj) {
- error("TODO: implement Inventory::selectedObject");
+void Inventory::selectedObject(InventoryObject *obj) {
+ Game *game = g_engine->getGame();
+ game->setCurrentObjectSprite("");
+ _gui.layoutChecked("prendre")->setVisible(false);
+ _gui.layoutChecked("textObject")->setVisible(false);
+ _selectedObject = obj;
+ if (!obj) {
+ _gui.spriteLayoutChecked("selectionSprite")->setVisible(false);
+ _gui.textLayout("text")->setText("");
+ game->inGameGui().spriteLayoutChecked("selectedObject")->unload();
+ } else {
+ TeSpriteLayout *selection = _gui.spriteLayoutChecked("selectionSprite");
+ selection->setVisible(obj->worldVisible());
+ TeLayout *parentLayout = dynamic_cast<TeLayout *>(obj->parent());
+ TeVector3f32 pos = parentLayout->position();
+ pos.z() = selection->position().z();
+ selection->setPosition(pos);
+ const Common::String &objId = obj->name();
+ static const char *textStyle = "<section style=\"center\" /><color r=\"200\" g=\"200\" b=\"200\"/><font file=\"Common/Fonts/Colaborate-Regular.otf\" size=\"24\" />";
+ Common::String text = Common::String::format("%s%s<br/>%s", textStyle,
+ objectName(objId).c_str(),
+ objectDescription(objId).c_str());
+ _gui.textLayout("text")->setText(text);
+ _gui.buttonLayoutChecked("lire")->setEnable(isDocument(objId));
+ game->setCurrentObjectSprite(obj->spritePath());
+ TeLayout *textObj = _gui.layout("textObject");
+ for (unsigned int i = 0; i < textObj->childCount(); i++) {
+ if (textObj->child(i)->name() == obj->name()) {
+ textObj->setVisible(true);
+ textObj->child(i)->setVisible(true);
+ } else {
+ textObj->child(i)->setVisible(false);
+ }
+ }
+ game->inGameGui().spriteLayoutChecked("selectedObject")->load(obj->spritePath());
+ }
}
const Common::String &Inventory::selectedObject() {
@@ -378,7 +448,53 @@ const Common::String &Inventory::selectedObject() {
}
bool Inventory::updateLayout() {
- error("TODO: implement Inventory::updateLayout");
+ int pageNo = 0;
+ bool finished = false;
+ while (!finished) {
+ TeLayout *page = _gui.layout(Common::String::format("page%d", pageNo));
+ if (!page)
+ break;
+ int slotNo = 0;
+ while (true) {
+ const Common::String slotStr = Common::String::format("page%dSlot%d", pageNo, slotNo);
+ TeLayout *slotLayout = _gui.layout(slotStr);
+ if (!slotLayout)
+ break;
+
+ // Take a copy of the list as we are deleting some
+ // and that removes them from the parent's list.
+ Common::Array<Te3DObject2 *> children = slotLayout->childList();
+ for (Te3DObject2 *child : children) {
+ InventoryObject *invObj = dynamic_cast<InventoryObject *>(child);
+ if (invObj)
+ slotLayout->removeChild(child);
+ }
+ slotNo++;
+ }
+ pageNo++;
+ }
+
+ pageNo = 0;
+ auto invObjIter = _invObjects.begin();
+ while (!finished) {
+ TeLayout *page = _gui.layout(Common::String::format("page%d", pageNo));
+ if (!page)
+ break;
+ int slotNo = 0;
+ while (true) {
+ const Common::String slotStr = Common::String::format("page%dSlot%d", pageNo, slotNo);
+ TeLayout *slotLayout = _gui.layout(slotStr);
+ if (!slotLayout)
+ break;
+ slotLayout->addChild(*invObjIter);
+ invObjIter++;
+ slotNo++;
+ if (invObjIter == _invObjects.end())
+ return true;
+ }
+ pageNo++;
+ }
+ return false;
}
diff --git a/engines/tetraedge/game/inventory.h b/engines/tetraedge/game/inventory.h
index 9743a8609d3..1a4b4ac04ac 100644
--- a/engines/tetraedge/game/inventory.h
+++ b/engines/tetraedge/game/inventory.h
@@ -73,7 +73,7 @@ public:
InventoryObject *selectedInventoryObject();
void selectedObject(const Common::String &objname);
- void selectedObject(InventoryObject &obj);
+ void selectedObject(InventoryObject *obj);
const Common::String &selectedObject();
bool updateLayout();
diff --git a/engines/tetraedge/game/lua_binds.cpp b/engines/tetraedge/game/lua_binds.cpp
index bd15a0e3128..c4b156bcba6 100644
--- a/engines/tetraedge/game/lua_binds.cpp
+++ b/engines/tetraedge/game/lua_binds.cpp
@@ -165,6 +165,37 @@ static int tolua_ExportedFunctions_TakeObject00(lua_State *L) {
error("#ferror in function 'TakeObject': %d %d %s", err.index, err.array, err.type);
}
+static void RemoveObject(const Common::String &obj) {
+ Game *game = g_engine->getGame();
+ game->inventory().removeObject(obj);
+}
+
+static int tolua_ExportedFunctions_RemoveObject00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isnoobj(L, 2, &err)) {
+ Common::String s1(tolua_tostring(L, 1, nullptr));
+ RemoveObject(s1);
+ return 0;
+ }
+ error("#ferror in function 'RemoveObject': %d %d %s", err.index, err.array, err.type);
+}
+
+static void RemoveObject() {
+ Game *game = g_engine->getGame();
+ game->inventory().removeSelectedObject();
+}
+
+static int tolua_ExportedFunctions_RemoveObject01(lua_State *L) {
+ tolua_Error err;
+ if (!tolua_isnoobj(L, 1, &err)) {
+ tolua_ExportedFunctions_RemoveObject00(L);
+ } else {
+ RemoveObject();
+ }
+ return 0;
+}
+
+
static void AddNumber(const Common::String &number) {
Game *game = g_engine->getGame();
if (!game->inventory().cellphone()->addNumber(number))
@@ -281,6 +312,45 @@ static int tolua_ExportedFunctions_MoveCharacterPlayerDisabled00(lua_State *L) {
error("#ferror in function 'MoveCharacterPlayerDisabled': %d %d %s", err.index, err.array, err.type);
}
+static void SetRunMode(bool run) {
+ Game *game = g_engine->getGame();
+ game->scene()._character->walkMode(run ? "Jog" : "Walk");
+}
+
+static int tolua_ExportedFunctions_SetRunMode00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isboolean(L, 1, 0, &err) && tolua_isnoobj(L, 2, &err)) {
+ SetRunMode(tolua_toboolean(L, 1, 0));
+ return 0;
+ }
+ error("#ferror in function 'SetRunMode': %d %d %s", err.index, err.array, err.type);
+}
+
+static void SetRunMode2(const Common::String &charName, const Common::String &mode) {
+ Game *game = g_engine->getGame();
+ Character *character = game->scene().character(charName);
+ if (character == game->scene()._character)
+ return;
+
+ if (character) {
+ character->walkMode(mode);
+ } else {
+ debug("[SetRunMode2] Character not found %s", charName.c_str());
+ }
+}
+
+static int tolua_ExportedFunctions_SetRunMode200(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isstring(L, 2, 0, &err)
+ && tolua_isnoobj(L, 3, &err)) {
+ Common::String s1(tolua_tostring(L, 1, nullptr));
+ Common::String s2(tolua_tostring(L, 2, nullptr));
+ SetRunMode2(s1, s2);
+ return 0;
+ }
+ error("#ferror in function 'AddMarker': %d %d %s", err.index, err.array, err.type);
+}
+
static void AddCallback(const Common::String &charName, const Common::String &animName, const Common::String &fnName, float triggerFrame, float maxCalls) {
Game *game = g_engine->getGame();
Character *c = game->scene().character(charName);
@@ -411,6 +481,27 @@ static int tolua_ExportedFunctions_RequestAutoSave00(lua_State *L) {
return 0;
}
+static void SetVisibleButtonZoomed(bool val) {
+ Game *game = g_engine->getGame();
+ TeButtonLayout *btn = game->scene().hitObjectGui().buttonLayout("DeZoomedButton");
+ if (!btn) {
+ debug("[SetVisibleButtonZoomed] No \"DeZoomedButton\" in this scene");
+ } else {
+ btn->setVisible(val);
+ }
+}
+
+static int tolua_ExportedFunctions_SetVisibleButtonZoomed00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isboolean(L, 1, 0, &err) && tolua_isnoobj(L, 2, &err)) {
+ bool b1 = tolua_toboolean(L, 1, 0);
+ SetVisibleButtonZoomed(b1);
+ return 0;
+ }
+ error("#ferror in function 'SetVisibleButtonZoomed': %d %d %s", err.index, err.array, err.type);
+
+}
+
static void HideObject(const Common::String &objName) {
Game *game = g_engine->getGame();
TeIntrusivePtr<TeModel> model = game->scene().model(objName);
@@ -419,14 +510,14 @@ static void HideObject(const Common::String &objName) {
return;
}
- debug("[HideObject] Object 3D \"%s\" doesn't exist.", objName.c_str());
+ //debug("[HideObject] Object 3D \"%s\" doesn't exist.", objName.c_str());
TeLayout *layout = game->scene().bgGui().layout(objName);
if (layout) {
layout->setVisible(false);
return;
}
- debug("[HideObject] \"Set\" Object 2D \"%s\" doesn't exist.", objName.c_str());
+ //debug("[HideObject] \"Set\" Object 2D \"%s\" doesn't exist.", objName.c_str());
layout = game->forGui().layout(objName);
if (layout) {
layout->setVisible(false);
@@ -454,14 +545,14 @@ static void ShowObject(const Common::String &objName) {
return;
}
- debug("[ShowObject] Object 3D \"%s\" doesn't exist.", objName.c_str());
+ //debug("[ShowObject] Object 3D \"%s\" doesn't exist.", objName.c_str());
TeLayout *layout = game->scene().bgGui().layout(objName);
if (layout) {
layout->setVisible(true);
return;
}
- debug("[ShowObject] \"Set\" Object 2D \"%s\" doesn't exist.", objName.c_str());
+ //debug("[ShowObject] \"Set\" Object 2D \"%s\" doesn't exist.", objName.c_str());
layout = game->forGui().layout(objName);
if (layout) {
layout->setVisible(true);
@@ -520,7 +611,6 @@ static void PlaceCharacterOnDummy(const Common::String &charname, const Common::
} else {
warning("[PlaceCharacterOnDummy] Character not found %s", charname.c_str());
}
-
}
static int tolua_ExportedFunctions_PlaceCharacterOnDummy00(lua_State *L) {
@@ -590,11 +680,11 @@ static int tolua_ExportedFunctions_SetCharacterOrientation00(lua_State *L) {
error("#ferror in function 'SetCharacterOrientation': %d %d %s", err.index, err.array, err.type);
}
-static void SetCharacterAnimation(const Common::String &charname, const Common::String &animname, bool repeat, bool b2, int i1, int i2) {
+static void SetCharacterAnimation(const Common::String &charname, const Common::String &animname, bool repeat, bool b2, int startframe, int endframe) {
Game *game = g_engine->getGame();
Character *c = game->scene().character(charname);
assert(c);
- bool result = c->setAnimation(animname, repeat, b2, false, i1, i2);
+ bool result = c->setAnimation(animname, repeat, b2, false, startframe, endframe);
if (!result) {
warning("[SetCharacterAnimation] Character's animation \"%s\" doesn't exist for the character\"%s\" ",
animname.c_str(), charname.c_str());
@@ -889,7 +979,8 @@ static void HideBillboard(const Common::String &name) {
Game *game = g_engine->getGame();
Billboard *bb = game->scene().billboard(name);
if (!bb) {
- error("[HideBillboard] Billboard not found %s", name.c_str());
+ warning("[HideBillboard] Billboard not found %s", name.c_str());
+ return;
}
bb->model()->setVisible(false);
}
@@ -904,6 +995,47 @@ static int tolua_ExportedFunctions_HideBillboard00(lua_State *L) {
error("#ferror in function 'HideBillboard': %d %d %s", err.index, err.array, err.type);
}
+
+static void Wait(float seconds) {
+ Game *game = g_engine->getGame();
+ game->scene().waitTimeTimer().start();
+ game->scene().waitTimeTimer().stop();
+ game->scene().waitTimeTimer().start();
+ game->scene().setWaitTime(seconds * 1000000.0);
+}
+
+static int tolua_ExportedFunctions_Wait00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isnumber(L, 1, 0, &err) && tolua_isnoobj(L, 2, &err)) {
+ double d = tolua_tonumber(L, 1, 0.0);
+ Wait(d);
+ return 0;
+ }
+ error("#ferror in function 'Wait': %d %d %s", err.index, err.array, err.type);
+}
+
+static int tolua_ExportedFunctions_WaitAndWaitForEnd00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isnumber(L, 1, 0, &err) && tolua_isnoobj(L, 2, &err)) {
+ double d = tolua_tonumber(L, 1, 0.0);
+ Wait(d);
+
+ Game::YieldedCallback callback;
+ callback._luaThread = TeLuaThread::threadFromState(L);
+ callback._luaFnName = "OnWaitFinished";
+
+ Game *game = g_engine->getGame();
+ for (const auto &cb : game->yieldedCallbacks()) {
+ if (cb._luaFnName == callback._luaFnName)
+ error("WaitAndWaitForEnd: Reentrency error, your are already in a yielded/sync function call");
+ }
+
+ game->yieldedCallbacks().push_back(callback);
+ return callback._luaThread->yield();
+ }
+ error("#ferror in function 'WaitAndWaitForEnd': %d %d %s", err.index, err.array, err.type);
+}
+
static void SetBackground(const Common::String &name) {
Game *game = g_engine->getGame();
if (!game->setBackground(name))
@@ -1703,7 +1835,7 @@ void LuaOpenBinds(lua_State *L) {
tolua_ExportedFunctions_StartAnimationAndWaitForEnd00); */
// tolua_function(L, "AddAnimToSet", tolua_ExportedFunctions_AddAnimToSet00); // Unused
tolua_function(L, "RequestAutoSave", tolua_ExportedFunctions_RequestAutoSave00);
- /*tolua_function(L, "SetVisibleButtonZoomed", tolua_ExportedFunctions_SetVisibleButtonZoomed00);*/
+ tolua_function(L, "SetVisibleButtonZoomed", tolua_ExportedFunctions_SetVisibleButtonZoomed00);
tolua_function(L, "AddMarker", tolua_ExportedFunctions_AddMarker00);
tolua_function(L, "SetVisibleMarker", tolua_ExportedFunctions_SetVisibleMarker00);
tolua_function(L, "DeleteMarker", tolua_ExportedFunctions_DeleteMarker00);
@@ -1732,8 +1864,8 @@ void LuaOpenBinds(lua_State *L) {
tolua_function(L, "Selected", tolua_ExportedFunctions_Selected00);
tolua_function(L, "TakeObject", tolua_ExportedFunctions_TakeObject00);
// tolua_function(L, "TakeObjectInHand", tolua_ExportedFunctions_TakeObjectInHand00); // Unused
- /*tolua_function(L, "RemoveObject", tolua_ExportedFunctions_RemoveObject00);
- tolua_function(L, "RemoveObject", tolua_ExportedFunctions_RemoveObject01);*/
+ tolua_function(L, "RemoveObject", tolua_ExportedFunctions_RemoveObject00);
+ tolua_function(L, "RemoveObject", tolua_ExportedFunctions_RemoveObject01);
tolua_function(L, "AddNumber", tolua_ExportedFunctions_AddNumber00);
tolua_function(L, "ShowDocument", tolua_ExportedFunctions_ShowDocument00);
// tolua_function(L, "ShowDocumentAndWaitForEnd", tolua_ExportedFunctions_ShowDocumentAndWaitForEnd00); // Unused
@@ -1766,8 +1898,8 @@ void LuaOpenBinds(lua_State *L) {
tolua_function(L, "SetCharacterPlayerVisible", tolua_ExportedFunctions_SetCharacterPlayerVisible00);
tolua_function(L, "MoveCharacterPlayerDisabled",
tolua_ExportedFunctions_MoveCharacterPlayerDisabled00);
- /*tolua_function(L, "SetRunMode", tolua_ExportedFunctions_SetRunMode00);
- tolua_function(L, "SetRunMode2", tolua_ExportedFunctions_SetRunMode200); */
+ tolua_function(L, "SetRunMode", tolua_ExportedFunctions_SetRunMode00);
+ tolua_function(L, "SetRunMode2", tolua_ExportedFunctions_SetRunMode200);
// tolua_function(L, "SetCharacterColor", tolua_ExportedFunctions_SetCharacterColor00); // Unused
// tolua_function(L, "SetCharacterSound", tolua_ExportedFunctions_SetCharacterSound00); // Unused
/*tolua_function(L, "SetCharacterShadow", tolua_ExportedFunctions_SetCharacterShadow00);*/
@@ -1801,9 +1933,9 @@ void LuaOpenBinds(lua_State *L) {
tolua_function(L, "ShowBillboard", tolua_ExportedFunctions_ShowBillboard00);
tolua_function(L, "HideBillboard", tolua_ExportedFunctions_HideBillboard00);
/*tolua_function(L, "UnlockAchievement", tolua_ExportedFunctions_UnlockAchievement00);
- tolua_function(L, "Save", tolua_ExportedFunctions_Save00);
+ tolua_function(L, "Save", tolua_ExportedFunctions_Save00);*/
tolua_function(L, "Wait", tolua_ExportedFunctions_Wait00);
- tolua_function(L, "WaitAndWaitForEnd", tolua_ExportedFunctions_WaitAndWaitForEnd00); */
+ tolua_function(L, "WaitAndWaitForEnd", tolua_ExportedFunctions_WaitAndWaitForEnd00);
// tolua_function(L, "OpenFinalURL", tolua_ExportedFunctions_OpenFinalURL00); // Unused
/*tolua_function(L, "FinishGame", tolua_ExportedFunctions_FinishGame00);
tolua_function(L, "RequestMainMenu", tolua_ExportedFunctions_RequestMainMenu00);*/
diff --git a/engines/tetraedge/game/question2.cpp b/engines/tetraedge/game/question2.cpp
index 356e3df2f88..469578fbb5a 100644
--- a/engines/tetraedge/game/question2.cpp
+++ b/engines/tetraedge/game/question2.cpp
@@ -67,6 +67,7 @@ void Question2::leave() {
}
void Question2::load() {
+ // TODO: set field_0xd0 = 0
setName("dialog2");
setSizeType(RELATIVE_TO_PARENT);
const TeVector3f32 usersz = userSize();
@@ -78,6 +79,7 @@ void Question2::load() {
addChild(backgroundButton);
backgroundButton->setVisible(false);
}
+ size();
}
bool Question2::onAnswerValidated(Answer &answer) {
@@ -91,10 +93,7 @@ void Question2::pushAnswer(const Common::String &name, const Common::String &loc
Answer *answer = new Answer();
answer->load(name, locName, path);
answer->_onButtonValidatedSignal.add(this, &Question2::onAnswerValidated);
- TeLayout *alayout = answer->layout();
- if (!alayout)
- error("No Answer layout after loading %s!", path.c_str());
- TeButtonLayout *blayout = dynamic_cast<TeButtonLayout *>(alayout);
+ TeButtonLayout *blayout = dynamic_cast<TeButtonLayout *>(answer->layout());
if (!blayout)
error("No Answer button layout after loading %s!", path.c_str());
@@ -102,24 +101,24 @@ void Question2::pushAnswer(const Common::String &name, const Common::String &loc
_answers.push_back(answer);
float xpos;
+ blayout->setSizeType(RELATIVE_TO_PARENT);
blayout->setPositionType(RELATIVE_TO_PARENT);
if (!path.contains("Cal_FIN.lua")) {
- setSize(TeVector3f32(0.45f, 0.065f, 1.0f));
+ blayout->setSize(TeVector3f32(0.45f, 0.065f, 1.0f));
xpos = 0.3f;
} else {
- setSize(TeVector3f32(0.15f, 0.065f, 1.0f));
+ blayout->setSize(TeVector3f32(0.15f, 0.065f, 1.0f));
xpos = 0.15f;
}
- setPosition(TeVector3f32(xpos, _answers.size() * 0.08f + 0.06f, 1.0f));
+ blayout->setPosition(TeVector3f32(xpos, _answers.size() * 0.08f + 0.06f, 1.0f));
blayout->_upLayout->setSizeType(RELATIVE_TO_PARENT);
blayout->_upLayout->setSize(TeVector3f32(1.0f, 1.0f, 1.0f));
blayout->_downLayout->setSizeType(RELATIVE_TO_PARENT);
blayout->_downLayout->setSize(TeVector3f32(1.0f, 1.0f, 1.0f));
- TeSpriteLayout *calepinLayout = _gui.spriteLayout("Calepin");
- if (calepinLayout)
- calepinLayout->addChild(alayout);
+ TeSpriteLayout *calepinLayout = _gui.spriteLayoutChecked("Calepin");
+ calepinLayout->addChild(blayout);
enter();
}
diff --git a/engines/tetraedge/te/te_button_layout.cpp b/engines/tetraedge/te/te_button_layout.cpp
index ecc10794d76..977bd535bc8 100644
--- a/engines/tetraedge/te/te_button_layout.cpp
+++ b/engines/tetraedge/te/te_button_layout.cpp
@@ -33,7 +33,7 @@ class TeZPriorityMouseCallback : public TeCallback1Param<TeButtonLayout, const C
public:
TeZPriorityMouseCallback(TeButtonLayout *layout, TMethod method) : TeCallback1Param<TeButtonLayout, const Common::Point &>(layout, method), _pri(0.0) {}
virtual float &priority() override {
- _pri =_object->position().z();
+ _pri =_object->worldPosition().z();
return _pri;
}
float _pri;
diff --git a/engines/tetraedge/te/te_music.cpp b/engines/tetraedge/te/te_music.cpp
index 6651f8727ed..38ee93a16e6 100644
--- a/engines/tetraedge/te/te_music.cpp
+++ b/engines/tetraedge/te/te_music.cpp
@@ -82,7 +82,7 @@ bool TeMusic::play() {
soundType = Audio::Mixer::kMusicSoundType;
}
- debug("playing %s on channel %s at vol %d", _actualPath.toString().c_str(), _channelName.c_str(), vol);
+ //debug("playing %s on channel %s at vol %d", _actualPath.toString().c_str(), _channelName.c_str(), vol);
mixer->playStream(soundType, &_sndHandle, stream, -1, vol);
_sndHandleValid = true;
_isPaused = false;
diff --git a/engines/tetraedge/te/te_music.h b/engines/tetraedge/te/te_music.h
index 4180f6370de..041c97594fb 100644
--- a/engines/tetraedge/te/te_music.h
+++ b/engines/tetraedge/te/te_music.h
@@ -65,7 +65,7 @@ public:
float volume();
TeSignal0Param &onStopSignal() { return _onStopSignal; }
-
+
void setRetain(bool retain) { _retain = retain; }
bool retain() const { return _retain; }
Commit: 61e35200676c0bc545546d7dbfa75bf9ce8c5ac0
https://github.com/scummvm/scummvm/commit/61e35200676c0bc545546d7dbfa75bf9ce8c5ac0
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2023-01-16T17:36:43+01:00
Commit Message:
TETRAEDGE: More WIP. Fixed various object problems.
Changed paths:
engines/tetraedge/game/cellphone.h
engines/tetraedge/game/character.cpp
engines/tetraedge/game/document.h
engines/tetraedge/game/game.cpp
engines/tetraedge/game/in_game_scene.cpp
engines/tetraedge/game/inventory.cpp
engines/tetraedge/game/inventory.h
engines/tetraedge/game/inventory_menu.h
engines/tetraedge/game/lua_binds.cpp
engines/tetraedge/game/object3d.cpp
engines/tetraedge/game/object_settings_xml_parser.cpp
engines/tetraedge/game/object_settings_xml_parser.h
engines/tetraedge/te/te_image.cpp
engines/tetraedge/te/te_music.cpp
engines/tetraedge/te/te_music.h
diff --git a/engines/tetraedge/game/cellphone.h b/engines/tetraedge/game/cellphone.h
index 35c5e68f067..e4f93031621 100644
--- a/engines/tetraedge/game/cellphone.h
+++ b/engines/tetraedge/game/cellphone.h
@@ -36,6 +36,7 @@ namespace Tetraedge {
class Cellphone : public TeLayout {
public:
Cellphone();
+ virtual ~Cellphone() {}
bool addNumber(const Common::String &num);
void currentPage(int offset);
diff --git a/engines/tetraedge/game/character.cpp b/engines/tetraedge/game/character.cpp
index 0b458c40f3a..18f1b483459 100644
--- a/engines/tetraedge/game/character.cpp
+++ b/engines/tetraedge/game/character.cpp
@@ -27,6 +27,7 @@
#include "tetraedge/tetraedge.h"
#include "tetraedge/game/character.h"
+#include "tetraedge/game/application.h"
#include "tetraedge/game/game.h"
#include "tetraedge/game/character_settings_xml_parser.h"
#include "tetraedge/te/te_model_animation.h"
@@ -421,19 +422,20 @@ bool Character::onBonesUpdate(const Common::String &boneName, TeMatrix4x4 &boneM
bool resetX = false;
if (game->scene()._character == this) {
for (const auto &walkSettings : _characterSettings._walkSettings) {
- resetX |= (walkSettings._key.contains("Walk") || walkSettings._key.contains("Jog"));
- resetX |= (walkSettings._value._walkParts[0]._file == animfile ||
- walkSettings._value._walkParts[1]._file == animfile ||
- walkSettings._value._walkParts[2]._file == animfile ||
- walkSettings._value._walkParts[3]._file == animfile);
+ if (walkSettings._key.contains("Walk") || walkSettings._key.contains("Jog")) {
+ resetX |= (walkSettings._value._walkParts[0]._file.contains(animfile)
+ || walkSettings._value._walkParts[1]._file.contains(animfile)
+ || walkSettings._value._walkParts[2]._file.contains(animfile)
+ || walkSettings._value._walkParts[3]._file.contains(animfile));
+ }
}
- resetX |= animfile.contains(_characterSettings._idleAnimFileName);
+ resetX |= _characterSettings._idleAnimFileName.contains(animfile);
} else {
- resetX = (animfile.contains(_characterSettings._idleAnimFileName) ||
- animfile.contains(walkAnim(WalkPart_Start)) ||
- animfile.contains(walkAnim(WalkPart_Loop)) ||
- animfile.contains(walkAnim(WalkPart_EndD)) ||
- animfile.contains(walkAnim(WalkPart_EndG)));
+ resetX = (_characterSettings._idleAnimFileName.contains(animfile) ||
+ walkAnim(WalkPart_Start).contains(animfile) ||
+ walkAnim(WalkPart_Loop).contains(animfile) ||
+ walkAnim(WalkPart_EndD).contains(animfile) ||
+ walkAnim(WalkPart_EndG).contains(animfile));
}
if (resetX) {
boneMatrix.setValue(0, 3, 0.0f);
@@ -516,7 +518,11 @@ bool Character::onModelAnimationFinished() {
const Common::Path loadedPath = _model->anim()->_loadedPath;
const Common::String animfile = loadedPath.getLastComponent().toString();
- // TODO: Do something with _unrecalAnims here.
+ bool shouldAdjust = true;
+ for (const auto &unrecal : g_engine->getApplication()->unrecalAnims()) {
+ if (animfile.contains(unrecal))
+ shouldAdjust = false;
+ }
Game *game = g_engine->getGame();
bool isWalkAnim = false;
@@ -538,7 +544,7 @@ bool Character::onModelAnimationFinished() {
animfile.contains(walkAnim(WalkPart_EndG)));
}
- if (!isWalkAnim) {
+ if (!isWalkAnim && shouldAdjust) {
int pereBone = _curModelAnim->findBone("Pere");
const TeTRS endTRS = trsFromAnim(*_curModelAnim, pereBone, _curModelAnim->lastFrame());
TeVector3f32 trans = endTRS.getTranslation();
diff --git a/engines/tetraedge/game/document.h b/engines/tetraedge/game/document.h
index 688fb029381..307e1f4f882 100644
--- a/engines/tetraedge/game/document.h
+++ b/engines/tetraedge/game/document.h
@@ -34,7 +34,7 @@ class DocumentsBrowser;
class Document : public TeLayout {
public:
Document(DocumentsBrowser *browser);
- ~Document() {
+ virtual ~Document() {
unload();
if (parent()) {
parent()->removeChild(this);
diff --git a/engines/tetraedge/game/game.cpp b/engines/tetraedge/game/game.cpp
index ff4faee4042..ab688078ca8 100644
--- a/engines/tetraedge/game/game.cpp
+++ b/engines/tetraedge/game/game.cpp
@@ -636,7 +636,6 @@ bool Game::initWarp(const Common::String &zone, const Common::String &scene, boo
_gameSounds.remove_at(i);
i--;
}
- _gameSounds.clear();
for (auto &randsoundlist : _randomSounds) {
for (auto *randsound : randsoundlist._value) {
@@ -669,7 +668,7 @@ static const char *DIALOG_IDS[20] = {
"KFJ", "KM", "KN", "KFM"};
bool Game::launchDialog(const Common::String &dname, uint param_2, const Common::String &charname,
- const Common::String &animfile, float param_5) {
+ const Common::String &animfile, float animblend) {
Application *app = g_engine->getApplication();
const Common::String *locdname = app->_loc.value(dname);
if (!locdname)
@@ -684,7 +683,7 @@ bool Game::launchDialog(const Common::String &dname, uint param_2, const Common:
}
const Common::String sndfile = dname + ".ogg";
- _dialog2.pushDialog(dname, *locdname, sndfile, charname, animfile, param_5);
+ _dialog2.pushDialog(dname, *locdname, sndfile, charname, animfile, animblend);
return true;
}
@@ -698,7 +697,7 @@ void Game::leave(bool flag) {
_notifier.unload();
g_engine->getInputMgr()->_mouseLUpSignal.remove(this, &Game::onMouseClick);
_question2.unload();
- _inventory.cellphone()->unload();
+ _inventory.cellphone()->leave();
_dialog2.unload();
_inventory.unload();
_documentsBrowser.unload();
@@ -779,12 +778,12 @@ bool Game::loadScene(const Common::String &name) {
}
bool Game::onAnswered(const Common::String &val) {
- _luaScript.execute("OnAnswered", TeVariant(val));
+ _luaScript.execute("OnAnswered", val);
return false;
}
bool Game::onCallNumber(Common::String val) {
- _luaScript.execute("OnCallNumber", TeVariant(val));
+ _luaScript.execute("OnCallNumber", val);
return false;
}
@@ -1290,7 +1289,8 @@ void Game::playSound(const Common::String &name, int repeats, float volume) {
}
} else if (repeats == -1) {
for (GameSound *snd : _gameSounds) {
- if (snd->getAccessName() == name) {
+ const Common::String accessName = snd->getAccessName().toString();
+ if (accessName == name) {
snd->setRetain(true);
return;
}
@@ -1401,11 +1401,12 @@ bool Game::startAnimation(const Common::String &animName, int loopcount, bool re
void Game::stopSound(const Common::String &name) {
for (unsigned int i = 0; i < _gameSounds.size(); i++) {
GameSound *sound = _gameSounds[i];
- if (sound->getAccessName() == name) {
+ if (sound->rawPath() == name) {
sound->stop();
sound->deleteLater();
+ _gameSounds.remove_at(i);
+ break;
}
- _gameSounds.remove_at(i);
}
g_engine->getSoundManager()->stopFreeSound(name);
}
@@ -1511,7 +1512,7 @@ void Game::update() {
Common::Array<Character *> characters = _scene._characters;
for (Character *c : characters) {
- if (!c->_model->anim().get())
+ if (c->_model->anim())
c->permanentUpdate();
}
@@ -1529,7 +1530,12 @@ void Game::update() {
_objectif.update();
_scene.update();
} else {
- warning("TODO: Game::update: Stop sounds before warping");
+ TeSoundManager *soundmgr = g_engine->getSoundManager();
+ for (auto &music : soundmgr->musics()) {
+ const Common::String &chanName = music->channelName();
+ if (chanName != "music" && chanName != "sfx" && chanName != "dialog")
+ music->stop();
+ }
changeWarp2(_warpZone, _warpScene, _warpFadeFlag);
}
}
diff --git a/engines/tetraedge/game/in_game_scene.cpp b/engines/tetraedge/game/in_game_scene.cpp
index 2db2f4e6e3e..651edb984cb 100644
--- a/engines/tetraedge/game/in_game_scene.cpp
+++ b/engines/tetraedge/game/in_game_scene.cpp
@@ -702,6 +702,7 @@ bool InGameScene::loadObject(const Common::String &name) {
if (!obj) {
obj = new Object3D();
if (!obj->loadModel(name)) {
+ warning("InGameScene::loadObject: Loading %s failed", name.c_str());
delete obj;
return false;
}
@@ -713,11 +714,25 @@ bool InGameScene::loadObject(const Common::String &name) {
}
bool InGameScene::loadObjectMaterials(const Common::String &name) {
- error("TODO: InGameScene::loadObjectMaterials");
+ TeImage img;
+ bool retval = false;
+ for (auto &obj : _objects) {
+ if (obj._name.empty())
+ continue;
+
+ Common::Path mpath = _loadedPath.getParent().join(name).join(obj._name + ".png");
+ if (img.load(mpath)) {
+ Te3DTexture *tex = new Te3DTexture();
+ tex->load(img);
+ obj._model->_meshes[0].defaultMaterial(tex);
+ retval = true;
+ }
+ }
+ return retval;
}
bool InGameScene::loadObjectMaterials(const Common::String &path, const Common::String &name) {
- error("TODO: InGameScene::loadObjectMaterials");
+ error("TODO: InGameScene::loadObjectMaterials(%s, %s)", path.c_str(), name.c_str());
}
bool InGameScene::loadPlayerCharacter(const Common::String &name) {
@@ -1086,6 +1101,8 @@ void InGameScene::update() {
float waitTime = _waitTimeTimer.timeFromLastTimeElapsed();
if (_waitTime != -1.0 && waitTime > _waitTime) {
+ _waitTime = -1.0;
+ _waitTimeTimer.stop();
bool resumed = false;
for (unsigned int i = 0; i < game->yieldedCallbacks().size(); i++) {
Game::YieldedCallback &yc = game->yieldedCallbacks()[i];
diff --git a/engines/tetraedge/game/inventory.cpp b/engines/tetraedge/game/inventory.cpp
index a342b2749c7..45cffe2cf24 100644
--- a/engines/tetraedge/game/inventory.cpp
+++ b/engines/tetraedge/game/inventory.cpp
@@ -167,6 +167,7 @@ void Inventory::unload() {
break;
}
}
+ _gui.unload();
}
void Inventory::loadCellphone() {
@@ -369,9 +370,9 @@ void Inventory::removeObject(const Common::String &objname) {
if (childObj && childObj->name() == objname) {
if (_selectedObject == childObj)
selectedObject(nullptr);
- for (auto &invObj : _invObjects) {
- if (invObj->name() == objname) {
- _invObjects.remove(invObj);
+ for (auto iter = _invObjects.begin(); iter != _invObjects.end(); iter++) {
+ if ((*iter)->name() == objname) {
+ _invObjects.erase(iter);
break;
}
}
diff --git a/engines/tetraedge/game/inventory.h b/engines/tetraedge/game/inventory.h
index 1a4b4ac04ac..a6d88901ea8 100644
--- a/engines/tetraedge/game/inventory.h
+++ b/engines/tetraedge/game/inventory.h
@@ -40,6 +40,7 @@ public:
};
Inventory();
+ virtual ~Inventory() {}
void enter();
void leave();
diff --git a/engines/tetraedge/game/inventory_menu.h b/engines/tetraedge/game/inventory_menu.h
index 349a2a6105c..4225207df6d 100644
--- a/engines/tetraedge/game/inventory_menu.h
+++ b/engines/tetraedge/game/inventory_menu.h
@@ -29,6 +29,7 @@ namespace Tetraedge {
class InventoryMenu : public TeLayout {
public:
InventoryMenu();
+ virtual ~InventoryMenu() {}
void enter();
void leave();
diff --git a/engines/tetraedge/game/lua_binds.cpp b/engines/tetraedge/game/lua_binds.cpp
index c4b156bcba6..5d7747c38de 100644
--- a/engines/tetraedge/game/lua_binds.cpp
+++ b/engines/tetraedge/game/lua_binds.cpp
@@ -71,7 +71,7 @@ static int tolua_ExportedFunctions_LoadObjectMaterials01(lua_State *L) {
LoadObjectMaterials(s1, s2);
return 0;
}
- error("#ferror in function 'LoadObjectMaterials': %d %d %s", err.index, err.array, err.type);
+ return tolua_ExportedFunctions_LoadObjectMaterials00(L);
}
@@ -374,7 +374,29 @@ static int tolua_ExportedFunctions_AddCallback00(lua_State *L) {
AddCallback(s1, s2, s3, n1, n2);
return 0;
}
- error("#ferror in function 'AddMarker': %d %d %s", err.index, err.array, err.type);
+ error("#ferror in function 'AddCallback': %d %d %s", err.index, err.array, err.type);
+}
+
+static void AddCallbackPlayer(const Common::String &animName, const Common::String &fnName, float triggerFrame, float maxCalls) {
+ Game *game = g_engine->getGame();
+ Character *c = game->scene()._character;
+ assert(c);
+ c->addCallback(animName, fnName, triggerFrame, maxCalls);
+}
+
+static int tolua_ExportedFunctions_AddCallbackPlayer00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isstring(L, 2, 0, &err)
+ && tolua_isnumber(L, 3, 0, &err) && tolua_isnumber(L, 4, 1, &err)
+ && tolua_isnoobj(L, 5, &err)) {
+ Common::String s2(tolua_tostring(L, 1, nullptr));
+ Common::String s3(tolua_tostring(L, 2, nullptr));
+ double n1 = tolua_tonumber(L, 3, 0.0);
+ double n2 = tolua_tonumber(L, 4, -1.0);
+ AddCallbackPlayer(s2, s3, n1, n2);
+ return 0;
+ }
+ error("#ferror in function 'AddCallbackPlayer': %d %d %s", err.index, err.array, err.type);
}
static void AddMarker(const Common::String &markerName, const Common::String &imgPath, float x, float y,
@@ -722,18 +744,19 @@ static int tolua_ExportedFunctions_SetCharacterAnimationAndWaitForEnd00(lua_Stat
double f3 = tolua_tonumber(L, 5, -1.0);
double f4 = tolua_tonumber(L, 6, 9999.0);
SetCharacterAnimation(s1, s2, b1, b2, (int)f3, (int)f4);
- Game::YieldedCallback cb;
- cb._luaFnName = "OnCharacterAnimationFinished";
- cb._luaParam = s1;
- cb._luaParam2 = s2;
- cb._luaThread = TeLuaThread::threadFromState(L);
+
+ Game::YieldedCallback callback;
+ callback._luaThread = TeLuaThread::threadFromState(L);
+ callback._luaFnName = "OnCharacterAnimationFinished";
+ callback._luaParam = s1;
+ callback._luaParam2 = s2;
Game *game = g_engine->getGame();
- for (const auto &gamecb : game->yieldedCallbacks()) {
- if (gamecb._luaFnName == cb._luaFnName && gamecb._luaParam == s1 && gamecb._luaParam2 == s2)
+ for (const auto &cb : game->yieldedCallbacks()) {
+ if (cb._luaFnName == callback._luaFnName && cb._luaParam == s1 && cb._luaParam2 == s2)
error("SetCharacterAnimationAndWaitForEnd: Reentrency error, your are already in a yielded/sync function call");
}
- game->yieldedCallbacks().push_back(cb);
- return cb._luaThread->yield();
+ game->yieldedCallbacks().push_back(callback);
+ return callback._luaThread->yield();
}
error("#ferror in function 'SetCharacterAnimationAndWaitForEnd': %d %d %s", err.index, err.array, err.type);
}
@@ -776,18 +799,18 @@ static int tolua_ExportedFunctions_BlendCharacterAnimationAndWaitForEnd00(lua_St
bool b2 = tolua_toboolean(L, 5, 0);
BlendCharacterAnimation(s1, s2, f1, b1, b2);
- Game::YieldedCallback cb;
- cb._luaFnName = "OnCharacterAnimationFinished";
- cb._luaParam = s1;
- cb._luaParam2 = s2;
- cb._luaThread = TeLuaThread::threadFromState(L);
+ Game::YieldedCallback callback;
+ callback._luaThread = TeLuaThread::threadFromState(L);
+ callback._luaFnName = "OnCharacterAnimationFinished";
+ callback._luaParam = s1;
+ callback._luaParam2 = s2;
Game *game = g_engine->getGame();
- for (const auto &gamecb : game->yieldedCallbacks()) {
- if (gamecb._luaFnName == cb._luaFnName && gamecb._luaParam == s1 && gamecb._luaParam2 == s2)
+ for (const auto &cb : game->yieldedCallbacks()) {
+ if (cb._luaFnName == callback._luaFnName && cb._luaParam == s1 && cb._luaParam2 == s2)
error("BlendCharacterAnimationAndWaitForEnd: Reentrency error, your are already in a yielded/sync function call");
}
- game->yieldedCallbacks().push_back(cb);
- return cb._luaThread->yield();
+ game->yieldedCallbacks().push_back(callback);
+ return callback._luaThread->yield();
}
error("#ferror in function 'BlendCharacterAnimationAndWaitForEnd': %d %d %s", err.index, err.array, err.type);
}
@@ -1023,13 +1046,11 @@ static int tolua_ExportedFunctions_WaitAndWaitForEnd00(lua_State *L) {
Game::YieldedCallback callback;
callback._luaThread = TeLuaThread::threadFromState(L);
callback._luaFnName = "OnWaitFinished";
-
Game *game = g_engine->getGame();
for (const auto &cb : game->yieldedCallbacks()) {
if (cb._luaFnName == callback._luaFnName)
error("WaitAndWaitForEnd: Reentrency error, your are already in a yielded/sync function call");
}
-
game->yieldedCallbacks().push_back(callback);
return callback._luaThread->yield();
}
@@ -1053,10 +1074,10 @@ static int tolua_ExportedFunctions_SetBackground00(lua_State *L) {
}
static void LaunchDialog(const Common::String &name, uint param_2, const Common::String &charname,
- const Common::String &animfile, float param_5) {
+ const Common::String &animfile, float animblend) {
Game *game = g_engine->getGame();
- if (!game->launchDialog(name, param_2, charname, animfile, param_5))
+ if (!game->launchDialog(name, param_2, charname, animfile, animblend))
warning("[LaunchDialog] Dialog \"%s\" doesn't exist.", name.c_str());
}
@@ -1092,13 +1113,11 @@ static int tolua_ExportedFunctions_LaunchDialogAndWaitForEnd00(lua_State *L) {
callback._luaThread = TeLuaThread::threadFromState(L);
callback._luaFnName = "OnDialogFinished";
callback._luaParam = s1;
-
Game *game = g_engine->getGame();
for (const auto &cb : game->yieldedCallbacks()) {
if (cb._luaFnName == callback._luaFnName && cb._luaParam == callback._luaParam)
error("LaunchDialogAndWaitForEnd: Reentrency error, your are already in a yielded/sync function call");
}
-
game->yieldedCallbacks().push_back(callback);
return callback._luaThread->yield();
}
@@ -1477,17 +1496,18 @@ static int tolua_ExportedFunctions_PlaySoundAndWaitForEnd00(lua_State *L) {
double d1 = tolua_tonumber(L, 2, -1.0);
double d2 = tolua_tonumber(L, 3, 1.0);
PlaySound(s1, d1, d2);
- Game::YieldedCallback cb;
- cb._luaFnName = "OnFreeSoundFinished";
- cb._luaParam = s1;
- cb._luaThread = TeLuaThread::threadFromState(L);
+
+ Game::YieldedCallback callback;
+ callback._luaThread = TeLuaThread::threadFromState(L);
+ callback._luaFnName = "OnFreeSoundFinished";
+ callback._luaParam = s1;
Game *game = g_engine->getGame();
- for (const auto &gamecb : game->yieldedCallbacks()) {
- if (gamecb._luaFnName == cb._luaFnName && gamecb._luaParam == s1)
+ for (const auto &cb : game->yieldedCallbacks()) {
+ if (cb._luaFnName == callback._luaFnName && cb._luaParam == s1)
error("PlaySoundAndWaitForEnd: Reentrency error, your are already in a yielded/sync function call");
}
- game->yieldedCallbacks().push_back(cb);
- return cb._luaThread->yield();
+ game->yieldedCallbacks().push_back(callback);
+ return callback._luaThread->yield();
}
error("#ferror in function 'PlaySoundAndWaitForEnd': %d %d %s", err.index, err.array, err.type);
}
@@ -1540,11 +1560,11 @@ static int tolua_ExportedFunctions_PlayMusic00(lua_State *L) {
error("#ferror in function 'PlayMusic': %d %d %s", err.index, err.array, err.type);
}
-static void SetObjectOnCharacter(const Common::String &charName, const Common::String &obj, const Common::String &boneName) {
+static void SetObjectOnCharacter(const Common::String &charName, const Common::String &objName, const Common::String &boneName) {
Game *game = g_engine->getGame();
- Object3D *obj3d = game->scene().object3D(obj);
+ Object3D *obj3d = game->scene().object3D(objName);
if (!obj3d) {
- warning("[SetObjectOnCharacter] Object not found %s", obj.c_str());
+ warning("[SetObjectOnCharacter] Object not found %s", objName.c_str());
return;
}
@@ -1554,7 +1574,8 @@ static void SetObjectOnCharacter(const Common::String &charName, const Common::S
static int tolua_ExportedFunctions_SetObjectOnCharacter00(lua_State *L) {
tolua_Error err;
- if (tolua_isstring(L, 1, 0, &err) && tolua_isstring(L, 2, 0, &err) && tolua_isstring(L, 3, 0, &err) && tolua_isnoobj(L, 4, &err)) {
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isstring(L, 2, 0, &err)
+ && tolua_isstring(L, 3, 0, &err) && tolua_isnoobj(L, 4, &err)) {
Common::String s1(tolua_tostring(L, 1, nullptr));
Common::String s2(tolua_tostring(L, 2, nullptr));
Common::String s3(tolua_tostring(L, 3, nullptr));
@@ -1739,16 +1760,17 @@ static int tolua_ExportedFunctions_MoveCharacterToAndWaitForEnd00(lua_State *L)
float f1 = tolua_tonumber(L, 3, 0.0);
float f2 = tolua_tonumber(L, 4, 0.0);
MoveCharacterTo(s1, s2, f1, f2);
- Game::YieldedCallback cb;
- cb._luaFnName = "OnDisplacementFinished";
- cb._luaThread = TeLuaThread::threadFromState(L);
+
+ Game::YieldedCallback callback;
+ callback._luaThread = TeLuaThread::threadFromState(L);
+ callback._luaFnName = "OnDisplacementFinished";
Game *game = g_engine->getGame();
- for (const auto &gamecb : game->yieldedCallbacks()) {
- if (gamecb._luaFnName == cb._luaFnName)
+ for (const auto &cb : game->yieldedCallbacks()) {
+ if (cb._luaFnName == callback._luaFnName)
error("MoveCharacterToAndWaitForEnd: Reentrency error, your are already in a yielded/sync function call");
}
- game->yieldedCallbacks().push_back(cb);
- return cb._luaThread->yield();
+ game->yieldedCallbacks().push_back(callback);
+ return callback._luaThread->yield();
}
error("#ferror in function 'MoveCharacterToAndWaitForEnd': %d %d %s", err.index, err.array, err.type);
}
@@ -1904,7 +1926,7 @@ void LuaOpenBinds(lua_State *L) {
// tolua_function(L, "SetCharacterSound", tolua_ExportedFunctions_SetCharacterSound00); // Unused
/*tolua_function(L, "SetCharacterShadow", tolua_ExportedFunctions_SetCharacterShadow00);*/
tolua_function(L, "AddCallback", tolua_ExportedFunctions_AddCallback00);
- /*tolua_function(L, "AddCallbackPlayer", tolua_ExportedFunctions_AddCallbackPlayer00); */
+ tolua_function(L, "AddCallbackPlayer", tolua_ExportedFunctions_AddCallbackPlayer00);
// tolua_function(L, "AddCallbackAnimation2D", tolua_ExportedFunctions_AddCallbackAnimation2D00); // Unused
// tolua_function(L, "DeleteCallback", tolua_ExportedFunctions_DeleteCallback00); // Unused
// tolua_function(L, "DeleteCallbackPlayer", tolua_ExportedFunctions_DeleteCallbackPlayer00); // Unused
diff --git a/engines/tetraedge/game/object3d.cpp b/engines/tetraedge/game/object3d.cpp
index 9b676a57ee0..44981d8aae9 100644
--- a/engines/tetraedge/game/object3d.cpp
+++ b/engines/tetraedge/game/object3d.cpp
@@ -66,6 +66,7 @@ bool Object3D::loadSettings(const Common::String &path) {
error("Object3D::loadSettings: Can't load %s", path.c_str());
if (!parser.parse())
error("Object3D::loadSettings: Can't parse %s", path.c_str());
+ parser.finalize();
return true;
}
diff --git a/engines/tetraedge/game/object_settings_xml_parser.cpp b/engines/tetraedge/game/object_settings_xml_parser.cpp
index 88259dc3d14..d5d617212b8 100644
--- a/engines/tetraedge/game/object_settings_xml_parser.cpp
+++ b/engines/tetraedge/game/object_settings_xml_parser.cpp
@@ -29,13 +29,18 @@ bool ObjectSettingsXmlParser::parserCallback_ObjectsSettings(ParserNode *node) {
}
bool ObjectSettingsXmlParser::parserCallback_Object(ParserNode *node) {
+ // Save the last object.
+ _objectSettings->setVal(_curObject._name, _curObject);
const Common::String &objname = node->values["name"];
- _curObject._name = objname;
- _objectSettings->setVal(objname, _curObject);
_curObject.clear();
+ _curObject._name = objname;
return true;
}
+void ObjectSettingsXmlParser::finalize() {
+ _objectSettings->setVal(_curObject._name, _curObject);
+}
+
bool ObjectSettingsXmlParser::parserCallback_modelFileName(ParserNode *node) {
_textTagType = TagModelFileName;
return true;
diff --git a/engines/tetraedge/game/object_settings_xml_parser.h b/engines/tetraedge/game/object_settings_xml_parser.h
index 6328f814041..a6d7c244078 100644
--- a/engines/tetraedge/game/object_settings_xml_parser.h
+++ b/engines/tetraedge/game/object_settings_xml_parser.h
@@ -34,6 +34,8 @@ public:
_objectSettings = settings;
}
+ void finalize();
+
// Parser
CUSTOM_XML_PARSER(ObjectSettingsXmlParser) {
XML_KEY(ObjectsSettings)
diff --git a/engines/tetraedge/te/te_image.cpp b/engines/tetraedge/te/te_image.cpp
index e834c50304d..ca974f4fb04 100644
--- a/engines/tetraedge/te/te_image.cpp
+++ b/engines/tetraedge/te/te_image.cpp
@@ -94,7 +94,8 @@ bool TeImage::load(const Common::Path &path) {
TeCore *core = g_engine->getCore();
TeICodec *codec = core->createVideoCodec(path);
if (!codec->load(path)) {
- error("TeImage::load: Failed to load %s.", path.toString().c_str());
+ warning("TeImage::load: Failed to load %s.", path.toString().c_str());
+ return false;
}
Common::SharedPtr<TePalette> nullpal;
diff --git a/engines/tetraedge/te/te_music.cpp b/engines/tetraedge/te/te_music.cpp
index 38ee93a16e6..c7ba5010e9a 100644
--- a/engines/tetraedge/te/te_music.cpp
+++ b/engines/tetraedge/te/te_music.cpp
@@ -70,7 +70,7 @@ bool TeMusic::play() {
}
Audio::AudioStream *stream = Audio::makeVorbisStream(streamfile, DisposeAfterUse::YES);
byte vol = round(_volume * 255.0);
- int channelId = _channelName.hash();
+ //int channelId = _channelName.hash();
Audio::Mixer *mixer = g_system->getMixer();
Audio::Mixer::SoundType soundType = Audio::Mixer::kPlainSoundType;
@@ -204,6 +204,8 @@ void TeMusic::update() {
hasStopped = true;
if (hasStopped) {
+ g_system->getMixer()->stopHandle(_sndHandle);
+ _sndHandle = Audio::SoundHandle();
_isPaused = false;
_isPlaying = false;
_sndHandleValid = false;
diff --git a/engines/tetraedge/te/te_music.h b/engines/tetraedge/te/te_music.h
index 041c97594fb..c05793f0f98 100644
--- a/engines/tetraedge/te/te_music.h
+++ b/engines/tetraedge/te/te_music.h
@@ -59,6 +59,9 @@ public:
void setChannelName(const Common::String &name) {
_channelName = name;
}
+ const Common::String &channelName() const {
+ return _channelName;
+ }
void setFilePath(const Common::String &name);
void update();
void volume(float vol);
@@ -69,6 +72,8 @@ public:
void setRetain(bool retain) { _retain = retain; }
bool retain() const { return _retain; }
+ const Common::String &rawPath() { return _rawPath; }
+
private:
Common::String _rawPath; // Plain name of file requested
Common::Path _actualPath; // actual path after finding it
Commit: e3aff0967403ec0c5c85b2ef90deed4faa14595b
https://github.com/scummvm/scummvm/commit/e3aff0967403ec0c5c85b2ef90deed4faa14595b
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2023-01-16T17:36:43+01:00
Commit Message:
TETRAEDGE: Lua bind functions now complete.
Also fixed pathfinding a little.
Changed paths:
engines/tetraedge/game/in_game_scene.h
engines/tetraedge/game/lua_binds.cpp
engines/tetraedge/te/te_free_move_zone.cpp
engines/tetraedge/te/te_free_move_zone.h
diff --git a/engines/tetraedge/game/in_game_scene.h b/engines/tetraedge/game/in_game_scene.h
index a9527ce74cd..17fb23d1698 100644
--- a/engines/tetraedge/game/in_game_scene.h
+++ b/engines/tetraedge/game/in_game_scene.h
@@ -197,6 +197,7 @@ public:
Common::Array<Object3D *> object3Ds() { return _object3Ds; }
void setWaitTime(float usecs) { _waitTime = usecs; }
TeTimer &waitTimeTimer() { return _waitTimeTimer; }
+ Common::Array<TeLight> &lights() { return _lights; }
private:
TeColor _shadowColor;
diff --git a/engines/tetraedge/game/lua_binds.cpp b/engines/tetraedge/game/lua_binds.cpp
index 5d7747c38de..f6efcc25c64 100644
--- a/engines/tetraedge/game/lua_binds.cpp
+++ b/engines/tetraedge/game/lua_binds.cpp
@@ -74,7 +74,6 @@ static int tolua_ExportedFunctions_LoadObjectMaterials01(lua_State *L) {
return tolua_ExportedFunctions_LoadObjectMaterials00(L);
}
-
static void PlayMovie(const Common::String &vidpath, const Common::String &musicpath) {
Application *app = g_engine->getApplication();
app->mouseCursorLayout().load("pictures/cursor.png");
@@ -93,6 +92,28 @@ static int tolua_ExportedFunctions_PlayMovie00(lua_State *L) {
error("#ferror in function 'PlayMovie': %d %d %s", err.index, err.array, err.type);
}
+static int tolua_ExportedFunctions_PlayMovieAndWaitForEnd00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isstring(L, 2, 0, &err) && tolua_isnoobj(L, 3, &err)) {
+ Common::String s1(tolua_tostring(L, 1, nullptr));
+ Common::String s2(tolua_tostring(L, 2, nullptr));
+ PlayMovie(s1, s2);
+
+ Game::YieldedCallback callback;
+ callback._luaThread = TeLuaThread::threadFromState(L);
+ callback._luaFnName = "OnMovieFinished";
+ callback._luaParam = s1;
+ Game *game = g_engine->getGame();
+ for (const auto &cb : game->yieldedCallbacks()) {
+ if (cb._luaFnName == callback._luaFnName && cb._luaParam == s1)
+ error("PlayMovieAndWaitForEnd: Reentrency error, your are already in a yielded/sync function call");
+ }
+ game->yieldedCallbacks().push_back(callback);
+ return callback._luaThread->yield();
+ }
+ error("#ferror in function 'PlayMovieAndWaitForEnd': %d %d %s", err.index, err.array, err.type);
+}
+
static void AddRandomSound(const Common::String &s1, const Common::String &s2, float f1, float f2){
Game *game = g_engine->getGame();
game->addRandomSound(s1, s2, f1, f2);
@@ -195,7 +216,6 @@ static int tolua_ExportedFunctions_RemoveObject01(lua_State *L) {
return 0;
}
-
static void AddNumber(const Common::String &number) {
Game *game = g_engine->getGame();
if (!game->inventory().cellphone()->addNumber(number))
@@ -351,6 +371,24 @@ static int tolua_ExportedFunctions_SetRunMode200(lua_State *L) {
error("#ferror in function 'AddMarker': %d %d %s", err.index, err.array, err.type);
}
+static void SetCharacterShadow(const Common::String &charName, bool val) {
+ //Game *game = g_engine->getGame();
+ //Character *character = game->scene().character(charName);
+ // Note: the game fetches the character then does nothing here??
+}
+
+static int tolua_ExportedFunctions_SetCharacterShadow00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isboolean(L, 2, 0, &err)
+ && tolua_isnoobj(L, 3, &err)) {
+ Common::String s1(tolua_tostring(L, 1, nullptr));
+ bool b1 = tolua_toboolean(L, 2, 0);
+ SetCharacterShadow(s1, b1);
+ return 0;
+ }
+ error("#ferror in function 'SetCharacterShadow': %d %d %s", err.index, err.array, err.type);
+}
+
static void AddCallback(const Common::String &charName, const Common::String &animName, const Common::String &fnName, float triggerFrame, float maxCalls) {
Game *game = g_engine->getGame();
Character *c = game->scene().character(charName);
@@ -493,6 +531,32 @@ int tolua_ExportedFunctions_StartAnimation00(lua_State *L) {
}
+int tolua_ExportedFunctions_StartAnimationAndWaitForEnd00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isnumber(L, 2, 1, &err)
+ && tolua_isboolean(L, 3, 1, &err) && tolua_isnoobj(L, 4, &err)) {
+ Common::String s1(tolua_tostring(L, 1, nullptr));
+ double d1 = tolua_tonumber(L, 2, -1.0);
+ bool b1 = tolua_toboolean(L, 3, 0);
+ StartAnimation(s1, d1, b1);
+
+ Game::YieldedCallback callback;
+ callback._luaThread = TeLuaThread::threadFromState(L);
+ callback._luaFnName = "OnFinishedAnim";
+ callback._luaParam = s1;
+ Game *game = g_engine->getGame();
+ for (const auto &cb : game->yieldedCallbacks()) {
+ if (cb._luaFnName == callback._luaFnName && cb._luaParam == s1)
+ error("StartAnimationAndWaitForEnd: Reentrency error, your are already in a yielded/sync function call");
+ }
+ game->yieldedCallbacks().push_back(callback);
+ return callback._luaThread->yield();
+
+ }
+ error("#ferror in function 'StartAnimationAndWaitForEnd': %d %d %s", err.index, err.array, err.type);
+
+}
+
static void RequestAutoSave() {
Game *game = g_engine->getGame();
game->setSaveRequested();
@@ -890,6 +954,57 @@ static int tolua_ExportedFunctions_SetGroundObjectRotation00(lua_State *L) {
error("#ferror in function 'SetGroundObjectRotation': %d %d %s", err.index, err.array, err.type);
}
+static void TranslateGroundObject(const Common::String &name, float x, float y, float z, float time) {
+ Game *game = g_engine->getGame();
+ Object3D *obj = game->scene().object3D(name);
+ if (!obj)
+ error("[TranslateGroundObject] Object not found %s", name.c_str());
+ TeVector3f32 pos = obj->model()->position();
+ obj->_translateStart = pos;
+ obj->_translateAmount = TeVector3f32(x, y, z);
+ obj->_translateTimer.start();
+ obj->_translateTime = time;
+}
+
+static int tolua_ExportedFunctions_TranslateGroundObject00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isnumber(L, 2, 0, &err)
+ && tolua_isnumber(L, 3, 0, &err) && tolua_isnumber(L, 4, 0, &err)
+ && tolua_isnumber(L, 5, 0, &err) && tolua_isnoobj(L, 6, &err)) {
+ Common::String s1(tolua_tostring(L, 1, nullptr));
+ float f1 = tolua_tonumber(L, 2, 0.0);
+ float f2 = tolua_tonumber(L, 3, 0.0);
+ float f3 = tolua_tonumber(L, 4, 0.0);
+ float f4 = tolua_tonumber(L, 5, 0.0);
+ TranslateGroundObject(s1, f1, f2, f3, f4);
+ return 0;
+ }
+ error("#ferror in function 'TranslateGroundObject': %d %d %s", err.index, err.array, err.type);
+}
+
+static void EnableLight(uint lightno, bool enable) {
+ Game *game = g_engine->getGame();
+ if (lightno > game->scene().lights().size()) {
+ error("[EnableLight] Light not found %d", lightno);
+ }
+ TeLight &light = game->scene().lights()[lightno];
+ if (enable)
+ light.enable(lightno);
+ else
+ light.disable(lightno);
+}
+
+static int tolua_ExportedFunctions_EnableLight00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isnumber(L, 1, 0, &err) && tolua_isboolean(L, 2, 0, &err) && tolua_isnoobj(L, 3, &err)) {
+ float f1 = tolua_tonumber(L, 1, 0.0);
+ bool b1 = tolua_toboolean(L, 2, 0);
+ EnableLight(f1, b1);
+ return 0;
+ }
+ error("#ferror in function 'EnableLight': %d %d %s", err.index, err.array, err.type);
+}
+
static void LoadBillBoard(const Common::String &name) {
Game *game = g_engine->getGame();
game->scene().loadBillboard(name);
@@ -1018,6 +1133,35 @@ static int tolua_ExportedFunctions_HideBillboard00(lua_State *L) {
error("#ferror in function 'HideBillboard': %d %d %s", err.index, err.array, err.type);
}
+static void UnlockAchievement(int val) {
+ Game *game = g_engine->getGame();
+ game->addToScore(val);
+}
+
+static int tolua_ExportedFunctions_UnlockAchievement00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isnumber(L, 1, 0, &err) && tolua_isnoobj(L, 2, &err)) {
+ double d = tolua_tonumber(L, 1, 0.0);
+ UnlockAchievement(d);
+ return 0;
+ }
+ error("#ferror in function 'UnlockAchievement': %d %d %s", err.index, err.array, err.type);
+}
+
+static void Save(const Common::String &name) {
+ Game *game = g_engine->getGame();
+ game->saveBackup(name);
+}
+
+static int tolua_ExportedFunctions_Save00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isnoobj(L, 2, &err)) {
+ Common::String s1(tolua_tostring(L, 1, nullptr));
+ Save(s1);
+ return 0;
+ }
+ error("#ferror in function 'Save': %d %d %s", err.index, err.array, err.type);
+}
static void Wait(float seconds) {
Game *game = g_engine->getGame();
@@ -1057,6 +1201,34 @@ static int tolua_ExportedFunctions_WaitAndWaitForEnd00(lua_State *L) {
error("#ferror in function 'WaitAndWaitForEnd': %d %d %s", err.index, err.array, err.type);
}
+static void FinishGame() {
+ Game *game = g_engine->getGame();
+ game->finishGame();
+}
+
+static int tolua_ExportedFunctions_FinishGame00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isnoobj(L, 1, &err)) {
+ FinishGame();
+ return 0;
+ }
+ error("#ferror in function 'FinishGame': %d %d %s", err.index, err.array, err.type);
+}
+
+static void RequestMainMenu() {
+ Game *game = g_engine->getGame();
+ game->_returnToMainMenu = true;
+}
+
+static int tolua_ExportedFunctions_RequestMainMenu00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isnoobj(L, 1, &err)) {
+ RequestMainMenu();
+ return 0;
+ }
+ error("#ferror in function 'RequestMainMenu': %d %d %s", err.index, err.array, err.type);
+}
+
static void SetBackground(const Common::String &name) {
Game *game = g_engine->getGame();
if (!game->setBackground(name))
@@ -1850,11 +2022,11 @@ void LuaOpenBinds(lua_State *L) {
// tolua_function(L, "RemoveBlockingObject", tolua_ExportedFunctions_RemoveBlockingObject00); // Unused
tolua_function(L, "ChangeWarp", tolua_ExportedFunctions_ChangeWarp00);
tolua_function(L, "PlayMovie", tolua_ExportedFunctions_PlayMovie00);
- /*tolua_function(L, "PlayMovieAndWaitForEnd", tolua_ExportedFunctions_PlayMovieAndWaitForEnd00);*/
+ tolua_function(L, "PlayMovieAndWaitForEnd", tolua_ExportedFunctions_PlayMovieAndWaitForEnd00);
// tolua_function(L, "StartAnimationPart", tolua_ExportedFunctions_StartAnimationPart00); // Unused
tolua_function(L, "StartAnimation", tolua_ExportedFunctions_StartAnimation00);
- /*tolua_function(L, "StartAnimationAndWaitForEnd",
- tolua_ExportedFunctions_StartAnimationAndWaitForEnd00); */
+ tolua_function(L, "StartAnimationAndWaitForEnd",
+ tolua_ExportedFunctions_StartAnimationAndWaitForEnd00);
// tolua_function(L, "AddAnimToSet", tolua_ExportedFunctions_AddAnimToSet00); // Unused
tolua_function(L, "RequestAutoSave", tolua_ExportedFunctions_RequestAutoSave00);
tolua_function(L, "SetVisibleButtonZoomed", tolua_ExportedFunctions_SetVisibleButtonZoomed00);
@@ -1924,7 +2096,7 @@ void LuaOpenBinds(lua_State *L) {
tolua_function(L, "SetRunMode2", tolua_ExportedFunctions_SetRunMode200);
// tolua_function(L, "SetCharacterColor", tolua_ExportedFunctions_SetCharacterColor00); // Unused
// tolua_function(L, "SetCharacterSound", tolua_ExportedFunctions_SetCharacterSound00); // Unused
- /*tolua_function(L, "SetCharacterShadow", tolua_ExportedFunctions_SetCharacterShadow00);*/
+ tolua_function(L, "SetCharacterShadow", tolua_ExportedFunctions_SetCharacterShadow00);
tolua_function(L, "AddCallback", tolua_ExportedFunctions_AddCallback00);
tolua_function(L, "AddCallbackPlayer", tolua_ExportedFunctions_AddCallbackPlayer00);
// tolua_function(L, "AddCallbackAnimation2D", tolua_ExportedFunctions_AddCallbackAnimation2D00); // Unused
@@ -1940,11 +2112,11 @@ void LuaOpenBinds(lua_State *L) {
tolua_function(L, "UnloadObject", tolua_ExportedFunctions_UnloadObject00);
tolua_function(L, "SetGroundObjectPosition", tolua_ExportedFunctions_SetGroundObjectPosition00);
tolua_function(L, "SetGroundObjectRotation", tolua_ExportedFunctions_SetGroundObjectRotation00);
- /*tolua_function(L, "TranslateGroundObject", tolua_ExportedFunctions_TranslateGroundObject00); */
+ tolua_function(L, "TranslateGroundObject", tolua_ExportedFunctions_TranslateGroundObject00);
// tolua_function(L, "RotateGroundObject", tolua_ExportedFunctions_RotateGroundObject00); // Unused
// tolua_function(L, "SetLightPlayerCharacter", tolua_ExportedFunctions_SetLightPlayerCharacter00); // Unused
// tolua_function(L, "SetLightPos", tolua_ExportedFunctions_SetLightPos00); // Unused
- /*tolua_function(L, "EnableLight", tolua_ExportedFunctions_EnableLight00); */
+ tolua_function(L, "EnableLight", tolua_ExportedFunctions_EnableLight00);
// tolua_function(L, "SetLightDiffuse", tolua_ExportedFunctions_SetLightDiffuse00); // Unused
// tolua_function(L, "SetLightAmbient", tolua_ExportedFunctions_SetLightAmbient00); // Unused
// tolua_function(L, "SetLightSpecular", tolua_ExportedFunctions_SetLightSpecular00); // Unused
@@ -1954,13 +2126,13 @@ void LuaOpenBinds(lua_State *L) {
tolua_function(L, "SetBillboardSize", tolua_ExportedFunctions_SetBillboardSize00);
tolua_function(L, "ShowBillboard", tolua_ExportedFunctions_ShowBillboard00);
tolua_function(L, "HideBillboard", tolua_ExportedFunctions_HideBillboard00);
- /*tolua_function(L, "UnlockAchievement", tolua_ExportedFunctions_UnlockAchievement00);
- tolua_function(L, "Save", tolua_ExportedFunctions_Save00);*/
+ tolua_function(L, "UnlockAchievement", tolua_ExportedFunctions_UnlockAchievement00);
+ tolua_function(L, "Save", tolua_ExportedFunctions_Save00);
tolua_function(L, "Wait", tolua_ExportedFunctions_Wait00);
tolua_function(L, "WaitAndWaitForEnd", tolua_ExportedFunctions_WaitAndWaitForEnd00);
// tolua_function(L, "OpenFinalURL", tolua_ExportedFunctions_OpenFinalURL00); // Unused
- /*tolua_function(L, "FinishGame", tolua_ExportedFunctions_FinishGame00);
- tolua_function(L, "RequestMainMenu", tolua_ExportedFunctions_RequestMainMenu00);*/
+ tolua_function(L, "FinishGame", tolua_ExportedFunctions_FinishGame00);
+ tolua_function(L, "RequestMainMenu", tolua_ExportedFunctions_RequestMainMenu00);
// tolua_function(L, "BFGRateImmediately", tolua_ExportedFunctions_BFGRateImmediately00); // Unused
// tolua_function(L, "BFGReportEvent", tolua_ExportedFunctions_BFGReportEvent00); // Unused
// tolua_function(L, "BFGReportEventWithValue", tolua_ExportedFunctions_BFGReportEventWithValue00); // Unused
diff --git a/engines/tetraedge/te/te_free_move_zone.cpp b/engines/tetraedge/te/te_free_move_zone.cpp
index 98cafcda9e4..41185547d95 100644
--- a/engines/tetraedge/te/te_free_move_zone.cpp
+++ b/engines/tetraedge/te/te_free_move_zone.cpp
@@ -48,6 +48,15 @@ class TeFreeMoveZoneGraph : micropather::Graph {
void deserialize(Common::ReadStream &stream);
void serialize(Common::WriteStream &stream) const;
+
+ float costForPoint(TeVector2s32 pt) {
+ int flg = flag(pt);
+ if (flg == 1)
+ return FLT_MAX;
+ if (flg == 2)
+ return _bordersDistance;
+ return 1.0;
+ }
};
@@ -358,7 +367,10 @@ void TeFreeMoveZone::setNbTriangles(unsigned int len) {
}
void TeFreeMoveZone::setPathFindingOccluder(const TeOBP &occluder) {
- error("TODO: Implement TeFreeMoveZone::setPathFindingOccluder");
+ _obp = occluder;
+ _projectedPointsDirty = true;
+ _bordersDirty = true;
+ _gridDirty = true;
}
void TeFreeMoveZone::setVertex(unsigned int offset, const TeVector3f32 &vertex) {
@@ -378,16 +390,20 @@ TeVector3f32 TeFreeMoveZone::transformAStarGridInWorldSpace(const TeVector2s32 &
_gridOffsetSomething.getX() * 0.5;
if (!_loadedFromBin) {
return TeVector3f32(offsetx, _gridWorldY, offsety);
+ } else {
+ TeVector3f32 result = _gridMatrix * TeVector3f32(offsetx, _gridWorldY, offsety);
+ return worldTransformationMatrix() * result;
}
- error("TODO: Implement TeFreeMoveZone::transformAStarGridInWorldSpace");
}
float TeFreeMoveZone::transformHeightMin(float minval) {
- error("TODO: Implement TeFreeMoveZone::transformHeightMin");
+ TeVector3f32 vec = worldTransformationMatrix() * TeVector3f32(_someGridVec1.getX(), minval, _someGridVec1.getY());
+ return vec.y();
}
-TeVector3f32 TeFreeMoveZone::transformVectorInWorldSpace(float param_3,float param_4) {
- error("TODO: Implement TeFreeMoveZone::transformVectorInWorldSpace");
+TeVector3f32 TeFreeMoveZone::transformVectorInWorldSpace(float x, float y) {
+ TeVector3f32 vec = _gridMatrix * TeVector3f32(x, _gridWorldY, y);
+ return worldTransformationMatrix() * vec;
}
void TeFreeMoveZone::updateBorders() {
@@ -449,37 +465,42 @@ void TeFreeMoveZoneGraph::AdjacentCost(void *state, Common::Array<micropather::S
pt = TeVector2s32(statept._x - 1, statept._y);
cost.state = reinterpret_cast<void *>(_size._x * pt._y + pt._x);
- cost.cost = (flag(pt) == 1 ? FLT_MAX : _bordersDistance);
+ cost.cost = costForPoint(pt);
adjacent->push_back(cost);
pt = TeVector2s32(statept._x - 1, statept._y + 1);
cost.state = reinterpret_cast<void *>(_size._x * pt._y + pt._x);
- cost.cost = (flag(pt) == 1 ? FLT_MAX : _bordersDistance);
+ cost.cost = costForPoint(pt);
+ adjacent->push_back(cost);
+
+ pt = TeVector2s32(statept._x, statept._y + 1);
+ cost.state = reinterpret_cast<void *>(_size._x * pt._y + pt._x);
+ cost.cost = costForPoint(pt);
adjacent->push_back(cost);
pt = TeVector2s32(statept._x + 1, statept._y + 1);
cost.state = reinterpret_cast<void *>(_size._x * pt._y + pt._x);
- cost.cost = (flag(pt) == 1 ? FLT_MAX : _bordersDistance);
+ cost.cost = costForPoint(pt);
adjacent->push_back(cost);
pt = TeVector2s32(statept._x + 1, statept._y);
cost.state = reinterpret_cast<void *>(_size._x * pt._y + pt._x);
- cost.cost = (flag(pt) == 1 ? FLT_MAX : _bordersDistance);
+ cost.cost = costForPoint(pt);
adjacent->push_back(cost);
pt = TeVector2s32(statept._x + 1, statept._y - 1);
cost.state = reinterpret_cast<void *>(_size._x * pt._y + pt._x);
- cost.cost = (flag(pt) == 1 ? FLT_MAX : _bordersDistance);
+ cost.cost = costForPoint(pt);
adjacent->push_back(cost);
pt = TeVector2s32(statept._x, statept._y - 1);
cost.state = reinterpret_cast<void *>(_size._x * pt._y + pt._x);
- cost.cost = (flag(pt) == 1 ? FLT_MAX : _bordersDistance);
+ cost.cost = costForPoint(pt);
adjacent->push_back(cost);
pt = TeVector2s32(statept._x - 1, statept._y - 1);
cost.state = reinterpret_cast<void *>(_size._x * pt._y + pt._x);
- cost.cost = (flag(pt) == 1 ? FLT_MAX : _bordersDistance);
+ cost.cost = costForPoint(pt);
adjacent->push_back(cost);
}
diff --git a/engines/tetraedge/te/te_free_move_zone.h b/engines/tetraedge/te/te_free_move_zone.h
index 4e3efb5fbc9..8861b007284 100644
--- a/engines/tetraedge/te/te_free_move_zone.h
+++ b/engines/tetraedge/te/te_free_move_zone.h
@@ -128,6 +128,7 @@ private:
TeVector2f32 _gridOffsetSomething;
TeVector2f32 _someGridVec1;
TeVector2f32 _someGridVec2;
+ TeMatrix4x4 _gridMatrix;
float _gridWorldY;
Commit: 4a8f9984d4123f29972c36d2715ab3bcaba15121
https://github.com/scummvm/scummvm/commit/4a8f9984d4123f29972c36d2715ab3bcaba15121
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2023-01-16T17:36:43+01:00
Commit Message:
TETRAEDGE: Fixed more bugs, started save/load support.
Changed paths:
engines/tetraedge/game/application.h
engines/tetraedge/game/cellphone.cpp
engines/tetraedge/game/cellphone.h
engines/tetraedge/game/character.cpp
engines/tetraedge/game/character.h
engines/tetraedge/game/confirm.cpp
engines/tetraedge/game/dialog2.cpp
engines/tetraedge/game/dialog2.h
engines/tetraedge/game/game.cpp
engines/tetraedge/game/game.h
engines/tetraedge/game/in_game_scene.cpp
engines/tetraedge/game/inventory.cpp
engines/tetraedge/game/inventory.h
engines/tetraedge/game/inventory_menu.cpp
engines/tetraedge/game/lua_binds.cpp
engines/tetraedge/game/scene_lights_xml_parser.cpp
engines/tetraedge/game/splash_screens.cpp
engines/tetraedge/metaengine.cpp
engines/tetraedge/metaengine.h
engines/tetraedge/te/te_bezier_curve.cpp
engines/tetraedge/te/te_bezier_curve.h
engines/tetraedge/te/te_button_layout.cpp
engines/tetraedge/te/te_core.cpp
engines/tetraedge/te/te_light.cpp
engines/tetraedge/te/te_light.h
engines/tetraedge/te/te_lua_context.cpp
engines/tetraedge/te/te_lua_context.h
engines/tetraedge/te/te_lua_gui_lua_callbacks.cpp
engines/tetraedge/te/te_model.cpp
engines/tetraedge/te/te_model_animation.cpp
engines/tetraedge/te/te_name_val_xml_parser.cpp
engines/tetraedge/te/te_text_base2.cpp
engines/tetraedge/te/te_text_layout.cpp
engines/tetraedge/te/te_tiled_surface.cpp
engines/tetraedge/te/te_timer.h
engines/tetraedge/tetraedge.cpp
engines/tetraedge/tetraedge.h
engines/tetraedge/to_lua.cpp
diff --git a/engines/tetraedge/game/application.h b/engines/tetraedge/game/application.h
index d5a43e8c21e..ce9a67715ad 100644
--- a/engines/tetraedge/game/application.h
+++ b/engines/tetraedge/game/application.h
@@ -98,7 +98,8 @@ public:
void setTutoActivated(bool val) { _tutoActivated = val; }
TeCamera *mainWindowCamera() { return _mainWindowCamera.get(); }
Common::Array<Common::String> &unrecalAnims() { return _unrecalAnims; }
- int difficulty() const { return _difficulty; }
+ int &difficulty() { return _difficulty; }
+ bool &tutoActivated() { return _tutoActivated; }
// TODO: Add accessors for these and make them private.
bool _finishedGame;
diff --git a/engines/tetraedge/game/cellphone.cpp b/engines/tetraedge/game/cellphone.cpp
index 0228fd3a17d..d91ee5654c4 100644
--- a/engines/tetraedge/game/cellphone.cpp
+++ b/engines/tetraedge/game/cellphone.cpp
@@ -41,7 +41,8 @@ bool Cellphone::addNumber(const Common::String &num) {
layout->setName(namePrefix + num);
layout->setSizeType(RELATIVE_TO_PARENT);
layout->setAnchor(TeVector3f32(0.5f, 0.0f, 0.0f));
- layout->setSize(TeVector3f32(1.0f, 1.0f, 0.0f));
+ // WORKAROUND: Original uses 1.0,1.0,1.0 here but then the text area is too high.
+ layout->setSize(TeVector3f32(1.0f, 0.6f, 0.0f));
layout->setPosition(TeVector3f32(0.5f, 0.08f, 0.0f));
layout->setTextSizeType(1);
layout->setTextSizeProportionalToWidth(46);
@@ -155,4 +156,21 @@ void Cellphone::unload() {
_gui.unload();
}
+Common::Error Cellphone::syncState(Common::Serializer &s) {
+ Common::Array<Common::String> numbers = _addedNumbers;
+ unsigned int numElems = numbers.size();
+ s.syncAsUint32LE(numElems);
+ numbers.resize(numElems);
+ for (unsigned int i = 0; i < numElems; i++) {
+ s.syncString(numbers[i]);
+ }
+ if (s.isLoading()) {
+ if (!_addedNumbers.empty())
+ leave();
+ for (auto num : numbers)
+ addNumber(num);
+ }
+ return Common::kNoError;
+}
+
} // end namespace Tetraedge
diff --git a/engines/tetraedge/game/cellphone.h b/engines/tetraedge/game/cellphone.h
index e4f93031621..f9d1c8922b3 100644
--- a/engines/tetraedge/game/cellphone.h
+++ b/engines/tetraedge/game/cellphone.h
@@ -61,6 +61,8 @@ public:
void unload();
+ Common::Error syncState(Common::Serializer &s);
+
TeLuaGUI &gui() { return _gui; }
private:
diff --git a/engines/tetraedge/game/character.cpp b/engines/tetraedge/game/character.cpp
index 18f1b483459..1d814ec639a 100644
--- a/engines/tetraedge/game/character.cpp
+++ b/engines/tetraedge/game/character.cpp
@@ -103,13 +103,21 @@ void Character::addCallback(const Common::String &animKey, const Common::String
// the way this gets used later, setting large negative is more correct.
c->_callsMade = (maxCalls == -1.0 ? -1e9 : 0.0f);
- const Common::String animPath = _model->anim()->_loadedPath.toString();
- if (_callbacks.contains(animPath)) {
- _callbacks[animPath].push_back(c);
+ const Common::Path animPath = _model->anim()->_loadedPath;
+
+ // Another difference.. the original messes with paths a bit - just
+ // use the file name, since it's already limited by character.
+ Common::String animName = animPath.getLastComponent().toString();
+ if (animName.empty())
+ animName = animPath.toString();
+
+ if (_callbacks.contains(animName)) {
+ _callbacks[animName].push_back(c);
} else {
+ Common::Path animKeyPath(animKey);
Common::Array<Callback *> callbacks;
callbacks.push_back(c);
- _callbacks.setVal(animKey, callbacks);
+ _callbacks.setVal(animKeyPath.getLastComponent().toString(), callbacks);
}
}
@@ -132,9 +140,8 @@ void Character::addCallback(const Common::String &animKey, const Common::String
return _cache.getVal(pathStr);
TeIntrusivePtr<TeModelAnimation> modelAnim = new TeModelAnimation();
- Common::Path foundPath = g_engine->getCore()->findFile(path);
- if (!modelAnim->load(foundPath)) {
- warning("Failed to load anim %s", foundPath.toString().c_str());
+ if (!modelAnim->load(path)) {
+ warning("Failed to load anim %s", path.toString().c_str());
}
_cache.setVal(pathStr, modelAnim);
@@ -191,6 +198,7 @@ bool Character::blendAnimation(const Common::String &animname, float amount, boo
_curModelAnim = animCacheLoad(animpath);
assert(_curModelAnim);
+ _curModelAnim->reset();
_curModelAnim->onFinished().add(this, &Character::onModelAnimationFinished);
_curModelAnim->bind(_model);
@@ -236,11 +244,11 @@ void Character::deleteAnim() {
void Character::deleteCallback(const Common::String &key, const Common::String &fnName, float f) {
_callbacksChanged = true;
assert(_model->anim());
- Common::String animPath = _model->anim()->_loadedPath.toString();
- if (!_callbacks.contains(animPath))
+ Common::String animFile = _model->anim()->_loadedPath.getLastComponent().toString();
+ if (!_callbacks.contains(animFile))
return;
- Common::Array<Callback *> &cbs = _callbacks.getVal(animPath);
+ Common::Array<Callback *> &cbs = _callbacks.getVal(animFile);
for (unsigned int i = 0; i < cbs.size(); i++) {
if (fnName.empty()) {
delete cbs[i];
@@ -257,7 +265,7 @@ void Character::deleteCallback(const Common::String &key, const Common::String &
cbs.clear();
if (cbs.empty())
- _callbacks.erase(animPath);
+ _callbacks.erase(animFile);
}
//static bool deserialize(TiXmlElement *param_1, Walk *param_2);
@@ -530,18 +538,18 @@ bool Character::onModelAnimationFinished() {
// TODO: check if this logic matches..
for (const auto &walkSettings : _characterSettings._walkSettings) {
isWalkAnim |= (walkSettings._key.contains("Walk") || walkSettings._key.contains("Jog"));
- isWalkAnim |= (walkSettings._value._walkParts[0]._file == animfile ||
- walkSettings._value._walkParts[1]._file == animfile ||
- walkSettings._value._walkParts[2]._file == animfile ||
- walkSettings._value._walkParts[3]._file == animfile);
+ isWalkAnim |= (walkSettings._value._walkParts[0]._file == animfile
+ || walkSettings._value._walkParts[1]._file == animfile
+ || walkSettings._value._walkParts[2]._file == animfile
+ || walkSettings._value._walkParts[3]._file == animfile);
}
isWalkAnim |= animfile.contains(_characterSettings._idleAnimFileName);
} else {
- isWalkAnim = (animfile.contains(_characterSettings._idleAnimFileName) ||
- animfile.contains(walkAnim(WalkPart_Start)) ||
- animfile.contains(walkAnim(WalkPart_Loop)) ||
- animfile.contains(walkAnim(WalkPart_EndD)) ||
- animfile.contains(walkAnim(WalkPart_EndG)));
+ isWalkAnim = (_characterSettings._idleAnimFileName.contains(animfile)
+ || walkAnim(WalkPart_Start).contains(animfile)
+ || walkAnim(WalkPart_Loop).contains(animfile)
+ || walkAnim(WalkPart_EndD).contains(animfile)
+ || walkAnim(WalkPart_EndG).contains(animfile));
}
if (!isWalkAnim && shouldAdjust) {
@@ -587,12 +595,15 @@ bool Character::onModelAnimationFinished() {
void Character::permanentUpdate() {
assert(_model->anim());
- const Common::String animPath = _model->anim()->_loadedPath.toString();
+ const Common::Path animPath = _model->anim()->_loadedPath;
int curFrame = _model->anim()->curFrame2();
Game *game = g_engine->getGame();
_callbacksChanged = false;
- if (_callbacks.contains(animPath)) {
- Common::Array<Callback *> &cbs = _callbacks.getVal(animPath);
+ // Diverge from original - just use filename for anim callbacks as the
+ // original does werid things with paths.
+ const Common::String animFile = animPath.getLastComponent().toString();
+ if (_callbacks.contains(animFile)) {
+ Common::Array<Callback *> &cbs = _callbacks.getVal(animFile);
for (Callback *cb : cbs) {
if (cb->_triggerFrame > cb->_lastCheckFrame && curFrame >= cb->_triggerFrame){
int callsMade = cb->_callsMade;
@@ -608,13 +619,13 @@ void Character::permanentUpdate() {
}
}
- if (animPath.contains("ka_esc_h")) {
+ if (animFile.contains("ka_esc_h")) {
if (_lastAnimFrame < 7 && _model->anim()->curFrame2() > 6) {
game->playSound("sounds/SFX/PAS_F_PAVE1.ogg", 1, 1.0f);
} else if (_lastAnimFrame < 22 && _model->anim()->curFrame2() > 21) {
game->playSound("sounds/SFX/PAS_F_PAVE2.ogg", 1, 1.0f);
}
- } else if (animPath.contains("ka_esc_b")) {
+ } else if (animFile.contains("ka_esc_b")) {
if (_lastAnimFrame < 12 && _model->anim()->curFrame2() > 11) {
game->playSound("sounds/SFX/PAS_F_PAVE1.ogg", 1, 1.0f);
} else if (_lastAnimFrame < 27 && _model->anim()->curFrame2() > 26) {
@@ -836,7 +847,7 @@ void Character::update(double msFromStart) {
if (crossprod.y() >= 0.0f) {
angle = -angle;
}
-
+ //debug("update: curve offset %f - angle %f (base %f)", offset, angle, baseAngle);
TeQuaternion rot = TeQuaternion::fromAxisAndAngle(TeVector3f32(0.0, 1.0, 0.0), baseAngle + angle);
_model->setRotation(rot);
@@ -973,8 +984,9 @@ void Character::walkTo(float curveEnd, bool walkFlag) {
play();
return; // NOTE: early return here.
} else {
+ // NPC walk
double intpart;
- double remainder = modf(walkEndLen, &intpart);
+ double remainder = modf(nloops, &intpart);
if (remainder >= 0.5) {
_walkEndAnimG = true;
intpart += 0.75;
diff --git a/engines/tetraedge/game/character.h b/engines/tetraedge/game/character.h
index 19384586a7e..86fc5036be4 100644
--- a/engines/tetraedge/game/character.h
+++ b/engines/tetraedge/game/character.h
@@ -151,7 +151,7 @@ public:
TeSignal1Param<const Common::String &> _onCharacterAnimFinishedSignal;
const CharacterSettings &characterSettings() const { return _characterSettings; }
- const Common::String &walkModeStr() const { return _walkModeStr; }
+ Common::String &walkModeStr() { return _walkModeStr; } // writable for loading games.
const Common::String &curAnimName() const { return _curAnimName; }
TeFreeMoveZone *freeMoveZone() { return _freeMoveZone; }
const Common::String &freeMoveZoneName() const { return _freeMoveZoneName; }
diff --git a/engines/tetraedge/game/confirm.cpp b/engines/tetraedge/game/confirm.cpp
index b27d994b0c3..70c565aa307 100644
--- a/engines/tetraedge/game/confirm.cpp
+++ b/engines/tetraedge/game/confirm.cpp
@@ -43,11 +43,11 @@ void Confirm::enter(const Common::String &guiPath, const Common::String &y) {
TeButtonLayout *yesButtonLayout = _gui.buttonLayout("yes");
if (yesButtonLayout)
- yesButtonLayout->onMouseClickValidated().add<Confirm>(this, &Confirm::onButtonYes);
+ yesButtonLayout->onMouseClickValidated().add(this, &Confirm::onButtonYes);
TeButtonLayout *noButtonLayout = _gui.buttonLayout("no");
if (noButtonLayout)
- noButtonLayout->onMouseClickValidated().add<Confirm>(this, &Confirm::onButtonNo);
+ noButtonLayout->onMouseClickValidated().add(this, &Confirm::onButtonNo);
TeLayout *textLayout = _gui.layout("text");
if (textLayout) {
diff --git a/engines/tetraedge/game/dialog2.cpp b/engines/tetraedge/game/dialog2.cpp
index e0340bc0e59..5c47508c6b7 100644
--- a/engines/tetraedge/game/dialog2.cpp
+++ b/engines/tetraedge/game/dialog2.cpp
@@ -73,7 +73,7 @@ void Dialog2::launchNextDialog() {
}
if (_currentDialogData._animBlend == 0.0f) {
- if (!c->setAnimation(_currentDialogData._animfile, false))
+ if (!c->setAnimation(_currentDialogData._animfile, false, true))
error("[Dialog2::launchNextDialog] Character's animation \"%s\" doesn't exist for the character\"%s\" \n",
_currentDialogData._animfile.c_str(), _currentDialogData._charname.c_str());
} else {
@@ -200,6 +200,8 @@ void Dialog2::startDownAnimation() {
}
void Dialog2::unload() {
+ if (!_gui.loaded())
+ return;
TeCurveAnim2<TeLayout,TeVector3f32> *dialogAnimUp = _gui.layoutAnchorLinearAnimation("dialogAnimationUp");
dialogAnimUp->stop();
TeCurveAnim2<TeLayout,TeVector3f32> *dialogAnimDown = _gui.layoutAnchorLinearAnimation("dialogAnimationDown");
diff --git a/engines/tetraedge/game/dialog2.h b/engines/tetraedge/game/dialog2.h
index a1f98b3772a..9bc73c55580 100644
--- a/engines/tetraedge/game/dialog2.h
+++ b/engines/tetraedge/game/dialog2.h
@@ -22,6 +22,8 @@
#ifndef TETRAEDGE_GAME_DIALOG2_H
#define TETRAEDGE_GAME_DIALOG2_H
+#include "common/serializer.h"
+
#include "tetraedge/te/te_timer.h"
#include "tetraedge/te/te_music.h"
#include "tetraedge/te/te_lua_gui.h"
diff --git a/engines/tetraedge/game/game.cpp b/engines/tetraedge/game/game.cpp
index ab688078ca8..fae906c6526 100644
--- a/engines/tetraedge/game/game.cpp
+++ b/engines/tetraedge/game/game.cpp
@@ -23,6 +23,7 @@
#include "common/path.h"
#include "common/str-array.h"
#include "common/system.h"
+#include "common/savefile.h"
#include "common/config-manager.h"
#include "tetraedge/tetraedge.h"
@@ -388,7 +389,13 @@ void Game::initLoadedBackupData() {
bool warpFlag = true;
if (!_loadName.empty()) {
warpFlag = false;
- error("TODO: Implemet Game::initLoadedBackupData loading part");
+ Common::InSaveFile *saveFile = g_engine->getSaveFileManager()->openForLoading(_loadName);
+ Common::Error result = g_engine->loadGameStream(saveFile);
+ if (result.getCode() == Common::kNoError) {
+ ExtendedSavegameHeader header;
+ if (MetaEngine::readSavegameHeader(saveFile, &header))
+ g_engine->setTotalPlayTime(header.playtime);
+ }
}
Application *app = g_engine->getApplication();
const Common::String firstWarpPath = app->_firstWarpPath;
@@ -737,8 +744,12 @@ void Game::leave(bool flag) {
Character::animCacheFreeAll();
}
-bool Game::loadBackup(const Common::String &path) {
- error("TODO: Implemet Game::loadBackup %s", path.c_str());
+void Game::loadBackup(const Common::String &path) {
+ if (_gameLoadState == 0) {
+ _gameLoadState = 1;
+ g_engine->getApplication()->showLoadingIcon(true);
+ onFinishedLoadingBackup(path);
+ }
}
bool Game::loadCharacter(const Common::String &name) {
@@ -748,9 +759,9 @@ bool Game::loadCharacter(const Common::String &name) {
result = _scene.loadCharacter(name);
if (result) {
character = _scene.character(name);
- character->_onCharacterAnimFinishedSignal.remove<Game>(this, &Game::onCharacterAnimationFinished);
- character->_onCharacterAnimFinishedSignal.add<Game>(this, &Game::onCharacterAnimationFinished);
- character->onFinished().add<Game>(this, &Game::onDisplacementFinished);
+ character->_onCharacterAnimFinishedSignal.remove(this, &Game::onCharacterAnimationFinished);
+ character->_onCharacterAnimFinishedSignal.add(this, &Game::onCharacterAnimationFinished);
+ character->onFinished().add(this, &Game::onDisplacementFinished);
}
}
return result;
@@ -759,10 +770,10 @@ bool Game::loadCharacter(const Common::String &name) {
bool Game::loadPlayerCharacter(const Common::String &name) {
bool result = _scene.loadPlayerCharacter(name);
if (result) {
- _scene._character->_characterAnimPlayerFinishedSignal.remove<Game>(this, &Game::onCharacterAnimationPlayerFinished);
- _scene._character->_characterAnimPlayerFinishedSignal.add<Game>(this, &Game::onCharacterAnimationPlayerFinished);
- _scene._character->onFinished().remove<Game>(this, &Game::onDisplacementFinished);
- _scene._character->onFinished().add<Game>(this, &Game::onDisplacementFinished);
+ _scene._character->_characterAnimPlayerFinishedSignal.remove(this, &Game::onCharacterAnimationPlayerFinished);
+ _scene._character->_characterAnimPlayerFinishedSignal.add(this, &Game::onCharacterAnimationPlayerFinished);
+ _scene._character->onFinished().remove(this, &Game::onDisplacementFinished);
+ _scene._character->onFinished().add(this, &Game::onDisplacementFinished);
}
return result;
}
@@ -1360,7 +1371,10 @@ void Game::resumeMovie() {
}
void Game::saveBackup(const Common::String &saveName) {
- warning("TODO: Implemet Game::saveBackup %s", saveName.c_str());
+ if (saveName == "save.xml")
+ g_engine->saveAutosaveIfEnabled();
+ else
+ warning("TODO: Implemet Game::saveBackup %s", saveName.c_str());
}
bool Game::setBackground(const Common::String &name) {
@@ -1411,6 +1425,36 @@ void Game::stopSound(const Common::String &name) {
g_engine->getSoundManager()->stopFreeSound(name);
}
+Common::Error Game::syncGame(Common::Serializer &s) {
+ Application *app = g_engine->getApplication();
+ s.setVersion(1);
+ inventory().syncState(s);
+ inventory().cellphone()->syncState(s);
+ // dialog2().syncState(s); // game saves this here, but doesn't actually save anything
+ _luaContext.syncState(s);
+ s.syncString(_currentZone);
+ s.syncString(_currentScene);
+ s.syncAsUint32LE(app->difficulty());
+ long elapsed = _playedTimer.timeFromLastTimeElapsed(); // TODO: + _loadedPlayTime;
+ s.syncAsDoubleLE(elapsed);
+ _playedTimer.stop();
+ _playedTimer.start();
+ s.syncAsUint32LE(_objectsTakenVal);
+ for (unsigned int i = 0; i < ARRAYSIZE(_objectsTakenBits); i++)
+ s.syncAsByte(_objectsTakenBits[i]);
+ s.syncAsUint32LE(_dialogsTold);
+ s.syncString(_prevSceneName);
+ Common::String mpath = _music.rawPath();
+ s.syncString(mpath);
+ if (s.isLoading())
+ _music.load(mpath);
+ s.syncString(_scene._character->walkModeStr());
+ s.syncAsByte(_firstInventory);
+ s.syncAsByte(app->tutoActivated());
+ app->showLoadingIcon(false);
+ return Common::kNoError;
+}
+
bool Game::unloadCharacter(const Common::String &charname) {
Character *c = _scene.character(charname);
if (!c)
@@ -1554,6 +1598,7 @@ bool Game::HitObject::onDown() {
}
bool Game::HitObject::onUp() {
+ debug("Game::HitObject mouseup: %s", _name.c_str());
_game->luaScript().execute("OnButtonUp", _name);
_game->_isCharacterIdle = true;
return false;
diff --git a/engines/tetraedge/game/game.h b/engines/tetraedge/game/game.h
index 866bebb30c8..2208b0d6b99 100644
--- a/engines/tetraedge/game/game.h
+++ b/engines/tetraedge/game/game.h
@@ -23,6 +23,7 @@
#define TETRAEDGE_GAME_GAME_H
#include "common/types.h"
+#include "common/serializer.h"
#include "common/str.h"
#include "common/random.h"
@@ -117,7 +118,7 @@ public:
bool launchDialog(const Common::String ¶m_1, uint param_2, const Common::String ¶m_3,
const Common::String ¶m_4, float param_5);
void leave(bool flag);
- bool loadBackup(const Common::String &path);
+ void loadBackup(const Common::String &path);
bool loadCharacter(const Common::String &name);
bool loadPlayerCharacter(const Common::String &name);
bool loadScene(const Common::String &name);
@@ -157,6 +158,7 @@ public:
bool startAnimation(const Common::String &animName, int loopcount, bool reversed);
void startAnimationPart(const Common::String ¶m_1, int param_2, int param_3, int param_4, bool param_5) {};
void stopSound(const Common::String &name);
+ Common::Error syncGame(Common::Serializer &s); // Basically replaces saveBackup from original..
bool unloadCharacter(const Common::String &character);
bool unloadCharacters();
bool unloadPlayerCharacter(const Common::String &character);
@@ -195,6 +197,7 @@ public:
TeTimer &walkTimer() { return _walkTimer; }
void setExitZone(const Common::String &zone) { _exitZone = zone; }
Common::RandomSource &randomSource() { return _randomSource; }
+ void setLoadName(const Common::String &loadName) { _loadName = loadName; }
private:
bool _luaShowOwnerError;
diff --git a/engines/tetraedge/game/in_game_scene.cpp b/engines/tetraedge/game/in_game_scene.cpp
index 651edb984cb..6e04185834a 100644
--- a/engines/tetraedge/game/in_game_scene.cpp
+++ b/engines/tetraedge/game/in_game_scene.cpp
@@ -686,6 +686,11 @@ bool InGameScene::loadLights(const Common::Path &path) {
_shadowNearPlane = parser.getShadowNearPlane();
_shadowFov = parser.getShadowFov();
+ TeLight::enableAll();
+ for (unsigned int i = 0; i < _lights.size(); i++) {
+ _lights[i].enable(i);
+ }
+
return true;
}
@@ -833,7 +838,7 @@ void InGameScene::loadBackground(const Common::Path &path) {
AnimObject *animobj = new AnimObject();
animobj->_name = layoutEntry._key;
animobj->_layout = layoutEntry._value;
- animobj->_layout->_tiledSurfacePtr->_frameAnim.onFinished().add<AnimObject>(animobj, &AnimObject::onFinished);
+ animobj->_layout->_tiledSurfacePtr->_frameAnim.onFinished().add(animobj, &AnimObject::onFinished);
if (animobj->_name != "root")
animobj->_layout->setVisible(false);
_animObjects.push_back(animobj);
@@ -874,6 +879,8 @@ void InGameScene::moveCharacterTo(const Common::String &charName, const Common::
if (!game->_movePlayerCharacterDisabled) {
c->setCurveStartLocation(c->characterSettings()._cutSceneCurveDemiPosition);
TeIntrusivePtr<TeBezierCurve> crve = curve(curveName);
+ if (!curveName.empty() && !crve)
+ warning("moveCharacterTo: curve %s not found", curveName.c_str());
c->placeOnCurve(crve);
c->setCurveOffset(curveOffset);
const Common::String walkStartAnim = c->walkAnim(Character::WalkPart_Start);
@@ -1123,6 +1130,7 @@ void InGameScene::update() {
error("TODO: handle _translateTime > 0 in InGameScene::update");
}
if (obj->_rotateTime >= 0) {
+ // Never actually used in the game.
error("TODO: handle _rotateTime > 0 in InGameScene::update");
}
}
diff --git a/engines/tetraedge/game/inventory.cpp b/engines/tetraedge/game/inventory.cpp
index 45cffe2cf24..40aa69fd1d3 100644
--- a/engines/tetraedge/game/inventory.cpp
+++ b/engines/tetraedge/game/inventory.cpp
@@ -498,5 +498,27 @@ bool Inventory::updateLayout() {
return false;
}
+Common::Error Inventory::syncState(Common::Serializer &s) {
+ unsigned int nitems = _invObjects.size();
+ s.syncAsUint32LE(nitems);
+ if (s.isLoading()) {
+ for (unsigned int i = 0; i < nitems; i++) {
+ Common::String objname;
+ s.syncString(objname);
+ addObject(objname);
+ }
+ } else if (nitems) {
+ // Add items in reverse order as the "addObject" on load will
+ // add to front of list.InventoryObject
+ auto iter = _invObjects.end();
+ while (iter != _invObjects.begin()) {
+ Common::String objname = (*iter)->name();
+ s.syncString(objname);
+ iter--;
+ }
+ }
+ return Common::kNoError;
+}
+
} // end namespace Tetraedge
diff --git a/engines/tetraedge/game/inventory.h b/engines/tetraedge/game/inventory.h
index a6d88901ea8..cfcdd344e5e 100644
--- a/engines/tetraedge/game/inventory.h
+++ b/engines/tetraedge/game/inventory.h
@@ -79,6 +79,8 @@ public:
bool updateLayout();
+ Common::Error syncState(Common::Serializer &s);
+
Cellphone *cellphone() { return _cellphone; }
private:
diff --git a/engines/tetraedge/game/inventory_menu.cpp b/engines/tetraedge/game/inventory_menu.cpp
index a98c855c2da..9dd250b5cc1 100644
--- a/engines/tetraedge/game/inventory_menu.cpp
+++ b/engines/tetraedge/game/inventory_menu.cpp
@@ -42,9 +42,8 @@ void InventoryMenu::leave() {
game->inventory().leave();
game->documentsBrowser().leave();
TeLayout *invMenu = _gui.layout("inventoryMenu");
- if (invMenu) {
+ if (invMenu)
invMenu->setVisible(false);
- }
}
void InventoryMenu::load() {
@@ -52,23 +51,22 @@ void InventoryMenu::load() {
setSizeType(RELATIVE_TO_PARENT);
TeVector3f32 usersz = userSize();
setSize(TeVector3f32(1.0f, 1.0f, usersz.z()));
+
_gui.load("InventoryMenu/InventoryMenu.lua");
- TeLayout *menu = _gui.layoutChecked("inventoryMenu");
- addChild(menu);
- TeButtonLayout *btn;
- btn = _gui.buttonLayoutChecked("quitButton");
- btn->onMouseClickValidated().add(this, &InventoryMenu::onQuitButton);
- btn = _gui.buttonLayoutChecked("quitBackground");
- btn->onMouseClickValidated().add(this, &InventoryMenu::onQuitButton);
- btn = _gui.buttonLayoutChecked("mainMenuButton");
- btn->onMouseClickValidated().add(this, &InventoryMenu::onMainMenuButton);
- btn = _gui.buttonLayoutChecked("documentsButton");
- btn->onMouseClickValidated().add(this, &InventoryMenu::onDocumentsButton);
- btn = _gui.buttonLayoutChecked("inventoryButton");
- btn->onMouseClickValidated().add(this, &InventoryMenu::onInventoryButton);
-
- TeLayout *invmenu = _gui.layoutChecked("inventoryMenu");
- invmenu->setVisible(false);
+ addChild(_gui.layoutChecked("inventoryMenu"));
+ _gui.buttonLayoutChecked("quitButton")->onMouseClickValidated()
+ .add(this, &InventoryMenu::onQuitButton);
+ _gui.buttonLayoutChecked("quitBackground")->onMouseClickValidated()
+ .add(this, &InventoryMenu::onQuitButton);
+ _gui.buttonLayoutChecked("mainMenuButton")->onMouseClickValidated()
+ .add(this, &InventoryMenu::onMainMenuButton);
+ _gui.buttonLayoutChecked("documentsButton")->onMouseClickValidated()
+ .add(this, &InventoryMenu::onDocumentsButton);
+ _gui.buttonLayoutChecked("inventoryButton")->onMouseClickValidated()
+ .add(this, &InventoryMenu::onInventoryButton);
+
+ _gui.layoutChecked("inventoryMenu")->setVisible(false);
+
setVisible(false);
}
diff --git a/engines/tetraedge/game/lua_binds.cpp b/engines/tetraedge/game/lua_binds.cpp
index f6efcc25c64..8edd80c1090 100644
--- a/engines/tetraedge/game/lua_binds.cpp
+++ b/engines/tetraedge/game/lua_binds.cpp
@@ -766,11 +766,11 @@ static int tolua_ExportedFunctions_SetCharacterOrientation00(lua_State *L) {
error("#ferror in function 'SetCharacterOrientation': %d %d %s", err.index, err.array, err.type);
}
-static void SetCharacterAnimation(const Common::String &charname, const Common::String &animname, bool repeat, bool b2, int startframe, int endframe) {
+static void SetCharacterAnimation(const Common::String &charname, const Common::String &animname, bool repeat, bool returnToIdle, int startframe, int endframe) {
Game *game = g_engine->getGame();
Character *c = game->scene().character(charname);
assert(c);
- bool result = c->setAnimation(animname, repeat, b2, false, startframe, endframe);
+ bool result = c->setAnimation(animname, repeat, returnToIdle, false, startframe, endframe);
if (!result) {
warning("[SetCharacterAnimation] Character's animation \"%s\" doesn't exist for the character\"%s\" ",
animname.c_str(), charname.c_str());
@@ -825,10 +825,10 @@ static int tolua_ExportedFunctions_SetCharacterAnimationAndWaitForEnd00(lua_Stat
error("#ferror in function 'SetCharacterAnimationAndWaitForEnd': %d %d %s", err.index, err.array, err.type);
}
-static void BlendCharacterAnimation(const Common::String &charname, const Common::String &animname, float blendAmount, bool repeat, bool b2) {
+static void BlendCharacterAnimation(const Common::String &charname, const Common::String &animname, float blendAmount, bool repeat, bool returnToIdle) {
Game *game = g_engine->getGame();
Character *c = game->scene().character(charname);
- bool result = c->blendAnimation(animname, blendAmount, repeat, b2);
+ bool result = c->blendAnimation(animname, blendAmount, repeat, returnToIdle);
if (!result) {
warning("[BlendCharacterAnimation] Character's animation \"%s\" doesn't exist for the character\"%s\" ",
animname.c_str(), charname.c_str());
@@ -1902,9 +1902,9 @@ static int tolua_ExportedFunctions_UnloadCharacter00(lua_State *L) {
error("#ferror in function 'UnloadCharacter': %d %d %s", err.index, err.array, err.type);
}
-static void MoveCharacterTo(const Common::String &charName, const Common::String &curveName, float f1,float f2) {
+static void MoveCharacterTo(const Common::String &charName, const Common::String &curveName, float curveStart, float curveEnd) {
Game *game = g_engine->getGame();
- game->scene().moveCharacterTo(charName, curveName, f1, f2);
+ game->scene().moveCharacterTo(charName, curveName, curveStart, curveEnd);
}
static int tolua_ExportedFunctions_MoveCharacterTo00(lua_State *L) {
diff --git a/engines/tetraedge/game/scene_lights_xml_parser.cpp b/engines/tetraedge/game/scene_lights_xml_parser.cpp
index 2d2da20620b..d7633185fa9 100644
--- a/engines/tetraedge/game/scene_lights_xml_parser.cpp
+++ b/engines/tetraedge/game/scene_lights_xml_parser.cpp
@@ -70,6 +70,12 @@ bool SceneLightsXmlParser::parserCallback_Lights(ParserNode *node) {
bool SceneLightsXmlParser::parserCallback_Light(ParserNode *node) {
_parent = Parent_Light;
_lights->push_back(TeLight());
+ TeLightType ltype = TeLightType::LightTypeDirectional;
+ if (node->values["Type"] == "Spot")
+ ltype = TeLightType::LightTypeSpot;
+ else if (node->values["Type"] == "Point")
+ ltype = TeLightType::LightTypePoint;
+ _lights->back().setType(ltype);
return true;
}
@@ -82,8 +88,8 @@ bool SceneLightsXmlParser::parserCallback_Position(ParserNode *node) {
}
bool SceneLightsXmlParser::parserCallback_Direction(ParserNode *node) {
- float h = (atof(node->values["h"].c_str()) * 3.141593) / 180.0;
- float v = (atof(node->values["v"].c_str()) * 3.141593) / 180.0;
+ float h = (atof(node->values["h"].c_str()) * M_PI) / 180.0;
+ float v = (atof(node->values["v"].c_str()) * M_PI) / 180.0;
_lights->back().setPositionRadial(TeVector2f32(h, v));
return true;
}
@@ -115,7 +121,7 @@ bool SceneLightsXmlParser::parserCallback_Attenuation(ParserNode *node) {
bool SceneLightsXmlParser::parserCallback_Cutoff(ParserNode *node) {
float f = atof(node->values["value"].c_str());
- _lights->back().setCutoff((f * 3.141593) / 180.0);
+ _lights->back().setCutoff((f * M_PI) / 180.0);
return true;
}
diff --git a/engines/tetraedge/game/splash_screens.cpp b/engines/tetraedge/game/splash_screens.cpp
index adbd33f04d4..f27f318b0be 100644
--- a/engines/tetraedge/game/splash_screens.cpp
+++ b/engines/tetraedge/game/splash_screens.cpp
@@ -68,7 +68,7 @@ bool SplashScreens::onAlarm() {
load(scriptName);
TeButtonLayout *btnLayout = buttonLayout("splash");
- btnLayout->onMouseClickValidated().add<SplashScreens>(this, &SplashScreens::onQuitSplash);
+ btnLayout->onMouseClickValidated().add(this, &SplashScreens::onQuitSplash);
TeLayout *splash = layout("splash");
app->_frontLayout.addChild(splash);
diff --git a/engines/tetraedge/metaengine.cpp b/engines/tetraedge/metaengine.cpp
index ea4c2035e6c..d4d1fb4b9e7 100644
--- a/engines/tetraedge/metaengine.cpp
+++ b/engines/tetraedge/metaengine.cpp
@@ -39,10 +39,15 @@ bool TetraedgeMetaEngine::hasFeature(MetaEngineFeature f) const {
(f == kSupportsListSaves) ||
(f == kSupportsDeleteSave) ||
(f == kSavesSupportMetaInfo) ||
- (f == kSavesSupportThumbnail) ||
+ // (f == kSavesSupportThumbnail) || // TODO: support save thumbnail
(f == kSupportsLoadingDuringStartup);
}
+void TetraedgeMetaEngine::getSavegameThumbnail(Graphics::Surface &thumb) {
+ thumb.create(320, 200, Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24));
+}
+
+
#if PLUGIN_ENABLED_DYNAMIC(TETRAEDGE)
REGISTER_PLUGIN_DYNAMIC(TETRAEDGE, PLUGIN_TYPE_ENGINE, TetraedgeMetaEngine);
#else
diff --git a/engines/tetraedge/metaengine.h b/engines/tetraedge/metaengine.h
index 13a43c89711..a992757f82d 100644
--- a/engines/tetraedge/metaengine.h
+++ b/engines/tetraedge/metaengine.h
@@ -31,6 +31,8 @@ public:
Common::Error createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const override;
+ void getSavegameThumbnail(Graphics::Surface &thumb) override;
+
/**
* Determine whether the engine supports the specified MetaEngine feature.
*
diff --git a/engines/tetraedge/te/te_bezier_curve.cpp b/engines/tetraedge/te/te_bezier_curve.cpp
index 8846cbbfd3a..400fbd1fc55 100644
--- a/engines/tetraedge/te/te_bezier_curve.cpp
+++ b/engines/tetraedge/te/te_bezier_curve.cpp
@@ -28,7 +28,7 @@
namespace Tetraedge {
TeBezierCurve::TeBezierCurve() : _length(0.0), _rawLength(0.0), _lengthNeedsUpdate(true),
-_rawLengthNeedsUpdate(true), _numiterations(1000) {
+_rawLengthNeedsUpdate(true), _numIterations(1000) {
}
//long TeBezierCurve::bounds(int start);
@@ -81,8 +81,8 @@ float TeBezierCurve::length() {
TeVector3f32 lastpt = _controlPoints[0];
lastpt.y() = 0;
- for (unsigned int i = 0; i < _numiterations; i++) {
- float amount = (float)i / _numiterations;
+ for (unsigned int i = 0; i < _numIterations; i++) {
+ float amount = (float)i / _numIterations;
TeVector3f32 pt = retrievePoint(amount);
pt.y() = 0;
float len = (lastpt - pt).length();
@@ -95,10 +95,10 @@ float TeBezierCurve::length() {
}
void TeBezierCurve::pseudoTangent(float offset, TeVector3f32 &v1, TeVector3f32 &v2) {
- const float step = 1.0f / _numiterations;
+ const float step = 1.0f / _numIterations;
if (step + offset <= 1.0f) {
v1 = retrievePoint(offset);
- v2 = retrievePoint(step + offset);
+ v2 = retrievePoint(offset + step);
} else {
v1 = retrievePoint(offset - step);
v2 = retrievePoint(offset);
@@ -182,7 +182,7 @@ void TeBezierCurve::setControlPoints(const Common::Array<TeVector3f32> &points)
void TeBezierCurve::setNbIterations(unsigned long iterations) {
_lengthNeedsUpdate = true;
_rawLengthNeedsUpdate = true;
- _numiterations = iterations;
+ _numIterations = iterations;
}
/*static*/
diff --git a/engines/tetraedge/te/te_bezier_curve.h b/engines/tetraedge/te/te_bezier_curve.h
index 2f199203b2f..358edb65a81 100644
--- a/engines/tetraedge/te/te_bezier_curve.h
+++ b/engines/tetraedge/te/te_bezier_curve.h
@@ -52,10 +52,10 @@ public:
static void deserialize(Common::ReadStream &stream, TeBezierCurve &curve);
const Common::Array<TeVector3f32> &controlPoints() { return _controlPoints; }
- unsigned int numIterations() const { return _numiterations; }
+ unsigned int numIterations() const { return _numIterations; }
private:
- unsigned int _numiterations;
+ unsigned int _numIterations;
float _length;
float _rawLength;
bool _lengthNeedsUpdate;
diff --git a/engines/tetraedge/te/te_button_layout.cpp b/engines/tetraedge/te/te_button_layout.cpp
index 977bd535bc8..4aac314f8bd 100644
--- a/engines/tetraedge/te/te_button_layout.cpp
+++ b/engines/tetraedge/te/te_button_layout.cpp
@@ -105,10 +105,12 @@ bool TeButtonLayout::onMouseLeftDown(const Common::Point &pt) {
enum State newState = _currentState;
switch (_currentState) {
case BUTTON_STATE_DOWN:
- newState = BUTTON_STATE_UP;
+ if (!mouseIn)
+ newState = BUTTON_STATE_UP;
/*
// TODO: should this be a click?
if (mouseIn) {
+ newState = BUTTON_STATE_UP;
debug("mouse clicked button '%s' (from leftdown)", name().c_str());
if (!_validationSound.empty()) {
TeSoundManager *sndMgr = g_engine->getSoundManager();
@@ -128,10 +130,6 @@ bool TeButtonLayout::onMouseLeftDown(const Common::Point &pt) {
break;
}
setState(newState);
- // FIXME: Why does this item block the mouse events.. should be below
- // the "yes" button but seems it's not?
- if (name() == "menu")
- return false;
return mouseIn && !_clickPassThrough;
}
@@ -140,7 +138,7 @@ bool TeButtonLayout::onMouseLeftUp(const Common::Point &pt) {
return false;
// Note: This doesn't exactly reproduce the original behavior, it's
- // very simplified.
+ // somewhat simplified.
bool mouseIn = isMouseIn(pt);
if (mouseIn)
@@ -158,10 +156,6 @@ bool TeButtonLayout::onMouseLeftUp(const Common::Point &pt) {
}
setState(newState);
_onMouseClickValidatedSignal.call();
- // FIXME: Why does this item block the mouse events.. should be below
- // the "yes" button but seems it's not?
- if (name() == "menu")
- return false;
return !_clickPassThrough;
}
break;
diff --git a/engines/tetraedge/te/te_core.cpp b/engines/tetraedge/te/te_core.cpp
index a85315b77f0..8f586a7d495 100644
--- a/engines/tetraedge/te/te_core.cpp
+++ b/engines/tetraedge/te/te_core.cpp
@@ -49,7 +49,7 @@ void TeCore::create() {
// TODO: Get language from the game definition. For now just default to en.
language("en");
_coreNotReady = false;
- _activityTrackingTimer.alarmSignal().add<TeCore>(this, &TeCore::onActivityTrackingAlarm);
+ _activityTrackingTimer.alarmSignal().add(this, &TeCore::onActivityTrackingAlarm);
warning("TODO: TeCore::create: Finish implementing me.");
}
diff --git a/engines/tetraedge/te/te_light.cpp b/engines/tetraedge/te/te_light.cpp
index f02c6990e8b..61ed3f02339 100644
--- a/engines/tetraedge/te/te_light.cpp
+++ b/engines/tetraedge/te/te_light.cpp
@@ -38,7 +38,7 @@ static inline uint _toGlLight(uint lightno) {
TeColor TeLight::_globalAmbientColor;
TeLight::TeLight() : _colAmbient(0, 0, 0, 0xff), _colDiffuse(0, 0, 0, 0xff), _colSpecular(0xff, 0xff, 0xff, 0xff),
-_constAtten(0.0f), _linearAtten(1.0f), _quadraticAtten(0.0f), _cutoff(0.0f), _exponent(0.0f), _type(LightTypePoint),
+_constAtten(1.0f), _linearAtten(0.0f), _quadraticAtten(0.0f), _cutoff(0.0f), _exponent(0.0f), _type(LightTypePoint),
_displaySize(3.0)
{
}
@@ -122,9 +122,9 @@ void TeLight::update(uint lightno) {
pos[2] = _position3d.z();
pos[3] = 1.0f;
glLightfv(glLight, GL_POSITION, pos);
- glLightfv(glLight, GL_CONSTANT_ATTENUATION, &_constAtten);
- glLightfv(glLight, GL_LINEAR_ATTENUATION, &_linearAtten);
- glLightfv(glLight, GL_QUADRATIC_ATTENUATION, &_quadraticAtten);
+ glLightf(glLight, GL_CONSTANT_ATTENUATION, _constAtten);
+ glLightf(glLight, GL_LINEAR_ATTENUATION, _linearAtten);
+ glLightf(glLight, GL_QUADRATIC_ATTENUATION, _quadraticAtten);
}
if (_type == LightTypeDirectional) {
@@ -140,8 +140,6 @@ void TeLight::update(uint lightno) {
glLightfv(glLight, GL_POSITION, pos);
}
- float atten;
- uint atype;
if (_type == LightTypeSpot) {
float pos[4];
float cosx = cosf(_positionRadial.getX());
@@ -154,13 +152,10 @@ void TeLight::update(uint lightno) {
pos[3] = 0.0;
glLightfv(glLight, GL_SPOT_DIRECTION, pos);
glLightf(glLight, GL_SPOT_CUTOFF, (_cutoff * 180.0) / M_PI);
- atten = _exponent;
- atype = GL_SPOT_EXPONENT;
+ glLightf(glLight, GL_SPOT_EXPONENT, _exponent);
} else {
- atten = 180.0;
- atype = GL_SPOT_CUTOFF;
+ glLightf(glLight, GL_SPOT_CUTOFF, 180.0);
}
- glLightf(glLight, atype, atten);
}
/*static*/
diff --git a/engines/tetraedge/te/te_light.h b/engines/tetraedge/te/te_light.h
index 72f2a05cd38..2ed67430525 100644
--- a/engines/tetraedge/te/te_light.h
+++ b/engines/tetraedge/te/te_light.h
@@ -67,6 +67,7 @@ public:
void setDisplaySize(float val) { _displaySize = val; }
void setPosition3d(const TeVector3f32 &pos) { _position3d = pos; }
void setPositionRadial(const TeVector2f32 &pos) { _positionRadial = pos; }
+ void setType(TeLightType ltype) { _type = ltype; }
const TeVector2f32 &positionRadial() const { return _positionRadial; }
const TeVector3f32 &position3d() const { return _position3d; }
diff --git a/engines/tetraedge/te/te_lua_context.cpp b/engines/tetraedge/te/te_lua_context.cpp
index dff65386901..10a2f85ca54 100644
--- a/engines/tetraedge/te/te_lua_context.cpp
+++ b/engines/tetraedge/te/te_lua_context.cpp
@@ -114,5 +114,92 @@ void TeLuaContext::setInRegistry(const Common::String &name, TeLuaGUI *gui) {
lua_settable(_luaState, LUA_REGISTRYINDEX);
}
+// Types for save file. Aligned with the Lua types at type of
+// writing, but don't save them just in case they could change.
+enum TeLuaSaveVarType {
+ None = 0,
+ Boolean = 1,
+ Number = 3,
+ String = 4
+};
+
+Common::Error TeLuaContext::syncState(Common::Serializer &s) {
+ // Save/Load globals. The format of saving is:
+ // [type][name][val] [type][name][val]...
+ // The type of "None" (0) is the end of the list (and has no name/val).
+ if (s.isSaving()) {
+ lua_pushvalue(_luaState, LUA_GLOBALSINDEX);
+ lua_pushnil(_luaState);
+ int nextresult = lua_next(_luaState, -2);
+ while (true) {
+ if (nextresult == 0) {
+ TeLuaSaveVarType stype = None;
+ s.syncAsUint32LE(stype);
+ lua_settop(_luaState, -2);
+ break;
+ }
+ unsigned int vtype = lua_type(_luaState, -1);
+ if (vtype == LUA_TBOOLEAN) {
+ TeLuaSaveVarType stype = Boolean;
+ Common::String name = lua_tolstring(_luaState, -2, nullptr);
+ s.syncAsUint32LE(stype);
+ s.syncString(name);
+ bool val = lua_toboolean(_luaState, -1);
+ s.syncAsByte(val);
+ } else if (vtype == LUA_TNUMBER) {
+ TeLuaSaveVarType stype = Number;
+ Common::String name = lua_tolstring(_luaState, -2, nullptr);
+ s.syncAsUint32LE(stype);
+ s.syncString(name);
+ double val = lua_tonumber(_luaState, -1);
+ s.syncAsDoubleLE(val);
+ } else if (vtype == LUA_TSTRING) {
+ TeLuaSaveVarType stype = String;
+ Common::String name = lua_tolstring(_luaState, -2, nullptr);
+ s.syncAsUint32LE(stype);
+ s.syncString(name);
+ Common::String val = lua_tostring(_luaState, -1);
+ s.syncString(val);
+ }
+ lua_settop(_luaState, -2);
+ nextresult = lua_next(_luaState, -2);
+ }
+ } else {
+ warning("Confirm loading in TeLuaContext::syncState");
+ // loading
+ TeLuaSaveVarType vtype = None;
+ s.syncAsUint32LE(vtype);
+ while (vtype != None) {
+ switch (vtype) {
+ case Boolean: {
+ byte b;
+ s.syncAsByte(b);
+ lua_pushboolean(_luaState, b);
+ break;
+ }
+ case Number: {
+ float d;
+ s.syncAsDoubleLE(d);
+ lua_pushnumber(_luaState, d);
+ break;
+ }
+ case String: {
+ Common::String str;
+ s.syncString(str);
+ lua_pushstring(_luaState, str.c_str());
+ break;
+ }
+ default:
+ error("Unexpected lua type on load %d", (int)vtype);
+ }
+ Common::String name;
+ s.syncString(name);
+ lua_setglobal(_luaState, name.c_str());
+ s.syncAsUint32LE(vtype);
+ }
+ }
+
+ return Common::kNoError;
+}
} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_lua_context.h b/engines/tetraedge/te/te_lua_context.h
index aa62bec492f..47597ec5f59 100644
--- a/engines/tetraedge/te/te_lua_context.h
+++ b/engines/tetraedge/te/te_lua_context.h
@@ -22,7 +22,9 @@
#ifndef TETRAEDGE_TE_TE_LUA_CONTEXT_H
#define TETRAEDGE_TE_TE_LUA_CONTEXT_H
+#include "common/error.h"
#include "common/str.h"
+#include "common/serializer.h"
#include "tetraedge/te/te_variant.h"
@@ -67,6 +69,9 @@ public:
void setGlobal(const Common::String &name, const Common::String &val);
void setInRegistry(const Common::String &name, TeLuaGUI *gui);
+
+ Common::Error syncState(Common::Serializer &s);
+
private:
lua_State *_luaState;
};
diff --git a/engines/tetraedge/te/te_lua_gui_lua_callbacks.cpp b/engines/tetraedge/te/te_lua_gui_lua_callbacks.cpp
index e8d8c93ad04..a7dbead85b3 100644
--- a/engines/tetraedge/te/te_lua_gui_lua_callbacks.cpp
+++ b/engines/tetraedge/te/te_lua_gui_lua_callbacks.cpp
@@ -400,6 +400,12 @@ int spriteLayoutBindings(lua_State *L) {
layout->setName(Common::String::format("%p", (void *)layout));
}
+ // WORKAROUND: ValStreet scene 11070 has a misnamed animation in the script.
+ // All references to it in script refer to it with the "ab".
+ // This scene is broken in the original game too.
+ if (layout->name() == "11070-1")
+ layout->setName("ab11070-1");
+
if (playNow) {
layout->play();
} else {
diff --git a/engines/tetraedge/te/te_model.cpp b/engines/tetraedge/te/te_model.cpp
index ebafd7b232e..5757a99031b 100644
--- a/engines/tetraedge/te/te_model.cpp
+++ b/engines/tetraedge/te/te_model.cpp
@@ -191,7 +191,7 @@ void TeModel::update() {
TeTRS trs = getBone(_modelAnim, b);
for (unsigned int i = 0; i < _boneBlenders.size(); i++) {
BonesBlender *blender = _boneBlenders[i];
- float complete = MIN((blender->_timer.getTimeFromStart() / 1000000.0f) / blender->_seconds, 1.0f);
+ float complete = blender->coef();
TeTRS endTRS = getBone(blender->_anim, b);
if (complete == 1.0f) {
delete blender;
diff --git a/engines/tetraedge/te/te_model_animation.cpp b/engines/tetraedge/te/te_model_animation.cpp
index 83c1c1f2716..effca334c15 100644
--- a/engines/tetraedge/te/te_model_animation.cpp
+++ b/engines/tetraedge/te/te_model_animation.cpp
@@ -25,6 +25,8 @@
#include "common/substream.h"
#include "common/zlib.h"
+#include "tetraedge/tetraedge.h"
+#include "tetraedge/te/te_core.h"
#include "tetraedge/te/te_model_animation.h"
namespace Tetraedge {
@@ -180,8 +182,9 @@ int TeModelAnimation::lastFrame() const {
}
bool TeModelAnimation::load(const Common::Path &path) {
+ Common::Path foundPath = g_engine->getCore()->findFile(path);
Common::File modelFile;
- if (!modelFile.open(path)) {
+ if (!modelFile.open(foundPath)) {
warning("[TeModel::load] Can't open file : %s.", path.toString().c_str());
return false;
}
diff --git a/engines/tetraedge/te/te_name_val_xml_parser.cpp b/engines/tetraedge/te/te_name_val_xml_parser.cpp
index 50e89b8605c..c5a4d96f0be 100644
--- a/engines/tetraedge/te/te_name_val_xml_parser.cpp
+++ b/engines/tetraedge/te/te_name_val_xml_parser.cpp
@@ -25,7 +25,17 @@ namespace Tetraedge {
// Parser callback methods
bool TeNameValXmlParser::parserCallback_value(ParserNode *node) {
- _map.setVal(node->values["name"], node->values["value"]);
+ Common::String valStr = node->values["value"];
+
+ // Replace """ with " character. This is the only character
+ // entity used in the game files.
+ unsigned int qpos = valStr.find(""");
+ while (qpos != Common::String::npos) {
+ valStr.replace(qpos, 6, "\"");
+ qpos = valStr.find(""");
+ }
+
+ _map.setVal(node->values["name"], valStr);
return true;
}
diff --git a/engines/tetraedge/te/te_text_base2.cpp b/engines/tetraedge/te/te_text_base2.cpp
index a8da12c91ca..8a0e602b69b 100644
--- a/engines/tetraedge/te/te_text_base2.cpp
+++ b/engines/tetraedge/te/te_text_base2.cpp
@@ -53,7 +53,10 @@ void TeTextBase2::build() {
_size = TeVector2s32(0, 0);
_wrappedLines.clear();
- font->wordWrapText(_text, _fontSize, _drawRect._x, _wrappedLines);
+ if (_text.find(' ') != Common::String::npos)
+ font->wordWrapText(_text, _fontSize, _drawRect._x, _wrappedLines);
+ else
+ _wrappedLines.push_back(_text);
Common::Array<float> lineoffsets;
float lineHeight = font->getHeight(_fontSize);
diff --git a/engines/tetraedge/te/te_text_layout.cpp b/engines/tetraedge/te/te_text_layout.cpp
index 8fe5cbb9d11..db3a34aeadf 100644
--- a/engines/tetraedge/te/te_text_layout.cpp
+++ b/engines/tetraedge/te/te_text_layout.cpp
@@ -151,27 +151,17 @@ const TeVector2s32 &TeTextLayout::textSize() const {
return _base.size();
}
-static int _roundVal(int i) {
- // this is a weird/broken rounding but seems to match
- // the original?
- i = ((i & 1) | (i >> 1));
- return i + i;
-}
-
void TeTextLayout::updateSize() {
if (!_sizeChanged)
return;
TeLayout::updateSize();
- TeMatrix4x4 transform = transformationMatrix();
- static const TeVector3f32 zeroVec(0, 0, 0);
- static const TeVector3f32 xUnitVec(1, 0, 0);
- static const TeVector3f32 yUnitVec(0, 1, 0);
+ TeMatrix4x4 transform = worldTransformationMatrix();
- const TeVector3f32 v1 = transform * zeroVec;
- const TeVector3f32 v2 = transform * xUnitVec;
- const TeVector3f32 v3 = transform * yUnitVec;
+ const TeVector3f32 v1 = transform * TeVector3f32(0, 0, 0);
+ const TeVector3f32 v2 = transform * TeVector3f32(1, 0, 0);
+ const TeVector3f32 v3 = transform * TeVector3f32(0, 1, 0);
const TeVector3f32 newSize((v2 - v1).length(), (v3 - v1).length(), 1.0);
const TeVector3f32 thisSize = size();
@@ -181,25 +171,12 @@ void TeTextLayout::updateSize() {
float newFontSize = 0;
if (_textSizeType == 0 || (_textSizeType == 1 && _textSizeProportionalToWidth == 0)) {
- if (_baseFontSize < 0)
- newFontSize = _roundVal(_baseFontSize);
- else
- newFontSize = _baseFontSize;
- } else if (_textSizeType == 1) {
newFontSize = _baseFontSize;
- float sizeProportionalToWidth = _textSizeProportionalToWidth;
- if (_textSizeProportionalToWidth < 0)
- sizeProportionalToWidth = _roundVal(_textSizeProportionalToWidth);
- else
- sizeProportionalToWidth = _textSizeProportionalToWidth;
- if (_baseFontSize < 0)
- newFontSize = _roundVal(_baseFontSize);
- else
- newFontSize = _baseFontSize;
- newFontSize = (thisSize.x() / sizeProportionalToWidth) * newFontSize;
+ } else if (_textSizeType == 1) {
+ newFontSize = (thisSize.x() / _textSizeProportionalToWidth) * _baseFontSize;
}
- //newFontSize *= thisSize.y();
+ newFontSize *= newSize.y();
_base.setFontSize(newFontSize);
_base.build();
diff --git a/engines/tetraedge/te/te_tiled_surface.cpp b/engines/tetraedge/te/te_tiled_surface.cpp
index 1e4245b803a..0b4337f9463 100644
--- a/engines/tetraedge/te/te_tiled_surface.cpp
+++ b/engines/tetraedge/te/te_tiled_surface.cpp
@@ -34,7 +34,7 @@ static void getRangeIntersection(float start1,float end1,float start2,float end2
TeTiledSurface::TeTiledSurface() : _shouldDraw(true), _codec(nullptr), _colorKeyActive(false), _colorKeyTolerence(0),
_bottomCrop(0), _topCrop(0), _leftCrop(0), _rightCrop(0), _imgFormat(TeImage::INVALID) {
- _frameAnim.frameChangedSignal().add<TeTiledSurface>(this, &TeTiledSurface::onFrameAnimCurrentFrameChanged);
+ _frameAnim.frameChangedSignal().add(this, &TeTiledSurface::onFrameAnimCurrentFrameChanged);
}
void TeTiledSurface::cont() {
diff --git a/engines/tetraedge/te/te_timer.h b/engines/tetraedge/te/te_timer.h
index 1cf59ac72ff..824dfd70539 100644
--- a/engines/tetraedge/te/te_timer.h
+++ b/engines/tetraedge/te/te_timer.h
@@ -23,6 +23,7 @@
#define TETRAEDGE_TE_TE_TIMER_H
#include "common/array.h"
+
#include "tetraedge/te/te_signal.h"
#include "tetraedge/te/te_real_timer.h"
diff --git a/engines/tetraedge/tetraedge.cpp b/engines/tetraedge/tetraedge.cpp
index 2b7329ad40b..8582389c303 100644
--- a/engines/tetraedge/tetraedge.cpp
+++ b/engines/tetraedge/tetraedge.cpp
@@ -27,6 +27,7 @@
#include "common/debug-channels.h"
#include "common/events.h"
#include "common/system.h"
+#include "common/savefile.h"
#include "engines/util.h"
#include "engines/dialogs.h"
#include "graphics/palette.h"
@@ -125,6 +126,39 @@ Common::String TetraedgeEngine::getGameId() const {
return _gameDescription->gameId;
}
+bool TetraedgeEngine::canSaveGameStateCurrently() {
+ return canSaveAutosaveCurrently() && !_application->isLockCursor();
+}
+
+bool TetraedgeEngine::canSaveAutosaveCurrently() {
+ return _game && _application && _game->running()
+ && !_game->currentScene().empty() && !_game->currentZone().empty();
+}
+
+Common::Error TetraedgeEngine::loadGameState(int slot) {
+ // In case autosaves are on, do a save first before loading the new save
+ saveAutosaveIfEnabled();
+
+ Common::String saveStateName = getSaveStateName(slot);
+
+ Common::InSaveFile *saveFile = getSaveFileManager()->openForLoading(saveStateName);
+
+ if (!saveFile)
+ return Common::kReadingFailed;
+
+ // The game will reopen the file and do the loading, see Game::initLoadedBackupData
+ _game->setLoadName(saveStateName);
+
+ delete saveFile;
+ return Common::kNoError;
+}
+
+Common::Error TetraedgeEngine::loadGameStream(Common::SeekableReadStream *stream) {
+ Common::Serializer s(stream, nullptr);
+ Common::Error retval = syncGame(s);
+ return retval;
+}
+
void TetraedgeEngine::configureSearchPaths() {
const Common::FSNode gameDataDir(ConfMan.get("path"));
SearchMan.addSubDirectoryMatching(gameDataDir, "Resources", 0, 5);
@@ -167,8 +201,6 @@ Common::Error TetraedgeEngine::run() {
_application->run();
- // Delay for a bit. All events loops should have a delay
- // to prevent the system being unduly loaded
g_system->delayMillis(10);
}
@@ -176,14 +208,7 @@ Common::Error TetraedgeEngine::run() {
}
Common::Error TetraedgeEngine::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;
+ return getGame()->syncGame(s);
}
void TetraedgeEngine::openConfigDialog() {
diff --git a/engines/tetraedge/tetraedge.h b/engines/tetraedge/tetraedge.h
index b1cd26b2948..f942697df21 100644
--- a/engines/tetraedge/tetraedge.h
+++ b/engines/tetraedge/tetraedge.h
@@ -92,9 +92,9 @@ public:
bool canLoadGameStateCurrently() override {
return true;
}
- bool canSaveGameStateCurrently() override {
- return true;
- }
+
+ bool canSaveGameStateCurrently() override;
+ bool canSaveAutosaveCurrently() override;
/**
* Uses a serializer to allow implementing savegame
@@ -106,11 +106,9 @@ public:
Common::Serializer s(nullptr, stream);
return syncGame(s);
}
- Common::Error loadGameStream(Common::SeekableReadStream *stream) override {
- Common::Serializer s(stream, nullptr);
- return syncGame(s);
- }
+ Common::Error loadGameState(int slot) override;
+ Common::Error loadGameStream(Common::SeekableReadStream *stream) override;
int getDefaultScreenWidth() const;
int getDefaultScreenHeight() const;
diff --git a/engines/tetraedge/to_lua.cpp b/engines/tetraedge/to_lua.cpp
index 979732d03d4..ffc930156a2 100644
--- a/engines/tetraedge/to_lua.cpp
+++ b/engines/tetraedge/to_lua.cpp
@@ -32,7 +32,7 @@ static char toluaname[128] = "tolua.";
static void tolua_push_globals_table(lua_State *L) {
/*
- lua_pushvalue(L, LUA_REGISTRYINDEX);
+ lua_pushvalue(L, LUA_GLOBALSINDEX);
lua_pushnumber(L, 2.0);
lua_rawget(L, -2);
lua_remove(L, -2);
Commit: 769d8d9b42f34faccef8b90e71f79a55b783e8bb
https://github.com/scummvm/scummvm/commit/769d8d9b42f34faccef8b90e71f79a55b783e8bb
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2023-01-16T17:36:43+01:00
Commit Message:
TETRAEDGE: Fix a lot of small rendering bugs.
Changed paths:
engines/tetraedge/game/application.cpp
engines/tetraedge/game/game.cpp
engines/tetraedge/game/in_game_scene.cpp
engines/tetraedge/game/inventory.cpp
engines/tetraedge/game/lua_binds.cpp
engines/tetraedge/te/te_3d_texture.cpp
engines/tetraedge/te/te_font3.cpp
engines/tetraedge/te/te_free_move_zone.cpp
engines/tetraedge/te/te_free_move_zone.h
engines/tetraedge/te/te_lua_context.cpp
engines/tetraedge/te/te_mesh.cpp
engines/tetraedge/te/te_model.cpp
engines/tetraedge/te/te_sprite_layout.cpp
engines/tetraedge/te/te_text_base2.cpp
engines/tetraedge/te/te_vector2s32.cpp
engines/tetraedge/te/te_vector2s32.h
engines/tetraedge/te/te_visual_fade.cpp
engines/tetraedge/tetraedge.cpp
diff --git a/engines/tetraedge/game/application.cpp b/engines/tetraedge/game/application.cpp
index 9055246d13e..4f99e4aeb5f 100644
--- a/engines/tetraedge/game/application.cpp
+++ b/engines/tetraedge/game/application.cpp
@@ -91,6 +91,7 @@ void Application::create() {
_mainWindow.setSize(TeVector3f32(winWidth, winHeight, 0.0));
_mainWindow.setSizeType(TeILayout::ABSOLUTE);
_mainWindow.setPositionType(TeILayout::ABSOLUTE);
+ _mainWindow.setPosition(TeVector3f32(0.0f, 0.0f ,0.0f));
TeResourceManager *resmgr = g_engine->getResourceManager();
_fontComic = resmgr->getResourceNoSearch<TeFont3>("Common/Fonts/ComicRelief.ttf");
diff --git a/engines/tetraedge/game/game.cpp b/engines/tetraedge/game/game.cpp
index fae906c6526..846691cc696 100644
--- a/engines/tetraedge/game/game.cpp
+++ b/engines/tetraedge/game/game.cpp
@@ -387,6 +387,8 @@ void Game::finishGame() {
void Game::initLoadedBackupData() {
bool warpFlag = true;
+ Application *app = g_engine->getApplication();
+ Common::String firstWarpPath;
if (!_loadName.empty()) {
warpFlag = false;
Common::InSaveFile *saveFile = g_engine->getSaveFileManager()->openForLoading(_loadName);
@@ -396,19 +398,19 @@ void Game::initLoadedBackupData() {
if (MetaEngine::readSavegameHeader(saveFile, &header))
g_engine->setTotalPlayTime(header.playtime);
}
+ } else {
+ firstWarpPath = app->_firstWarpPath;
+ _currentScene = app->_firstScene;
+ _currentZone = app->_firstZone;
+ _playedTimer.start();
+ _objectsTakenVal = 0;
+ for (int i = 0; i < ARRAYSIZE(_objectsTakenBits); i++) {
+ _objectsTakenBits[i] = 0;
+ }
+ _dialogsTold = 0;
+ if (_loadName == "NO_OWNER")
+ _luaShowOwnerError = true;
}
- Application *app = g_engine->getApplication();
- const Common::String firstWarpPath = app->_firstWarpPath;
- _currentScene = app->_firstScene;
- _currentZone = app->_firstZone;
- _playedTimer.start();
- _objectsTakenVal = 0;
- for (int i = 0; i < ARRAYSIZE(_objectsTakenBits); i++) {
- _objectsTakenBits[i] = 0;
- }
- _dialogsTold = 0;
- if (_loadName == "NO_OWNER")
- _luaShowOwnerError = true;
_gameLoadState = 0;
app->showLoadingIcon(false);
_loadName.clear();
@@ -798,13 +800,13 @@ bool Game::onCallNumber(Common::String val) {
return false;
}
-bool Game::onCharacterAnimationFinished(const Common::String &val) {
+bool Game::onCharacterAnimationFinished(const Common::String &charName) {
if (!_scene._character)
return false;
for (unsigned int i = 0; i < _yieldedCallbacks.size(); i++) {
YieldedCallback &cb = _yieldedCallbacks[i];
- if (cb._luaFnName == "OnCharacterAnimationFinished" && cb._luaParam == val) {
+ if (cb._luaFnName == "OnCharacterAnimationFinished" && cb._luaParam == charName) {
TeLuaThread *lua = cb._luaThread;
_yieldedCallbacks.remove_at(i);
if (lua) {
@@ -814,7 +816,7 @@ bool Game::onCharacterAnimationFinished(const Common::String &val) {
break;
}
}
- _luaScript.execute("OnCharacterAnimationFinished", val);
+ _luaScript.execute("OnCharacterAnimationFinished", charName);
return false;
}
diff --git a/engines/tetraedge/game/in_game_scene.cpp b/engines/tetraedge/game/in_game_scene.cpp
index 6e04185834a..fc9df5e7ff6 100644
--- a/engines/tetraedge/game/in_game_scene.cpp
+++ b/engines/tetraedge/game/in_game_scene.cpp
@@ -105,8 +105,8 @@ bool InGameScene::addMarker(const Common::String &markerName, const Common::Stri
newPos.x() = frontLayoutSize.x() * (x / 100.0);
newPos.y() = frontLayoutSize.y() * (y / 100.0);
} else {
- newPos.x() = x / 800.0;
- newPos.y() = y / 600.0;
+ newPos.x() = x / g_engine->getDefaultScreenWidth();
+ newPos.y() = y / g_engine->getDefaultScreenHeight();
}
markerSprite->setPosition(newPos);
@@ -865,9 +865,11 @@ void InGameScene::loadInteractions(const Common::Path &path) {
Game *game = g_engine->getGame();
TeSpriteLayout *root = game->findSpriteLayoutByName(bgbackground, "root");
TeLayout *background = _hitObjectGui.layoutChecked("background");
- // TODO: For all TeButtonLayout childen of background, call
- // setDoubleValidationProtectionEnabled(false)
- // For now our button doesn't implement that.
+ for (auto *child : background->childList()) {
+ TeButtonLayout *btn = dynamic_cast<TeButtonLayout *>(child);
+ if (btn)
+ btn->setDoubleValidationProtectionEnabled(false);
+ }
background->setRatioMode(TeILayout::RATIO_MODE_NONE);
root->addChild(background);
}
diff --git a/engines/tetraedge/game/inventory.cpp b/engines/tetraedge/game/inventory.cpp
index 40aa69fd1d3..aaf487d9bfb 100644
--- a/engines/tetraedge/game/inventory.cpp
+++ b/engines/tetraedge/game/inventory.cpp
@@ -498,25 +498,43 @@ bool Inventory::updateLayout() {
return false;
}
+#define DEBUG_SAVELOAD 1
+
Common::Error Inventory::syncState(Common::Serializer &s) {
unsigned int nitems = _invObjects.size();
s.syncAsUint32LE(nitems);
if (s.isLoading()) {
+#if DEBUG_SAVELOAD
+ debug("Inventory::syncState: --- Loading %d inventory items: ---", nitems);
+#endif
for (unsigned int i = 0; i < nitems; i++) {
Common::String objname;
s.syncString(objname);
addObject(objname);
+#if DEBUG_SAVELOAD
+ debug("Inventory::syncState: %s", objname.c_str());
+#endif
}
} else if (nitems) {
+#if DEBUG_SAVELOAD
+ debug("Inventory::syncState: --- Saving %d inventory items: --- ", _invObjects.size());
+#endif
// Add items in reverse order as the "addObject" on load will
// add to front of list.InventoryObject
auto iter = _invObjects.end();
while (iter != _invObjects.begin()) {
+ iter--;
Common::String objname = (*iter)->name();
s.syncString(objname);
- iter--;
+#if DEBUG_SAVELOAD
+ debug("Inventory::syncState: %s", objname.c_str());
+#endif
}
}
+
+#if DEBUG_SAVELOAD
+ debug("Inventory::syncState: -------- end --------");
+#endif
return Common::kNoError;
}
diff --git a/engines/tetraedge/game/lua_binds.cpp b/engines/tetraedge/game/lua_binds.cpp
index 8edd80c1090..0a199cffa0c 100644
--- a/engines/tetraedge/game/lua_binds.cpp
+++ b/engines/tetraedge/game/lua_binds.cpp
@@ -1716,9 +1716,13 @@ static int tolua_ExportedFunctions_PlayRandomSound00(lua_State *L) {
static void PlayMusic(const Common::String &path) {
TeMusic &music = g_engine->getApplication()->music();
+ // Note: stop and set repeat before starting,
+ // very slightly different to original because we can't
+ // change repeat value after starting.
+ music.stop();
+ music.repeat(false);
music.load(path);
music.play();
- music.repeat(false);
music.volume(1.0);
}
diff --git a/engines/tetraedge/te/te_3d_texture.cpp b/engines/tetraedge/te/te_3d_texture.cpp
index a129e438679..362582758a7 100644
--- a/engines/tetraedge/te/te_3d_texture.cpp
+++ b/engines/tetraedge/te/te_3d_texture.cpp
@@ -202,7 +202,17 @@ bool Te3DTexture::load(const TeImage &img) {
/*static*/
TeVector2s32 Te3DTexture::optimisedSize(const TeVector2s32 &size) {
- /* The maths here is a bit funky but it just picks the nearest power of 2 (up) */
+ //
+ // Note: When we enabled optimized sizes it leaves artifacts around movies
+ // etc unless the render size is exactly 800x600.
+ //
+ // This probably means there is a rounding error somewhere else, just leave
+ // off for now.
+ //
+ if (g_engine->getDefaultScreenWidth() != 800)
+ return size;
+
+ // The maths here is a bit funky but it just picks the nearest power of 2 (up)
int xsize = size._x - 1;
int ysize = size._y - 1;
@@ -224,6 +234,7 @@ TeVector2s32 Te3DTexture::optimisedSize(const TeVector2s32 &size) {
v2 = 8;
}
return TeVector2s32(v1, v2);
+
}
/*static*/
diff --git a/engines/tetraedge/te/te_font3.cpp b/engines/tetraedge/te/te_font3.cpp
index 54367dea86d..7ce34b4fa9b 100644
--- a/engines/tetraedge/te/te_font3.cpp
+++ b/engines/tetraedge/te/te_font3.cpp
@@ -86,7 +86,7 @@ Graphics::Font *TeFont3::getAtSize(unsigned int size) {
error("TeFont3::: Couldn't open font file %s.", getAccessName().toString().c_str());
_fontFile.seek(0);
- Graphics::Font *newFont = Graphics::loadTTFFont(_fontFile, size);
+ Graphics::Font *newFont = Graphics::loadTTFFont(_fontFile, size, Graphics::kTTFSizeModeCharacter, 0, Graphics::kTTFRenderModeNormal);
if (!newFont) {
error("TeFont3::: Couldn't load font %s at size %d.", _loadedPath.toString().c_str(), size);
}
diff --git a/engines/tetraedge/te/te_free_move_zone.cpp b/engines/tetraedge/te/te_free_move_zone.cpp
index 41185547d95..33aac199b26 100644
--- a/engines/tetraedge/te/te_free_move_zone.cpp
+++ b/engines/tetraedge/te/te_free_move_zone.cpp
@@ -81,8 +81,26 @@ float TeFreeMoveZone::bordersDistance() const {
return _graph->_bordersDistance;
}
+TeVector2s32 TeFreeMoveZone::aStarResolution() const {
+ TeVector2f32 diff = (_someGridVec2 - _someGridVec1);
+ TeVector2s32 retval = TeVector2s32(diff / _gridOffsetSomething) + TeVector2s32(1, 1);
+ if (retval._x > 2000)
+ retval._x = 200;
+ if (retval._y > 2000)
+ retval._y = 200;
+ return retval;
+}
+
void TeFreeMoveZone::buildAStar() {
- error("TODO: Implement TeFreeMoveZone::buildAStar");
+ preUpdateGrid();
+ TeVector2s32 resolution = aStarResolution();
+ _graph->setSize(resolution);
+ if (!_loadedFromBin) {
+ error("TODO: Implement TeFreeMoveZone::buildAStar for *not* loaded from bin case");
+ } else {
+ // Loaded from bin..
+ error("TODO: Implement TeFreeMoveZone::buildAStar for loaded from bin case");
+ }
}
void TeFreeMoveZone::calcGridMatrix() {
diff --git a/engines/tetraedge/te/te_free_move_zone.h b/engines/tetraedge/te/te_free_move_zone.h
index 8861b007284..0bd8c4a98b2 100644
--- a/engines/tetraedge/te/te_free_move_zone.h
+++ b/engines/tetraedge/te/te_free_move_zone.h
@@ -115,6 +115,8 @@ public:
Common::Array<TePickMesh2*> &pickMeshes, TeVector3f32 *outloc, bool lastHitFirst);
private:
+ TeVector2s32 aStarResolution() const;
+
Common::Array<TeActZone> *_actzones;
Common::Array<TeBlocker> *_blockers;
Common::Array<TeRectBlocker> *_rectBlockers;
diff --git a/engines/tetraedge/te/te_lua_context.cpp b/engines/tetraedge/te/te_lua_context.cpp
index 10a2f85ca54..9125975b88f 100644
--- a/engines/tetraedge/te/te_lua_context.cpp
+++ b/engines/tetraedge/te/te_lua_context.cpp
@@ -123,11 +123,17 @@ enum TeLuaSaveVarType {
String = 4
};
+#define DEBUG_SAVELOAD 1
+
Common::Error TeLuaContext::syncState(Common::Serializer &s) {
// Save/Load globals. The format of saving is:
// [type][name][val] [type][name][val]...
+ // Vals can be string, number (uint32), or boolean (byte)
// The type of "None" (0) is the end of the list (and has no name/val).
if (s.isSaving()) {
+#if DEBUG_SAVELOAD
+ debug("TeLuaContext::syncState: --- Saving globals: ---");
+#endif
lua_pushvalue(_luaState, LUA_GLOBALSINDEX);
lua_pushnil(_luaState);
int nextresult = lua_next(_luaState, -2);
@@ -139,66 +145,88 @@ Common::Error TeLuaContext::syncState(Common::Serializer &s) {
break;
}
unsigned int vtype = lua_type(_luaState, -1);
+ Common::String name = lua_tolstring(_luaState, -2, nullptr);
if (vtype == LUA_TBOOLEAN) {
TeLuaSaveVarType stype = Boolean;
- Common::String name = lua_tolstring(_luaState, -2, nullptr);
s.syncAsUint32LE(stype);
s.syncString(name);
bool val = lua_toboolean(_luaState, -1);
s.syncAsByte(val);
+#if DEBUG_SAVELOAD
+ debug("TeLuaContext::syncState: bool %s = %s", name.c_str(), val ? "true" : "false");
+#endif
} else if (vtype == LUA_TNUMBER) {
TeLuaSaveVarType stype = Number;
- Common::String name = lua_tolstring(_luaState, -2, nullptr);
s.syncAsUint32LE(stype);
s.syncString(name);
double val = lua_tonumber(_luaState, -1);
s.syncAsDoubleLE(val);
+#if DEBUG_SAVELOAD
+ debug("TeLuaContext::syncState: num %s = %f", name.c_str(), val);
+#endif
} else if (vtype == LUA_TSTRING) {
TeLuaSaveVarType stype = String;
- Common::String name = lua_tolstring(_luaState, -2, nullptr);
s.syncAsUint32LE(stype);
s.syncString(name);
Common::String val = lua_tostring(_luaState, -1);
s.syncString(val);
+#if DEBUG_SAVELOAD
+ debug("TeLuaContext::syncState: str %s = '%s'", name.c_str(), val.c_str());
+#endif
}
lua_settop(_luaState, -2);
nextresult = lua_next(_luaState, -2);
}
} else {
- warning("Confirm loading in TeLuaContext::syncState");
+#if DEBUG_SAVELOAD
+ debug("TeLuaContext::syncState: --- Loading globals: --- ");
+#endif
// loading
TeLuaSaveVarType vtype = None;
s.syncAsUint32LE(vtype);
while (vtype != None) {
+ Common::String name;
+ s.syncString(name);
switch (vtype) {
case Boolean: {
byte b;
s.syncAsByte(b);
lua_pushboolean(_luaState, b);
+#if DEBUG_SAVELOAD
+ debug("TeLuaContext::syncState: bool %s = %s", name.c_str(), b ? "true" : "false");
+#endif
break;
}
case Number: {
float d;
s.syncAsDoubleLE(d);
lua_pushnumber(_luaState, d);
+#if DEBUG_SAVELOAD
+ debug("TeLuaContext::syncState: num %s = %f", name.c_str(), d);
+#endif
break;
}
case String: {
Common::String str;
s.syncString(str);
lua_pushstring(_luaState, str.c_str());
+#if DEBUG_SAVELOAD
+ debug("TeLuaContext::syncState: str %s = '%s'", name.c_str(), str.c_str());
+#endif
break;
}
default:
error("Unexpected lua type on load %d", (int)vtype);
}
- Common::String name;
- s.syncString(name);
lua_setglobal(_luaState, name.c_str());
s.syncAsUint32LE(vtype);
}
}
+#if DEBUG_SAVELOAD
+ debug("TeLuaContext::syncState: -------- end --------");
+#endif
+
return Common::kNoError;
}
diff --git a/engines/tetraedge/te/te_mesh.cpp b/engines/tetraedge/te/te_mesh.cpp
index 51959d1fcfa..66186576662 100644
--- a/engines/tetraedge/te/te_mesh.cpp
+++ b/engines/tetraedge/te/te_mesh.cpp
@@ -80,6 +80,8 @@ void TeMesh::draw() {
/*
debug("Draw mesh %p (%s, %d verts %d norms %d indexes %d materials %d updated)", this, name().empty() ? "no name" : name().c_str(), _verticies.size(), _normals.size(), _indexes.size(), _materials.size(), _updatedVerticies.size());
debug(" renderMatrix %s", renderer->currentMatrix().toString().c_str());
+ if (!_materials.empty())
+ debug(" material %s", _materials[0].dump().c_str());
debug(" position %s", position().dump().c_str());
debug(" worldPos %s", worldPosition().dump().c_str());
debug(" scale %s", scale().dump().c_str());
diff --git a/engines/tetraedge/te/te_model.cpp b/engines/tetraedge/te/te_model.cpp
index 5757a99031b..e71c4112157 100644
--- a/engines/tetraedge/te/te_model.cpp
+++ b/engines/tetraedge/te/te_model.cpp
@@ -103,7 +103,7 @@ void TeModel::draw() {
renderer->pushMatrix();
renderer->multiplyMatrix(transform);
/*
- if (name().contains("Kate")) {
+ if (name().contains("DEPLIANT")) {
debug("Draw model %p (%s, %d meshes)", this, name().empty() ? "no name" : name().c_str(), _meshes.size());
debug(" renderMatrix %s", renderer->currentMatrix().toString().c_str());
//debug(" position %s", position().dump().c_str());
@@ -194,6 +194,7 @@ void TeModel::update() {
float complete = blender->coef();
TeTRS endTRS = getBone(blender->_anim, b);
if (complete == 1.0f) {
+ _modelAnim = blender->_anim;
delete blender;
_boneBlenders.remove_at(i);
trs = endTRS;
diff --git a/engines/tetraedge/te/te_sprite_layout.cpp b/engines/tetraedge/te/te_sprite_layout.cpp
index 7cc19c754ca..29819cf05cd 100644
--- a/engines/tetraedge/te/te_sprite_layout.cpp
+++ b/engines/tetraedge/te/te_sprite_layout.cpp
@@ -46,7 +46,8 @@ void TeSpriteLayout::draw() {
if (!worldVisible())
return;
- /*if (parent() && parent()->name() == "inventoryButton")
+ /*
+ if (name() == "DEPLIANT")
debug("Draw SpriteLayout %p (%s, surf %s, size %.01fx%.01f, surf %.01fx%.01f, %s)", this,
name().empty() ? "no name" : name().c_str(), _tiledSurfacePtr->getAccessName().toString().c_str(),
size().x(), size().y(),
diff --git a/engines/tetraedge/te/te_text_base2.cpp b/engines/tetraedge/te/te_text_base2.cpp
index 8a0e602b69b..a5676d8e277 100644
--- a/engines/tetraedge/te/te_text_base2.cpp
+++ b/engines/tetraedge/te/te_text_base2.cpp
@@ -18,6 +18,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
+
+//#define DUMP_RENDERED_FONTS 1
#ifdef DUMP_RENDERED_FONTS
#include "image/png.h"
@@ -73,7 +75,11 @@ void TeTextBase2::build() {
lineoffsets.push_back(height);
height += lineHeight + _interLine;
}
- _size._y = (int)ceilf(height);
+
+ // Round up to the nearest 2 pixels so it centres in the
+ // area without a half pixel offset.
+ _size._y = (((int)ceilf(height) + 1) / 2) * 2;
+ _size._x = ((_size._x + 1) / 2) * 2;
TeImage img;
Common::SharedPtr<TePalette> nullpal;
@@ -96,8 +102,7 @@ void TeTextBase2::build() {
_mesh.setConf(4, 4, TeMesh::MeshMode_TriangleStrip, 0, 0);
_mesh.defaultMaterial(texture);
- // FIXME: Original uses BLEND, but we need MODULATE to get right colors?
- //_mesh.setglTexEnv(GL_MODULATE);
+ _mesh.setglTexEnv(GL_BLEND);
_mesh.setShouldDraw(true);
_mesh.setColor(_globalColor);
_mesh.setVertex(0, TeVector3f32(_size._x * -0.5f, _size._y * -0.5f, 0.0f));
@@ -200,10 +205,7 @@ void TeTextBase2::drawEmptyChar(unsigned int offset) {
void TeTextBase2::drawLine(TeImage &img, const Common::String &str, int yoffset) {
TeIntrusivePtr<TeFont3> font = _fonts[0];
- // TODO: Add multi-color support if needed?
- // We set black here as the color is set on the mesh and we use
- // MODULATE blend in build()
- font->draw(img, str, _fontSize, yoffset, TeColor(0, 0, 0, 255), _alignStyle);
+ font->draw(img, str, _fontSize, yoffset, _globalColor, _alignStyle);
}
unsigned int TeTextBase2::endOfWord(unsigned int offset) const {
diff --git a/engines/tetraedge/te/te_vector2s32.cpp b/engines/tetraedge/te/te_vector2s32.cpp
index 2541e265f41..d25d145a210 100644
--- a/engines/tetraedge/te/te_vector2s32.cpp
+++ b/engines/tetraedge/te/te_vector2s32.cpp
@@ -34,4 +34,8 @@ void TeVector2s32::deserialize(Common::ReadStream &stream, TeVector2s32 &dest) {
dest._y = stream.readSint32LE();
}
+TeVector2s32 operator+(const TeVector2s32 &left, const TeVector2s32 &right) {
+ return TeVector2s32(left._x + right._x, left._y + right._y);
+}
+
} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_vector2s32.h b/engines/tetraedge/te/te_vector2s32.h
index ca0fdf449c6..1c96dc406a6 100644
--- a/engines/tetraedge/te/te_vector2s32.h
+++ b/engines/tetraedge/te/te_vector2s32.h
@@ -24,6 +24,7 @@
#include "common/rect.h"
#include "common/stream.h"
+#include "math/vector2d.h"
namespace Tetraedge {
@@ -32,6 +33,7 @@ public:
TeVector2s32();
TeVector2s32(int x_, int y_) : _x(x_), _y(y_) {};
TeVector2s32(const Common::Point &pt) : _x(pt.x), _y(pt.y) {};
+ explicit TeVector2s32(const Math::Vector2d &pt) : _x(pt.getX()), _y(pt.getY()) {};
bool operator!=(const TeVector2s32 &other) const {
return _x != other._x || _y != other._y;
@@ -62,6 +64,8 @@ public:
};
+TeVector2s32 operator+(const TeVector2s32 &left, const TeVector2s32 &right);
+
} // end namespace Tetraedge
#endif // TETRAEDGE_TE_TE_VECTOR2S32_H
diff --git a/engines/tetraedge/te/te_visual_fade.cpp b/engines/tetraedge/te/te_visual_fade.cpp
index 4773118de7f..f63cc2167d7 100644
--- a/engines/tetraedge/te/te_visual_fade.cpp
+++ b/engines/tetraedge/te/te_visual_fade.cpp
@@ -107,7 +107,9 @@ void TeVisualFade::init() {
// create an image the size of the window, no palette, format 6.
Common::SharedPtr<TePalette> nullpal;
_image.destroy();
- _image.create(1024, 768, nullpal, TeImage::RGBA8);
+ // TODO: should this get actual window size instead of default?
+ _image.create(g_engine->getDefaultScreenWidth(),
+ g_engine->getDefaultScreenHeight(), nullpal, TeImage::RGBA8);
_texturePtr->load(_image);
g_engine->getRenderer()->enableTexture();
_texturePtr->load(_image);
diff --git a/engines/tetraedge/tetraedge.cpp b/engines/tetraedge/tetraedge.cpp
index 8582389c303..2740b6cf257 100644
--- a/engines/tetraedge/tetraedge.cpp
+++ b/engines/tetraedge/tetraedge.cpp
@@ -165,11 +165,11 @@ void TetraedgeEngine::configureSearchPaths() {
}
int TetraedgeEngine::getDefaultScreenWidth() const {
- return 1024;
+ return 800;
}
int TetraedgeEngine::getDefaultScreenHeight() const {
- return 768;
+ return 600;
}
Common::Error TetraedgeEngine::run() {
Commit: 8b3c8844fe116223fc90c7e0f70e2a437075d6d6
https://github.com/scummvm/scummvm/commit/8b3c8844fe116223fc90c7e0f70e2a437075d6d6
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2023-01-16T17:36:43+01:00
Commit Message:
TETRAEDGE: Fix a lot of memory cleanup
Changed paths:
engines/tetraedge/game/application.cpp
engines/tetraedge/game/application.h
engines/tetraedge/game/cellphone.cpp
engines/tetraedge/game/character.cpp
engines/tetraedge/game/character.h
engines/tetraedge/game/game.cpp
engines/tetraedge/game/inventory.cpp
engines/tetraedge/game/inventory.h
engines/tetraedge/game/loc_file.cpp
engines/tetraedge/game/lua_binds.cpp
engines/tetraedge/game/object3d.cpp
engines/tetraedge/game/object3d.h
engines/tetraedge/game/owner_error_menu.cpp
engines/tetraedge/game/splash_screens.cpp
engines/tetraedge/te/te_3d_texture.cpp
engines/tetraedge/te/te_3d_texture.h
engines/tetraedge/te/te_image.cpp
engines/tetraedge/te/te_image.h
engines/tetraedge/te/te_images_sequence.cpp
engines/tetraedge/te/te_images_sequence.h
engines/tetraedge/te/te_lua_context.cpp
engines/tetraedge/te/te_lua_context.h
engines/tetraedge/te/te_lua_gui.h
engines/tetraedge/te/te_tiled_texture.cpp
engines/tetraedge/te/te_timer.cpp
engines/tetraedge/tetraedge.cpp
diff --git a/engines/tetraedge/game/application.cpp b/engines/tetraedge/game/application.cpp
index 4f99e4aeb5f..369d9a5493f 100644
--- a/engines/tetraedge/game/application.cpp
+++ b/engines/tetraedge/game/application.cpp
@@ -30,6 +30,7 @@
#include "tetraedge/tetraedge.h"
#include "tetraedge/game/game.h"
#include "tetraedge/game/application.h"
+#include "tetraedge/game/character.h"
#include "tetraedge/game/characters_shadow.h"
#include "tetraedge/game/in_game_scene.h"
#include "tetraedge/te/te_core.h"
@@ -74,6 +75,10 @@ _drawShadows(true) {
loadOptions("options.xml");
}
+Application::~Application() {
+ destroy();
+}
+
void Application::create() {
// TODO: Move mainWindowCamera to mainWindow?
@@ -286,7 +291,7 @@ void Application::create() {
}
void Application::destroy() {
- error("TODO: Implement Application::destroy");
+ Character::animCacheFreeAll();
}
void Application::startGame(bool newGame, int difficulty) {
diff --git a/engines/tetraedge/game/application.h b/engines/tetraedge/game/application.h
index ce9a67715ad..8bd2ce06290 100644
--- a/engines/tetraedge/game/application.h
+++ b/engines/tetraedge/game/application.h
@@ -48,6 +48,7 @@ namespace Tetraedge {
class Application {
public:
Application();
+ ~Application();
void create();
void destroy();
diff --git a/engines/tetraedge/game/cellphone.cpp b/engines/tetraedge/game/cellphone.cpp
index d91ee5654c4..3ec7dbe7d2f 100644
--- a/engines/tetraedge/game/cellphone.cpp
+++ b/engines/tetraedge/game/cellphone.cpp
@@ -37,7 +37,7 @@ bool Cellphone::addNumber(const Common::String &num) {
}
TeTextLayout *layout = new TeTextLayout();
- static const Common::String namePrefix("numRepertoire");
+ const Common::String namePrefix("numRepertoire");
layout->setName(namePrefix + num);
layout->setSizeType(RELATIVE_TO_PARENT);
layout->setAnchor(TeVector3f32(0.5f, 0.0f, 0.0f));
diff --git a/engines/tetraedge/game/character.cpp b/engines/tetraedge/game/character.cpp
index 1d814ec639a..8620831b3b4 100644
--- a/engines/tetraedge/game/character.cpp
+++ b/engines/tetraedge/game/character.cpp
@@ -38,6 +38,7 @@ namespace Tetraedge {
/*static*/ Common::HashMap<Common::String, Character::CharacterSettings> *Character::_globalCharacterSettings = nullptr;
/*static*/ Common::Array<Character::AnimCacheElement> Character::_animCache;
+/*static*/ Common::HashMap<Common::String, TeIntrusivePtr<TeModelAnimation>> Character::_animCacheMap;
uint Character::_animCacheSize = 0;
void Character::CharacterSettings::clear() {
@@ -93,6 +94,14 @@ Character::~Character() {
}
}
+/*static*/
+void Character::cleanup() {
+ if (_globalCharacterSettings)
+ delete _globalCharacterSettings;
+ _globalCharacterSettings = nullptr;
+ animCacheFreeAll();
+}
+
void Character::addCallback(const Common::String &animKey, const Common::String &fnName, float triggerFrame, float maxCalls) {
Callback *c = new Callback();
c->_luaFn = fnName;
@@ -125,26 +134,25 @@ void Character::addCallback(const Common::String &animKey, const Common::String
for (const auto &entry : _animCache)
_animCacheSize -= entry._size;
_animCache.clear();
+ _animCacheMap.clear();
}
/*static*/ void Character::animCacheFreeOldest() {
- _animCacheSize -= _animCache[_animCache.size() - 1]._size;
- _animCache.pop_back();
+ //_animCacheSize -= _animCache[_animCache.size() - 1]._size;
+ //_animCache.pop_back();
}
/*static*/ TeIntrusivePtr<TeModelAnimation> Character::animCacheLoad(const Common::Path &path) {
- static Common::HashMap<Common::String, TeIntrusivePtr<TeModelAnimation>> _cache;
-
const Common::String pathStr = path.toString();
- if (_cache.contains(pathStr))
- return _cache.getVal(pathStr);
+ if (_animCacheMap.contains(pathStr))
+ return _animCacheMap.getVal(pathStr);
TeIntrusivePtr<TeModelAnimation> modelAnim = new TeModelAnimation();
if (!modelAnim->load(path)) {
warning("Failed to load anim %s", path.toString().c_str());
}
- _cache.setVal(pathStr, modelAnim);
+ _animCacheMap.setVal(pathStr, modelAnim);
return modelAnim;
}
diff --git a/engines/tetraedge/game/character.h b/engines/tetraedge/game/character.h
index 86fc5036be4..191b1796524 100644
--- a/engines/tetraedge/game/character.h
+++ b/engines/tetraedge/game/character.h
@@ -176,6 +176,8 @@ public:
TeIntrusivePtr<TeBezierCurve> curve() { return _curve; }
void setRecallageY(bool val) { _recallageY = val; }
+ static void cleanup();
+
private:
float _walkCurveStart;
float _walkCurveLast;
@@ -237,6 +239,7 @@ private:
Common::HashMap<Common::String, Common::Array<Callback *>> _callbacks;
static Common::Array<AnimCacheElement> _animCache;
+ static Common::HashMap<Common::String, TeIntrusivePtr<TeModelAnimation>> _animCacheMap;
static uint _animCacheSize;
static Common::HashMap<Common::String, CharacterSettings> *_globalCharacterSettings;
diff --git a/engines/tetraedge/game/game.cpp b/engines/tetraedge/game/game.cpp
index 846691cc696..2eddff29f40 100644
--- a/engines/tetraedge/game/game.cpp
+++ b/engines/tetraedge/game/game.cpp
@@ -62,6 +62,9 @@ _firstInventory(true), _loadName("save.xml"), _randomSource("SyberiaGameRandom")
}
Game::~Game() {
+ if (_entered) {
+ leave(true);
+ }
delete _randomSound;
}
@@ -720,7 +723,18 @@ void Game::leave(bool flag) {
_scene.unloadCharacter(_scene._character->_model->name());
}
- warning("TODO: Game::leave: clear game sounds and randomsounds");
+ for (auto &sound : _gameSounds) {
+ delete sound;
+ }
+ _gameSounds.clear();
+
+ for (auto &randsoundlist : _randomSounds) {
+ for (auto *randsound : randsoundlist._value) {
+ delete randsound;
+ }
+ randsoundlist._value.clear();
+ }
+ _randomSounds.clear();
for (auto *hitobj : _gameHitObjects) {
delete hitobj;
@@ -1089,7 +1103,7 @@ bool Game::onMouseMove() {
if (!_entered)
return false;
- static const Common::Path DEFAULT_CURSOR("pictures/cursor.png");
+ const Common::Path DEFAULT_CURSOR("pictures/cursor.png");
Application *app = g_engine->getApplication();
diff --git a/engines/tetraedge/game/inventory.cpp b/engines/tetraedge/game/inventory.cpp
index aaf487d9bfb..a0e694d6993 100644
--- a/engines/tetraedge/game/inventory.cpp
+++ b/engines/tetraedge/game/inventory.cpp
@@ -351,11 +351,9 @@ void Inventory::unPauseAnims() {
void Inventory::removeObject(const Common::String &objname) {
int pageNo = 0;
- bool retval;
bool finished = false;
while (!finished) {
TeLayout *page = _gui.layout(Common::String::format("page%d", pageNo));
- retval = false;
if (!page)
break;
int slotNo = 0;
@@ -441,9 +439,8 @@ void Inventory::selectedObject(InventoryObject *obj) {
}
const Common::String &Inventory::selectedObject() {
- static const Common::String blank;
if (_selectedObject == nullptr)
- return blank;
+ return _blankStr;
else
return _selectedObject->name();
}
diff --git a/engines/tetraedge/game/inventory.h b/engines/tetraedge/game/inventory.h
index cfcdd344e5e..7d92c7e987f 100644
--- a/engines/tetraedge/game/inventory.h
+++ b/engines/tetraedge/game/inventory.h
@@ -92,6 +92,9 @@ private:
InventoryObject *_selectedObject;
Common::HashMap<Common::String, InventoryObjectData> _objectData;
+ // This is used when we need a reference to a blank str in selectedObject()
+ const Common::String _blankStr;
+
TeTimer _selectedTimer;
};
diff --git a/engines/tetraedge/game/loc_file.cpp b/engines/tetraedge/game/loc_file.cpp
index 3e511527187..10321ad432c 100644
--- a/engines/tetraedge/game/loc_file.cpp
+++ b/engines/tetraedge/game/loc_file.cpp
@@ -33,7 +33,7 @@ LocFile::LocFile() {
void LocFile::load(const Common::Path &path) {
TeNameValXmlParser parser;
- static const Common::String xmlHeader("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
+ const Common::String xmlHeader("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
Common::File locFile;
if (!locFile.open(path))
error("LocFile::load: failed to open %s.", path.toString().c_str());
diff --git a/engines/tetraedge/game/lua_binds.cpp b/engines/tetraedge/game/lua_binds.cpp
index 0a199cffa0c..4d396e24d82 100644
--- a/engines/tetraedge/game/lua_binds.cpp
+++ b/engines/tetraedge/game/lua_binds.cpp
@@ -1764,8 +1764,10 @@ static int tolua_ExportedFunctions_SetObjectOnCharacter00(lua_State *L) {
static void SetObjectRotation(const Common::String &obj, float xr, float yr, float zr) {
Game *game = g_engine->getGame();
Object3D *obj3d = game->scene().object3D(obj);
- if (!obj3d)
+ if (!obj3d) {
warning("[SetObjectRotation] Object not found %s", obj.c_str());
+ return;
+ }
const TeVector3f32 rot(xr * M_PI / 180.0, yr * M_PI / 180.0, zr * M_PI / 180.0);
obj3d->_objRotation = TeQuaternion::fromEuler(rot);
}
@@ -1788,8 +1790,10 @@ static int tolua_ExportedFunctions_SetObjectRotation00(lua_State *L) {
static void SetObjectTranslation(const Common::String &obj, float x, float y, float z) {
Game *game = g_engine->getGame();
Object3D *obj3d = game->scene().object3D(obj);
- if (!obj3d)
+ if (!obj3d) {
warning("[SetObjectTranslation] Object not found %s", obj.c_str());
+ return;
+ }
obj3d->_objTranslation = TeVector3f32(x, y, z);
}
@@ -1811,8 +1815,10 @@ static int tolua_ExportedFunctions_SetObjectTranslation00(lua_State *L) {
static void SetObjectScale(const Common::String &obj, float xs, float ys, float zs) {
Game *game = g_engine->getGame();
Object3D *obj3d = game->scene().object3D(obj);
- if (!obj3d)
+ if (!obj3d) {
warning("[SetObjectScale] Object not found %s", obj.c_str());
+ return;
+ }
obj3d->_objScale = TeVector3f32(xs, ys, zs);
}
@@ -1834,8 +1840,10 @@ static int tolua_ExportedFunctions_SetObjectScale00(lua_State *L) {
static void SetObjectFrames(const Common::String &obj, int start, int end) {
Game *game = g_engine->getGame();
Object3D *obj3d = game->scene().object3D(obj);
- if (!obj3d)
+ if (!obj3d) {
warning("[SetObjectFrames] Object not found %s", obj.c_str());
+ return;
+ }
obj3d->_startFrame = start;
obj3d->_endFrame = end;
}
diff --git a/engines/tetraedge/game/object3d.cpp b/engines/tetraedge/game/object3d.cpp
index 44981d8aae9..493a4280b7d 100644
--- a/engines/tetraedge/game/object3d.cpp
+++ b/engines/tetraedge/game/object3d.cpp
@@ -28,6 +28,13 @@ namespace Tetraedge {
/*static*/
Common::HashMap<Common::String, Object3D::ObjectSettings> *Object3D::_objectSettings = nullptr;
+/*static*/
+void Object3D::cleanup() {
+ if (_objectSettings)
+ delete _objectSettings;
+ _objectSettings = nullptr;
+}
+
// start and end frames not initialized in original, but to guarantee we don't use
// uninitialized values we set it here.
diff --git a/engines/tetraedge/game/object3d.h b/engines/tetraedge/game/object3d.h
index ccdffbe02b4..bae3d0e36cb 100644
--- a/engines/tetraedge/game/object3d.h
+++ b/engines/tetraedge/game/object3d.h
@@ -46,6 +46,7 @@ public:
bool loadModel(const Common::String &name);
static bool loadSettings(const Common::String &path);
+ static void cleanup();
TeIntrusivePtr<TeModel> model() { return _modelPtr; }
diff --git a/engines/tetraedge/game/owner_error_menu.cpp b/engines/tetraedge/game/owner_error_menu.cpp
index 0519ab69d57..ecb12101a99 100644
--- a/engines/tetraedge/game/owner_error_menu.cpp
+++ b/engines/tetraedge/game/owner_error_menu.cpp
@@ -34,7 +34,7 @@ OwnerErrorMenu::OwnerErrorMenu() : _entered(false) {
void OwnerErrorMenu::enter() {
_entered = true;
- static const Common::Path luaPath("menus/ownerError/ownerError.lua");
+ const Common::Path luaPath("menus/ownerError/ownerError.lua");
load(luaPath);
Application *app = g_engine->getApplication();
TeLayout *menuLayout = layoutChecked("menu");
diff --git a/engines/tetraedge/game/splash_screens.cpp b/engines/tetraedge/game/splash_screens.cpp
index f27f318b0be..96773bf6d47 100644
--- a/engines/tetraedge/game/splash_screens.cpp
+++ b/engines/tetraedge/game/splash_screens.cpp
@@ -37,7 +37,7 @@ void SplashScreens::enter() {
if (!_entered) {
_entered = true;
_splashNo = 0;
- static const Common::Path scriptPath("menus/splashes/splash0.lua");
+ const Common::Path scriptPath("menus/splashes/splash0.lua");
if (Common::File::exists(scriptPath)) {
TeLuaGUI::load(scriptPath.toString());
Application *app = g_engine->getApplication();
diff --git a/engines/tetraedge/te/te_3d_texture.cpp b/engines/tetraedge/te/te_3d_texture.cpp
index 362582758a7..8c3c515d63f 100644
--- a/engines/tetraedge/te/te_3d_texture.cpp
+++ b/engines/tetraedge/te/te_3d_texture.cpp
@@ -94,14 +94,14 @@ void Te3DTexture::destroy() {
_glTexture = NO_TEXTURE;
}
-void Te3DTexture::forceTexData(uint gltextures, uint xsize, uint ysize) {
+void Te3DTexture::forceTexData(uint gltexture, uint xsize, uint ysize) {
if (_glTexture != 0xffffffff) {
if (_createdTexture)
glDeleteTextures(1, &_glTexture);
_createdTexture = false;
_loaded = false;
}
- _glTexture = gltextures;
+ _glTexture = gltexture;
_width = xsize;
_height = ysize;
_texWidth = xsize;
diff --git a/engines/tetraedge/te/te_3d_texture.h b/engines/tetraedge/te/te_3d_texture.h
index 1696cbaf2d1..bba5ad26975 100644
--- a/engines/tetraedge/te/te_3d_texture.h
+++ b/engines/tetraedge/te/te_3d_texture.h
@@ -44,7 +44,7 @@ public:
void create();
void destroy();
- void forceTexData(uint gltextures, uint xsize, uint ysize);
+ void forceTexData(uint gltexture, uint xsize, uint ysize);
TeImage::Format getFormat() const { return _format; }
bool hasAlpha() const;
diff --git a/engines/tetraedge/te/te_image.cpp b/engines/tetraedge/te/te_image.cpp
index ca974f4fb04..c25def49905 100644
--- a/engines/tetraedge/te/te_image.cpp
+++ b/engines/tetraedge/te/te_image.cpp
@@ -28,7 +28,7 @@
namespace Tetraedge {
-TeImage::TeImage() : Surface(), _format(INVALID) {
+TeImage::TeImage() : ManagedSurface(), _format(INVALID) {
}
TeImage::TeImage(const TeImage &other) {
@@ -44,8 +44,8 @@ unsigned long TeImage::countPixelsOfColor(const TeColor &col) const {
}
void TeImage::create() {
- _format = INVALID;
- Graphics::Surface::free();
+ // Never used, but in original seems to do the same as destroy??
+ destroy();
}
void TeImage::create(uint xsize, uint ysize, Common::SharedPtr<TePalette> &pal,
@@ -54,8 +54,8 @@ void TeImage::create(uint xsize, uint ysize, Common::SharedPtr<TePalette> &pal,
Graphics::PixelFormat pxformat = ((teformat == TeImage::RGB8) ?
Graphics::PixelFormat(3, 8, 8, 8, 0, 16, 8, 0, 0) : Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24));
- Graphics::Surface::create(xsize, ysize, pxformat);
- Graphics::Surface::fillRect(Common::Rect(0, 0, xsize, ysize), 0);
+ Graphics::ManagedSurface::create(xsize, ysize, pxformat);
+ Graphics::ManagedSurface::fillRect(Common::Rect(0, 0, xsize, ysize), 0);
}
void TeImage::deserialize(Common::ReadStream &stream) {
@@ -63,7 +63,7 @@ void TeImage::deserialize(Common::ReadStream &stream) {
}
void TeImage::destroy() {
- Graphics::Surface::free();
+ Graphics::ManagedSurface::free();
_format = INVALID;
}
@@ -79,7 +79,7 @@ void TeImage::fill(byte r, byte g, byte b, byte a) {
Common::Rect wholeSurf(0, 0, w, h);
uint32 col = ((uint32)r << format.rShift) | ((uint32)g << format.gShift) | ((uint32)b << format.bShift) | ((uint32)a << format.aShift);
- Graphics::Surface::fillRect(wholeSurf, col);
+ Graphics::ManagedSurface::fillRect(wholeSurf, col);
}
void TeImage::getBuff(uint x, uint y, byte *pout, uint w_, uint h_) {
diff --git a/engines/tetraedge/te/te_image.h b/engines/tetraedge/te/te_image.h
index ae0aa47ffb5..16dacc6e9ae 100644
--- a/engines/tetraedge/te/te_image.h
+++ b/engines/tetraedge/te/te_image.h
@@ -27,7 +27,7 @@
#include "common/types.h"
#include "common/path.h"
-#include "graphics/surface.h"
+#include "graphics/managed_surface.h"
#include "tetraedge/te/te_color.h"
#include "tetraedge/te/te_palette.h"
@@ -36,12 +36,14 @@
namespace Tetraedge {
-class TeImage : public TeResource, public Graphics::Surface {
+class TeImage : public TeResource, public Graphics::ManagedSurface {
public:
TeImage();
TeImage(const TeImage &other);
- virtual ~TeImage() {};
+ virtual ~TeImage() {
+ destroy();
+ };
enum Format {
RGB8 = 5,
diff --git a/engines/tetraedge/te/te_images_sequence.cpp b/engines/tetraedge/te/te_images_sequence.cpp
index 3f90c9977dc..ffe55b35745 100644
--- a/engines/tetraedge/te/te_images_sequence.cpp
+++ b/engines/tetraedge/te/te_images_sequence.cpp
@@ -22,6 +22,7 @@
#include "common/file.h"
#include "image/png.h"
#include "graphics/surface.h"
+#include "graphics/managed_surface.h"
#include "tetraedge/te/te_images_sequence.h"
@@ -31,6 +32,10 @@ TeImagesSequence::TeImagesSequence() : _width(0), _height(0), _curFrame(0) {
}
TeImagesSequence::~TeImagesSequence() {
+ for (auto surf : _cachedSurfaces) {
+ if (surf)
+ delete surf;
+ }
}
/*static*/
@@ -56,8 +61,8 @@ bool TeImagesSequence::load(const Common::Path &path) {
}
Common::sort(children.begin(), children.end(), compareNodes);
-
- SearchMan.addDirectory(path.toString(), directory);
+ if (!SearchMan.hasArchive(path.toString()))
+ SearchMan.addDirectory(path.toString(), directory);
for (Common::FSNode &child : children) {
Common::String filePathStr = child.getPath();
@@ -82,7 +87,8 @@ bool TeImagesSequence::load(const Common::Path &path) {
}
// Only do the deep check for the first file to get dimensions.
- if (!_width) {
+ // If the images are small then cache them to avoid reloading each frame each time.
+ if (!_width || (_width < 100 && _height < 100)) {
Image::PNGDecoder png;
if (!png.loadStream(*stream)) {
warning("Image sequence failed to load png %s", filePath.toString().c_str());
@@ -90,11 +96,20 @@ bool TeImagesSequence::load(const Common::Path &path) {
return false;
}
- const Graphics::Surface *surf = png.getSurface();
- assert(surf);
- _width = surf->w;
- _height = surf->h;
_frameRate = fps;
+ const Graphics::Surface *pngsurf = png.getSurface();
+ assert(pngsurf);
+ _width = pngsurf->w;
+ _height = pngsurf->h;
+ if (_width < 100 && _height < 100) {
+ Graphics::ManagedSurface *surf = new Graphics::ManagedSurface();
+ surf->copyFrom(pngsurf);
+ _cachedSurfaces.push_back(surf);
+ } else {
+ _cachedSurfaces.push_back(nullptr);
+ }
+ } else {
+ _cachedSurfaces.push_back(nullptr);
}
_files.push_back(child);
@@ -111,26 +126,35 @@ bool TeImagesSequence::update(unsigned long i, TeImage &imgout) {
if (i >= _files.size())
return false;
- Common::SeekableReadStream *stream = _files[_curFrame].createReadStream();
- if (!stream)
- error("Open %s failed.. it was ok before?", _files[_curFrame].getName().c_str());
+ if (_cachedSurfaces[i] == nullptr) {
+ Common::SeekableReadStream *stream = _files[i].createReadStream();
+ if (!stream)
+ error("Open %s failed.. it was ok before?", _files[i].getName().c_str());
- Image::PNGDecoder png;
- if (!png.loadStream(*stream)) {
- warning("Image sequence failed to load png %s", _files[_curFrame].getName().c_str());
- delete stream;
- return false;
- }
+ Image::PNGDecoder png;
+ if (!png.loadStream(*stream)) {
+ warning("Image sequence failed to load png %s", _files[i].getName().c_str());
+ delete stream;
+ return false;
+ }
- const Graphics::Surface *surf = png.getSurface();
- assert(surf);
+ const Graphics::Surface *surf = png.getSurface();
+ assert(surf);
- imgout.setAccessName(_files[_curFrame].getPath());
+ imgout.setAccessName(_files[i].getPath());
- if (imgout.w == surf->w && imgout.h == surf->h && imgout.format == surf->format) {
- imgout.copyFrom(*surf);
- delete stream;
- return true;
+ if (imgout.w == surf->w && imgout.h == surf->h && imgout.format == surf->format) {
+ imgout.copyFrom(*surf);
+ delete stream;
+ return true;
+ }
+ } else {
+ const Graphics::ManagedSurface *surf = _cachedSurfaces[i];
+ if (imgout.w == surf->w && imgout.h == surf->h && imgout.format == surf->format) {
+ imgout.setAccessName(_files[i].getPath());
+ imgout.copyFrom(*surf);
+ return true;
+ }
}
error("TODO: Implement TeImagesSequence::update for different sizes");
diff --git a/engines/tetraedge/te/te_images_sequence.h b/engines/tetraedge/te/te_images_sequence.h
index 1f0a72bd3d2..fa0a5bdcb96 100644
--- a/engines/tetraedge/te/te_images_sequence.h
+++ b/engines/tetraedge/te/te_images_sequence.h
@@ -27,6 +27,7 @@
namespace Graphics {
struct Surface;
+class ManagedSurface;
}
namespace Tetraedge {
@@ -63,6 +64,7 @@ private:
unsigned int _width;
unsigned int _height;
Common::Array<Common::FSNode> _files;
+ Common::Array<Graphics::ManagedSurface *> _cachedSurfaces;
unsigned int _curFrame;
};
diff --git a/engines/tetraedge/te/te_lua_context.cpp b/engines/tetraedge/te/te_lua_context.cpp
index 9125975b88f..feb3ae66a32 100644
--- a/engines/tetraedge/te/te_lua_context.cpp
+++ b/engines/tetraedge/te/te_lua_context.cpp
@@ -44,6 +44,10 @@ TeLuaContext::TeLuaContext() : _luaState(nullptr) {
lua_atpanic(_luaState, luaPanicFunction);
}
+TeLuaContext::~TeLuaContext() {
+ destroy();
+}
+
void TeLuaContext::addBindings(void(*fn)(lua_State *)) {
fn(_luaState);
}
@@ -57,6 +61,7 @@ void TeLuaContext::create() {
void TeLuaContext::destroy() {
if (_luaState)
lua_close(_luaState);
+ _luaState = nullptr;
}
TeVariant TeLuaContext::global(const Common::String &name) {
@@ -189,7 +194,7 @@ Common::Error TeLuaContext::syncState(Common::Serializer &s) {
s.syncString(name);
switch (vtype) {
case Boolean: {
- byte b;
+ byte b = 0;
s.syncAsByte(b);
lua_pushboolean(_luaState, b);
#if DEBUG_SAVELOAD
@@ -198,7 +203,7 @@ Common::Error TeLuaContext::syncState(Common::Serializer &s) {
break;
}
case Number: {
- float d;
+ float d = 0;
s.syncAsDoubleLE(d);
lua_pushnumber(_luaState, d);
#if DEBUG_SAVELOAD
diff --git a/engines/tetraedge/te/te_lua_context.h b/engines/tetraedge/te/te_lua_context.h
index 47597ec5f59..e4e9856b4f7 100644
--- a/engines/tetraedge/te/te_lua_context.h
+++ b/engines/tetraedge/te/te_lua_context.h
@@ -42,6 +42,7 @@ class TeLuaGUI;
class TeLuaContext {
public:
TeLuaContext();
+ ~TeLuaContext();
void addBindings(void(*fn)(lua_State *));
void create();
diff --git a/engines/tetraedge/te/te_lua_gui.h b/engines/tetraedge/te/te_lua_gui.h
index c9254e229df..54e272f57a9 100644
--- a/engines/tetraedge/te/te_lua_gui.h
+++ b/engines/tetraedge/te/te_lua_gui.h
@@ -50,7 +50,9 @@ namespace Tetraedge {
class TeLuaGUI : public TeObject {
public:
TeLuaGUI();
- virtual ~TeLuaGUI() {};
+ virtual ~TeLuaGUI() {
+ unload();
+ };
virtual void enter() {};
virtual void leave() {};
diff --git a/engines/tetraedge/te/te_tiled_texture.cpp b/engines/tetraedge/te/te_tiled_texture.cpp
index 593055a2ff1..839cacdde03 100644
--- a/engines/tetraedge/te/te_tiled_texture.cpp
+++ b/engines/tetraedge/te/te_tiled_texture.cpp
@@ -48,8 +48,8 @@ bool TeTiledTexture::load(const Common::Path &path) {
if (resmgr->exists(path)) {
img = resmgr->getResourceNoSearch<TeImage>(path);
} else {
- TeImage *newImg = new TeImage();
- if (!newImg->load(path))
+ img = new TeImage();
+ if (!img->load(path))
return false;
}
load(*img);
@@ -117,8 +117,6 @@ bool TeTiledTexture::load(const TeImage &img) {
if (rows)
_somethingSize._y = _somethingSize._y / rows;
setAccessName(img.getAccessName().append(".tt"));
- if (img.getAccessName().toString() == "menus/inGame/Inventory.png")
- debug("loading inventory tiled texture");
return true;
}
@@ -133,8 +131,6 @@ bool TeTiledTexture::load(const TeIntrusivePtr<Te3DTexture> &texture) {
tileData->_vec2 = TeVector3f32(1.0, 1.0, 0.0);
tileData->_vec1 = TeVector3f32(0.0, 0.0, 0.0);
setAccessName(texture->getAccessName().append(".tt"));
- if (texture->getAccessName().toString() == "menus/inGame/Inventory.png")
- debug("loading inventory tiled texture from texture");
return true;
}
@@ -155,7 +151,7 @@ TeImage *TeTiledTexture::optimisedTileImage(Common::Array<TeImage> &images, cons
}
}
images.resize(images.size() + 1);
- TeImage &newImg = *images.end();
+ TeImage &newImg = images.back();
Common::SharedPtr<TePalette> nullPal;
newImg.create((uint)size._x, (uint)size._y, nullPal, format);
return &newImg;
diff --git a/engines/tetraedge/te/te_timer.cpp b/engines/tetraedge/te/te_timer.cpp
index 4802c446729..7ca28da0095 100644
--- a/engines/tetraedge/te/te_timer.cpp
+++ b/engines/tetraedge/te/te_timer.cpp
@@ -40,12 +40,17 @@ _startTime(0), _lastTimeElapsed(0), _startTimeOffset(0), _updated(false) {
}
TeTimer::~TeTimer() {
- if (!_stopped) {
- for (uint i = 0; i < _timers.size(); i++) {
- if (_timers[i] == this) {
- _timers.remove_at(i);
- break;
- }
+ for (uint i = 0; i < _timers.size(); i++) {
+ if (_timers[i] == this) {
+ _timers.remove_at(i);
+ break;
+ }
+ }
+ // Not done in original, but probably should be?
+ for (uint i = 0; i < _pausedTimers.size(); i++) {
+ if (_pausedTimers[i] == this) {
+ _pausedTimers.remove_at(i);
+ break;
}
}
}
diff --git a/engines/tetraedge/tetraedge.cpp b/engines/tetraedge/tetraedge.cpp
index 2740b6cf257..811384ffa42 100644
--- a/engines/tetraedge/tetraedge.cpp
+++ b/engines/tetraedge/tetraedge.cpp
@@ -34,6 +34,7 @@
#include "tetraedge/game/game.h"
#include "tetraedge/game/application.h"
+#include "tetraedge/game/character.h"
#include "tetraedge/te/te_core.h"
#include "tetraedge/te/te_renderer.h"
#include "tetraedge/te/te_resource_manager.h"
@@ -54,13 +55,15 @@ TetraedgeEngine::TetraedgeEngine(OSystem *syst, const ADGameDescription *gameDes
}
TetraedgeEngine::~TetraedgeEngine() {
- delete _application;
- delete _renderer;
delete _core;
delete _game;
- //delete _soundManager;
+ delete _application;
+ delete _renderer;
+ delete _soundManager;
delete _resourceManager;
delete _inputMgr;
+ Object3D::cleanup();
+ Character::cleanup();
}
/*static*/
Commit: 4479e6e3464d4cc48da3f77b4ddf7f677b520aee
https://github.com/scummvm/scummvm/commit/4479e6e3464d4cc48da3f77b4ddf7f677b520aee
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2023-01-16T17:36:43+01:00
Commit Message:
TETRAEDGE: Implement FreeMoveZone building
Changed paths:
engines/tetraedge/game/dialog2.cpp
engines/tetraedge/game/game.cpp
engines/tetraedge/game/lua_binds.cpp
engines/tetraedge/te/te_3d_texture.cpp
engines/tetraedge/te/te_button_layout.cpp
engines/tetraedge/te/te_font3.cpp
engines/tetraedge/te/te_free_move_zone.cpp
engines/tetraedge/te/te_free_move_zone.h
engines/tetraedge/te/te_lua_context.cpp
engines/tetraedge/te/te_lua_gui.cpp
engines/tetraedge/te/te_lua_gui_lua_callbacks.cpp
engines/tetraedge/te/te_pick_mesh2.h
engines/tetraedge/te/te_renderer.cpp
engines/tetraedge/te/te_scrolling_layout.cpp
engines/tetraedge/te/te_text_base2.cpp
engines/tetraedge/te/te_text_layout.cpp
engines/tetraedge/te/te_tiled_surface.cpp
engines/tetraedge/te/te_tiled_surface.h
diff --git a/engines/tetraedge/game/dialog2.cpp b/engines/tetraedge/game/dialog2.cpp
index 5c47508c6b7..83cb02ef0e4 100644
--- a/engines/tetraedge/game/dialog2.cpp
+++ b/engines/tetraedge/game/dialog2.cpp
@@ -74,11 +74,11 @@ void Dialog2::launchNextDialog() {
if (_currentDialogData._animBlend == 0.0f) {
if (!c->setAnimation(_currentDialogData._animfile, false, true))
- error("[Dialog2::launchNextDialog] Character's animation \"%s\" doesn't exist for the character\"%s\" \n",
+ error("[Dialog2::launchNextDialog] Character's animation \"%s\" doesn't exist for the character\"%s\"",
_currentDialogData._animfile.c_str(), _currentDialogData._charname.c_str());
} else {
if (!c->blendAnimation(_currentDialogData._animfile, _currentDialogData._animBlend, false, true))
- error("[Dialog2::launchNextDialog] Character's animation \"%s\" doesn't exist for the character\"%s\" \n",
+ error("[Dialog2::launchNextDialog] Character's animation \"%s\" doesn't exist for the character\"%s\"",
_currentDialogData._animfile.c_str(), _currentDialogData._charname.c_str());
}
}
diff --git a/engines/tetraedge/game/game.cpp b/engines/tetraedge/game/game.cpp
index 2eddff29f40..d8db0d019da 100644
--- a/engines/tetraedge/game/game.cpp
+++ b/engines/tetraedge/game/game.cpp
@@ -278,7 +278,8 @@ void Game::enter(bool newgame) {
_score = 0;
Application *app = g_engine->getApplication();
app->visualFade().init();
- Common::SharedPtr<TeCallback1Param<Game, const Common::Point &>> callbackptr(new TeCallback1Param<Game, const Common::Point &>(this, &Game::onMouseClick, -10000.0f));
+ // FIXME: Original puts this click handler at -10000.. but then it never gets hit?
+ Common::SharedPtr<TeCallback1Param<Game, const Common::Point &>> callbackptr(new TeCallback1Param<Game, const Common::Point &>(this, &Game::onMouseClick, 10000.0f));
g_engine->getInputMgr()->_mouseLUpSignal.push_back(callbackptr);
_movePlayerCharacterDisabled = false;
// TODO? Set character mouse move event no to -1
@@ -524,12 +525,12 @@ bool Game::initWarp(const Common::String &zone, const Common::String &scene, boo
Application *app = g_engine->getApplication();
if (forLuaExists) {
_forGui.load(forLuaPath);
- TeLayout *bg = _forGui.layout("background");
+ TeLayout *bg = _forGui.layoutChecked("background");
bg->setRatioMode(TeILayout::RATIO_MODE_NONE);
app->_frontLayout.addChild(bg);
// Note: Game also adds cellphone to both frontLayout *and* noScaleLayout2,
// so we reproduce the broken behavior exactly.
- TeLayout *cellbg = _inventory.cellphone()->gui().buttonLayout("background");
+ TeLayout *cellbg = _inventory.cellphone()->gui().buttonLayoutChecked("background");
app->_frontLayout.removeChild(cellbg);
app->_frontLayout.addChild(cellbg);
_objectif.reattachLayout(&app->_frontLayout);
@@ -727,7 +728,7 @@ void Game::leave(bool flag) {
delete sound;
}
_gameSounds.clear();
-
+
for (auto &randsoundlist : _randomSounds) {
for (auto *randsound : randsoundlist._value) {
delete randsound;
diff --git a/engines/tetraedge/game/lua_binds.cpp b/engines/tetraedge/game/lua_binds.cpp
index 4d396e24d82..b49cea8f36a 100644
--- a/engines/tetraedge/game/lua_binds.cpp
+++ b/engines/tetraedge/game/lua_binds.cpp
@@ -514,7 +514,10 @@ static void StartAnimation(const Common::String name, int loops, bool repeat) {
if (game->startAnimation(name, loops, repeat))
return;
- error("[StartAnimation] Animation \"%s\" doesn't exist.", name.c_str());
+ // NOTE: Not error, some game scripts try to start animations that don't
+ // exist. eg, ValVoralberg/14030 loads anim 14020, which is in a different
+ // zone
+ warning("[StartAnimation] Animation \"%s\" doesn't exist.", name.c_str());
}
int tolua_ExportedFunctions_StartAnimation00(lua_State *L) {
@@ -714,7 +717,7 @@ static int tolua_ExportedFunctions_PlaceCharacterOnDummy00(lua_State *L) {
}
error("#ferror in function 'SetCharacterRotation': %d %d %s", err.index, err.array, err.type);
}
-
+
static void SetCharacterRotation(const Common::String &charname, float rx, float ry, float rz) {
TeQuaternion quat = TeQuaternion::fromEuler(TeVector3f32(rx * M_PI / 180.0, ry * M_PI / 180.0, rz * M_PI / 180.0));
Game *game = g_engine->getGame();
@@ -1248,7 +1251,7 @@ static int tolua_ExportedFunctions_SetBackground00(lua_State *L) {
static void LaunchDialog(const Common::String &name, uint param_2, const Common::String &charname,
const Common::String &animfile, float animblend) {
Game *game = g_engine->getGame();
-
+
if (!game->launchDialog(name, param_2, charname, animfile, animblend))
warning("[LaunchDialog] Dialog \"%s\" doesn't exist.", name.c_str());
}
@@ -1588,12 +1591,24 @@ static int tolua_ExportedFunctions_SetRecallageY00(lua_State *L) {
error("#ferror in function 'SetRecallageY': %d %d %s", err.index, err.array, err.type);
}
-static void DisabledZone(const Common::String &s1, bool b) {
+static void DisabledZone(const Common::String &zone, bool disable) {
Game *game = g_engine->getGame();
if (!game->scene().markerGui().loaded())
return;
- warning("TODO: Implement DisabledZone");
+ TeLayout *bg = game->scene().markerGui().layout("background");
+ if (!bg) {
+ warning("DisabledZone(%s): No background in markerGui", zone.c_str());
+ return;
+ }
+ for (auto *child : bg->childList()) {
+ TeLayout *childLayout = dynamic_cast<TeLayout *>(child);
+ if (!childLayout)
+ continue;
+ if (child->name() == zone) {
+ child->setVisible(!disable);
+ }
+ }
}
static int tolua_ExportedFunctions_DisabledZone00(lua_State *L) {
diff --git a/engines/tetraedge/te/te_3d_texture.cpp b/engines/tetraedge/te/te_3d_texture.cpp
index 8c3c515d63f..bd9ee1b3575 100644
--- a/engines/tetraedge/te/te_3d_texture.cpp
+++ b/engines/tetraedge/te/te_3d_texture.cpp
@@ -234,7 +234,6 @@ TeVector2s32 Te3DTexture::optimisedSize(const TeVector2s32 &size) {
v2 = 8;
}
return TeVector2s32(v1, v2);
-
}
/*static*/
diff --git a/engines/tetraedge/te/te_button_layout.cpp b/engines/tetraedge/te/te_button_layout.cpp
index 4aac314f8bd..93db4cc9fc7 100644
--- a/engines/tetraedge/te/te_button_layout.cpp
+++ b/engines/tetraedge/te/te_button_layout.cpp
@@ -99,8 +99,8 @@ bool TeButtonLayout::onMouseLeftDown(const Common::Point &pt) {
// very simplified.
bool mouseIn = isMouseIn(pt);
- if (mouseIn)
- debug("mouse down on button '%s' (current state %d)", name().c_str(), _currentState);
+ //if (mouseIn)
+ // debug("mouse down on button '%s' (current state %d)", name().c_str(), _currentState);
enum State newState = _currentState;
switch (_currentState) {
@@ -141,8 +141,8 @@ bool TeButtonLayout::onMouseLeftUp(const Common::Point &pt) {
// somewhat simplified.
bool mouseIn = isMouseIn(pt);
- if (mouseIn)
- debug("mouse up on button '%s' (current state %d)", name().c_str(), _currentState);
+ //if (mouseIn)
+ // debug("mouse up on button '%s' (current state %d)", name().c_str(), _currentState);
enum State newState = _currentState;
switch (_currentState) {
diff --git a/engines/tetraedge/te/te_font3.cpp b/engines/tetraedge/te/te_font3.cpp
index 7ce34b4fa9b..9c6e33a221f 100644
--- a/engines/tetraedge/te/te_font3.cpp
+++ b/engines/tetraedge/te/te_font3.cpp
@@ -149,6 +149,9 @@ void TeFont3::draw(TeImage &destImage, const Common::String &str, int fontSize,
bool TeFont3::load(const Common::Path &path) {
+ if (_loadedPath == path && _fontFile.isOpen())
+ return true; // already open
+
setAccessName(path);
_loadedPath = path;
diff --git a/engines/tetraedge/te/te_free_move_zone.cpp b/engines/tetraedge/te/te_free_move_zone.cpp
index 33aac199b26..ac4f09d405c 100644
--- a/engines/tetraedge/te/te_free_move_zone.cpp
+++ b/engines/tetraedge/te/te_free_move_zone.cpp
@@ -93,10 +93,44 @@ TeVector2s32 TeFreeMoveZone::aStarResolution() const {
void TeFreeMoveZone::buildAStar() {
preUpdateGrid();
- TeVector2s32 resolution = aStarResolution();
- _graph->setSize(resolution);
+ const TeVector2s32 graphSize = aStarResolution();
+ _graph->setSize(graphSize);
+
+ // Original checks these inside the loop below, seems like a waste as they never change?
+ if (graphSize._x == 0 || graphSize._y == 0)
+ return;
+
if (!_loadedFromBin) {
- error("TODO: Implement TeFreeMoveZone::buildAStar for *not* loaded from bin case");
+ for (int x = 0; x < graphSize._x; x++) {
+ for (int y = 0; y < graphSize._y; y++) {
+ byte blockerIntersection = hasBlockerIntersection(TeVector2s32(x, y));
+ if (blockerIntersection == 1) {
+ _graph->_flags[_graph->_size._x * y + x] = 1;
+ } else {
+ if (!hasCellBorderIntersection(TeVector2s32(x, y))) {
+ const float gridOffX = _gridOffsetSomething.getX();
+ const float gridOffY = _gridOffsetSomething.getY();
+ TeVector3f32 vout;
+ float fout;
+ TeVector3f32 gridPt(x * gridOffX + _someGridVec1.getX() + gridOffX * 0.5,
+ 1000000.0,
+ gridOffY * 0.5 + y * gridOffY + _someGridVec1.getY());
+ bool doesIntersect = intersect(gridPt, TeVector3f32(0.0, -1.0, 0.0), vout, fout, true, nullptr);
+ if (!doesIntersect)
+ doesIntersect = intersect(gridPt, TeVector3f32(0.0, 1.0, 0.0), vout, fout, true, nullptr);
+
+ if (!doesIntersect)
+ _graph->_flags[graphSize._x * y + x] = 1;
+ else if (blockerIntersection == 2)
+ _graph->_flags[graphSize._x * y + x] = 2;
+ else
+ _graph->_flags[graphSize._x * y + x] = 0;
+ } else {
+ _graph->_flags[graphSize._x * y + x] = 2;
+ }
+ }
+ }
+ }
} else {
// Loaded from bin..
error("TODO: Implement TeFreeMoveZone::buildAStar for loaded from bin case");
@@ -111,8 +145,8 @@ void TeFreeMoveZone::clear() {
setNbTriangles(0);
_pickMeshDirty = true;
_projectedPointsDirty = true;
- _vectorArray.clear();
- _uintArray2.clear();
+ _transformedVerticies.clear();
+ _borders.clear();
// TODO: Some other point vector here.
_gridDirty = true;
_graph->_flags.clear();
@@ -213,9 +247,9 @@ void TeFreeMoveZone::deserialize(Common::ReadStream &stream, TeFreeMoveZone &des
dest._gridDirty = (stream.readByte() != 0);
Te3DObject2::deserializeVectorArray(stream, dest._freeMoveZoneVerticies);
- Te3DObject2::deserializeUintArray(stream, dest._uintArray1);
- Te3DObject2::deserializeVectorArray(stream, dest._vectorArray);
- Te3DObject2::deserializeUintArray(stream, dest._uintArray2);
+ Te3DObject2::deserializeUintArray(stream, dest._pickMesh);
+ Te3DObject2::deserializeVectorArray(stream, dest._transformedVerticies);
+ Te3DObject2::deserializeUintArray(stream, dest._borders);
TeOBP::deserialize(stream, dest._obp);
@@ -241,10 +275,10 @@ void TeFreeMoveZone::draw() {
renderer->enableWireFrame();
TePickMesh2::draw();
TeMesh mesh;
- mesh.setConf(_uintArray2.size(), _uintArray2.size(), TeMesh::MeshMode_Lines, 0, 0);
- for (unsigned int i = 0; i < _uintArray2.size(); i++) {
+ mesh.setConf(_borders.size(), _borders.size(), TeMesh::MeshMode_Lines, 0, 0);
+ for (unsigned int i = 0; i < _borders.size(); i++) {
mesh.setIndex(i, i);
- mesh.setVertex(i, verticies()[_uintArray2[i]]);
+ mesh.setVertex(i, verticies()[_borders[i]]);
}
const TeColor prevColor = renderer->currentColor();
@@ -264,12 +298,115 @@ TeVector3f32 TeFreeMoveZone::findNearestPointOnBorder(const TeVector2f32 &pt) {
error("TODO: Implement TeFreeMoveZone::findNearestPointOnBorder");
}
+static int segmentIntersection(const TeVector2f32 &s1start, const TeVector2f32 &s1end,
+ const TeVector2f32 &s2start, const TeVector2f32 &s2end,
+ TeVector2f32 *sout, float *fout1, float *fout2) {
+ TeVector2f32 s1len = s1end - s1start;
+ TeVector2f32 s2len = s2end - s2start;
+ float squarelen = s1len.getX() * s2len.getX() + s1len.getY() * s2len.getY();
+ int result = 0;
+ if (squarelen != 0) {
+ result = 1;
+ float intersection1 = -((s1len.getY() * s1start.getX() +
+ (s1len.getX() * s2start.getY() - s1len.getX() * s1start.getY())) -
+ s1len.getY() * s2start.getX()) / squarelen;
+ if (intersection1 >= 0.0f && intersection1 <= 1.0f) {
+ float intersection2 = -((s2len.getY() * s2start.getY() +
+ (s2len.getX() * s1start.getX() - s2len.getX() * s2start.getX())) -
+ s2len.getY() * s1start.getY()) / squarelen;
+ if (intersection2 >= 0.0f && intersection2 <= 1.0f) {
+ result = 2;
+ if (sout || fout1 || fout2) {
+ // Seems like these are always null?
+ error("TODO: implement output in segmentIntersection");
+ }
+ }
+ }
+ }
+ return result;
+}
+
+
bool TeFreeMoveZone::hasBlockerIntersection(const TeVector2s32 &pt) {
- error("TODO: Implement TeFreeMoveZone::hasBlockerIntersection");
+ TeVector2f32 borders[4];
+
+ const float gridOffsetX = _gridOffsetSomething.getX();
+ const float gridOffsetY = _gridOffsetSomething.getX();
+ borders[0] = TeVector2f32(pt._x * gridOffsetX + _someGridVec1.getX(),
+ pt._y * gridOffsetY + _someGridVec1.getY());
+ borders[1] = TeVector2f32(pt._x * gridOffsetX + _someGridVec1.getX() + gridOffsetX,
+ pt._y * gridOffsetY + _someGridVec1.getY());
+ borders[2] = TeVector2f32(pt._x * gridOffsetX + _someGridVec1.getX(),
+ pt._y * gridOffsetY + _someGridVec1.getY() + gridOffsetY);
+ borders[3] = TeVector2f32(pt._x * gridOffsetX + _someGridVec1.getX() + gridOffsetX,
+ pt._y * gridOffsetY + _someGridVec1.getY() + gridOffsetY);
+
+ for (unsigned int i = 0; i < _blockers->size(); i++) {
+ const TeBlocker &blocker = (*_blockers)[i];
+
+ if (blocker._s != name())
+ continue;
+
+ for (unsigned int b = 0; b < 4; b++) {
+ int si = segmentIntersection(borders[b], borders[(b + 1) % 4], blocker._pts[0],
+ blocker._pts[1], nullptr, nullptr, nullptr);
+ if (si == 2)
+ return 2;
+ }
+
+ TeVector2f32 borderVec = ((borders[0] + borders[3]) / 2.0) - blocker._pts[0];
+ TeVector2f32 blockerVec = blocker._pts[1] - blocker._pts[0];
+ float dotVal = borderVec.dotProduct(blockerVec.getNormalized());
+ float crosVal = borderVec.crossProduct(blockerVec);
+ if ((crosVal < 0.0) && (0.0 <= dotVal)) {
+ if (dotVal < blockerVec.length())
+ return 1;
+ }
+ }
+ return 0;
}
bool TeFreeMoveZone::hasCellBorderIntersection(const TeVector2s32 &pt) {
- error("TODO: Implement TeFreeMoveZone::hasCellBorderIntersection");
+ TeVector2f32 borders[4];
+
+ const float gridOffsetX = _gridOffsetSomething.getX();
+ const float gridOffsetY = _gridOffsetSomething.getX();
+ borders[0] = TeVector2f32(pt._x * gridOffsetX + _someGridVec1.getX(),
+ pt._y * gridOffsetY + _someGridVec1.getY());
+ borders[1] = TeVector2f32(pt._x * gridOffsetX + _someGridVec1.getX() + gridOffsetX,
+ pt._y * gridOffsetY + _someGridVec1.getY());
+ borders[2] = TeVector2f32(pt._x * gridOffsetX + _someGridVec1.getX(),
+ pt._y * gridOffsetY + _someGridVec1.getY() + gridOffsetY);
+ borders[3] = TeVector2f32(pt._x * gridOffsetX + _someGridVec1.getX() + gridOffsetX,
+ pt._y * gridOffsetY + _someGridVec1.getY() + gridOffsetY);
+
+ int iresult = 0;
+ for (unsigned int border = 0; border < _borders.size() / 2; border++) {
+ TeVector2f32 v1;
+ TeVector2f32 v2;
+ unsigned int off1 = _pickMesh[_borders[border * 2]];
+ unsigned int off2 = _pickMesh[_borders[border * 2 + 1]];
+ if (!_loadedFromBin) {
+ v1 = TeVector2f32(_transformedVerticies[off1].x(), _transformedVerticies[off1].z());
+ v2 = TeVector2f32(_transformedVerticies[off2].x(), _transformedVerticies[off2].z());
+ } else {
+ TeMatrix4x4 gridInverse = _gridMatrix;
+ gridInverse.inverse();
+ const TeVector3f32 v1_inv = gridInverse * _freeMoveZoneVerticies[off1];
+ const TeVector3f32 v2_inv = gridInverse * _freeMoveZoneVerticies[off2];
+ v1 = TeVector2f32(v1_inv.x(), v1_inv.z());
+ v2 = TeVector2f32(v2_inv.x(), v2_inv.z());
+ }
+ iresult = segmentIntersection(borders[0], borders[1], v1, v2, nullptr, nullptr, nullptr);
+ if (iresult == 2) break;
+ iresult = segmentIntersection(borders[1], borders[2], v1, v2, nullptr, nullptr, nullptr);
+ if (iresult == 2) break;
+ iresult = segmentIntersection(borders[2], borders[3], v1, v2, nullptr, nullptr, nullptr);
+ if (iresult == 2) break;
+ iresult = segmentIntersection(borders[3], borders[0], v1, v2, nullptr, nullptr, nullptr);
+ if (iresult == 2) break;
+ }
+ return iresult == 2;
}
TeActZone *TeFreeMoveZone::isInZone(const TeVector3f32 &pt) {
@@ -282,7 +419,81 @@ bool TeFreeMoveZone::onViewportChanged() {
}
void TeFreeMoveZone::preUpdateGrid() {
- error("TODO: Implement TeFreeMoveZone::preUpdateGrid");
+ updateTransformedVertices();
+ updatePickMesh();
+ updateBorders();
+ if (_loadedFromBin) {
+ calcGridMatrix();
+ }
+
+ TeMatrix4x4 gridInverse = _gridMatrix;
+ gridInverse.inverse();
+
+ TeVector3f32 newVec;
+ if (_transformedVerticies.empty() || _pickMesh.empty()) {
+ debug("[TeFreeMoveZone::buildAStar] %s have no mesh or is entierly occluded", name().c_str());
+ } else {
+ if (!_loadedFromBin) {
+ newVec = _transformedVerticies[_pickMesh[0]];
+ } else {
+ newVec = gridInverse * _freeMoveZoneVerticies[_pickMesh[0]];
+ }
+ _someGridVec1.setX(newVec.x());
+ _someGridVec1.setY(newVec.z());
+
+ _gridWorldY = newVec.y();
+ }
+ for (unsigned int i = 0; i < _pickMesh.size(); i++) {
+ unsigned int vertNo = _pickMesh[_pickMesh[i]];
+
+ if (!_loadedFromBin)
+ newVec = _transformedVerticies[vertNo];
+ else
+ newVec = gridInverse * _freeMoveZoneVerticies[vertNo];
+
+ if (_someGridVec1.getX() <= newVec.x()) {
+ if (_someGridVec2.getX() < newVec.x()) {
+ _someGridVec2.setX(newVec.x());
+ }
+ } else {
+ _someGridVec1.setX(newVec.x());
+ }
+
+ if (_someGridVec1.getY() <= newVec.z()) {
+ if (_someGridVec2.getY() < newVec.z()) {
+ _someGridVec2.setY(newVec.z());
+ }
+ } else {
+ _someGridVec1.setY(newVec.z());
+ }
+
+ if (newVec.y() < _gridWorldY) {
+ _gridWorldY = newVec.y();
+ }
+ }
+
+ if (!_loadedFromBin) {
+ if (!name().contains("19000"))
+ _gridOffsetSomething = TeVector2f32(5.0f, 5.0f);
+ else
+ _gridOffsetSomething = TeVector2f32(2.0f, 2.0f);
+ } else {
+ const TeVector2f32 gridVecDiff = _someGridVec2 - _someGridVec1;
+ float minSide = MIN(gridVecDiff.getX(), gridVecDiff.getY()) / 20.0f;
+ _gridOffsetSomething.setX(minSide);
+ _gridOffsetSomething.setY(minSide);
+
+ error("FIXME: Finish preUpdateGrid for non-loaded-from-bin case.");
+ /*
+ // what's this field?
+ if (_field_0x414.x != 0.0)
+ _gridOffsetSomething = _field_0x414;
+ */
+ }
+
+ TeMatrix4x4 worldTrans = worldTransformationMatrix();
+ worldTrans.inverse();
+ _inverseWorldTransform = worldTrans;
}
TeVector2s32 TeFreeMoveZone::projectOnAStarGrid(const TeVector3f32 &pt) {
@@ -296,34 +507,6 @@ TeVector2s32 TeFreeMoveZone::projectOnAStarGrid(const TeVector3f32 &pt) {
return TeVector2s32((int)projected.getX(), (int)projected.getY());
}
-static int segmentIntersection(const TeVector2f32 &s1start, const TeVector2f32 &s1end,
- const TeVector2f32 &s2start, const TeVector2f32 &s2end,
- TeVector2f32 *sout, float *fout1, float *fout2) {
- TeVector2f32 s1len = s1end - s1start;
- TeVector2f32 s2len = s2end - s2start;
- float squarelen = s1len.getX() * s2len.getX() + s1len.getY() * s2len.getY();
- int result = 0;
- if (squarelen != 0) {
- result = 1;
- float intersection1 = -((s1len.getY() * s1start.getX() +
- (s1len.getX() * s2start.getY() - s1len.getX() * s1start.getY())) -
- s1len.getY() * s2start.getX()) / squarelen;
- if (intersection1 >= 0.0f && intersection1 <= 1.0f) {
- float intersection2 = -((s2len.getY() * s2start.getY() +
- (s2len.getX() * s1start.getX() - s2len.getX() * s2start.getX())) -
- s2len.getY() * s1start.getY()) / squarelen;
- if (intersection2 >= 0.0f && intersection2 <= 1.0f) {
- result = 2;
- if (sout || fout1 || fout2) {
- // Seems like these are always null?
- error("TODO: implement output in segmentIntersection");
- }
- }
- }
- }
- return result;
-}
-
Common::Array<TeVector3f32> TeFreeMoveZone::removeInsignificantPoints(const Common::Array<TeVector3f32> &points) {
if (points.size() < 2)
return points;
@@ -337,10 +520,10 @@ Common::Array<TeVector3f32> TeFreeMoveZone::removeInsignificantPoints(const Comm
do {
const TeVector2f32 pt1(points[point1].x(), points[point1].z());
const TeVector2f32 pt2(points[point2].x(), points[point2].z());
- for (unsigned int i = 0; i * 2 < _uintArray2.size() / 2; i++) {
- const TeVector3f32 transpt3d1 = worldTransformationMatrix() * verticies()[_uintArray2[i * 2]];
+ for (unsigned int i = 0; i * 2 < _borders.size() / 2; i++) {
+ const TeVector3f32 transpt3d1 = worldTransformationMatrix() * verticies()[_borders[i * 2]];
const TeVector2f32 transpt1(transpt3d1.x(), transpt3d1.z());
- const TeVector3f32 transpt3d2 = worldTransformationMatrix() * verticies()[_uintArray2[i * 2 + 1]];
+ const TeVector3f32 transpt3d2 = worldTransformationMatrix() * verticies()[_borders[i * 2 + 1]];
const TeVector2f32 transpt2(transpt3d2.x(), transpt3d2.z());
if (segmentIntersection(pt1, pt2, transpt1, transpt2, nullptr, nullptr, nullptr) == 2)
break;
@@ -425,7 +608,45 @@ TeVector3f32 TeFreeMoveZone::transformVectorInWorldSpace(float x, float y) {
}
void TeFreeMoveZone::updateBorders() {
- error("TODO: Implement TeFreeMoveZone::updateBorders");
+ if (!_bordersDirty)
+ return;
+
+ updatePickMesh();
+
+ if (_verticies.size() > 2) {
+ for (unsigned int triNo1 = 0; triNo1 < _verticies.size() / 3; triNo1++) {
+ for (unsigned int vecNo1 = 0; vecNo1 < 3; vecNo1++) {
+ unsigned int left1 = triNo1 * 3 + vecNo1;
+ unsigned int left2 = triNo1 * 3 + (vecNo1 == 2 ? 0 : vecNo1 + 1);
+ const TeVector3f32 vleft1 = _verticies[left1];
+ const TeVector3f32 vleft2 = _verticies[left2];
+
+ bool skip = false;
+ for (unsigned int triNo2 = 0; triNo2 < _verticies.size() / 3; triNo2++) {
+ if (skip)
+ break;
+
+ for (unsigned int vecNo2 = 0; vecNo2 < 3; vecNo2++) {
+ if (triNo2 == triNo1)
+ continue;
+ unsigned int right1 = triNo2 * 3 + vecNo2;
+ unsigned int right2 = triNo2 * 3 + (vecNo2 == 2 ? 0 : vecNo2 + 1);
+ TeVector3f32 vright1 = _verticies[right1];
+ TeVector3f32 vright2 = _verticies[right2];
+ if (vright1 == vleft1 && vright2 == vleft2 && vright1 == vleft2 && vright2 == vleft1) {
+ skip = true;
+ break;
+ }
+ }
+ }
+ if (!skip) {
+ _borders.push_back(left1);
+ _borders.push_back(left2);
+ }
+ }
+ }
+ }
+ _bordersDirty = false;
}
void TeFreeMoveZone::updateGrid(bool force) {
@@ -444,7 +665,29 @@ void TeFreeMoveZone::updatePickMesh() {
if (!_pickMeshDirty)
return;
- error("TODO: Implement TeFreeMoveZone::updatePickMesh");
+ updateTransformedVertices();
+ _pickMesh.clear();
+ _pickMesh.reserve(_freeMoveZoneVerticies.size());
+ int vecNo = 0;
+ for (unsigned int tri = 0; tri < _freeMoveZoneVerticies.size() / 3; tri++) {
+ _pickMesh.push_back(vecNo);
+ _pickMesh.push_back(vecNo + 1);
+ _pickMesh.push_back(vecNo + 2);
+ vecNo += 3;
+ }
+
+ debug("[TeFreeMoveZone::updatePickMesh] %s nb triangles reduced from : %d to : %d", name().c_str(),
+ _freeMoveZoneVerticies.size() / 3, _pickMesh.size() / 3);
+
+ TePickMesh2::setNbTriangles(_pickMesh.size() / 3);
+
+ for (unsigned int i = 0; i < _pickMesh.size(); i++) {
+ _verticies[i] = _freeMoveZoneVerticies[_pickMesh[i]];
+ }
+ _bordersDirty = true;
+ _pickMeshDirty = false;
+ _projectedPointsDirty = true;
+ _gridDirty = true;
}
void TeFreeMoveZone::updateProjectedPoints() {
@@ -458,7 +701,12 @@ void TeFreeMoveZone::updateTransformedVertices() {
if (!_transformedVerticiesDirty)
return;
- error("TODO: Implement TeFreeMoveZone::updateTransformedVertices");
+ const TeMatrix4x4 worldTransform = worldTransformationMatrix();
+ _transformedVerticies.resize(_freeMoveZoneVerticies.size());
+ for (unsigned int i = 0; i < _transformedVerticies.size(); i++) {
+ _transformedVerticies[i] = worldTransform * _freeMoveZoneVerticies[i];
+ }
+ _transformedVerticiesDirty = false;
}
/*========*/
diff --git a/engines/tetraedge/te/te_free_move_zone.h b/engines/tetraedge/te/te_free_move_zone.h
index 0bd8c4a98b2..9f6dcc6442a 100644
--- a/engines/tetraedge/te/te_free_move_zone.h
+++ b/engines/tetraedge/te/te_free_move_zone.h
@@ -122,15 +122,16 @@ private:
Common::Array<TeRectBlocker> *_rectBlockers;
Common::Array<TeVector3f32> _freeMoveZoneVerticies;
- // TODO: Find better names..
- Common::Array<unsigned int> _uintArray1;
- Common::Array<TeVector3f32> _vectorArray;
- Common::Array<unsigned int> _uintArray2;
+ Common::Array<unsigned int> _pickMesh;
+ Common::Array<TeVector3f32> _transformedVerticies;
+ Common::Array<unsigned int> _borders;
+ // TODO: Find better names..
TeVector2f32 _gridOffsetSomething;
TeVector2f32 _someGridVec1;
TeVector2f32 _someGridVec2;
TeMatrix4x4 _gridMatrix;
+ TeMatrix4x4 _inverseWorldTransform;
float _gridWorldY;
diff --git a/engines/tetraedge/te/te_lua_context.cpp b/engines/tetraedge/te/te_lua_context.cpp
index feb3ae66a32..15b7c8b880c 100644
--- a/engines/tetraedge/te/te_lua_context.cpp
+++ b/engines/tetraedge/te/te_lua_context.cpp
@@ -33,7 +33,7 @@ namespace Tetraedge {
static int luaPanicFunction(lua_State *state) {
const char *msg = lua_tolstring(state, -1, nullptr);
- warning("Lua: %s\n",msg);
+ warning("Lua: %s",msg);
lua_settop(state, -2);
return 1;
}
diff --git a/engines/tetraedge/te/te_lua_gui.cpp b/engines/tetraedge/te/te_lua_gui.cpp
index e6d55d14ed5..26e60c63ee5 100644
--- a/engines/tetraedge/te/te_lua_gui.cpp
+++ b/engines/tetraedge/te/te_lua_gui.cpp
@@ -287,6 +287,7 @@ void TeLuaGUI::unload() {
delete iter._value;
}
_colorLinearAnimations.clear();
+ _loaded = false;
}
TeVariant TeLuaGUI::value(const Common::String &globalName) {
diff --git a/engines/tetraedge/te/te_lua_gui_lua_callbacks.cpp b/engines/tetraedge/te/te_lua_gui_lua_callbacks.cpp
index a7dbead85b3..db034856396 100644
--- a/engines/tetraedge/te/te_lua_gui_lua_callbacks.cpp
+++ b/engines/tetraedge/te/te_lua_gui_lua_callbacks.cpp
@@ -214,7 +214,7 @@ static bool _g_bWidescreen = false;
int layoutBindings(lua_State *L) {
if (lua_type(L, -1) != LUA_TTABLE) {
- warning("layoutBindings:: the lua value is not a table\n");
+ warning("layoutBindings:: the lua value is not a table");
return 0;
}
@@ -232,7 +232,7 @@ int layoutBindings(lua_State *L) {
layout->setScale(TeVector3f32(0.7500001f, 1.0f ,1.0f));
}
} else {
- warning("[TeLuaGUI.layoutBindings] Unreconized attribute : %s\n", s);
+ warning("[TeLuaGUI.layoutBindings] Unreconized attribute : %s", s);
}
} else if (type == LUA_TNUMBER) {
Te3DObject2 *obj = TeLuaTo<Te3DObject2*>(L, -1);
diff --git a/engines/tetraedge/te/te_pick_mesh2.h b/engines/tetraedge/te/te_pick_mesh2.h
index 584a3cf88b9..42c1a4235aa 100644
--- a/engines/tetraedge/te/te_pick_mesh2.h
+++ b/engines/tetraedge/te/te_pick_mesh2.h
@@ -53,7 +53,7 @@ public:
Common::Array<TeVector3f32> &verticies() { return _verticies; }
const Common::Array<TeVector3f32> &verticies() const { return _verticies; }
-private:
+protected:
Common::Array<TeVector3f32> _verticies;
unsigned int _lastTriangleHit;
diff --git a/engines/tetraedge/te/te_renderer.cpp b/engines/tetraedge/te/te_renderer.cpp
index ea5e0b0ee9d..464d6632cad 100644
--- a/engines/tetraedge/te/te_renderer.cpp
+++ b/engines/tetraedge/te/te_renderer.cpp
@@ -265,7 +265,7 @@ void TeRenderer::init() {
debug("[TeRenderer::init] Sentil buffer bits : %d", bits);
glGetIntegerv(GL_DEPTH_BITS, &bits);
debug("[TeRenderer::init] Depth buffer bits : %d", bits);
- //debug("[TeRenderer::init] Extensions : %s\n", glGetString(GL_EXTENSIONS));
+ //debug("[TeRenderer::init] Extensions : %s", glGetString(GL_EXTENSIONS));
//TeOpenGLExtensions::loadExtensions(); // this does nothing in the game?
_currentColor = TeColor(255, 255, 255, 255);
_scissorEnabled = false;
diff --git a/engines/tetraedge/te/te_scrolling_layout.cpp b/engines/tetraedge/te/te_scrolling_layout.cpp
index 9f027a624a9..01522966b52 100644
--- a/engines/tetraedge/te/te_scrolling_layout.cpp
+++ b/engines/tetraedge/te/te_scrolling_layout.cpp
@@ -23,7 +23,12 @@
namespace Tetraedge {
-TeScrollingLayout::TeScrollingLayout() : _autoScrollDelay(0), _contentLayout(nullptr) {
+TeScrollingLayout::TeScrollingLayout() : _contentLayout(nullptr),
+ _enclose(true), _mouseControl(true), _autoScrollLoop(-1), _autoScrollDelay(1500),
+ _autoScrollAnimation1Enabled(true), _autoScrollAnimation2Enabled(true),
+ _autoScrollAnimation1Speed(0.1), _autoScrollAnimation2Speed(0.1),
+ _autoScrollAnimation1Delay(1000), _autoScrollAnimation2Delay(1000)
+{
}
void TeScrollingLayout::setContentLayout(TeLayout *layout) {
diff --git a/engines/tetraedge/te/te_text_base2.cpp b/engines/tetraedge/te/te_text_base2.cpp
index a5676d8e277..deefe76c733 100644
--- a/engines/tetraedge/te/te_text_base2.cpp
+++ b/engines/tetraedge/te/te_text_base2.cpp
@@ -18,7 +18,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
-
+
//#define DUMP_RENDERED_FONTS 1
#ifdef DUMP_RENDERED_FONTS
diff --git a/engines/tetraedge/te/te_text_layout.cpp b/engines/tetraedge/te/te_text_layout.cpp
index db3a34aeadf..77750a593cd 100644
--- a/engines/tetraedge/te/te_text_layout.cpp
+++ b/engines/tetraedge/te/te_text_layout.cpp
@@ -107,8 +107,9 @@ void TeTextLayout::setText(const Common::String &val) {
if (parser.fontFile().size()) {
Common::Path fontPath(parser.fontFile());
+ fontPath = g_engine->getCore()->findFile(fontPath);
TeIntrusivePtr<TeFont3> font = g_engine->getResourceManager()->getResource<TeFont3>(fontPath);
- font->load(fontPath);
+ //font->load(fontPath); // lazy load this later.
_base.setFont(0, font);
}
if (parser.style().size())
diff --git a/engines/tetraedge/te/te_tiled_surface.cpp b/engines/tetraedge/te/te_tiled_surface.cpp
index 0b4337f9463..f2c123fe550 100644
--- a/engines/tetraedge/te/te_tiled_surface.cpp
+++ b/engines/tetraedge/te/te_tiled_surface.cpp
@@ -41,6 +41,10 @@ void TeTiledSurface::cont() {
_frameAnim.cont();
}
+TeTiledSurface::~TeTiledSurface() {
+ unload();
+}
+
void TeTiledSurface::draw() {
if (_tiledTexture && _tiledTexture->isLoaded())
TeModel::draw();
diff --git a/engines/tetraedge/te/te_tiled_surface.h b/engines/tetraedge/te/te_tiled_surface.h
index 9e9c77a42ea..85e54ead249 100644
--- a/engines/tetraedge/te/te_tiled_surface.h
+++ b/engines/tetraedge/te/te_tiled_surface.h
@@ -38,6 +38,7 @@ namespace Tetraedge {
class TeTiledSurface : public TeModel {
public:
TeTiledSurface();
+ virtual ~TeTiledSurface();
virtual int bufferSize() { return 1; } // unused?
void cont();
Commit: 066dd8e15584a77661f7557db1364f0448a66661
https://github.com/scummvm/scummvm/commit/066dd8e15584a77661f7557db1364f0448a66661
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2023-01-16T17:36:43+01:00
Commit Message:
TETRAEDGE: More improvements
Changed paths:
engines/tetraedge/game/cellphone.h
engines/tetraedge/game/character_settings_xml_parser.h
engines/tetraedge/game/game.cpp
engines/tetraedge/game/in_game_scene.cpp
engines/tetraedge/game/in_game_scene.h
engines/tetraedge/game/inventory_objects_xml_parser.h
engines/tetraedge/game/loc_file.cpp
engines/tetraedge/game/main_menu.cpp
engines/tetraedge/game/object_settings_xml_parser.h
engines/tetraedge/game/scene_lights_xml_parser.h
engines/tetraedge/metaengine.h
engines/tetraedge/te/te_camera.cpp
engines/tetraedge/te/te_core.cpp
engines/tetraedge/te/te_free_move_zone.cpp
engines/tetraedge/te/te_lua_gui_lua_callbacks.cpp
engines/tetraedge/te/te_model.cpp
engines/tetraedge/te/te_model_animation.cpp
engines/tetraedge/te/te_name_val_xml_parser.h
engines/tetraedge/te/te_pick_mesh2.cpp
engines/tetraedge/te/te_ray_intersection.cpp
engines/tetraedge/te/te_ray_intersection.h
engines/tetraedge/te/te_text_layout_xml_parser.h
engines/tetraedge/te/te_vector3f32.cpp
engines/tetraedge/te/te_vector3f32.h
diff --git a/engines/tetraedge/game/cellphone.h b/engines/tetraedge/game/cellphone.h
index f9d1c8922b3..d23d3c80a92 100644
--- a/engines/tetraedge/game/cellphone.h
+++ b/engines/tetraedge/game/cellphone.h
@@ -25,7 +25,7 @@
#include "common/array.h"
#include "common/callback.h"
#include "common/str.h"
-#include "common/xmlparser.h"
+#include "common/formats/xmlparser.h"
#include "tetraedge/te/te_layout.h"
#include "tetraedge/te/te_text_layout.h"
diff --git a/engines/tetraedge/game/character_settings_xml_parser.h b/engines/tetraedge/game/character_settings_xml_parser.h
index 1c15e95e0f9..f7b41b58402 100644
--- a/engines/tetraedge/game/character_settings_xml_parser.h
+++ b/engines/tetraedge/game/character_settings_xml_parser.h
@@ -22,7 +22,7 @@
#ifndef TETRAEDGE_GAME_CHARACTER_SETTINGS_XML_PARSER_H
#define TETRAEDGE_GAME_CHARACTER_SETTINGS_XML_PARSER_H
-#include "common/xmlparser.h"
+#include "common/formats/xmlparser.h"
#include "tetraedge/game/character.h"
#include "tetraedge/te/te_vector3f32.h"
diff --git a/engines/tetraedge/game/game.cpp b/engines/tetraedge/game/game.cpp
index d8db0d019da..1c8444032db 100644
--- a/engines/tetraedge/game/game.cpp
+++ b/engines/tetraedge/game/game.cpp
@@ -988,16 +988,16 @@ bool Game::onMouseClick(const Common::Point &pt) {
if (_previousMousePos == TeVector2s32(-1, -1)) {
_previousMousePos = pt;
} else {
- TeVector3f32 winSize = app->getMainWindow().size();
- TeVector2s32 lastMousePos = _previousMousePos;
+ const TeVector3f32 winSize = app->getMainWindow().size();
+ const TeVector2s32 prevMousePos = _previousMousePos;
_previousMousePos = pt;
- float xdist = pt.x / winSize.x() - lastMousePos._x / winSize.x();
- float ydist = pt.y / winSize.y() - lastMousePos._y / winSize.y();
+ float xdist = (pt.x - prevMousePos._x) / winSize.x();
+ float ydist = (pt.y - prevMousePos._y) / winSize.y();
float sqrdist = xdist * xdist + ydist * ydist;
- if (sqrdist > 0.0001 && (!_walkTimer.running() || _walkTimer.timeElapsed() > 300000.0
+ if (sqrdist < 0.0001 && (!_walkTimer.running() || _walkTimer.timeElapsed() > 300000.0
|| (_scene._character && _scene._character->walkModeStr() != "Walk"))) {
return false;
- // Double-click, but already jogging
+ // Normal walk click
}
}
@@ -1006,11 +1006,12 @@ bool Game::onMouseClick(const Common::Point &pt) {
Common::String nearestMeshName = "None";
TeIntrusivePtr<TeCamera> curCamera = _scene.currentCamera();
- Common::Array<TePickMesh2*> pickMeshes = _scene.pickMeshes();
+ Common::Array<TePickMesh2*> pickMeshes = _scene.clickMeshes();
TePickMesh2 *nearestMesh = TeFreeMoveZone::findNearestMesh(curCamera, pt, pickMeshes, nullptr, false);
if (nearestMesh) {
nearestMeshName = nearestMesh->name();
- _lastCharMoveMousePos = TeVector2s32(0, 0);
+ debug("Game::onMouseClick: Click near mesh %s", nearestMeshName.c_str());
+ _lastCharMoveMousePos = TeVector2s32();
}
if (app->isLockCursor() || _movePlayerCharacterDisabled)
@@ -1025,49 +1026,51 @@ bool Game::onMouseClick(const Common::Point &pt) {
|| charAnim == character->walkAnim(Character::WalkPart_EndD)
|| charAnim == character->walkAnim(Character::WalkPart_EndG)) {
_luaScript.execute("On");
- if (!_scene.isObjectBlocking(nearestMeshName)) {
- if (character->freeMoveZone()) {
- TeVector3f32 charPos = character->_model->position();
- TeIntrusivePtr<TeBezierCurve> curve = character->freeMoveZone()->curve(charPos, TeVector2s32(pt), 8.0, true);
- if (curve) {
- _scene.setCurve(curve);
- character->setCurveStartLocation(TeVector3f32());
- if (curve->controlPoints().size() == 1) {
- character->endMove();
- } else {
- if (!_walkTimer.running() || _walkTimer.timeElapsed() > 300000) {
- _walkTimer.stop();
- _walkTimer.start();
- character->walkMode("Walk");
- } else {
- // Note: original checks the timer elapsed again here.. why?
- _walkTimer.stop();
- character->walkMode("Jog");
- }
- character->placeOnCurve(curve);
- character->setCurveOffset(0.0);
- if (charAnim != character->walkAnim(Character::WalkPart_Start)) {
- character->setAnimation(character->walkAnim(Character::WalkPart_Start), false);
- }
- character->walkTo(1.0, false);
- _sceneCharacterVisibleFromLoad = false;
- _lastCharMoveMousePos = pt;
- }
+ if (!_scene.isObjectBlocking(nearestMeshName) && character->freeMoveZone()) {
+ const TeVector3f32 charPos = character->_model->position();
+ TeIntrusivePtr<TeBezierCurve> curve = character->freeMoveZone()->curve(charPos, pt, 8.0, true);
+ if (!curve)
+ return false;
+
+ _scene.setCurve(curve);
+ character->setCurveStartLocation(TeVector3f32());
+ if (curve->controlPoints().size() == 1) {
+ character->endMove();
+ } else {
+ if (!_walkTimer.running() || _walkTimer.timeElapsed() > 300000) {
+ _walkTimer.stop();
+ _walkTimer.start();
+ character->walkMode("Walk");
} else {
- return false;
+ // Note: original checks the timer elapsed again here.. why?
+ _walkTimer.stop();
+ character->walkMode("Jog");
}
+ character->placeOnCurve(curve);
+ character->setCurveOffset(0.0);
+ if (charAnim != character->walkAnim(Character::WalkPart_Start)) {
+ character->setAnimation(character->walkAnim(Character::WalkPart_Start), false);
+ }
+ character->walkTo(1.0, false);
+ _sceneCharacterVisibleFromLoad = false;
+ _lastCharMoveMousePos = pt;
}
}
- TeVector3f32 lastPoint = _scene.curve()->controlPoints().back();
- character->setAnimation(character->walkAnim(Character::WalkPart_Loop), true);
- character->walkTo(1.0, false);
- _isCharacterWalking = true;
- _posPlayer = lastPoint;
+ // FIXME: The original never checks for empty/null curve here.. why?
+ if (_scene.curve() && _scene.curve()->length()) {
+ TeVector3f32 lastPoint = _scene.curve()->controlPoints().back();
+ character->setAnimation(character->walkAnim(Character::WalkPart_Loop), true);
+ character->walkTo(1.0, false);
+ _isCharacterWalking = true;
+ _posPlayer = lastPoint;
+ }
}
-
- if (!_sceneCharacterVisibleFromLoad || (character->curAnimName() == character->characterSettings()._idleAnimFileName)) {
+
+ // Note: charAnim above may no longer be valid as anim may have changed.
+ if (_sceneCharacterVisibleFromLoad || (character->curAnimName() == character->characterSettings()._idleAnimFileName)) {
_lastCharMoveMousePos = TeVector2s32(0, 0);
- _movePlayerCharacterDisabled = true;
+ _movePlayerCharacterDisabled = false;
+ _isCharacterIdle = true;
_isCharacterWalking = false;
if (nearestMesh) {
character->stop();
diff --git a/engines/tetraedge/game/in_game_scene.cpp b/engines/tetraedge/game/in_game_scene.cpp
index fc9df5e7ff6..48ffd9592b1 100644
--- a/engines/tetraedge/game/in_game_scene.cpp
+++ b/engines/tetraedge/game/in_game_scene.cpp
@@ -42,7 +42,7 @@
#include "tetraedge/te/te_lua_script.h"
#include "tetraedge/te/te_lua_thread.h"
-//#define DEBUG_PATHFINDING 1
+#define DEBUG_PATHFINDING 1
namespace Tetraedge {
@@ -204,9 +204,9 @@ void InGameScene::close() {
delete zone;
_freeMoveZones.clear();
_hitObjects.clear();
- for (TePickMesh2 *mesh : _pickMeshes)
+ for (TePickMesh2 *mesh : _clickMeshes)
delete mesh;
- _pickMeshes.clear();
+ _clickMeshes.clear();
_bezierCurves.clear();
_dummies.clear();
freeSceneObjects();
@@ -289,6 +289,8 @@ void InGameScene::deserializeModel(Common::ReadStream &stream, TeIntrusivePtr<Te
TeQuaternion rot;
TeColor col;
TeMesh mesh;
+
+ assert(pickmesh);
TeVector3f32::deserialize(stream, vec);
model->setPosition(vec);
@@ -328,7 +330,7 @@ void InGameScene::deserializeModel(Common::ReadStream &stream, TeIntrusivePtr<Te
pickmesh->setNbTriangles(indexcount / 3);
for (unsigned int i = 0; i < indexcount; i++) {
vec = mesh.vertex(mesh.index(i));
- pickmesh->verticies().push_back(vec);
+ pickmesh->verticies()[i] = vec;
}
model->addMesh(mesh);
}
@@ -351,6 +353,11 @@ void InGameScene::draw() {
zone->setVisible(true);
zone->draw();
}
+
+ for (TePickMesh2 *mesh : _clickMeshes) {
+ mesh->setVisible(true);
+ mesh->draw();
+ }
#endif
TeLight::updateGlobal();
@@ -583,12 +590,13 @@ bool InGameScene::load(const Common::Path &path) {
TePickMesh2 *pickmesh = new TePickMesh2();
deserializeModel(scenefile, model, pickmesh);
if (modelname.contains("Clic")) {
+ //debug("Loaded clickMesh %s", modelname.c_str());
_hitObjects.push_back(model);
- model->setVisible(false);
+ model->setVisible(true);
model->setColor(TeColor(0, 0xff, 0, 0xff));
models().push_back(model);
pickmesh->setName(modelname);
- _pickMeshes.push_back(pickmesh);
+ _clickMeshes.push_back(pickmesh);
} else {
delete pickmesh;
if (modelname.substr(0, 2) != "ZB") {
diff --git a/engines/tetraedge/game/in_game_scene.h b/engines/tetraedge/game/in_game_scene.h
index 17fb23d1698..7fb5318b2ed 100644
--- a/engines/tetraedge/game/in_game_scene.h
+++ b/engines/tetraedge/game/in_game_scene.h
@@ -180,7 +180,7 @@ public:
TeLuaGUI &hitObjectGui() { return _hitObjectGui; }
TeLuaGUI &markerGui() { return _markerGui; }
- Common::Array<TePickMesh2 *> &pickMeshes() { return _pickMeshes; }
+ Common::Array<TePickMesh2 *> &clickMeshes() { return _clickMeshes; }
float shadowFarPlane() const { return _shadowFarPlane; }
float shadowNearPlane() const { return _shadowNearPlane; }
@@ -218,7 +218,7 @@ private:
Common::Array<Object3D *> _object3Ds;
Common::Array<Billboard *> _billboards;
Common::Array<TeSpriteLayout *> _sprites;
- Common::Array<TePickMesh2 *> _pickMeshes;
+ Common::Array<TePickMesh2 *> _clickMeshes;
Common::HashMap<Common::String, SoundStep> _soundSteps;
Common::HashMap<Common::String, Common::Array<Callback*>> _callbacks;
diff --git a/engines/tetraedge/game/inventory_objects_xml_parser.h b/engines/tetraedge/game/inventory_objects_xml_parser.h
index 6f86575527d..904fb1d7d87 100644
--- a/engines/tetraedge/game/inventory_objects_xml_parser.h
+++ b/engines/tetraedge/game/inventory_objects_xml_parser.h
@@ -21,7 +21,7 @@
#include "common/hashmap.h"
#include "common/str.h"
-#include "common/xmlparser.h"
+#include "common/formats/xmlparser.h"
#include "tetraedge/game/inventory.h"
#ifndef TETRAEDGE_GAME_INVENTORY_OBJECTS_XML_PARSER_H
diff --git a/engines/tetraedge/game/loc_file.cpp b/engines/tetraedge/game/loc_file.cpp
index 10321ad432c..89b43242403 100644
--- a/engines/tetraedge/game/loc_file.cpp
+++ b/engines/tetraedge/game/loc_file.cpp
@@ -21,7 +21,7 @@
#include "common/file.h"
#include "common/textconsole.h"
-#include "common/xmlparser.h"
+#include "common/formats/xmlparser.h"
#include "tetraedge/game/loc_file.h"
#include "tetraedge/te/te_name_val_xml_parser.h"
diff --git a/engines/tetraedge/game/main_menu.cpp b/engines/tetraedge/game/main_menu.cpp
index ec92bbee2ce..fec813c658a 100644
--- a/engines/tetraedge/game/main_menu.cpp
+++ b/engines/tetraedge/game/main_menu.cpp
@@ -62,7 +62,7 @@ void MainMenu::enter() {
_entered = true;
load("menus/mainMenu/mainMenu.lua");
- TeLayout *menuLayout = layout("menu");
+ TeLayout *menuLayout = layoutChecked("menu");
appSpriteLayout.addChild(menuLayout);
app->mouseCursorLayout().setVisible(true);
diff --git a/engines/tetraedge/game/object_settings_xml_parser.h b/engines/tetraedge/game/object_settings_xml_parser.h
index a6d7c244078..328b4a04236 100644
--- a/engines/tetraedge/game/object_settings_xml_parser.h
+++ b/engines/tetraedge/game/object_settings_xml_parser.h
@@ -22,7 +22,7 @@
#ifndef TETRAEDGE_GAME_OBJECT_SETTINGS_XML_PARSER_H
#define TETRAEDGE_GAME_OBJECT_SETTINGS_XML_PARSER_H
-#include "common/xmlparser.h"
+#include "common/formats/xmlparser.h"
#include "tetraedge/game/object3d.h"
#include "tetraedge/te/te_vector3f32.h"
diff --git a/engines/tetraedge/game/scene_lights_xml_parser.h b/engines/tetraedge/game/scene_lights_xml_parser.h
index 0b85362ec5f..a6159b0b099 100644
--- a/engines/tetraedge/game/scene_lights_xml_parser.h
+++ b/engines/tetraedge/game/scene_lights_xml_parser.h
@@ -22,7 +22,7 @@
#ifndef TETRAEDGE_GAME_SCENE_LIGHTS_XML_PARSER_H
#define TETRAEDGE_GAME_SCENE_LIGHTS_XML_PARSER_H
-#include "common/xmlparser.h"
+#include "common/formats/xmlparser.h"
#include "tetraedge/te/te_light.h"
#include "tetraedge/te/te_vector3f32.h"
diff --git a/engines/tetraedge/metaengine.h b/engines/tetraedge/metaengine.h
index a992757f82d..08c9d062c27 100644
--- a/engines/tetraedge/metaengine.h
+++ b/engines/tetraedge/metaengine.h
@@ -22,7 +22,7 @@
#ifndef TETRAEDGE_METAENGINE_H
#define TETRAEDGE_METAENGINE_H
-#include "common/achievements.h"
+#include "engines/achievements.h"
#include "engines/advancedDetector.h"
class TetraedgeMetaEngine : public AdvancedMetaEngine {
diff --git a/engines/tetraedge/te/te_camera.cpp b/engines/tetraedge/te/te_camera.cpp
index bb2eb7bf4dc..ed8c8217d4d 100644
--- a/engines/tetraedge/te/te_camera.cpp
+++ b/engines/tetraedge/te/te_camera.cpp
@@ -136,24 +136,25 @@ void TeCamera::draw() {
error("TODO: Implement TeCamera::draw");
}
-void TeCamera::getRay(const TeVector2s32 &pxloc, TeVector3f32 &out1, TeVector3f32 &out2) {
+void TeCamera::getRay(const TeVector2s32 &pxloc, TeVector3f32 &raypos, TeVector3f32 &raydir) {
+ raypos = position();
+
float xval = (pxloc._x - _viewportX) / fabs(_viewportW);
- out2.x() = xval * 2 - 1;
+ raydir.x() = xval * 2 - 1;
float yval = (pxloc._y - _viewportY) / fabs(_viewportH);
- out2.y() = yval * 2 - 1;
- out2.z() = 1.0;
+ raydir.y() = yval * 2 - 1;
+ raydir.z() = 1.0;
- TeMatrix4x4 inverse = projectionMatrix();
- inverse.inverse();
- out2 = inverse * out2;
- out2.normalize();
+ TeMatrix4x4 projInverse = _projectionMatrix;
+ projInverse.inverse();
+ raydir = projInverse * raydir;
+ raydir.normalize();
- TeVector3f32 pos = position();
- TeQuaternion rot = rotation();
- out1 = pos;
+ TeQuaternion rot = _rotation;
rot.normalize();
- TeMatrix4x4 rotmatrix = rot.toTeMatrix();
- out2 = rotmatrix * out2;
+ const TeMatrix4x4 rotmatrix = rot.toTeMatrix();
+
+ raydir = rotmatrix * raydir;
}
void TeCamera::loadBin(const Common::String &path) {
diff --git a/engines/tetraedge/te/te_core.cpp b/engines/tetraedge/te/te_core.cpp
index 8f586a7d495..59cccba30b2 100644
--- a/engines/tetraedge/te/te_core.cpp
+++ b/engines/tetraedge/te/te_core.cpp
@@ -156,6 +156,8 @@ Common::Path TeCore::findFile(const Common::Path &path) {
testPath.joinInPlace(fname);
if (Common::File::exists(testPath) || Common::FSNode(path).exists()) {
return testPath;
+ } else {
+ debug("not found %s", testPath.toString().c_str());
}
}
}
diff --git a/engines/tetraedge/te/te_free_move_zone.cpp b/engines/tetraedge/te/te_free_move_zone.cpp
index ac4f09d405c..daf300a7756 100644
--- a/engines/tetraedge/te/te_free_move_zone.cpp
+++ b/engines/tetraedge/te/te_free_move_zone.cpp
@@ -176,13 +176,13 @@ TeVector3f32 TeFreeMoveZone::correctCharacterPosition(const TeVector3f32 &pos, b
return intersectPoint;
}
-TeIntrusivePtr<TeBezierCurve> TeFreeMoveZone::curve(const TeVector3f32 &startpt, const TeVector2s32 &endpt, float param_5, bool findMeshFlag) {
+TeIntrusivePtr<TeBezierCurve> TeFreeMoveZone::curve(const TeVector3f32 &startpt, const TeVector2s32 &clickPt, float param_5, bool findMeshFlag) {
updateGrid(false);
Common::Array<TePickMesh2 *> meshes;
TeVector3f32 newend;
meshes.push_back(this);
- TePickMesh2 *nearest = findNearestMesh(_camera, endpt, meshes, &newend, findMeshFlag);
+ TePickMesh2 *nearest = findNearestMesh(_camera, clickPt, meshes, &newend, findMeshFlag);
if (!nearest)
return TeIntrusivePtr<TeBezierCurve>();
@@ -803,54 +803,52 @@ void TeFreeMoveZoneGraph::serialize(Common::WriteStream &stream) const {
}
/*static*/
-TePickMesh2 *TeFreeMoveZone::findNearestMesh(TeIntrusivePtr<TeCamera> &camera, const TeVector2s32 &frompt,
+TePickMesh2 *TeFreeMoveZone::findNearestMesh(TeIntrusivePtr<TeCamera> &camera, const TeVector2s32 &fromPt,
Common::Array<TePickMesh2*> &pickMeshes, TeVector3f32 *outloc, bool lastHitFirst) {
- TeVector3f32 locresult;
- TePickMesh2 *nearest = nullptr;
- float furthest = camera->_orthFarVal;
- if (!pickMeshes.empty()) {
- TeVector3f32 v1;
- TeVector3f32 v2;
- for (unsigned int i = 0; i < pickMeshes.size(); i++) {
- TePickMesh2 *mesh = pickMeshes[i];
- const TeMatrix4x4 transform = mesh->worldTransformationMatrix();
- if (lastHitFirst) {
- unsigned int tricount = mesh->verticies().size() / 3;
- unsigned int vert = mesh->lastTriangleHit() * 3;
- if (mesh->lastTriangleHit() >= tricount)
- vert = 0;
- const TeVector3f32 v3 = transform * mesh->verticies()[vert];
- const TeVector3f32 v4 = transform * mesh->verticies()[vert + 1];
- const TeVector3f32 v5 = transform * mesh->verticies()[vert + 2];
- TeVector3f32 result;
- float fresult;
- int intresult = TeRayIntersection::intersect(v1, v2, v3, v4, v5, result, fresult);
- if (intresult == 1 && fresult < furthest && fresult >= camera->_orthNearVal)
- return mesh;
- }
- for (unsigned int tri = 0; tri < mesh->verticies().size() / 3; tri++) {
- const TeVector3f32 v3 = transform * mesh->verticies()[tri * 3];
- const TeVector3f32 v4 = transform * mesh->verticies()[tri * 3 + 1];
- const TeVector3f32 v5 = transform * mesh->verticies()[tri * 3 + 1];
- camera->getRay(frompt, v1, v2);
- TeVector3f32 result;
- float fresult;
- int intresult = TeRayIntersection::intersect(v1, v2, v3, v4, v5, result, fresult);
- if (intresult == 1 && fresult < furthest && fresult >= camera->_orthNearVal) {
- mesh->setLastTriangleHit(tri);
- locresult = result;
- furthest = fresult;
- nearest = mesh;
- if (lastHitFirst)
- break;
- }
+ TeVector3f32 closestLoc;
+ TePickMesh2 *nearestMesh = nullptr;
+ float closestDist = camera->_orthFarVal;
+ TeVector3f32 rayLoc;
+ TeVector3f32 rayDir;
+ for (unsigned int i = 0; i < pickMeshes.size(); i++) {
+ TePickMesh2 *mesh = pickMeshes[i];
+ const TeMatrix4x4 meshWorldTransform = mesh->worldTransformationMatrix();
+ if (lastHitFirst) {
+ unsigned int tricount = mesh->verticies().size() / 3;
+ unsigned int vert = mesh->lastTriangleHit() * 3;
+ if (mesh->lastTriangleHit() >= tricount)
+ vert = 0;
+ const TeVector3f32 v1 = meshWorldTransform * mesh->verticies()[vert];
+ const TeVector3f32 v2 = meshWorldTransform * mesh->verticies()[vert + 1];
+ const TeVector3f32 v3 = meshWorldTransform * mesh->verticies()[vert + 2];
+ TeVector3f32 intersectLoc;
+ float intersectDist;
+ int intResult = TeRayIntersection::intersect(rayLoc, rayDir, v1, v2, v3, intersectLoc, intersectDist);
+ if (intResult == 1 && intersectDist < closestDist && intersectDist >= camera->_orthNearVal)
+ return mesh;
+ }
+ for (unsigned int tri = 0; tri < mesh->verticies().size() / 3; tri++) {
+ const TeVector3f32 v1 = meshWorldTransform * mesh->verticies()[tri * 3];
+ const TeVector3f32 v2 = meshWorldTransform * mesh->verticies()[tri * 3 + 1];
+ const TeVector3f32 v3 = meshWorldTransform * mesh->verticies()[tri * 3 + 2];
+ camera->getRay(fromPt, rayLoc, rayDir);
+ TeVector3f32 intersectLoc;
+ float intersectDist;
+ int intResult = TeRayIntersection::intersect(rayLoc, rayDir, v1, v2, v3, intersectLoc, intersectDist);
+ if (intResult == 1 && intersectDist < closestDist && intersectDist >= camera->_orthNearVal) {
+ mesh->setLastTriangleHit(tri);
+ closestLoc = intersectLoc;
+ closestDist = intersectDist;
+ nearestMesh = mesh;
+ if (lastHitFirst)
+ break;
}
}
}
if (outloc) {
- *outloc = locresult;
+ *outloc = closestLoc;
}
- return nearest;
+ return nearestMesh;
}
diff --git a/engines/tetraedge/te/te_lua_gui_lua_callbacks.cpp b/engines/tetraedge/te/te_lua_gui_lua_callbacks.cpp
index db034856396..c922904da83 100644
--- a/engines/tetraedge/te/te_lua_gui_lua_callbacks.cpp
+++ b/engines/tetraedge/te/te_lua_gui_lua_callbacks.cpp
@@ -253,7 +253,7 @@ int layoutBindings(lua_State *L) {
lua_pushlightuserdata(L, static_cast<Te3DObject2*>(layout));
return true;
} else {
- warning("layoutBindings:: multiple objects with name %s\n", layout->name().c_str());
+ warning("layoutBindings:: multiple objects with name %s", layout->name().c_str());
delete layout;
return false;
}
@@ -261,7 +261,7 @@ int layoutBindings(lua_State *L) {
int listLayoutBindings(lua_State *L) {
if (lua_type(L, -1) != LUA_TTABLE) {
- warning("listLayoutBindings:: the lua value is not a table\n");
+ warning("listLayoutBindings:: the lua value is not a table");
return 0;
}
@@ -292,7 +292,7 @@ int listLayoutBindings(lua_State *L) {
layout->setScale(TeVector3f32(0.7500001f, 1.0f ,1.0f));
}
} else {
- warning("[TeLuaGUI.layoutBindings] Unreconized attribute : %s\n", s);
+ warning("[TeLuaGUI.layoutBindings] Unreconized attribute : %s", s);
}
} else if (type == LUA_TNUMBER) {
Te3DObject2 *obj = TeLuaTo<Te3DObject2*>(L, -1);
@@ -313,7 +313,7 @@ int listLayoutBindings(lua_State *L) {
lua_pushlightuserdata(L, static_cast<Te3DObject2*>(layout));
return true;
} else {
- warning("listLayoutBindings:: multiple objects with name %s\n", layout->name().c_str());
+ warning("listLayoutBindings:: multiple objects with name %s", layout->name().c_str());
delete layout;
return false;
}
@@ -321,7 +321,7 @@ int listLayoutBindings(lua_State *L) {
int spriteLayoutBindings(lua_State *L) {
if (lua_type(L, -1) != LUA_TTABLE) {
- warning("spriteLayoutBindings:: the lua value is not a table\n");
+ warning("spriteLayoutBindings:: the lua value is not a table");
return 0;
}
@@ -379,7 +379,7 @@ int spriteLayoutBindings(lua_State *L) {
layout->setScale(TeVector3f32(0.7500001,1.0,1.0));
}
} else {
- warning("[TeLuaGUI.layoutBindings] Unreconized attribute : %s\n", s);
+ warning("[TeLuaGUI.layoutBindings] Unreconized attribute : %s", s);
}
}
lua_settop(L, -2);
@@ -429,7 +429,7 @@ int spriteLayoutBindings(lua_State *L) {
lua_pushlightuserdata(L, static_cast<Te3DObject2*>(layout));
return true;
} else {
- warning("layoutBindings:: multiple objects with name %s\n", layout->name().c_str());
+ warning("layoutBindings:: multiple objects with name %s", layout->name().c_str());
delete layout;
return false;
}
@@ -505,7 +505,7 @@ int buttonLayoutBindings(lua_State *L) {
int checkboxLayoutBindings(lua_State *L) {
if (lua_type(L, -1) != LUA_TTABLE) {
- warning("checkboxLayoutBindings:: the lua value is not a table\n");
+ warning("checkboxLayoutBindings:: the lua value is not a table");
return 0;
}
@@ -575,7 +575,7 @@ int checkboxLayoutBindings(lua_State *L) {
int layoutPositionLinearAnimationBindings(lua_State *L) {
if (lua_type(L, -1) != LUA_TTABLE) {
- warning("layoutPositionLinearAnimationBindings:: the lua value is not a table\n");
+ warning("layoutPositionLinearAnimationBindings:: the lua value is not a table");
return 0;
}
@@ -584,7 +584,7 @@ int layoutPositionLinearAnimationBindings(lua_State *L) {
int layoutAnchorLinearAnimationBindings(lua_State *L) {
if (lua_type(L, -1) != LUA_TTABLE) {
- warning("layoutAnchorLinearAnimationBindings:: the lua value is not a table\n");
+ warning("layoutAnchorLinearAnimationBindings:: the lua value is not a table");
return 0;
}
@@ -639,7 +639,7 @@ int layoutAnchorLinearAnimationBindings(lua_State *L) {
int textLayoutBindings(lua_State *L) {
if (lua_type(L, -1) != LUA_TTABLE) {
- warning("textLayoutBindings:: the lua value is not a table\n");
+ warning("textLayoutBindings:: the lua value is not a table");
return 0;
}
@@ -689,7 +689,7 @@ int textLayoutBindings(lua_State *L) {
lua_pushlightuserdata(L, static_cast<Te3DObject2*>(layout));
return true;
} else {
- warning("textLayoutBindings:: multiple objects with name %s\n", layout->name().c_str());
+ warning("textLayoutBindings:: multiple objects with name %s", layout->name().c_str());
delete layout;
return false;
}
@@ -697,7 +697,7 @@ int textLayoutBindings(lua_State *L) {
int clipLayoutBindings(lua_State *L) {
if (lua_type(L, -1) != LUA_TTABLE) {
- warning("clipLayoutBindings:: the lua value is not a table\n");
+ warning("clipLayoutBindings:: the lua value is not a table");
return 0;
}
@@ -706,7 +706,7 @@ int clipLayoutBindings(lua_State *L) {
int colorLinearAnimationBindings(lua_State *L) {
if (lua_type(L, -1) != LUA_TTABLE) {
- warning("colorLinearAnimationBindings:: the lua value is not a table\n");
+ warning("colorLinearAnimationBindings:: the lua value is not a table");
return 0;
}
@@ -758,7 +758,7 @@ int colorLinearAnimationBindings(lua_State *L) {
int rotationLinearAnimationBindings(lua_State *L) {
if (lua_type(L, -1) != LUA_TTABLE) {
- warning("rotationLinearAnimationBindings:: the lua value is not a table\n");
+ warning("rotationLinearAnimationBindings:: the lua value is not a table");
return 0;
}
@@ -767,7 +767,7 @@ int rotationLinearAnimationBindings(lua_State *L) {
int scrollingLayoutBindings(lua_State *L) {
if (lua_type(L, -1) != LUA_TTABLE) {
- warning("scrollingLayoutBindings:: the lua value is not a table\n");
+ warning("scrollingLayoutBindings:: the lua value is not a table");
return 0;
}
@@ -840,7 +840,7 @@ int scrollingLayoutBindings(lua_State *L) {
lua_pushlightuserdata(L, static_cast<Te3DObject2*>(layout));
return true;
} else {
- warning("scrollingLayoutBindings:: multiple objects with name %s\n", layout->name().c_str());
+ warning("scrollingLayoutBindings:: multiple objects with name %s", layout->name().c_str());
delete layout;
return false;
}
@@ -848,7 +848,7 @@ int scrollingLayoutBindings(lua_State *L) {
int extendedTextLayoutBindings(lua_State *L) {
if (lua_type(L, -1) != LUA_TTABLE) {
- warning("extendedTextLayoutBindings:: the lua value is not a table\n");
+ warning("extendedTextLayoutBindings:: the lua value is not a table");
return 0;
}
@@ -902,7 +902,7 @@ int extendedTextLayoutBindings(lua_State *L) {
lua_pushlightuserdata(L, static_cast<Te3DObject2*>(layout));
return true;
} else {
- warning("extendedTextLayoutBindings:: multiple objects with name %s\n", layout->name().c_str());
+ warning("extendedTextLayoutBindings:: multiple objects with name %s", layout->name().c_str());
delete layout;
return false;
}
diff --git a/engines/tetraedge/te/te_model.cpp b/engines/tetraedge/te/te_model.cpp
index e71c4112157..ef1de05bba7 100644
--- a/engines/tetraedge/te/te_model.cpp
+++ b/engines/tetraedge/te/te_model.cpp
@@ -21,8 +21,8 @@
#include "common/file.h"
#include "common/util.h"
-#include "common/zlib.h"
#include "common/substream.h"
+#include "common/compression/zlib.h"
#include "tetraedge/tetraedge.h"
#include "tetraedge/te/te_light.h"
diff --git a/engines/tetraedge/te/te_model_animation.cpp b/engines/tetraedge/te/te_model_animation.cpp
index effca334c15..5a1888be26b 100644
--- a/engines/tetraedge/te/te_model_animation.cpp
+++ b/engines/tetraedge/te/te_model_animation.cpp
@@ -23,7 +23,7 @@
#include "common/file.h"
#include "common/stream.h"
#include "common/substream.h"
-#include "common/zlib.h"
+#include "common/compression/zlib.h"
#include "tetraedge/tetraedge.h"
#include "tetraedge/te/te_core.h"
diff --git a/engines/tetraedge/te/te_name_val_xml_parser.h b/engines/tetraedge/te/te_name_val_xml_parser.h
index e014de5c478..5bdbe2257f7 100644
--- a/engines/tetraedge/te/te_name_val_xml_parser.h
+++ b/engines/tetraedge/te/te_name_val_xml_parser.h
@@ -22,7 +22,7 @@
#ifndef TETRAEDGE_TE_TE_NAME_VAL_XML_PARSER_H
#define TETRAEDGE_TE_TE_NAME_VAL_XML_PARSER_H
-#include "common/xmlparser.h"
+#include "common/formats/xmlparser.h"
namespace Tetraedge {
diff --git a/engines/tetraedge/te/te_pick_mesh2.cpp b/engines/tetraedge/te/te_pick_mesh2.cpp
index 91f4eb85da0..6380d6d1acd 100644
--- a/engines/tetraedge/te/te_pick_mesh2.cpp
+++ b/engines/tetraedge/te/te_pick_mesh2.cpp
@@ -50,6 +50,7 @@ void TePickMesh2::draw() {
const TeColor prevCol = renderer->currentColor();
+ renderer->enableWireFrame(); // NOTE: added this so we can draw _clickMeshes in scene.
renderer->setCurrentColor(TeColor(0xff, 0, 0, 0xff));
renderer->pushMatrix();
renderer->multiplyMatrix(transformationMatrix());
@@ -57,6 +58,7 @@ void TePickMesh2::draw() {
renderer->popMatrix();
renderer->setCurrentColor(prevCol);
+ renderer->disableWireFrame();
}
bool TePickMesh2::intersect(const TeVector3f32 &v1, const TeVector3f32 &v2, TeVector3f32 &vout, float &fout, bool lastHitFirst, unsigned long *triangleHitOut) {
diff --git a/engines/tetraedge/te/te_ray_intersection.cpp b/engines/tetraedge/te/te_ray_intersection.cpp
index ddbbd9e6dae..53eab70700d 100644
--- a/engines/tetraedge/te/te_ray_intersection.cpp
+++ b/engines/tetraedge/te/te_ray_intersection.cpp
@@ -30,39 +30,74 @@ TePickMesh *getMesh(const TeVector3f32 ¶m_1, const TeVector3f32 ¶m_2, co
error("TODO: implement TeRayIntersection::getMesh");
}
-int intersect(const TeVector3f32 &v1, const TeVector3f32 &v2, const TeVector3f32 &v3,
- const TeVector3f32 &v4, const TeVector3f32 &v5, TeVector3f32 &vout, float &fout) {
- const TeVector3f32 v4_v3 = (v4 - v3);
- const TeVector3f32 v5_v3 = (v5 - v3);
- TeVector3f32 v = v4_v3 ^ v5_v3;
+// This is a version from https://www.lighthouse3d.com/tutorials/maths/ray-triangle-intersection/
+int intersect(const TeVector3f32 &p, const TeVector3f32 &d, const TeVector3f32 &v0,
+ const TeVector3f32 &v1, const TeVector3f32 &v2, TeVector3f32 &vout, float &fout) {
+ const TeVector3f32 e1 = v1 - v0;
+ const TeVector3f32 e2 = v2 - v0;
+ const TeVector3f32 h = d ^ e2;
+
+ if (h == TeVector3f32())
+ return -1;
+
+ float a = e1.dotProduct(h);
+ if (fabs(a) < 1e-6)
+ return 0;
+
+ float f = 1 / a;
+ TeVector3f32 s = p - v0;
+ float u = f * s.dotProduct(h);
+ if (u < 0.0 || u > 1.0)
+ return 0;
+
+ TeVector3f32 q = TeVector3f32::crossProduct(s, e1);
+ float v = f * d.dotProduct(q);
+
+ if (v < 0.0 || u + v > 1.0)
+ return 0;
+
+ float t = f * e2.dotProduct(q);
+
+ if (t < 0.00001)
+ return 0;
+
+ fout = t;
+ vout = p + t * d;
+
+ return 1;
+}
+
+/*
+int intersect(const TeVector3f32 &rayPos, const TeVector3f32 &rayDir, const TeVector3f32 &v1,
+ const TeVector3f32 &v2, const TeVector3f32 &v3, TeVector3f32 &vout, float &fout) {
+ const TeVector3f32 v2_v1 = v2 - v1;
+ const TeVector3f32 v3_v1 = v3 - v1;
+ const TeVector3f32 v = v2_v1 ^ v3_v1;
if (v == TeVector3f32(0.0f, 0.0f, 0.0f))
return -1;
int result = -1;
- float f1 = v.dotProduct(v1 - v3);
- float f2 = v.dotProduct(v2);
+ float f1 = v.dotProduct(rayPos - v1);
+ float f2 = v.dotProduct(rayDir);
if (fabs(f2) > 1e-9) {
f2 = -f1 / f2;
fout = f2;
result = 0;
if (f2 >= 0.0) {
- vout = v1 + (v2 * f2);
- float dot1 = v4_v3.dotProduct(v4_v3);
- float dot2 = v4_v3.dotProduct(v5_v3);
- float dot3 = v5_v3.dotProduct(v5_v3);
- const TeVector3f32 vout_v3 = vout - v3;
- float dots1 = (dot2 * dot2) - (dot1 * dot3);
- float dot4 = vout_v3.dotProduct(v4_v3);
- float dot5 = vout_v3.dotProduct(v5_v3);
- float dots2 = ((dot2 * dot5) - (dot3 * dot4)) / dots1;
- if (dots2 >= 0.0) {
- result = 0;
- if (dots2 <= 1.0) {
- float dots3 = (dot2 * dot4 - dot1 * dot5) / dots1;
- if (dots3 >= 0 && dots2 + dots3 <= 1.0)
- result = 1;
- }
+ vout = rayPos + (rayDir * f2);
+ float dot1 = v2_v1.dotProduct(v2_v1);
+ float dot2 = v2_v1.dotProduct(v3_v1);
+ float dot3 = v3_v1.dotProduct(v3_v1);
+ const TeVector3f32 vout_v1 = vout - v1;
+ float dots1 = dot2 * dot2 - dot1 * dot3;
+ float dot4 = vout_v1.dotProduct(v2_v1);
+ float dot5 = vout_v1.dotProduct(v3_v1);
+ float dots2 = (dot2 * dot5 - dot3 * dot4) / dots1;
+ if (dots2 >= 0.0 && dots2 <= 1.0) {
+ float dots3 = (dot2 * dot4 - dot1 * dot5) / dots1;
+ if (dots3 >= 0.0 && dots2 + dots3 <= 1.0)
+ result = 1;
}
}
} else {
@@ -72,10 +107,56 @@ int intersect(const TeVector3f32 &v1, const TeVector3f32 &v2, const TeVector3f32
}
return result;
}
+*/
+/*
+bool testIntersection(const TeVector3f32 &v1, const TeVector3f32 &v2, const TeVector3f32 &v3, const TeVector3f32 &orig, TeVector3f32 &dir) {
+ TeVector3f32 qvec,tvec;
-}
+ TeVector3f32 e1 = v2 - v1;
+ TeVector3f32 e2 = v3 - v1;
+
+ TeVector3f32 pvec = TeVector3f32::crossProduct(dir, e2);
+ dir.normalize();
+ float det = pvec.dotProduct(e1);
+//#ifdef TEST_CULL
+ if (det < FLT_EPSILON)
+ return false;
+
+ tvec = orig - v1;
+ float u = tvec.dotProduct(pvec);
+ if (u < 0.0 || u > det) {
+ return false;
+ }
+ CROSS(qvec,tvec,e1);
+ float v = dir.dotProduct(qvec);
+ if (v < 0.0f || v + u > det) {
+ return false;
+ }
+#else
+ if (det < FLT_EPSILON && det > -FLT_EPSILON ) {
+ return false;
+ }
+
+ float invDet = 1.0f / det;
+ tvec = orig - v1;
+ // NORMALIZE(tvec);
+ float u = invDet * tvec.dotProduct(pvec);
+ if (u <0.0f || u > 1.0f) {
+ return false;
+ }
+
+ qvec = TeVector3f32::crossProduct(tvec, e1);
+ float v = invDet * qvec.dotProduct(dir);
+ if (v < 0.0f || u+v > 1.0f) {
+ return false;
+ }
+#endif
+ return true;
+}
+*/
+} // end namespace TeRayIntersection
} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_ray_intersection.h b/engines/tetraedge/te/te_ray_intersection.h
index d4f4f19c329..f628632ff52 100644
--- a/engines/tetraedge/te/te_ray_intersection.h
+++ b/engines/tetraedge/te/te_ray_intersection.h
@@ -34,8 +34,8 @@ namespace TeRayIntersection {
TePickMesh *getMesh(const TeVector3f32 ¶m_1, const TeVector3f32 ¶m_2, const Common::Array<TePickMesh *> &pickMeshes,
float param_4, float param_5, TeVector3f32 *param_6);
-int intersect(const TeVector3f32 &v1, const TeVector3f32 &v2, const TeVector3f32 &v3,
- const TeVector3f32 &v4, const TeVector3f32 &v5, TeVector3f32 &vout, float &fout);
+int intersect(const TeVector3f32 &rayPos, const TeVector3f32 &rayDir, const TeVector3f32 &v1,
+ const TeVector3f32 &v2, const TeVector3f32 &v3, TeVector3f32 &vout, float &fout);
} // end namespace TeRayIntersection
diff --git a/engines/tetraedge/te/te_text_layout_xml_parser.h b/engines/tetraedge/te/te_text_layout_xml_parser.h
index c1a5affc73a..4bab07863b6 100644
--- a/engines/tetraedge/te/te_text_layout_xml_parser.h
+++ b/engines/tetraedge/te/te_text_layout_xml_parser.h
@@ -24,7 +24,7 @@
#include "common/array.h"
#include "common/str.h"
-#include "common/xmlparser.h"
+#include "common/formats/xmlparser.h"
#include "tetraedge/te/te_color.h"
diff --git a/engines/tetraedge/te/te_vector3f32.cpp b/engines/tetraedge/te/te_vector3f32.cpp
index 6cebd5c3eae..dc2b7d4aa0d 100644
--- a/engines/tetraedge/te/te_vector3f32.cpp
+++ b/engines/tetraedge/te/te_vector3f32.cpp
@@ -51,8 +51,8 @@ TeVector3f32 operator^(const TeVector3f32 &left, const TeVector3f32 &right) {
float ly = left.y();
float lz = left.z();
retval.x() = ly * rz - lz * ry;
- retval.y() = lz * rx - rz * lx;
- retval.z() = ry * lx - ly * rx;
+ retval.y() = lz * rx - lx * rz;
+ retval.z() = lx * ry - ly * rx;
return retval;
}
diff --git a/engines/tetraedge/te/te_vector3f32.h b/engines/tetraedge/te/te_vector3f32.h
index 951fe0157d3..eeb839f54be 100644
--- a/engines/tetraedge/te/te_vector3f32.h
+++ b/engines/tetraedge/te/te_vector3f32.h
@@ -33,7 +33,7 @@ class TeQuaternion;
class TeVector3f32 : public Math::Vector3d {
public:
- TeVector3f32() { };
+ TeVector3f32() { }; // Note: vector3d constructor sets 0, 0, 0
TeVector3f32(float x_, float y_, float z_) {
set(x_, y_, z_);
}
Commit: eba2fb9b5f151743eaeca8374cb7b1a9e5a31dd4
https://github.com/scummvm/scummvm/commit/eba2fb9b5f151743eaeca8374cb7b1a9e5a31dd4
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2023-01-16T17:36:43+01:00
Commit Message:
MATH: Add ray triangle intersection and tests
Changed paths:
A test/math/ray.h
A test/math/vector3d.h
math/ray.cpp
math/ray.h
diff --git a/math/ray.cpp b/math/ray.cpp
index b50cd0e594c..33f3232553f 100644
--- a/math/ray.cpp
+++ b/math/ray.cpp
@@ -45,6 +45,11 @@ void Ray::rotate(const Quaternion &rot) {
_direction.normalize();
}
+void Ray::rotateDirection(const Quaternion &rot) {
+ rot.transform(_direction);
+ _direction.normalize();
+}
+
void Ray::translate(const Vector3d &v) {
_origin += v;
}
@@ -78,4 +83,38 @@ bool Ray::intersectAABB(const AABB &aabb) const {
return true;
}
+// Algorithm adapted from https://www.lighthouse3d.com/tutorials/maths/ray-triangle-intersection/
+bool Ray::intersectTriangle(const Vector3d &v0, const Vector3d &v1,
+ const Vector3d &v2, Vector3d &vout, float &fout) const {
+ const Vector3d e1 = v1 - v0;
+ const Vector3d e2 = v2 - v0;
+ const Vector3d h = Vector3d::crossProduct(_direction, e2);
+
+ float a = e1.dotProduct(h);
+ if (fabs(a) < 1e-6f)
+ return false;
+
+ float f = 1.0f / a;
+ const Vector3d s = _origin - v0;
+ float u = f * s.dotProduct(h);
+ if (u < 0.0f || u > 1.0f)
+ return false;
+
+ const Vector3d q = Vector3d::crossProduct(s, e1);
+ float v = f * _direction.dotProduct(q);
+
+ if (v < 0.0f || u + v > 1.0f)
+ return false;
+
+ float t = f * e2.dotProduct(q);
+
+ if (t < 1e-6f)
+ return false;
+
+ fout = t;
+ vout = _origin + t * _direction;
+
+ return true;
+}
+
}
diff --git a/math/ray.h b/math/ray.h
index b09f8b4af18..fb6a8293db6 100644
--- a/math/ray.h
+++ b/math/ray.h
@@ -48,10 +48,15 @@ public:
void transform(const Matrix4 &matrix);
/**
- * Rotate the ray using a quaternion
+ * Rotate the ray using a quaternion - rotates both origin and direction
*/
void rotate(const Quaternion &rot);
+ /**
+ * Rotate the ray direction only using a quaternion - origin stays fixed
+ */
+ void rotateDirection(const Quaternion &rot);
+
/**
* Translate the ray by a vector
*/
@@ -62,6 +67,17 @@ public:
*/
bool intersectAABB(const AABB &aabb) const;
+ /**
+ * Test and return the intersection of the ray with a triangle defned by 3 verticies
+ *
+ * @param v0 first triangle vertex
+ * @param v1 second triangle vertex
+ * @param v2 third triangle vertex
+ * @param loc If return is true, set to the intersection point
+ * @param dist If return is true, set to distance along the ray (relative to direction)
+ */
+ bool intersectTriangle(const Vector3d &v0, const Vector3d &v1, const Vector3d &v2, Vector3d &loc, float &dist) const;
+
private:
Vector3d _origin;
Vector3d _direction;
diff --git a/test/math/ray.h b/test/math/ray.h
new file mode 100644
index 00000000000..5345583d0f3
--- /dev/null
+++ b/test/math/ray.h
@@ -0,0 +1,62 @@
+#include <cxxtest/TestSuite.h>
+
+#include "math/ray.h"
+
+class RayTestSuite : public CxxTest::TestSuite {
+public:
+ // Test Constructors
+ void test_Ray() {
+ Math::Ray r;
+
+ TS_ASSERT(r.getOrigin() == Math::Vector3d());
+ TS_ASSERT(r.getDirection() == Math::Vector3d());
+
+ Math::Vector3d o(3, 2, 1);
+ Math::Vector3d d(0, 1, 2);
+
+ Math::Ray r2(o, d);
+
+ TS_ASSERT(r2.getOrigin() == o);
+ TS_ASSERT(r2.getDirection() == d);
+ }
+
+ void test_translate() {
+ Math::Vector3d o(3, 2, 1);
+ Math::Vector3d d(0, 1, 2);
+ Math::Ray r(o, d);
+
+ r.translate(Math::Vector3d(0.5, 0.2, 0.1));
+ TS_ASSERT(r.getDirection() == d);
+ Math::Vector3d o2 = r.getOrigin();
+
+ TS_ASSERT_DELTA(o2.x(), 3.5, 0.0001);
+ TS_ASSERT_DELTA(o2.y(), 2.2, 0.0001);
+ TS_ASSERT_DELTA(o2.z(), 1.1, 0.0001);
+ }
+
+ // TODO: Add tests for transform, rotate, rotateDirection, intersectAABB
+ void test_intersectTriangle() {
+ // A triangle that covers around the origin on the y plane.
+ const Math::Vector3d v1(0, 0, -20);
+ const Math::Vector3d v2(0, -10, 20);
+ const Math::Vector3d v3(0, 10, 20);
+
+ // A ray that points along the x axis, should hit the triangle at the origin
+ Math::Ray r(Math::Vector3d(-9.5, 0, 0.7), Math::Vector3d(1, 0, 0));
+
+ Math::Vector3d loc(7, 8, 9); // add values to ensure it's changed
+ float dist = 99.0f;
+ bool result = r.intersectTriangle(v1, v2, v3, loc, dist);
+ // Should hit at the origin
+ TS_ASSERT(result);
+ TS_ASSERT_DELTA(dist, 9.5f, 0.0001);
+ TS_ASSERT_DELTA(loc.x(), 0.0f, 0.0001);
+ TS_ASSERT_DELTA(loc.y(), 0.0f, 0.0001);
+ TS_ASSERT_DELTA(loc.z(), 0.7f, 0.0001);
+
+ // A ray that points along the x axis in the opposite direction, should never hit the triangle
+ Math::Ray r2(Math::Vector3d(-1, 0, 0), Math::Vector3d(-1, 0, 0));
+ result = r2.intersectTriangle(v1, v2, v3, loc, dist);
+ TS_ASSERT(!result);
+ }
+};
diff --git a/test/math/vector3d.h b/test/math/vector3d.h
new file mode 100644
index 00000000000..8534bdc9a24
--- /dev/null
+++ b/test/math/vector3d.h
@@ -0,0 +1,144 @@
+#include <cxxtest/TestSuite.h>
+
+#include "math/vector3d.h"
+
+class Vector3dTestSuite : public CxxTest::TestSuite {
+public:
+ // Test Constructors
+ void test_Vector3d() {
+ Math::Vector3d v;
+
+ TS_ASSERT(v.x() == 0.0f);
+ TS_ASSERT(v.y() == 0.0f);
+ TS_ASSERT(v.z() == 0.0f);
+
+ Math::Vector3d v2(3, 2.2, 1);
+
+ TS_ASSERT(v2.x() == 3.0f);
+ TS_ASSERT(v2.y() == 2.2f);
+ TS_ASSERT(v2.z() == 1.0f);
+
+ Math::Vector3d v3(v2);
+
+ TS_ASSERT(v3.x() == 3.0f);
+ TS_ASSERT(v3.y() == 2.2f);
+ TS_ASSERT(v3.z() == 1.0f);
+ }
+
+ void test_set() {
+ Math::Vector3d v(2, 4, 6);
+ v.set(1, 2, 3);
+
+ TS_ASSERT(v.x() == 1.0f);
+ TS_ASSERT(v.y() == 2.0f);
+ TS_ASSERT(v.z() == 3.0f);
+ }
+
+ void test_crossProduct() {
+ Math::Vector3d v1(1, 0, 0);
+ Math::Vector3d v2(0, 1, 0);
+
+ Math::Vector3d c12 = Math::Vector3d::crossProduct(v1, v2);
+ Math::Vector3d c21 = Math::Vector3d::crossProduct(v2, v1);
+
+ TS_ASSERT(c12 == Math::Vector3d(0, 0, 1));
+ TS_ASSERT(c21 == Math::Vector3d(0, 0, -1));
+ }
+
+ void test_length() {
+ Math::Vector3d v(1, 0, 1);
+ TS_ASSERT_DELTA(v.length(), sqrt(2), 0.0001);
+
+ Math::Vector3d v2(2, 2, 2);
+ TS_ASSERT_DELTA(v2.length(), sqrt(12), 0.0001);
+
+ // check static version too
+ TS_ASSERT_DELTA(Math::Vector3d::length(v2), v2.length(), 0.0001);
+ }
+
+ void test_interpolate() {
+ Math::Vector3d v1(1, 0, 2);
+ Math::Vector3d v2(0, 5, 3);
+
+ Math::Vector3d int1 = Math::Vector3d::interpolate(v1, v2, 0.1);
+ TS_ASSERT_DELTA(int1.x(), 0.9, 0.0001);
+ TS_ASSERT_DELTA(int1.y(), 0.5, 0.0001);
+ TS_ASSERT_DELTA(int1.z(), 2.1, 0.0001);
+ }
+
+ /* all the below tests are for functions in Math::Vector, but add tests
+ * here as we can't directly instantiate that */
+
+ void test_setValue() {
+ Math::Vector3d v(3, 7, 9);
+
+ v.setValue(0, 1);
+ TS_ASSERT(v.x() == 1.0f);
+ TS_ASSERT(v.y() == 7.0f);
+ TS_ASSERT(v.z() == 9.0f);
+
+ v.setValue(1, 3);
+ v.setValue(2, 2);
+ TS_ASSERT(v.x() == 1.0f);
+ TS_ASSERT(v.y() == 3.0f);
+ TS_ASSERT(v.z() == 2.0f);
+ }
+
+ void test_getValue() {
+ Math::Vector3d v(5, 6, 7);
+
+ TS_ASSERT(v.getValue(0) == 5.0f);
+ TS_ASSERT(v.getValue(1) == 6.0f);
+ TS_ASSERT(v.getValue(2) == 7.0f);
+ }
+
+ void test_dotProduct() {
+ Math::Vector3d v1(1, 2, 3);
+ Math::Vector3d v2(6, 5, 4);
+
+ float result = v2.dotProduct(v1);
+
+ TS_ASSERT_DELTA(result, 28.0f, 0.0001f);
+ }
+
+ void test_dotProductOrthogonal() {
+ Math::Vector3d v1(6, 0, 0);
+ Math::Vector3d v2(0, 9, 0);
+
+ float result = v2.dotProduct(v1);
+
+ TS_ASSERT_EQUALS(result, 0.0f);
+ }
+
+ void test_normalizeTrivial() {
+ Math::Vector3d v(0, 1, 0);
+
+ Math::Vector3d vn = v.getNormalized();
+
+ v.normalize();
+
+ TS_ASSERT_EQUALS(vn, v);
+ TS_ASSERT(v.x() == 0);
+ TS_ASSERT(v.y() == 1);
+ TS_ASSERT(v.z() == 0);
+ }
+
+ void test_normalize() {
+ Math::Vector3d v(2, 4, 6);
+
+ Math::Vector3d vn = v.getNormalized();
+ v.normalize();
+
+ TS_ASSERT_EQUALS(vn, v);
+ TS_ASSERT_DELTA(v.x(), 2 / sqrt(56), 0.0001);
+ TS_ASSERT_DELTA(v.y(), 4 / sqrt(56), 0.0001);
+ TS_ASSERT_DELTA(v.z(), 6 / sqrt(56), 0.0001);
+ }
+
+ void test_magnitude() {
+ Math::Vector3d v(3, 2.5, 1);
+
+ TS_ASSERT_DELTA(v.getMagnitude(), sqrt(16.25), 0.0001);
+ }
+
+};
Commit: 7424452fff76a13ae3dd705b861d5833da56963b
https://github.com/scummvm/scummvm/commit/7424452fff76a13ae3dd705b861d5833da56963b
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2023-01-16T17:36:43+01:00
Commit Message:
TETRAEDGE: More fixes, can now complete first act.
Changed paths:
engines/tetraedge/game/game.cpp
engines/tetraedge/game/in_game_scene.cpp
engines/tetraedge/game/inventory.cpp
engines/tetraedge/game/lua_binds.cpp
engines/tetraedge/te/te_camera.cpp
engines/tetraedge/te/te_camera.h
engines/tetraedge/te/te_core.cpp
engines/tetraedge/te/te_free_move_zone.cpp
engines/tetraedge/te/te_model_animation.cpp
engines/tetraedge/te/te_pick_mesh2.cpp
engines/tetraedge/te/te_ray_intersection.cpp
engines/tetraedge/te/te_ray_intersection.h
diff --git a/engines/tetraedge/game/game.cpp b/engines/tetraedge/game/game.cpp
index 1c8444032db..f203d9ba2bc 100644
--- a/engines/tetraedge/game/game.cpp
+++ b/engines/tetraedge/game/game.cpp
@@ -1068,7 +1068,7 @@ bool Game::onMouseClick(const Common::Point &pt) {
// Note: charAnim above may no longer be valid as anim may have changed.
if (_sceneCharacterVisibleFromLoad || (character->curAnimName() == character->characterSettings()._idleAnimFileName)) {
- _lastCharMoveMousePos = TeVector2s32(0, 0);
+ _lastCharMoveMousePos = TeVector2s32();
_movePlayerCharacterDisabled = false;
_isCharacterIdle = true;
_isCharacterWalking = false;
diff --git a/engines/tetraedge/game/in_game_scene.cpp b/engines/tetraedge/game/in_game_scene.cpp
index 48ffd9592b1..cd47e7c6040 100644
--- a/engines/tetraedge/game/in_game_scene.cpp
+++ b/engines/tetraedge/game/in_game_scene.cpp
@@ -42,7 +42,7 @@
#include "tetraedge/te/te_lua_script.h"
#include "tetraedge/te/te_lua_thread.h"
-#define DEBUG_PATHFINDING 1
+//#define DEBUG_PATHFINDING 1
namespace Tetraedge {
@@ -186,6 +186,13 @@ Character *InGameScene::character(const Common::String &name) {
return c;
}
+ // WORKAROUND: Didn't find char, try again with case insensitive
+ // for "OScar" typo in scenes/ValTrain/19000.
+ for (Character *c : _characters) {
+ if (c->_model->name().compareToIgnoreCase(name) == 0)
+ return c;
+ }
+
return nullptr;
}
@@ -327,6 +334,7 @@ void InGameScene::deserializeModel(Common::ReadStream &stream, TeIntrusivePtr<Te
col.deserialize(stream);
mesh.setColor(i, col);
}
+
pickmesh->setNbTriangles(indexcount / 3);
for (unsigned int i = 0; i < indexcount; i++) {
vec = mesh.vertex(mesh.index(i));
@@ -592,7 +600,7 @@ bool InGameScene::load(const Common::Path &path) {
if (modelname.contains("Clic")) {
//debug("Loaded clickMesh %s", modelname.c_str());
_hitObjects.push_back(model);
- model->setVisible(true);
+ model->setVisible(false);
model->setColor(TeColor(0, 0xff, 0, 0xff));
models().push_back(model);
pickmesh->setName(modelname);
diff --git a/engines/tetraedge/game/inventory.cpp b/engines/tetraedge/game/inventory.cpp
index a0e694d6993..a70d7738648 100644
--- a/engines/tetraedge/game/inventory.cpp
+++ b/engines/tetraedge/game/inventory.cpp
@@ -495,7 +495,7 @@ bool Inventory::updateLayout() {
return false;
}
-#define DEBUG_SAVELOAD 1
+//#define DEBUG_SAVELOAD 1
Common::Error Inventory::syncState(Common::Serializer &s) {
unsigned int nitems = _invObjects.size();
diff --git a/engines/tetraedge/game/lua_binds.cpp b/engines/tetraedge/game/lua_binds.cpp
index b49cea8f36a..c01a0b4d757 100644
--- a/engines/tetraedge/game/lua_binds.cpp
+++ b/engines/tetraedge/game/lua_binds.cpp
@@ -40,8 +40,9 @@ using namespace ToLua;
static void LoadObjectMaterials(const Common::String &objname) {
Game *game = g_engine->getGame();
bool result = game->scene().loadObjectMaterials(objname);
+ // Not an error if it fails, eg ValAttic/16050 calls this but has no object
if (!result)
- error("[LoadObjectMaterials] Object \"%s\" doesn't exist or no Object in this scene.",
+ warning("[LoadObjectMaterials] Object \"%s\" doesn't exist or no Object in this scene.",
objname.c_str());
}
@@ -795,7 +796,9 @@ static int tolua_ExportedFunctions_SetCharacterAnimation00(lua_State *L) {
SetCharacterAnimation(s1, s2, b1, b2, (int)f3, (int)f4);
return 0;
}
- error("#ferror in function 'SetCharacterAnimation': %d %d %s", err.index, err.array, err.type);
+ // Incorrectly called in scenes/ValTrain/19000 line 305 with a 0.5 parameter instead of bool
+ warning("#ferror in function 'SetCharacterAnimation': %d %d %s", err.index, err.array, err.type);
+ return 0;
}
static int tolua_ExportedFunctions_SetCharacterAnimationAndWaitForEnd00(lua_State *L) {
@@ -1363,7 +1366,10 @@ static int tolua_ExportedFunctions_DeleteTask00(lua_State *L) {
DeleteTask(s1, s2);
return 0;
}
- error("#ferror in function 'DeleteTask': %d %d %s", err.index, err.array, err.type);
+ // Note: There is an incorrect call to this in scenes/ValChurch/13120/Logic13120.lua
+ // which only passes a single string.
+ warning("#ferror in function 'DeleteTask': %d %d %s", err.index, err.array, err.type);
+ return 0;
}
static void SetVisibleButtonHelp(bool val) {
diff --git a/engines/tetraedge/te/te_camera.cpp b/engines/tetraedge/te/te_camera.cpp
index ed8c8217d4d..eee6d0af931 100644
--- a/engines/tetraedge/te/te_camera.cpp
+++ b/engines/tetraedge/te/te_camera.cpp
@@ -20,6 +20,7 @@
*/
#include "common/math.h"
+#include "math/ray.h"
#include "tetraedge/tetraedge.h"
#include "tetraedge/te/te_camera.h"
@@ -136,25 +137,29 @@ void TeCamera::draw() {
error("TODO: Implement TeCamera::draw");
}
-void TeCamera::getRay(const TeVector2s32 &pxloc, TeVector3f32 &raypos, TeVector3f32 &raydir) {
- raypos = position();
+Math::Ray TeCamera::getRay(const TeVector2s32 &pxloc) {
+ const Math::Vector3d origin = position();
- float xval = (pxloc._x - _viewportX) / fabs(_viewportW);
- raydir.x() = xval * 2 - 1;
- float yval = (pxloc._y - _viewportY) / fabs(_viewportH);
- raydir.y() = yval * 2 - 1;
- raydir.z() = 1.0;
+ // point offset relative to viewport
+ const float xval = (pxloc._x - _viewportX) / fabs(_viewportW);
+ const float yval = (_viewportH - (pxloc._y - _viewportY)) / fabs(_viewportH);
+
+ // normalized to -1..1
+ const TeVector3f32 projectedPoint(xval * 2.0f - 1.0f, yval * 2.0f - 1.0f, 1.0f);
TeMatrix4x4 projInverse = _projectionMatrix;
- projInverse.inverse();
- raydir = projInverse * raydir;
- raydir.normalize();
+ bool inverted = projInverse.inverse();
+ if (!inverted)
+ error("failed to invert camera projection");
+ TeVector3f32 unprojectedPoint = projInverse * projectedPoint;
+ unprojectedPoint.normalize();
TeQuaternion rot = _rotation;
rot.normalize();
- const TeMatrix4x4 rotmatrix = rot.toTeMatrix();
-
- raydir = rotmatrix * raydir;
+ TeMatrix4x4 rotMatrix = rot.toTeMatrix();
+ TeVector3f32 rayDir = rotMatrix * unprojectedPoint;
+ Math::Ray ray(origin, rayDir);
+ return ray;
}
void TeCamera::loadBin(const Common::String &path) {
diff --git a/engines/tetraedge/te/te_camera.h b/engines/tetraedge/te/te_camera.h
index 8ab03c86b15..43d8e4ae854 100644
--- a/engines/tetraedge/te/te_camera.h
+++ b/engines/tetraedge/te/te_camera.h
@@ -23,6 +23,8 @@
#define TETRAEDGE_TE_TE_CAMERA_H
#include "common/str.h"
+#include "math/ray.h"
+
#include "tetraedge/te/te_3d_object2.h"
#include "tetraedge/te/te_matrix4x4.h"
#include "tetraedge/te/te_references_counter.h"
@@ -45,7 +47,7 @@ public:
void buildPerspectiveMatrix3();
void draw() override;
- void getRay(const TeVector2s32 ¶m_1, TeVector3f32 &out1, TeVector3f32 &out2);
+ Math::Ray getRay(const TeVector2s32 &pxloc);
void loadBin(const Common::String &path);
void loadBin(const Common::ReadStream &stream);
diff --git a/engines/tetraedge/te/te_core.cpp b/engines/tetraedge/te/te_core.cpp
index 59cccba30b2..efb5096e32e 100644
--- a/engines/tetraedge/te/te_core.cpp
+++ b/engines/tetraedge/te/te_core.cpp
@@ -154,11 +154,8 @@ Common::Path TeCore::findFile(const Common::Path &path) {
testPath.joinInPlace(langs[langtype]);
}
testPath.joinInPlace(fname);
- if (Common::File::exists(testPath) || Common::FSNode(path).exists()) {
+ if (Common::File::exists(testPath) || Common::FSNode(path).exists())
return testPath;
- } else {
- debug("not found %s", testPath.toString().c_str());
- }
}
}
diff --git a/engines/tetraedge/te/te_free_move_zone.cpp b/engines/tetraedge/te/te_free_move_zone.cpp
index daf300a7756..81e769b2680 100644
--- a/engines/tetraedge/te/te_free_move_zone.cpp
+++ b/engines/tetraedge/te/te_free_move_zone.cpp
@@ -808,34 +808,40 @@ TePickMesh2 *TeFreeMoveZone::findNearestMesh(TeIntrusivePtr<TeCamera> &camera, c
TeVector3f32 closestLoc;
TePickMesh2 *nearestMesh = nullptr;
float closestDist = camera->_orthFarVal;
- TeVector3f32 rayLoc;
- TeVector3f32 rayDir;
+ Math::Ray camRay;
for (unsigned int i = 0; i < pickMeshes.size(); i++) {
TePickMesh2 *mesh = pickMeshes[i];
const TeMatrix4x4 meshWorldTransform = mesh->worldTransformationMatrix();
if (lastHitFirst) {
+ // Note: it seems like a bug in the original.. this never sets
+ // the ray parameters?? It should still find the right triangle below.
unsigned int tricount = mesh->verticies().size() / 3;
unsigned int vert = mesh->lastTriangleHit() * 3;
if (mesh->lastTriangleHit() >= tricount)
vert = 0;
- const TeVector3f32 v1 = meshWorldTransform * mesh->verticies()[vert];
+ const TeVector3f32 v1 = meshWorldTransform * mesh->verticies()[vert + 0];
const TeVector3f32 v2 = meshWorldTransform * mesh->verticies()[vert + 1];
const TeVector3f32 v3 = meshWorldTransform * mesh->verticies()[vert + 2];
TeVector3f32 intersectLoc;
float intersectDist;
- int intResult = TeRayIntersection::intersect(rayLoc, rayDir, v1, v2, v3, intersectLoc, intersectDist);
- if (intResult == 1 && intersectDist < closestDist && intersectDist >= camera->_orthNearVal)
+ bool intResult = camRay.intersectTriangle(v1, v2, v3, intersectLoc, intersectDist);
+ if (intResult && intersectDist < closestDist && intersectDist >= camera->_orthNearVal)
return mesh;
}
for (unsigned int tri = 0; tri < mesh->verticies().size() / 3; tri++) {
- const TeVector3f32 v1 = meshWorldTransform * mesh->verticies()[tri * 3];
+ const TeVector3f32 v1 = meshWorldTransform * mesh->verticies()[tri * 3 + 0];
const TeVector3f32 v2 = meshWorldTransform * mesh->verticies()[tri * 3 + 1];
const TeVector3f32 v3 = meshWorldTransform * mesh->verticies()[tri * 3 + 2];
- camera->getRay(fromPt, rayLoc, rayDir);
+ camRay = camera->getRay(fromPt);
TeVector3f32 intersectLoc;
float intersectDist;
- int intResult = TeRayIntersection::intersect(rayLoc, rayDir, v1, v2, v3, intersectLoc, intersectDist);
- if (intResult == 1 && intersectDist < closestDist && intersectDist >= camera->_orthNearVal) {
+ bool intResult = camRay.intersectTriangle(v1, v2, v3, intersectLoc, intersectDist);
+ /*debug("PickMesh2 %s intersect Ray(%s, %s) Triangle(%s, %s, %s) -> %s", mesh->name().c_str(),
+ TeVector3f32(camRay.getOrigin()).dump().c_str(),
+ TeVector3f32(camRay.getDirection()).dump().c_str(),
+ v1.dump().c_str(), v2.dump().c_str(), v3.dump().c_str(),
+ intResult ? "hit!" : "no hit");*/
+ if (intResult && intersectDist < closestDist && intersectDist >= camera->_orthNearVal) {
mesh->setLastTriangleHit(tri);
closestLoc = intersectLoc;
closestDist = intersectDist;
diff --git a/engines/tetraedge/te/te_model_animation.cpp b/engines/tetraedge/te/te_model_animation.cpp
index 5a1888be26b..560ec007bd9 100644
--- a/engines/tetraedge/te/te_model_animation.cpp
+++ b/engines/tetraedge/te/te_model_animation.cpp
@@ -144,15 +144,13 @@ TeVector3f32 TeModelAnimation::getNMOTranslation(unsigned long boneNo, float amo
//TeTRS TeModelAnimation::getTRS(const Common::String &boneName, unsigned long frame, bool param_5);
-TeTRS TeModelAnimation::getTRS(unsigned long boneNo, unsigned long frame, bool param_5) const {
+TeTRS TeModelAnimation::getTRS(unsigned long boneNo, unsigned long frame, bool forceUseFbx) const {
TeTRS retval;
- if (!_useNMOArrays || param_5) {
+ if (!_useNMOArrays || forceUseFbx) {
unsigned int nframes = 0;
if (!_useNMOArrays) {
- if (_fbxArrays.size()) {
- nframes = _fbxArrays[0].size();
- }
+ nframes = _fbxArrays[0].size();
} else {
nframes = _numNMOFrames;
}
@@ -305,7 +303,10 @@ void TeModelAnimation::setBoneName(uint boneNo, const Common::String &bname) {
void TeModelAnimation::setRotation(unsigned long num, float amount, const TeQuaternion &rot) {
if (!_useNMOArrays) {
- _fbxArrays[num][(int)amount].setRotation(rot);
+ uint frame = amount;
+ if (_fbxArrays[num].size() <= frame)
+ _fbxArrays[num].resize(frame + 1);
+ _fbxArrays[num][frame].setRotation(rot);
} else {
NMORotation nmorot;
nmorot._rot = rot;
@@ -321,7 +322,10 @@ void TeModelAnimation::setScale(unsigned long num, float amount, const TeVector3
void TeModelAnimation::setTranslation(unsigned long num, float amount, const TeVector3f32 &trans) {
if (!_useNMOArrays) {
- _fbxArrays[num][(int)amount].setTranslation(trans);
+ uint frame = amount;
+ if (_fbxArrays[num].size() <= frame)
+ _fbxArrays[num].resize(frame + 1);
+ _fbxArrays[num][frame].setTranslation(trans);
} else {
NMOTranslation nmotrans;
nmotrans._trans = trans;
@@ -336,7 +340,7 @@ void TeModelAnimation::unbind() {
void TeModelAnimation::update(double proportion) {
int frames;
- if (_useNMOArrays == 0) {
+ if (!_useNMOArrays) {
if (_fbxArrays.empty())
return;
diff --git a/engines/tetraedge/te/te_pick_mesh2.cpp b/engines/tetraedge/te/te_pick_mesh2.cpp
index 6380d6d1acd..7e4f160e4b3 100644
--- a/engines/tetraedge/te/te_pick_mesh2.cpp
+++ b/engines/tetraedge/te/te_pick_mesh2.cpp
@@ -61,43 +61,44 @@ void TePickMesh2::draw() {
renderer->disableWireFrame();
}
-bool TePickMesh2::intersect(const TeVector3f32 &v1, const TeVector3f32 &v2, TeVector3f32 &vout, float &fout, bool lastHitFirst, unsigned long *triangleHitOut) {
+bool TePickMesh2::intersect(const TeVector3f32 &origin, const TeVector3f32 &dir, TeVector3f32 &hitPtOut, float &hitDistOut, bool lastHitFirst, unsigned long *triangleHitOut) {
if (_verticies.size() / 3 == 0)
return false;
- TeVector3f32 intersection;
- float f;
+ TeVector3f32 hitPt;
+ float hitDist;
const TeMatrix4x4 worldTrans = worldTransformationMatrix();
+ const Math::Ray ray(origin, dir);
if (lastHitFirst) {
const TeVector3f32 triv1 = worldTrans * _verticies[_lastTriangleHit * 3 + 0];
const TeVector3f32 triv2 = worldTrans * _verticies[_lastTriangleHit * 3 + 1];
const TeVector3f32 triv3 = worldTrans * _verticies[_lastTriangleHit * 3 + 2];
- int result = TeRayIntersection::intersect(v1, v2, triv1, triv2, triv3, intersection, f);
- if (result == 1 && f >= 0.0 && f < FLT_MAX) {
- vout = v1 + v2 * f;
- fout = f;
+ bool result = ray.intersectTriangle(triv1, triv2, triv3, hitPt, hitDist);
+ if (result && hitDist >= 0.0 && hitDist < FLT_MAX) {
+ hitPtOut = origin + dir * hitDist;
+ hitDistOut = hitDist;
if (triangleHitOut)
*triangleHitOut = _lastTriangleHit;
return true;
}
}
- float hitf = FLT_MAX;
+ float lastHitDist = FLT_MAX;
for (unsigned int i = 0; i < _verticies.size() / 3; i++) {
const TeVector3f32 triv1 = worldTrans * _verticies[i * 3 + 0];
const TeVector3f32 triv2 = worldTrans * _verticies[i * 3 + 1];
const TeVector3f32 triv3 = worldTrans * _verticies[i * 3 + 2];
- int result = TeRayIntersection::intersect(v1, v2, triv1, triv2, triv3, intersection, f);
- if (result == 1 && f >= 0.0 && f < FLT_MAX) {
+ bool result = ray.intersectTriangle(triv1, triv2, triv3, hitPt, hitDist);
+ if (result && hitDist >= 0.0 && hitDist < FLT_MAX) {
_lastTriangleHit = i;
- hitf = f;
+ lastHitDist = hitDist;
if (lastHitFirst)
break;
}
}
- if (hitf != FLT_MAX) {
- vout = v1 + v2 * hitf;
- fout = hitf;
+ if (lastHitDist != FLT_MAX) {
+ hitPtOut = origin + dir * lastHitDist;
+ hitDistOut = lastHitDist;
if (triangleHitOut)
*triangleHitOut = _lastTriangleHit;
return true;
diff --git a/engines/tetraedge/te/te_ray_intersection.cpp b/engines/tetraedge/te/te_ray_intersection.cpp
index 53eab70700d..9526563d69a 100644
--- a/engines/tetraedge/te/te_ray_intersection.cpp
+++ b/engines/tetraedge/te/te_ray_intersection.cpp
@@ -30,42 +30,43 @@ TePickMesh *getMesh(const TeVector3f32 ¶m_1, const TeVector3f32 ¶m_2, co
error("TODO: implement TeRayIntersection::getMesh");
}
+/*
// This is a version from https://www.lighthouse3d.com/tutorials/maths/ray-triangle-intersection/
int intersect(const TeVector3f32 &p, const TeVector3f32 &d, const TeVector3f32 &v0,
- const TeVector3f32 &v1, const TeVector3f32 &v2, TeVector3f32 &vout, float &fout) {
+ const TeVector3f32 &v1, const TeVector3f32 &v2, TeVector3f32 &hitPt, float &hitDist) {
const TeVector3f32 e1 = v1 - v0;
const TeVector3f32 e2 = v2 - v0;
- const TeVector3f32 h = d ^ e2;
+ const TeVector3f32 h = TeVector3f32::crossProduct(d, e2);
if (h == TeVector3f32())
return -1;
float a = e1.dotProduct(h);
- if (fabs(a) < 1e-6)
+ if (fabs(a) < 1e-6f)
return 0;
- float f = 1 / a;
- TeVector3f32 s = p - v0;
+ float f = 1.0f / a;
+ const TeVector3f32 s = p - v0;
float u = f * s.dotProduct(h);
- if (u < 0.0 || u > 1.0)
+ if (u < 0.0f || u > 1.0f)
return 0;
- TeVector3f32 q = TeVector3f32::crossProduct(s, e1);
+ const TeVector3f32 q = TeVector3f32::crossProduct(s, e1);
float v = f * d.dotProduct(q);
- if (v < 0.0 || u + v > 1.0)
+ if (v < 0.0f || u + v > 1.0f)
return 0;
float t = f * e2.dotProduct(q);
- if (t < 0.00001)
+ if (t < 1e-6f)
return 0;
- fout = t;
- vout = p + t * d;
+ hitDist = t;
+ hitPt = p + t * d;
return 1;
-}
+}*/
/*
int intersect(const TeVector3f32 &rayPos, const TeVector3f32 &rayDir, const TeVector3f32 &v1,
diff --git a/engines/tetraedge/te/te_ray_intersection.h b/engines/tetraedge/te/te_ray_intersection.h
index f628632ff52..5b9a65f13e4 100644
--- a/engines/tetraedge/te/te_ray_intersection.h
+++ b/engines/tetraedge/te/te_ray_intersection.h
@@ -34,8 +34,9 @@ namespace TeRayIntersection {
TePickMesh *getMesh(const TeVector3f32 ¶m_1, const TeVector3f32 ¶m_2, const Common::Array<TePickMesh *> &pickMeshes,
float param_4, float param_5, TeVector3f32 *param_6);
-int intersect(const TeVector3f32 &rayPos, const TeVector3f32 &rayDir, const TeVector3f32 &v1,
- const TeVector3f32 &v2, const TeVector3f32 &v3, TeVector3f32 &vout, float &fout);
+// Replaced with Math::Ray::intersectTriangle
+//int intersect(const TeVector3f32 &rayPos, const TeVector3f32 &rayDir, const TeVector3f32 &v1,
+// const TeVector3f32 &v2, const TeVector3f32 &v3, TeVector3f32 &vout, float &fout);
} // end namespace TeRayIntersection
Commit: 0ba854df9ab95b2b7fc7548e9b59986e7fc969a0
https://github.com/scummvm/scummvm/commit/0ba854df9ab95b2b7fc7548e9b59986e7fc969a0
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2023-01-16T17:36:43+01:00
Commit Message:
TETRAEDGE: More fixes, can now complete game.
Changed paths:
engines/tetraedge/game/character.cpp
engines/tetraedge/game/characters_shadow.cpp
engines/tetraedge/game/dialog2.cpp
engines/tetraedge/game/game.cpp
engines/tetraedge/game/in_game_scene.cpp
engines/tetraedge/game/lua_binds.cpp
engines/tetraedge/game/question2.cpp
engines/tetraedge/game/question2.h
engines/tetraedge/game/scene_lights_xml_parser.cpp
engines/tetraedge/te/te_animation.cpp
engines/tetraedge/te/te_animation.h
engines/tetraedge/te/te_core.cpp
engines/tetraedge/te/te_curve_anim2.h
engines/tetraedge/te/te_frame_anim.cpp
engines/tetraedge/te/te_frame_anim.h
engines/tetraedge/te/te_light.cpp
engines/tetraedge/te/te_light.h
engines/tetraedge/te/te_model.cpp
engines/tetraedge/te/te_model_animation.cpp
engines/tetraedge/te/te_model_animation.h
engines/tetraedge/te/te_model_vertex_animation.h
engines/tetraedge/te/te_ray_intersection.cpp
engines/tetraedge/te/te_renderer.cpp
engines/tetraedge/te/te_signal.h
diff --git a/engines/tetraedge/game/character.cpp b/engines/tetraedge/game/character.cpp
index 8620831b3b4..3076eeb6529 100644
--- a/engines/tetraedge/game/character.cpp
+++ b/engines/tetraedge/game/character.cpp
@@ -112,6 +112,14 @@ void Character::addCallback(const Common::String &animKey, const Common::String
// the way this gets used later, setting large negative is more correct.
c->_callsMade = (maxCalls == -1.0 ? -1e9 : 0.0f);
+ //
+ // WORKAROUND: This callback seems to be set too late.. frame 31, but it
+ // only gets to 15? Some bug in the way anim blends hand off?
+ // for scenes/CitSpace2/34230/Logic34230.lua
+ //
+ if (fnName == "ChangeClef" && c->_triggerFrame == 31)
+ c->_triggerFrame = 15;
+
const Common::Path animPath = _model->anim()->_loadedPath;
// Another difference.. the original messes with paths a bit - just
@@ -126,6 +134,7 @@ void Character::addCallback(const Common::String &animKey, const Common::String
Common::Path animKeyPath(animKey);
Common::Array<Callback *> callbacks;
callbacks.push_back(c);
+
_callbacks.setVal(animKeyPath.getLastComponent().toString(), callbacks);
}
}
@@ -142,10 +151,13 @@ void Character::addCallback(const Common::String &animKey, const Common::String
//_animCache.pop_back();
}
-/*static*/ TeIntrusivePtr<TeModelAnimation> Character::animCacheLoad(const Common::Path &path) {
+/*static*/
+TeIntrusivePtr<TeModelAnimation> Character::animCacheLoad(const Common::Path &path) {
const Common::String pathStr = path.toString();
- if (_animCacheMap.contains(pathStr))
- return _animCacheMap.getVal(pathStr);
+ if (_animCacheMap.contains(pathStr)) {
+ // Copy from the cache (keep the cached instance clean)
+ return new TeModelAnimation(*_animCacheMap.getVal(pathStr));
+ }
TeIntrusivePtr<TeModelAnimation> modelAnim = new TeModelAnimation();
if (!modelAnim->load(path)) {
@@ -531,6 +543,10 @@ bool Character::onBonesUpdate(const Common::String &boneName, TeMatrix4x4 &boneM
}
bool Character::onModelAnimationFinished() {
+ // this shouldn't happen but check to be sure..
+ if (!_model->anim())
+ return false;
+
const Common::Path loadedPath = _model->anim()->_loadedPath;
const Common::String animfile = loadedPath.getLastComponent().toString();
@@ -613,6 +629,8 @@ void Character::permanentUpdate() {
if (_callbacks.contains(animFile)) {
Common::Array<Callback *> &cbs = _callbacks.getVal(animFile);
for (Callback *cb : cbs) {
+ //debug("check cb for %s frame %d against %d. speed %.02f", animFile.c_str(),
+ // curFrame, cb->_triggerFrame, _model->anim()->speed());
if (cb->_triggerFrame > cb->_lastCheckFrame && curFrame >= cb->_triggerFrame){
int callsMade = cb->_callsMade;
cb->_callsMade++;
@@ -934,8 +952,9 @@ void Character::walkTo(float curveEnd, bool walkFlag) {
_walkCurveLast = _walkCurveStart;
_walkCurveNextLength = 0.0f;
_walkedLength = 0.0f;
- assert(_curve);
- if (_curve->controlPoints().size()) {
+ if (!_curve)
+ warning("_curve not set in Character::walkTo");
+ if (_curve && _curve->controlPoints().size()) {
const float walkEndLen = (walkFlag ? 0 : _walkEndGAnimLen);
_walkCurveLen = _curve->length();
_walkEndAnimG = false;
diff --git a/engines/tetraedge/game/characters_shadow.cpp b/engines/tetraedge/game/characters_shadow.cpp
index 19025678183..5bde6f4dc9c 100644
--- a/engines/tetraedge/game/characters_shadow.cpp
+++ b/engines/tetraedge/game/characters_shadow.cpp
@@ -64,7 +64,7 @@ void CharactersShadow::createTexture(InGameScene *scene) {
if (light) {
TeQuaternion q1 = TeQuaternion::fromAxisAndAngle(TeVector3f32(0, 1, 0), light->positionRadial().getX() - M_PI_2);
TeQuaternion q2 = TeQuaternion::fromAxisAndAngle(TeVector3f32(1, 0, 0), light->positionRadial().getY());
- _camera->rotate(q2 * q1);
+ _camera->setRotation(q2 * q1);
_camera->setPosition(light->position3d());
}
_camera->_fov = scene->shadowFov() * M_PI / 180.0;
diff --git a/engines/tetraedge/game/dialog2.cpp b/engines/tetraedge/game/dialog2.cpp
index 83cb02ef0e4..1df74bf3ead 100644
--- a/engines/tetraedge/game/dialog2.cpp
+++ b/engines/tetraedge/game/dialog2.cpp
@@ -107,7 +107,10 @@ void Dialog2::load() {
size(); // refresh size? seems to do nothing with result again.
TeButtonLayout *dialogBtn = _gui.buttonLayoutChecked("dialog");
- dialogBtn->onMouseClickValidated().add(this, &Dialog2::onSkipButton);
+
+ // WORKAROUND: Ensure this is always above the Game (which is set to pri 10000)
+ Common::SharedPtr<TeCallback0Param<Dialog2>> callbackptr(new TeCallback0Param<Dialog2>(this, &Dialog2::onSkipButton, 20000.0f));
+ dialogBtn->onMouseClickValidated().push_back(callbackptr);
TeCurveAnim2<TeLayout,TeVector3f32> *dialogAnimUp = _gui.layoutAnchorLinearAnimation("dialogAnimationUp");
TeCurveAnim2<TeLayout,TeVector3f32> *dialogAnimDown = _gui.layoutAnchorLinearAnimation("dialogAnimationDown");
diff --git a/engines/tetraedge/game/game.cpp b/engines/tetraedge/game/game.cpp
index f203d9ba2bc..e50ba5db78d 100644
--- a/engines/tetraedge/game/game.cpp
+++ b/engines/tetraedge/game/game.cpp
@@ -475,11 +475,13 @@ bool Game::initWarp(const Common::String &zone, const Common::String &scene, boo
scenePath.joinInPlace(scene);
_sceneZonePath = scenePath;
- const Common::Path intLuaPath = scenePath.join(Common::String::format("Int%s.lua", scene.c_str()));
- const Common::Path logicLuaPath = scenePath.join(Common::String::format("Logic%s.lua", scene.c_str()));
- const Common::Path setLuaPath = scenePath.join(Common::String::format("Set%s.lua", scene.c_str()));
- Common::Path forLuaPath = scenePath.join(Common::String::format("For%s.lua", scene.c_str()));
- const Common::Path markerLuaPath = scenePath.join(Common::String::format("Marker%s.lua", scene.c_str()));
+ TeCore *core = g_engine->getCore();
+
+ const Common::Path intLuaPath = core->findFile(scenePath.join(Common::String::format("Int%s.lua", scene.c_str())));
+ const Common::Path logicLuaPath = core->findFile(scenePath.join(Common::String::format("Logic%s.lua", scene.c_str())));
+ const Common::Path setLuaPath = core->findFile(scenePath.join(Common::String::format("Set%s.lua", scene.c_str())));
+ Common::Path forLuaPath = core->findFile(scenePath.join(Common::String::format("For%s.lua", scene.c_str())));
+ const Common::Path markerLuaPath = core->findFile(scenePath.join(Common::String::format("Marker%s.lua", scene.c_str())));
bool intLuaExists = Common::File::exists(intLuaPath);
bool logicLuaExists = Common::File::exists(logicLuaPath);
@@ -650,13 +652,16 @@ bool Game::initWarp(const Common::String &zone, const Common::String &scene, boo
i--;
}
- for (auto &randsoundlist : _randomSounds) {
+ // Take a copy and clear the global list first, as deleting a sound can cause the
+ // next sound to trigger (which might have been deleted already).
+ Common::HashMap<Common::String, Common::Array<RandomSound *>> rsounds = _randomSounds;
+ _randomSounds.clear();
+ for (auto &randsoundlist : rsounds) {
for (auto *randsound : randsoundlist._value) {
delete randsound;
}
randsoundlist._value.clear();
}
- _randomSounds.clear();
_scene.initScroll();
return true;
@@ -1065,7 +1070,7 @@ bool Game::onMouseClick(const Common::Point &pt) {
_posPlayer = lastPoint;
}
}
-
+
// Note: charAnim above may no longer be valid as anim may have changed.
if (_sceneCharacterVisibleFromLoad || (character->curAnimName() == character->characterSettings()._idleAnimFileName)) {
_lastCharMoveMousePos = TeVector2s32();
@@ -1531,8 +1536,9 @@ void Game::update() {
app->_lockCursorButton.setVisible(false);
}
- TeButtonLayout *invbtn = _inGameGui.buttonLayoutChecked("inventoryButton");
- invbtn->setVisible(!app->isLockCursor() && !_dialog2.isDialogPlaying());
+ TeButtonLayout *invbtn = _inGameGui.buttonLayout("inventoryButton");
+ if (invbtn)
+ invbtn->setVisible(!app->isLockCursor() && !_dialog2.isDialogPlaying());
Character *player = _scene._character;
if (player) {
diff --git a/engines/tetraedge/game/in_game_scene.cpp b/engines/tetraedge/game/in_game_scene.cpp
index cd47e7c6040..8ee2628edff 100644
--- a/engines/tetraedge/game/in_game_scene.cpp
+++ b/engines/tetraedge/game/in_game_scene.cpp
@@ -43,6 +43,7 @@
#include "tetraedge/te/te_lua_thread.h"
//#define DEBUG_PATHFINDING 1
+//#define DEBUG_LIGHTS 1
namespace Tetraedge {
@@ -178,7 +179,7 @@ bool InGameScene::changeBackground(const Common::String &name) {
}
Character *InGameScene::character(const Common::String &name) {
- if (_character->_model->name() == name)
+ if (_character && _character->_model->name() == name)
return _character;
for (Character *c : _characters) {
@@ -296,7 +297,7 @@ void InGameScene::deserializeModel(Common::ReadStream &stream, TeIntrusivePtr<Te
TeQuaternion rot;
TeColor col;
TeMesh mesh;
-
+
assert(pickmesh);
TeVector3f32::deserialize(stream, vec);
@@ -361,7 +362,7 @@ void InGameScene::draw() {
zone->setVisible(true);
zone->draw();
}
-
+
for (TePickMesh2 *mesh : _clickMeshes) {
mesh->setVisible(true);
mesh->draw();
@@ -430,6 +431,7 @@ InGameScene::SoundStep InGameScene::findSoundStep(const Common::String &name) {
void InGameScene::freeGeometry() {
_loadedPath.set("");
+
for (TeFreeMoveZone *zone : _freeMoveZones)
delete zone;
_freeMoveZones.clear();
@@ -707,6 +709,16 @@ bool InGameScene::loadLights(const Common::Path &path) {
_lights[i].enable(i);
}
+#if DEBUG_LIGHTS
+ debug("--- Scene lights ---");
+ debug("Shadow: %s no:%d far:%.02f near:%.02f fov:%.02f", _shadowColor.dump().c_str(), _shadowLightNo, _shadowFarPlane, _shadowNearPlane, _shadowFov);
+ debug("Global: %s", TeLight::globalAmbient().dump().c_str());
+ for (unsigned int i = 0; i < _lights.size(); i++) {
+ debug("%s", _lights[i].dump().c_str());
+ }
+ debug("--- end lights ---");
+#endif
+
return true;
}
@@ -1015,7 +1027,17 @@ void InGameScene::setVisibleMarker(const Common::String &markerName, bool val) {
if (!isMarker(markerName))
return;
- error("TODO: Implement InGameScene::setVisibleMarker");
+ Game *game = g_engine->getGame();
+ TeLayout *bg = game->forGui().layout("background");
+ if (!bg)
+ return;
+
+ for (Te3DObject2 *child : bg->childList()) {
+ if (child->name() == markerName) {
+ child->setVisible(val);
+ break;
+ }
+ }
}
void InGameScene::unloadCharacter(const Common::String &name) {
@@ -1023,6 +1045,9 @@ void InGameScene::unloadCharacter(const Common::String &name) {
_character->removeAnim();
_character->deleteAnim();
_character->deleteAllCallback();
+ if (_character->_model->anim())
+ _character->_model->anim()->stop(); // TODO: added this
+ _character->setFreeMoveZone(nullptr); // TODO: added this
// TODO: deleteLater() something here..
_character = nullptr;
}
@@ -1033,6 +1058,9 @@ void InGameScene::unloadCharacter(const Common::String &name) {
c->deleteAnim();
c->deleteAllCallback();
// TODO: deleteLater() something here..
+ if (c->_model->anim())
+ c->_model->anim()->stop(); // TODO: added this
+ c->setFreeMoveZone(nullptr); // TODO: added this
_characters.remove_at(i);
break;
}
@@ -1145,7 +1173,9 @@ void InGameScene::update() {
for (Object3D *obj : _object3Ds) {
// TODO: update object3ds if they are translating or rotating.
if (obj->_translateTime >= 0) {
- error("TODO: handle _translateTime > 0 in InGameScene::update");
+ float time = MIN((float)(obj->_translateTimer.getTimeFromStart() / 1000000.0), obj->_translateTime);
+ TeVector3f32 trans = obj->_translateStart + (obj->_translateAmount * (time / obj->_translateTime));
+ obj->model()->setPosition(trans);
}
if (obj->_rotateTime >= 0) {
// Never actually used in the game.
diff --git a/engines/tetraedge/game/lua_binds.cpp b/engines/tetraedge/game/lua_binds.cpp
index c01a0b4d757..b06f6c3e2fe 100644
--- a/engines/tetraedge/game/lua_binds.cpp
+++ b/engines/tetraedge/game/lua_binds.cpp
@@ -107,7 +107,7 @@ static int tolua_ExportedFunctions_PlayMovieAndWaitForEnd00(lua_State *L) {
Game *game = g_engine->getGame();
for (const auto &cb : game->yieldedCallbacks()) {
if (cb._luaFnName == callback._luaFnName && cb._luaParam == s1)
- error("PlayMovieAndWaitForEnd: Reentrency error, your are already in a yielded/sync function call");
+ warning("PlayMovieAndWaitForEnd: Reentrency error, your are already in a yielded/sync function call");
}
game->yieldedCallbacks().push_back(callback);
return callback._luaThread->yield();
@@ -551,7 +551,7 @@ int tolua_ExportedFunctions_StartAnimationAndWaitForEnd00(lua_State *L) {
Game *game = g_engine->getGame();
for (const auto &cb : game->yieldedCallbacks()) {
if (cb._luaFnName == callback._luaFnName && cb._luaParam == s1)
- error("StartAnimationAndWaitForEnd: Reentrency error, your are already in a yielded/sync function call");
+ warning("StartAnimationAndWaitForEnd: Reentrency error, your are already in a yielded/sync function call");
}
game->yieldedCallbacks().push_back(callback);
return callback._luaThread->yield();
@@ -823,7 +823,7 @@ static int tolua_ExportedFunctions_SetCharacterAnimationAndWaitForEnd00(lua_Stat
Game *game = g_engine->getGame();
for (const auto &cb : game->yieldedCallbacks()) {
if (cb._luaFnName == callback._luaFnName && cb._luaParam == s1 && cb._luaParam2 == s2)
- error("SetCharacterAnimationAndWaitForEnd: Reentrency error, your are already in a yielded/sync function call");
+ warning("SetCharacterAnimationAndWaitForEnd: Reentrency error, your are already in a yielded/sync function call");
}
game->yieldedCallbacks().push_back(callback);
return callback._luaThread->yield();
@@ -877,7 +877,7 @@ static int tolua_ExportedFunctions_BlendCharacterAnimationAndWaitForEnd00(lua_St
Game *game = g_engine->getGame();
for (const auto &cb : game->yieldedCallbacks()) {
if (cb._luaFnName == callback._luaFnName && cb._luaParam == s1 && cb._luaParam2 == s2)
- error("BlendCharacterAnimationAndWaitForEnd: Reentrency error, your are already in a yielded/sync function call");
+ warning("BlendCharacterAnimationAndWaitForEnd: Reentrency error, your are already in a yielded/sync function call");
}
game->yieldedCallbacks().push_back(callback);
return callback._luaThread->yield();
@@ -1199,7 +1199,7 @@ static int tolua_ExportedFunctions_WaitAndWaitForEnd00(lua_State *L) {
Game *game = g_engine->getGame();
for (const auto &cb : game->yieldedCallbacks()) {
if (cb._luaFnName == callback._luaFnName)
- error("WaitAndWaitForEnd: Reentrency error, your are already in a yielded/sync function call");
+ warning("WaitAndWaitForEnd: Reentrency error, your are already in a yielded/sync function call");
}
game->yieldedCallbacks().push_back(callback);
return callback._luaThread->yield();
@@ -1294,7 +1294,7 @@ static int tolua_ExportedFunctions_LaunchDialogAndWaitForEnd00(lua_State *L) {
Game *game = g_engine->getGame();
for (const auto &cb : game->yieldedCallbacks()) {
if (cb._luaFnName == callback._luaFnName && cb._luaParam == callback._luaParam)
- error("LaunchDialogAndWaitForEnd: Reentrency error, your are already in a yielded/sync function call");
+ warning("LaunchDialogAndWaitForEnd: Reentrency error, your are already in a yielded/sync function call");
}
game->yieldedCallbacks().push_back(callback);
return callback._luaThread->yield();
@@ -1513,8 +1513,10 @@ static int tolua_ExportedFunctions_ActivateAnchorZone00(lua_State *L) {
static void SetCharacterLookChar(const Common::String &charname, const Common::String &destname, bool tall) {
Game *game = g_engine->getGame();
Character *character = game->scene().character(charname);
- if (!character)
- error("[SetCharacterLookChar] Character \"%s\" doesn't exist", charname.c_str());
+ if (!character) {
+ warning("[SetCharacterLookChar] Character \"%s\" doesn't exist", charname.c_str());
+ return;
+ }
character->setLookingAtTallThing(tall);
if (destname.empty()) {
character->setCharLookingAt(nullptr);
@@ -1567,14 +1569,14 @@ static void SetCharacterMeshVisible(const Common::String &charName, const Common
static int tolua_ExportedFunctions_SetCharacterMeshVisible00(lua_State *L) {
tolua_Error err;
- if (tolua_isstring(L, 1, 0, &err) && tolua_isboolean(L, 2, 1, &err) && tolua_isnoobj(L, 3, &err)) {
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isstring(L, 2, 0, &err) && tolua_isboolean(L, 3, 1, &err) && tolua_isnoobj(L, 4, &err)) {
Common::String s1(tolua_tostring(L, 1, nullptr));
Common::String s2(tolua_tostring(L, 2, nullptr));
bool b = tolua_toboolean(L, 3, 0);
SetCharacterMeshVisible(s1, s2, b);
return 0;
}
- error("#ferror in function 'SetRecallageY': %d %d %s", err.index, err.array, err.type);
+ error("#ferror in function 'SetCharacterMeshVisible': %d %d %s", err.index, err.array, err.type);
}
static void SetRecallageY(const Common::String &charName, bool val) {
@@ -1697,7 +1699,7 @@ static int tolua_ExportedFunctions_PlaySoundAndWaitForEnd00(lua_State *L) {
Game *game = g_engine->getGame();
for (const auto &cb : game->yieldedCallbacks()) {
if (cb._luaFnName == callback._luaFnName && cb._luaParam == s1)
- error("PlaySoundAndWaitForEnd: Reentrency error, your are already in a yielded/sync function call");
+ warning("PlaySoundAndWaitForEnd: Reentrency error, your are already in a yielded/sync function call");
}
game->yieldedCallbacks().push_back(callback);
return callback._luaThread->yield();
@@ -1972,7 +1974,7 @@ static int tolua_ExportedFunctions_MoveCharacterToAndWaitForEnd00(lua_State *L)
Game *game = g_engine->getGame();
for (const auto &cb : game->yieldedCallbacks()) {
if (cb._luaFnName == callback._luaFnName)
- error("MoveCharacterToAndWaitForEnd: Reentrency error, your are already in a yielded/sync function call");
+ warning("MoveCharacterToAndWaitForEnd: Reentrency error, your are already in a yielded/sync function call");
}
game->yieldedCallbacks().push_back(callback);
return callback._luaThread->yield();
diff --git a/engines/tetraedge/game/question2.cpp b/engines/tetraedge/game/question2.cpp
index 469578fbb5a..09ce43b64ad 100644
--- a/engines/tetraedge/game/question2.cpp
+++ b/engines/tetraedge/game/question2.cpp
@@ -78,6 +78,10 @@ void Question2::load() {
if (backgroundButton) {
addChild(backgroundButton);
backgroundButton->setVisible(false);
+
+ // WORKAROUND: Block clicks going to the Game (which is set to pri 10000)
+ Common::SharedPtr<TeCallback0Param<Question2>> callbackptr(new TeCallback0Param<Question2>(this, &Question2::onBackgroundClick, 20000.0f));
+ backgroundButton->onMouseClickValidated().push_back(callbackptr);
}
size();
}
diff --git a/engines/tetraedge/game/question2.h b/engines/tetraedge/game/question2.h
index 6468adafa8b..7582f06920d 100644
--- a/engines/tetraedge/game/question2.h
+++ b/engines/tetraedge/game/question2.h
@@ -48,6 +48,7 @@ public:
void enter();
void leave();
void load();
+ bool onBackgroundClick() {}
bool onAnswerValidated(Answer &answer);
void pushAnswer(const Common::String &name, const Common::String &unk, const Common::String &path);
void unload();
diff --git a/engines/tetraedge/game/scene_lights_xml_parser.cpp b/engines/tetraedge/game/scene_lights_xml_parser.cpp
index d7633185fa9..d2f1505568a 100644
--- a/engines/tetraedge/game/scene_lights_xml_parser.cpp
+++ b/engines/tetraedge/game/scene_lights_xml_parser.cpp
@@ -113,20 +113,30 @@ bool SceneLightsXmlParser::parserCallback_Specular(ParserNode *node) {
}
bool SceneLightsXmlParser::parserCallback_Attenuation(ParserNode *node) {
- _lights->back().setConstAtten(atof(node->values["constant"].c_str()));
- _lights->back().setLinearAtten(atof(node->values["linear"].c_str()));
- _lights->back().setQuadraticAtten(atof(node->values["quadratic"].c_str()));
+ float c = atof(node->values["constant"].c_str());
+ float l = atof(node->values["linear"].c_str());
+ float q = atof(node->values["quadratic"].c_str());
+ if (c < 0 || l < 0 || q < 0)
+ warning("Loaded invalid lighting attenuation vals %f %f %f", c, l, q);
+ _lights->back().setConstAtten(c);
+ _lights->back().setLinearAtten(l);
+ _lights->back().setQuadraticAtten(q);
return true;
}
bool SceneLightsXmlParser::parserCallback_Cutoff(ParserNode *node) {
- float f = atof(node->values["value"].c_str());
- _lights->back().setCutoff((f * M_PI) / 180.0);
+ float cutoff = atof(node->values["value"].c_str());
+ if (cutoff < 0.0f || (cutoff > 90.0f && cutoff != 180.0f))
+ warning("Loaded invalid lighting cutoff value %f", cutoff);
+ _lights->back().setCutoff((cutoff * M_PI) / 180.0);
return true;
}
bool SceneLightsXmlParser::parserCallback_Exponent(ParserNode *node) {
- _lights->back().setExponent(atof(node->values["value"].c_str()));
+ float expon = atof(node->values["value"].c_str());
+ if (expon < 0.0f || expon > 128.0f)
+ warning("Loaded invalid lighting exponent value %f", expon);
+ _lights->back().setExponent(expon);
return true;
}
diff --git a/engines/tetraedge/te/te_animation.cpp b/engines/tetraedge/te/te_animation.cpp
index 08b9cc9bf3d..5256ce11d5f 100644
--- a/engines/tetraedge/te/te_animation.cpp
+++ b/engines/tetraedge/te/te_animation.cpp
@@ -57,6 +57,12 @@ void TeAnimation::removeThisFromAnimations() {
break;
}
}
+
+ for (iter = anims->begin(); iter != anims->end(); iter++) {
+ if (*iter == this) {
+ error("anim was added twice to active anims");
+ }
+ }
}
void TeAnimation::pause() {
diff --git a/engines/tetraedge/te/te_animation.h b/engines/tetraedge/te/te_animation.h
index ed1da6436cb..41ee20eec7e 100644
--- a/engines/tetraedge/te/te_animation.h
+++ b/engines/tetraedge/te/te_animation.h
@@ -40,7 +40,7 @@ public:
void play() {
cont();
}
- virtual void update(double time) = 0;
+ virtual void update(double millis) = 0;
void seekToStart();
//void staticDestroy();
diff --git a/engines/tetraedge/te/te_core.cpp b/engines/tetraedge/te/te_core.cpp
index efb5096e32e..f85f50ac040 100644
--- a/engines/tetraedge/te/te_core.cpp
+++ b/engines/tetraedge/te/te_core.cpp
@@ -154,7 +154,8 @@ Common::Path TeCore::findFile(const Common::Path &path) {
testPath.joinInPlace(langs[langtype]);
}
testPath.joinInPlace(fname);
- if (Common::File::exists(testPath) || Common::FSNode(path).exists())
+ //debug("check for %s", testPath.toString());
+ if (Common::File::exists(testPath) || Common::FSNode(testPath).exists())
return testPath;
}
}
diff --git a/engines/tetraedge/te/te_curve_anim2.h b/engines/tetraedge/te/te_curve_anim2.h
index f13bdae1fa2..5f7103f3d79 100644
--- a/engines/tetraedge/te/te_curve_anim2.h
+++ b/engines/tetraedge/te/te_curve_anim2.h
@@ -46,10 +46,10 @@ public:
_interp.load(curve);
}
- void update(double time) {
- _lastUpdateTime = time;
+ void update(double millis) {
+ _lastUpdateTime = millis;
- double amount = _interp.interpole(time, _duration);
+ double amount = _interp.interpole(millis, _duration);
const S interpVal = linearInterpolation<S>(_startVal, _endVal, amount);
//debug("CurveAnim %.02f/%.02f (%.02f) -> %s", time, _maxTime, amount, interpVal.toString().c_str());
diff --git a/engines/tetraedge/te/te_frame_anim.cpp b/engines/tetraedge/te/te_frame_anim.cpp
index c115c8ec994..40a9bc3282b 100644
--- a/engines/tetraedge/te/te_frame_anim.cpp
+++ b/engines/tetraedge/te/te_frame_anim.cpp
@@ -29,10 +29,10 @@ TeFrameAnim::TeFrameAnim() : _nbFrames(0), _frameRate(25.0f), _reversed(false),
_numFramesToShow(-1), _startTime(0), _endTime(FLT_MAX), _loopCount(0), _lastFrameShown(-1) {
}
-void TeFrameAnim::update(double amount) {
+void TeFrameAnim::update(double millis) {
int minFrame = MIN(_minFrame, _nbFrames);
int maxFrame = MIN(_minFrame + _numFramesToShow, _nbFrames);
- double frameNo = _frameRate * amount / 1000.0;
+ double frameNo = _frameRate * millis / 1000.0;
int loopsDone;
int framesToPlay = maxFrame - minFrame;
diff --git a/engines/tetraedge/te/te_frame_anim.h b/engines/tetraedge/te/te_frame_anim.h
index c3b1c4869e9..ca717ee6588 100644
--- a/engines/tetraedge/te/te_frame_anim.h
+++ b/engines/tetraedge/te/te_frame_anim.h
@@ -30,8 +30,9 @@ namespace Tetraedge {
class TeFrameAnim : public TeAnimation {
public:
TeFrameAnim();
+ virtual ~TeFrameAnim() {}
- void update(double amount) override;
+ void update(double millis) override;
TeSignal0Param &frameChangedSignal() { return _frameChangedSignal; };
diff --git a/engines/tetraedge/te/te_light.cpp b/engines/tetraedge/te/te_light.cpp
index 61ed3f02339..55d42947e30 100644
--- a/engines/tetraedge/te/te_light.cpp
+++ b/engines/tetraedge/te/te_light.cpp
@@ -93,6 +93,8 @@ void TeLight::transformSpotPoint(TeVector3f32 &pt) {
}
void TeLight::update(uint lightno) {
+ if (lightno > GL_MAX_LIGHTS)
+ error("Invalid light no %d", lightno);
float col[4];
const uint glLight = _toGlLight(lightno);
col[0] = _colAmbient.r() / 255.0f;
@@ -106,7 +108,12 @@ void TeLight::update(uint lightno) {
col[2] = _colDiffuse.b() / 255.0f;
col[3] = 1.0;
glLightfv(glLight, GL_DIFFUSE, col);
- if (col[0] < 0.01f && col[1] < 0.01f && col[2] < 0.01f)
+
+ // WORKAROUND: Original game sets 0.01 as threshold here to avoid enabling
+ // the "shadow" light. However, CitStation/31130 has shadowlight with values
+ // 4,0,0 which means it gets enabled.
+
+ if (col[0] < 0.02f && col[1] < 0.02f && col[2] < 0.02f)
glDisable(glLight);
col[0] = _colSpecular.r() / 255.0f;
@@ -168,5 +175,28 @@ void TeLight::updateGlobal() {
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, col);
}
+Common::String TeLight::dump() const {
+ const char *ltype;
+ switch (_type) {
+ case LightTypeSpot:
+ ltype = "Spot";
+ break;
+ case LightTypePoint:
+ ltype = "Point";
+ break;
+ case LightTypeDirectional:
+ ltype = "Directional";
+ break;
+ default:
+ error("Invalid light type %d", (int)_type);
+ }
+
+ return Common::String::format("%sLight(\n\tamb:%s diff:%s spec:%s\n\tpos:%s posRad:%s atten:%.02f %.02f %.02f\n\tcutoff:%.02f exp:%.02f dispSz:%.02f\n)",
+ ltype, _colAmbient.dump().c_str(), _colDiffuse.dump().c_str(),
+ _colSpecular.dump().c_str(), _position3d.dump().c_str(),
+ _positionRadial.dump().c_str(), _constAtten, _linearAtten,
+ _quadraticAtten, _cutoff, _exponent, _displaySize);
+}
+
} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_light.h b/engines/tetraedge/te/te_light.h
index 2ed67430525..38d45756e6f 100644
--- a/engines/tetraedge/te/te_light.h
+++ b/engines/tetraedge/te/te_light.h
@@ -54,6 +54,7 @@ public:
void update(uint lightno);
static void updateGlobal();
static void setGlobalAmbient(const TeColor &col) { _globalAmbientColor = col; }
+ static const TeColor &globalAmbient() { return _globalAmbientColor; }
void setSpecular(const TeColor &col) { _colSpecular = col; }
void setDiffuse(const TeColor &col) { _colDiffuse = col; }
@@ -72,6 +73,8 @@ public:
const TeVector2f32 &positionRadial() const { return _positionRadial; }
const TeVector3f32 &position3d() const { return _position3d; }
+ Common::String dump() const;
+
private:
TeVector3f32 _position3d;
TeVector2f32 _positionRadial;
diff --git a/engines/tetraedge/te/te_model.cpp b/engines/tetraedge/te/te_model.cpp
index ef1de05bba7..c5b1d4b67cc 100644
--- a/engines/tetraedge/te/te_model.cpp
+++ b/engines/tetraedge/te/te_model.cpp
@@ -118,6 +118,7 @@ void TeModel::draw() {
mesh.draw();
}
renderer->popMatrix();
+ // Note: no corresponding enableAll - they can be enabled inside TeMaterial::apply
TeLight::disableAll();
}
}
diff --git a/engines/tetraedge/te/te_model_animation.cpp b/engines/tetraedge/te/te_model_animation.cpp
index 560ec007bd9..a5c28c8f329 100644
--- a/engines/tetraedge/te/te_model_animation.cpp
+++ b/engines/tetraedge/te/te_model_animation.cpp
@@ -76,6 +76,7 @@ void TeModelAnimation::destroy() {
_nmoRotArrays.clear();
_nmoScaleArrays.clear();
_fbxArrays.clear();
+ _numNMOFrames = 0;
}
int TeModelAnimation::findBone(const Common::String &bname) {
@@ -338,7 +339,7 @@ void TeModelAnimation::unbind() {
_model.release();
}
-void TeModelAnimation::update(double proportion) {
+void TeModelAnimation::update(double millis) {
int frames;
if (!_useNMOArrays) {
if (_fbxArrays.empty())
@@ -351,7 +352,7 @@ void TeModelAnimation::update(double proportion) {
if (frames) {
_curFrameValFresh = false;
- _curFrame2 = calcCurrentFrame(proportion);
+ _curFrame2 = calcCurrentFrame(millis);
if (_finishedSignalPending) {
_finishedSignalPending = false;
_onFinishedSignal.call();
diff --git a/engines/tetraedge/te/te_model_animation.h b/engines/tetraedge/te/te_model_animation.h
index 5152b082bd2..4604c818c76 100644
--- a/engines/tetraedge/te/te_model_animation.h
+++ b/engines/tetraedge/te/te_model_animation.h
@@ -54,7 +54,7 @@ public:
TeModelAnimation();
- ~TeModelAnimation() {
+ virtual ~TeModelAnimation() {
destroy();
}
@@ -89,7 +89,7 @@ public:
void setScale(unsigned long num, float amount, const TeVector3f32 &scale);
void setTranslation(unsigned long num, float amount, const TeVector3f32 &trans);
void unbind();
- void update(double proportion) override;
+ void update(double millis) override;
int curFrame2() const { return _curFrame2; }
float speed() const { return _speed; }
diff --git a/engines/tetraedge/te/te_model_vertex_animation.h b/engines/tetraedge/te/te_model_vertex_animation.h
index 9e3e7ce9e76..71e29eaccdd 100644
--- a/engines/tetraedge/te/te_model_vertex_animation.h
+++ b/engines/tetraedge/te/te_model_vertex_animation.h
@@ -47,6 +47,9 @@ public:
};
TeModelVertexAnimation();
+ virtual ~TeModelVertexAnimation() {
+ _keydata.clear();
+ }
void bind(TeIntrusivePtr<TeModel> &model);
// void deleteLater() // original overrides this, but just calls the super.
@@ -59,7 +62,7 @@ public:
bool load(Common::ReadStream &stream);
void save(Common::WriteStream &stream) const;
- void update(double amount) override;
+ void update(double millis) override;
private:
float _lastMillis;
diff --git a/engines/tetraedge/te/te_ray_intersection.cpp b/engines/tetraedge/te/te_ray_intersection.cpp
index 9526563d69a..6fcdad15a17 100644
--- a/engines/tetraedge/te/te_ray_intersection.cpp
+++ b/engines/tetraedge/te/te_ray_intersection.cpp
@@ -44,7 +44,7 @@ int intersect(const TeVector3f32 &p, const TeVector3f32 &d, const TeVector3f32 &
float a = e1.dotProduct(h);
if (fabs(a) < 1e-6f)
return 0;
-
+
float f = 1.0f / a;
const TeVector3f32 s = p - v0;
float u = f * s.dotProduct(h);
@@ -56,15 +56,15 @@ int intersect(const TeVector3f32 &p, const TeVector3f32 &d, const TeVector3f32 &
if (v < 0.0f || u + v > 1.0f)
return 0;
-
+
float t = f * e2.dotProduct(q);
-
+
if (t < 1e-6f)
return 0;
-
+
hitDist = t;
hitPt = p + t * d;
-
+
return 1;
}*/
diff --git a/engines/tetraedge/te/te_renderer.cpp b/engines/tetraedge/te/te_renderer.cpp
index 464d6632cad..0ac997fbebe 100644
--- a/engines/tetraedge/te/te_renderer.cpp
+++ b/engines/tetraedge/te/te_renderer.cpp
@@ -272,7 +272,6 @@ void TeRenderer::init() {
_scissorX = _scissorY = _scissorWidth = _scissorHeight = 0;
}
-
void TeRenderer::loadIdentityMatrix() {
_matriciesStacks[_matrixMode].loadIdentity();
}
diff --git a/engines/tetraedge/te/te_signal.h b/engines/tetraedge/te/te_signal.h
index ebad199faa3..bf4b93644e0 100644
--- a/engines/tetraedge/te/te_signal.h
+++ b/engines/tetraedge/te/te_signal.h
@@ -57,8 +57,7 @@ public:
typename Common::Array<TeICallback0ParamPtr>::iterator end_ = this->end();
for (; i < end_; i++) {
if ((*i)->equals(item.get())) {
- this->erase(i);
- break;
+ i = this->erase(i);
}
}
}
@@ -98,8 +97,7 @@ public:
typename Common::Array<TeICallback1ParamPtr<T>>::iterator end_ = this->end();
for (; i < end_; i++) {
if ((*i)->equals(item.get())) {
- this->erase(i);
- break;
+ i = this->erase(i);
}
}
}
@@ -138,8 +136,7 @@ public:
typename Common::Array<TeICallback2ParamPtr<S, T>>::iterator end_ = this->end();
for (; i < end_; i++) {
if ((*i)->equals(item.get())) {
- this->erase(i);
- break;
+ i = this->erase(i);
}
}
}
Commit: f84785ff3ae75f1fdad08f570b20a6ee026d70e4
https://github.com/scummvm/scummvm/commit/f84785ff3ae75f1fdad08f570b20a6ee026d70e4
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2023-01-16T17:36:43+01:00
Commit Message:
TETRAEDGE: Cleanups, started working on credits etc
Scrolling text now mostly works, but isn't clipped to the dialog box.
Changed paths:
A engines/tetraedge/te/te_i_text_layout.cpp
A engines/tetraedge/te/te_i_text_layout.h
engines/tetraedge/game/application.cpp
engines/tetraedge/game/application.h
engines/tetraedge/game/bonus_menu.cpp
engines/tetraedge/game/bonus_menu.h
engines/tetraedge/game/cellphone.cpp
engines/tetraedge/game/character.cpp
engines/tetraedge/game/character.h
engines/tetraedge/game/confirm.cpp
engines/tetraedge/game/credits.cpp
engines/tetraedge/game/credits.h
engines/tetraedge/game/dialog2.cpp
engines/tetraedge/game/documents_browser.cpp
engines/tetraedge/game/gallery_menu.cpp
engines/tetraedge/game/game.cpp
engines/tetraedge/game/game.h
engines/tetraedge/game/global_bonus_menu.cpp
engines/tetraedge/game/how_to.cpp
engines/tetraedge/game/in_game_scene.cpp
engines/tetraedge/game/inventory.cpp
engines/tetraedge/game/loc_file.h
engines/tetraedge/game/main_menu.cpp
engines/tetraedge/game/notifier.cpp
engines/tetraedge/game/objectif.cpp
engines/tetraedge/game/question2.h
engines/tetraedge/game/scene_lights_xml_parser.cpp
engines/tetraedge/game/splash_screens.cpp
engines/tetraedge/metaengine.cpp
engines/tetraedge/module.mk
engines/tetraedge/te/te_3d_texture.cpp
engines/tetraedge/te/te_3d_texture.h
engines/tetraedge/te/te_button_layout.cpp
engines/tetraedge/te/te_button_layout.h
engines/tetraedge/te/te_camera.cpp
engines/tetraedge/te/te_core.cpp
engines/tetraedge/te/te_extended_text_layout.cpp
engines/tetraedge/te/te_extended_text_layout.h
engines/tetraedge/te/te_font3.cpp
engines/tetraedge/te/te_free_move_zone.cpp
engines/tetraedge/te/te_free_move_zone.h
engines/tetraedge/te/te_i_3d_object2.cpp
engines/tetraedge/te/te_i_3d_object2.h
engines/tetraedge/te/te_image.cpp
engines/tetraedge/te/te_layout.cpp
engines/tetraedge/te/te_light.cpp
engines/tetraedge/te/te_list_layout.cpp
engines/tetraedge/te/te_lua_context.cpp
engines/tetraedge/te/te_lua_gui.cpp
engines/tetraedge/te/te_lua_gui.h
engines/tetraedge/te/te_lua_gui_lua_callbacks.cpp
engines/tetraedge/te/te_material.cpp
engines/tetraedge/te/te_matrix4x4.cpp
engines/tetraedge/te/te_model_vertex_animation.cpp
engines/tetraedge/te/te_music.cpp
engines/tetraedge/te/te_palette.cpp
engines/tetraedge/te/te_ray_intersection.cpp
engines/tetraedge/te/te_renderer.cpp
engines/tetraedge/te/te_renderer.h
engines/tetraedge/te/te_scrolling_layout.cpp
engines/tetraedge/te/te_scrolling_layout.h
engines/tetraedge/te/te_sprite_layout.cpp
engines/tetraedge/te/te_text_base2.cpp
engines/tetraedge/te/te_text_base2.h
engines/tetraedge/te/te_text_layout.cpp
engines/tetraedge/te/te_text_layout.h
engines/tetraedge/te/te_text_layout_xml_parser.cpp
engines/tetraedge/te/te_text_layout_xml_parser.h
engines/tetraedge/te/te_theora.cpp
engines/tetraedge/te/te_tiled_surface.cpp
engines/tetraedge/te/te_visual_fade.h
engines/tetraedge/tetraedge.cpp
engines/tetraedge/tetraedge.h
engines/tetraedge/to_lua.cpp
diff --git a/engines/tetraedge/game/application.cpp b/engines/tetraedge/game/application.cpp
index 369d9a5493f..e05f2bcbd40 100644
--- a/engines/tetraedge/game/application.cpp
+++ b/engines/tetraedge/game/application.cpp
@@ -26,6 +26,7 @@
#include "common/events.h"
#include "graphics/opengl/system_headers.h"
+#include "graphics/scaler.h"
#include "tetraedge/tetraedge.h"
#include "tetraedge/game/game.h"
@@ -64,10 +65,10 @@ _drawShadows(true) {
_firstScene = tempGui.value("firstScene").toString();
TeSoundManager *soundmgr = g_engine->getSoundManager();
- soundmgr->setChannelVolume("sfx", 0.7);
- soundmgr->setChannelVolume("music", 0.7);
- soundmgr->setChannelVolume("dialog", 0.7);
- soundmgr->setChannelVolume("video", 0.7);
+ soundmgr->setChannelVolume("sfx", 0.7f);
+ soundmgr->setChannelVolume("music", 0.7f);
+ soundmgr->setChannelVolume("dialog", 0.7f);
+ soundmgr->setChannelVolume("video", 0.7f);
// TODO: Configure freemium things here?
// Note: original has an app run timer, but it's never used?
@@ -96,7 +97,7 @@ void Application::create() {
_mainWindow.setSize(TeVector3f32(winWidth, winHeight, 0.0));
_mainWindow.setSizeType(TeILayout::ABSOLUTE);
_mainWindow.setPositionType(TeILayout::ABSOLUTE);
- _mainWindow.setPosition(TeVector3f32(0.0f, 0.0f ,0.0f));
+ _mainWindow.setPosition(TeVector3f32(0.0f, 0.0f, 0.0f));
TeResourceManager *resmgr = g_engine->getResourceManager();
_fontComic = resmgr->getResourceNoSearch<TeFont3>("Common/Fonts/ComicRelief.ttf");
@@ -483,6 +484,18 @@ void Application::captureFade() {
_visFade.captureFrame();
}
+void Application::getSavegameThumbnail(Graphics::Surface &thumb) {
+ captureFade();
+ Graphics::Surface screen;
+ _visFade.texture()->writeTo(screen);
+ screen.flipVertical(Common::Rect(screen.w, screen.h));
+ Common::ScopedPtr<Graphics::Surface> scaledScreen(screen.scale(kThumbnailWidth, kThumbnailHeight2, true));
+ //scaledScreen->convertToInPlace(Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0));
+ thumb.copyFrom(*scaledScreen);
+ screen.free();
+ scaledScreen->free();
+}
+
bool Application::isFading() {
return _visFade.blackFading() || _visFade.fading();
}
diff --git a/engines/tetraedge/game/application.h b/engines/tetraedge/game/application.h
index 8bd2ce06290..9d88c203c76 100644
--- a/engines/tetraedge/game/application.h
+++ b/engines/tetraedge/game/application.h
@@ -82,6 +82,8 @@ public:
void loadOptions(const Common::String &fname);
void saveOptions(const Common::String &fname);
+ void getSavegameThumbnail(Graphics::Surface &thumb);
+
Common::String getHelpText(const Common::String &key);
const char *inAppUnlockFullVersionID();
diff --git a/engines/tetraedge/game/bonus_menu.cpp b/engines/tetraedge/game/bonus_menu.cpp
index bc734d7cc4f..f0ccb12b348 100644
--- a/engines/tetraedge/game/bonus_menu.cpp
+++ b/engines/tetraedge/game/bonus_menu.cpp
@@ -32,11 +32,68 @@ BonusMenu::BonusMenu() {
}
void BonusMenu::enter(const Common::String &scriptName) {
- error("TODO: implement me.");
+ bool loaded = load(scriptName);
+ if (!loaded)
+ error("BonusMenu::enter: failed to load %s", scriptName.c_str());
+ Application *app = g_engine->getApplication();
+ app->_frontLayout.addChild(layoutChecked("menu"));
+
+ buttonLayoutChecked("quitButton")->onMouseClickValidated().add(this, &BonusMenu::onQuitButton);
+
+ int btnNo = 0;
+ while (true) {
+ const Common::String btnNoStr = Common::String::format("%d", btnNo);
+ TeButtonLayout *btn = buttonLayout(btnNoStr);
+ if (!btn)
+ break;
+ SaveButton *saveBtn = new SaveButton(btn, btnNoStr);
+ _saveButtons.push_back(saveBtn);
+
+ // TODO: Finish this.
+
+ btnNo++;
+ }
+
+ btnNo = 0;
+ while( true ) {
+ const Common::String btnNoStr = Common::String::format("slot%d", btnNo);
+ TeLayout *l = layout(btnNoStr);
+ if (!l)
+ break;
+
+ if (btnNo < (int)_saveButtons.size()) {
+ l->addChild(_saveButtons[btnNo]);
+ }
+ btnNo = btnNo + 1;
+ }
+
+ TeButtonLayout *slideBtn = buttonLayoutChecked("slideButton");
+ slideBtn->onButtonChangedToStateDownSignal().add(this, &BonusMenu::onSlideButtonDown);
+
+ TeInputMgr *inputmgr = g_engine->getInputMgr();
+ inputmgr->_mouseMoveSignal.add(this, &BonusMenu::onMouseMove);
+
+ _pageNo = 0;
+
+ TeButtonLayout *leftBtn = buttonLayout("leftButton");
+ if (leftBtn)
+ leftBtn->onMouseClickValidated().add(this, &BonusMenu::onLeftButton);
+
+ TeButtonLayout *rightBtn = buttonLayout("rightButton");
+ if (rightBtn)
+ rightBtn->onMouseClickValidated().add(this, &BonusMenu::onRightButton);
+
+ // TODO: more stuff here with "text" values (also finish loop above)
+ warning("TODO: Finish BonusMenu::enter(%s)", scriptName.c_str());
+
+ TeButtonLayout *pictureBtn = buttonLayout("fullScreenPictureButton");
+ if (pictureBtn) {
+ pictureBtn->onMouseClickValidated().add(this, &BonusMenu::onPictureButton);
+ }
}
void BonusMenu::enter() {
- error("TODO: implement me.");
+ error("TODO: implement BonusMenu::enter()");
}
void BonusMenu::leave() {
@@ -44,23 +101,58 @@ void BonusMenu::leave() {
delete s;
}
_saveButtons.clear();
- warning("TODO: remove oMouseMove signal from inputmgr.");
+ TeInputMgr *inputmgr = g_engine->getInputMgr();
+ inputmgr->_mouseMoveSignal.remove(this, &BonusMenu::onMouseMove);
TeLuaGUI::unload();
}
bool BonusMenu::onLeftButton() {
- error("TODO: implement me.");
+ TeCurveAnim2<TeLayout, TeVector3f32> *slideAnim = layoutPositionLinearAnimation("slideAnimation");
+
+ if (!slideAnim->_runTimer.running() && _pageNo != 0) {
+ TeLayout *slotsLayout = layout("slots");
+ TeVector3f32 slotsPos = slotsLayout->userPosition();
+ slideAnim->_startVal = slotsPos;
+ slotsPos.x() += value("slideTranslation").toFloat64();
+ slideAnim->_endVal = slotsPos;
+
+ slideAnim->_callbackObj = layoutChecked("slots");
+ slideAnim->_callbackMethod = &TeLayout::setPosition;
+ slideAnim->play();
+
+ _pageNo--;
+
+ buttonLayoutChecked("slideButton")->reset();
+
+ warning("TODO: Finish BonusMenu::onLeftButton");
+ // TODO: Set values depending on whether saves exist (lines 95-120)
+ }
+
return false;
}
-bool BonusMenu::onMouseMove() {
- error("TODO: implement me.");
+bool BonusMenu::onMouseMove(const Common::Point &pt) {
+ TeButtonLayout *slideLayout = buttonLayout("slideButton");
+ if (slideLayout->state() == TeButtonLayout::BUTTON_STATE_DOWN) {
+ TeCurveAnim2<TeLayout, TeVector3f32> *slideAnim = layoutPositionLinearAnimation("slideAnimation");
+ if (!slideAnim->_runTimer.running()) {
+ warning("TODO: implement BonusMenu::onMouseMove");
+ }
+ }
+
return false;
}
bool BonusMenu::onPictureButton() {
- error("TODO: implement me.");
- return false;
+ TeButtonLayout *btn = buttonLayoutChecked("menu");
+ btn->setVisible(true);
+
+ Application *app = g_engine->getApplication();
+ TeSpriteLayout *pictureLayout = spriteLayoutChecked("fullScreenPictureLayout");
+ app->_frontLayout.removeChild(pictureLayout);
+ pictureLayout->setVisible(true);
+
+ return true;
}
bool BonusMenu::onQuitButton() {
@@ -75,7 +167,26 @@ bool BonusMenu::onQuitButton() {
}
bool BonusMenu::onRightButton() {
- error("TODO: implement me.");
+ TeCurveAnim2<TeLayout, TeVector3f32> *slideAnim = layoutPositionLinearAnimation("slideAnimation");
+
+ if (!slideAnim->_runTimer.running() && _pageNo < (int)_saveButtons.size() - 1) {
+ TeLayout *slotsLayout = layout("slots");
+ TeVector3f32 slotsPos = slotsLayout->userPosition();
+ slideAnim->_startVal = slotsPos;
+ slotsPos.x() -= value("slideTranslation").toFloat64();
+ slideAnim->_endVal = slotsPos;
+
+ slideAnim->_callbackObj = layoutChecked("slots");
+ slideAnim->_callbackMethod = &TeLayout::setPosition;
+ slideAnim->play();
+
+ _pageNo++;
+
+ buttonLayoutChecked("slideButton")->reset();
+
+ // TODO: Set values depending on whether saves exist (lines 95-120)
+ warning("TODO: Finish BonusMenu::onRightButton");
+ }
return false;
}
@@ -87,12 +198,19 @@ bool BonusMenu::onSlideButtonDown() {
return false;
}
+BonusMenu::SaveButton::SaveButton(TeButtonLayout *btn, const Common::String &name) {
+ setName(name);
+ btn->setEnable(true);
+ // TODO: Add child something here?
+ btn->onMouseClickValidated().add(this, &BonusMenu::SaveButton::onLoadSave);
+}
+
Common::String BonusMenu::SaveButton::path() const {
return Common::String("Backup/") + name() + ".xml";
}
bool BonusMenu::SaveButton::onLoadSave() {
- error("TODO: implement me.");
+ error("TODO: implement BonusMenu::SaveButton::onLoadSave");
}
} // end namespace Tetraedge
diff --git a/engines/tetraedge/game/bonus_menu.h b/engines/tetraedge/game/bonus_menu.h
index 4cb63291fa1..5a57cdeb66a 100644
--- a/engines/tetraedge/game/bonus_menu.h
+++ b/engines/tetraedge/game/bonus_menu.h
@@ -36,6 +36,7 @@ public:
class SaveButton : public TeLayout {
public:
+ SaveButton(TeButtonLayout *btn, const Common::String &name);
bool onLoadSave();
Common::String path() const;
};
@@ -49,7 +50,7 @@ public:
}
bool onLeftButton();
- bool onMouseMove();
+ bool onMouseMove(const Common::Point &pt);
bool onPictureButton();
bool onQuitButton();
bool onRightButton();
@@ -61,6 +62,7 @@ private:
Common::Array<SaveButton *> _saveButtons;
TeVector2s32 _slideBtnStartMousePos;
Common::String _gameName;
+ int _pageNo;
};
} // end namespace Tetraedge
diff --git a/engines/tetraedge/game/cellphone.cpp b/engines/tetraedge/game/cellphone.cpp
index 3ec7dbe7d2f..f2a47e2c330 100644
--- a/engines/tetraedge/game/cellphone.cpp
+++ b/engines/tetraedge/game/cellphone.cpp
@@ -41,7 +41,7 @@ bool Cellphone::addNumber(const Common::String &num) {
layout->setName(namePrefix + num);
layout->setSizeType(RELATIVE_TO_PARENT);
layout->setAnchor(TeVector3f32(0.5f, 0.0f, 0.0f));
- // WORKAROUND: Original uses 1.0,1.0,1.0 here but then the text area is too high.
+ // WORKAROUND: Original uses (1.0, 1.0, 1.0) here but then the text area is too high.
layout->setSize(TeVector3f32(1.0f, 0.6f, 0.0f));
layout->setPosition(TeVector3f32(0.5f, 0.08f, 0.0f));
layout->setTextSizeType(1);
diff --git a/engines/tetraedge/game/character.cpp b/engines/tetraedge/game/character.cpp
index 3076eeb6529..7827158b957 100644
--- a/engines/tetraedge/game/character.cpp
+++ b/engines/tetraedge/game/character.cpp
@@ -179,7 +179,7 @@ float Character::animLength(const TeModelAnimation &modelanim, long bone, long l
return ((endtrans.z() - starttrans.z()) + secondtrans.z()) - starttrans.z();
}
-float Character::animLengthFromFile(const Common::String &animname, uint *pframeCount, uint lastframe /* = 9999 */) {
+float Character::animLengthFromFile(const Common::String &animname, uint32 *pframeCount, uint lastframe /* = 9999 */) {
if (animname.empty()) {
*pframeCount = 0;
return 0.0f;
@@ -288,7 +288,6 @@ void Character::deleteCallback(const Common::String &key, const Common::String &
_callbacks.erase(animFile);
}
-//static bool deserialize(TiXmlElement *param_1, Walk *param_2);
void Character::endMove() {
if (_model->name() == "Kate")
walkMode("Walk");
@@ -388,7 +387,7 @@ bool Character::loadModel(const Common::String &mname, bool unused) {
arr[1] = TeVector3f32(-60.0, 0.0, 60.0);
arr[2] = TeVector3f32(60.0, 0.0, -60.0);
arr[3] = TeVector3f32(60.0, 0.0, 60.0);
- pmodel->setQuad(shadow, arr, TeColor(0xff,0xff,0xff,0x50));
+ pmodel->setQuad(shadow, arr, TeColor(0xff, 0xff, 0xff, 0x50));
}
return true;
}
@@ -581,7 +580,6 @@ bool Character::onModelAnimationFinished() {
const TeTRS endTRS = trsFromAnim(*_curModelAnim, pereBone, _curModelAnim->lastFrame());
TeVector3f32 trans = endTRS.getTranslation();
trans.x() = -trans.x();
- trans.y() = 0;
TeVector3f32 newpos;
if (!_recallageY) {
@@ -592,6 +590,7 @@ bool Character::onModelAnimationFinished() {
newpos = _model->worldTransformationMatrix() * trans;
} else if (!_freeMoveZone) {
trans.x() = -trans.x();
+ trans.y() = 0.0;
newpos = _model->worldTransformationMatrix() * trans;
} else {
newpos = correctPosition(_model->worldTransformationMatrix() * trans);
@@ -798,7 +797,7 @@ void Character::update(double msFromStart) {
_walkCurveNextLength = speedFromAnim(msFromStart) * _walkCurveIncrement + _walkCurveNextLength;
if (_curve->controlPoints().size() < 2) {
- blendAnimation(_characterSettings._idleAnimFileName, 0.0667, true, false);
+ blendAnimation(_characterSettings._idleAnimFileName, 0.0667f, true, false);
endMove();
return;
}
@@ -884,7 +883,7 @@ void Character::update(double msFromStart) {
endMove();
}
if (endGAnim.empty()) {
- blendAnimation(_characterSettings._idleAnimFileName, 0.0667, true, false);
+ blendAnimation(_characterSettings._idleAnimFileName, 0.0667f, true, false);
endMove();
}
}
@@ -965,7 +964,7 @@ void Character::walkTo(float curveEnd, bool walkFlag) {
if (game->scene()._character == this && _walkModeStr == "Walk") {
int looplen = (int)(nloops * _walkLoopAnimFrameCount);
int repeats = looplen / _walkLoopAnimFrameCount;
- uint remainder = looplen % _walkLoopAnimFrameCount;
+ uint32 remainder = looplen % _walkLoopAnimFrameCount;
uint framecounts[4];
diff --git a/engines/tetraedge/game/character.h b/engines/tetraedge/game/character.h
index 191b1796524..8eb0b41e9da 100644
--- a/engines/tetraedge/game/character.h
+++ b/engines/tetraedge/game/character.h
@@ -100,7 +100,7 @@ public:
static TeIntrusivePtr<TeModelAnimation> animCacheLoad(const Common::Path &path);
float animLength(const TeModelAnimation &modelanim, long bone, long lastframe);
- float animLengthFromFile(const Common::String &animname, uint *pframeCount, uint lastframe = 9999);
+ float animLengthFromFile(const Common::String &animname, uint32 *pframeCount, uint lastframe = 9999);
bool blendAnimation(const Common::String &animname, float amount, bool repeat, bool returnToIdle);
TeVector3f32 correctPosition(const TeVector3f32 &pos);
float curveOffset();
diff --git a/engines/tetraedge/game/confirm.cpp b/engines/tetraedge/game/confirm.cpp
index 70c565aa307..c535e0a7c73 100644
--- a/engines/tetraedge/game/confirm.cpp
+++ b/engines/tetraedge/game/confirm.cpp
@@ -63,27 +63,27 @@ void Confirm::enter(const Common::String &guiPath, const Common::String &y) {
error("Missing translations for ok and cancel");
}
- TeTextLayout *yesUpLayout = _gui.textLayout("yesUpLayout");
+ TeITextLayout *yesUpLayout = _gui.textLayout("yesUpLayout");
if (yesUpLayout)
yesUpLayout->setText(textAttributs + *okButtonLoc);
- TeTextLayout *yesDownLayout = _gui.textLayout("yesDownLayout");
+ TeITextLayout *yesDownLayout = _gui.textLayout("yesDownLayout");
if (yesDownLayout)
yesDownLayout->setText(textAttributsDown + *okButtonLoc);
- TeTextLayout *yesRollOverLayout = _gui.textLayout("yesRollOverLayout");
+ TeITextLayout *yesRollOverLayout = _gui.textLayout("yesRollOverLayout");
if (yesRollOverLayout)
yesRollOverLayout->setText(textAttributs + *okButtonLoc);
- TeTextLayout *noUpLayout = _gui.textLayout("noUpLayout");
+ TeITextLayout *noUpLayout = _gui.textLayout("noUpLayout");
if (noUpLayout)
noUpLayout->setText(textAttributs + *cancelButtonLoc);
- TeTextLayout *noDownLayout = _gui.textLayout("noDownLayout");
+ TeITextLayout *noDownLayout = _gui.textLayout("noDownLayout");
if (noDownLayout)
noDownLayout->setText(textAttributsDown + *cancelButtonLoc);
- TeTextLayout *noRollOverLayout = _gui.textLayout("noRollOverLayout");
+ TeITextLayout *noRollOverLayout = _gui.textLayout("noRollOverLayout");
if (noRollOverLayout)
noRollOverLayout->setText(textAttributs + *cancelButtonLoc);
}
diff --git a/engines/tetraedge/game/credits.cpp b/engines/tetraedge/game/credits.cpp
index 572acc67079..b726fdb4294 100644
--- a/engines/tetraedge/game/credits.cpp
+++ b/engines/tetraedge/game/credits.cpp
@@ -20,19 +20,113 @@
*/
#include "common/textconsole.h"
+
+#include "tetraedge/tetraedge.h"
#include "tetraedge/game/credits.h"
+#include "tetraedge/game/application.h"
namespace Tetraedge {
-Credits::Credits() {
+Credits::Credits() : _animCounter(0), _returnToOptions(false) {
}
-void Credits::enter(bool flag) {
- error("TODO: Implement Credits::enter");
+void Credits::enter(bool returnToOptions) {
+ _returnToOptions = returnToOptions;
+ _animCounter = 0;
+ _timer.start();
+ // TODO: set _field0x50 = 0;
+ _gui.load("menus/credits/credits.lua");
+ Application *app = g_engine->getApplication();
+ app->_frontLayout.addChild(_gui.layoutChecked("menu"));
+
+ Common::String musicPath = _gui.value("musicPath").toString();
+ if (!app->music().isPlaying() || app->music().path() != musicPath) {
+ app->music().stop();
+ app->music().load(musicPath);
+ app->music().play();
+ app->music().volume(1.0f);
+ }
+
+ TeButtonLayout *bgbtn = _gui.buttonLayout("background");
+ if (bgbtn) {
+ bgbtn->onMouseClickValidated().add(this, &Credits::onQuitButton);
+ }
+
+ TeCurveAnim2<TeLayout, TeVector3f32> *posAnim = _gui.layoutPositionLinearAnimation("scrollTextPositionAnim");
+ if (!posAnim)
+ error("Credits gui - couldn't find scrollTextPositionAnim");
+ posAnim->onFinished().add(this, &Credits::onAnimFinished);
+ posAnim->_callbackObj = _gui.layoutChecked("text");
+ posAnim->_callbackMethod = &TeLayout::setPosition;
+ posAnim->play();
+
+ TeCurveAnim2<TeLayout, TeVector3f32> *anchorAnim = _gui.layoutAnchorLinearAnimation("scrollTextAnchorAnim");
+ if (!anchorAnim)
+ error("Credits gui - couldn't find scrollTextAnchorAnim");
+
+ anchorAnim->_callbackObj = _gui.layoutChecked("text");
+ anchorAnim->_callbackMethod = &TeLayout::setAnchor;
+ anchorAnim->play();
+
+ TeCurveAnim2<TeLayout, TeVector3f32> *bgPosAnim = _gui.layoutPositionLinearAnimation("scrollBackgroundPositionAnim");
+ if (!bgPosAnim)
+ error("Credits gui - couldn't find scrollBackgroundPositionAnim");
+
+ bgPosAnim->_callbackObj = _gui.layoutChecked("backgroundSprite");
+ bgPosAnim->_callbackMethod = &TeLayout::setAnchor;
+ bgPosAnim->play();
+
+ _curveAnim._runTimer.pausable(false);
+ _curveAnim.stop();
+ _curveAnim._startVal = TeColor(0xff, 0xff, 0xff, 0);
+ _curveAnim._endVal = TeColor(0xff, 0xff, 0xff, 0xff);
+ Common::Array<float> curve;
+ curve.push_back(0.0f);
+ curve.push_back(0.0f);
+ curve.push_back(0.0f);
+ curve.push_back(0.0f);
+ curve.push_back(1.0f);
+ _curveAnim._repeatCount = 1;
+ _curveAnim.setCurve(curve);
+ _curveAnim._duration = 12000;
+
+ TeLayout *backgrounds = _gui.layoutChecked("Backgrounds");
+ if (_animCounter < backgrounds->childCount()) {
+ TeSpriteLayout *bgchild = dynamic_cast<TeSpriteLayout *>(backgrounds->child(_animCounter));
+ if (!bgchild)
+ error("Child of backgrounds is not a TeSpriteLayout");
+ _curveAnim._callbackObj = bgchild;
+ _curveAnim._callbackMethod = &TeLayout::setColor;
+ _curveAnim.play();
+ const Common::String bgAnimName = bgchild->name() + "Anim";
+ bgPosAnim = _gui.layoutPositionLinearAnimation(bgAnimName);
+ if (!bgPosAnim)
+ error("Couldn't find bg position anim %s", bgAnimName.c_str());
+ bgPosAnim->_callbackObj = bgchild;
+ bgPosAnim->_callbackMethod = &TeLayout::setPosition;
+ bgPosAnim->play();
+ }
+ _curveAnim.onFinished().add(this, &Credits::onBackgroundAnimFinished);
}
void Credits::leave() {
- error("TODO: Implement Credits::leave");
+ _curveAnim.stop();
+ for (auto anim : _gui.layoutPositionLinearAnimations()) {
+ anim._value->stop();
+ }
+ if (_gui.loaded()) {
+ Application *app = g_engine->getApplication();
+ app->captureFade();
+ app->_frontLayout.removeChild(_gui.layoutChecked("menu"));
+ _timer.stop();
+ _gui.unload();
+ if (_returnToOptions)
+ error("TODO: Implement returning to options menu");
+ else
+ app->mainMenu().enter();
+ app->fade();
+ _curveAnim.onFinished().remove(this, &Credits::onBackgroundAnimFinished);
+ }
}
bool Credits::onAnimFinished() {
@@ -41,8 +135,24 @@ bool Credits::onAnimFinished() {
}
bool Credits::onBackgroundAnimFinished() {
- //TeLayout *buttonsLayout = _gui.layout("buttons");
- error("TODO: Implement Credits::onBackgroundAnimFinished");
+ _animCounter++;
+ TeLayout *backgrounds = _gui.layoutChecked("Backgrounds");
+ if (_animCounter < backgrounds->childCount()) {
+ TeSpriteLayout *bgchild = dynamic_cast<TeSpriteLayout *>(backgrounds->child(_animCounter));
+ if (!bgchild)
+ error("Children of credits Backgrounds should be Sprites.");
+ _curveAnim._callbackObj = bgchild;
+ _curveAnim._callbackMethod = &TeLayout::setColor;
+ _curveAnim.play();
+ const Common::String bgAnimName = bgchild->name() + "Anim";
+ TeCurveAnim2<TeLayout, TeVector3f32> *bgposanim = _gui.layoutPositionLinearAnimation(bgAnimName);
+ if (!bgposanim)
+ error("Couldn't find bg position anim %s", bgAnimName.c_str());
+ bgposanim->_callbackObj = bgchild;
+ bgposanim->_callbackMethod = &TeLayout::setPosition;
+ bgposanim->play();
+ }
+ return false;
}
bool Credits::onPadButtonUp(uint button) {
@@ -54,13 +164,12 @@ bool Credits::onPadButtonUp(uint button) {
}
bool Credits::onQuitButton() {
- TeCurveAnim2<TeI3DObject2, TeVector3f32> *anim1 = _gui.layoutPositionLinearAnimation("scrollTextPositionAnim");
+ TeCurveAnim2<TeLayout, TeVector3f32> *anim1 = _gui.layoutPositionLinearAnimation("scrollTextPositionAnim");
anim1->stop();
- TeCurveAnim2<TeI3DObject2, TeVector3f32> *anim2 = _gui.layoutPositionLinearAnimation("scrollTextAnchorAnim");
+ TeCurveAnim2<TeLayout, TeVector3f32> *anim2 = _gui.layoutAnchorLinearAnimation("scrollTextAnchorAnim");
anim2->stop();
leave();
return true;
}
-
} // end namespace Tetraedge
diff --git a/engines/tetraedge/game/credits.h b/engines/tetraedge/game/credits.h
index fada8eefdaa..c39740ba877 100644
--- a/engines/tetraedge/game/credits.h
+++ b/engines/tetraedge/game/credits.h
@@ -45,9 +45,9 @@ private:
TeTimer _timer;
TeLuaGUI _gui;
TeCurveAnim2<Te3DObject2, TeColor> _curveAnim;
- TeColor _col1;
- TeColor _col2;
Common::Array<double> _doubleArr;
+ int _animCounter;
+ bool _returnToOptions; // if true, return to OptionsMenu instead of MainMenu.
};
} // end namespace Tetraedge
diff --git a/engines/tetraedge/game/dialog2.cpp b/engines/tetraedge/game/dialog2.cpp
index 1df74bf3ead..159f076eb23 100644
--- a/engines/tetraedge/game/dialog2.cpp
+++ b/engines/tetraedge/game/dialog2.cpp
@@ -112,8 +112,8 @@ void Dialog2::load() {
Common::SharedPtr<TeCallback0Param<Dialog2>> callbackptr(new TeCallback0Param<Dialog2>(this, &Dialog2::onSkipButton, 20000.0f));
dialogBtn->onMouseClickValidated().push_back(callbackptr);
- TeCurveAnim2<TeLayout,TeVector3f32> *dialogAnimUp = _gui.layoutAnchorLinearAnimation("dialogAnimationUp");
- TeCurveAnim2<TeLayout,TeVector3f32> *dialogAnimDown = _gui.layoutAnchorLinearAnimation("dialogAnimationDown");
+ TeCurveAnim2<TeLayout, TeVector3f32> *dialogAnimUp = _gui.layoutAnchorLinearAnimation("dialogAnimationUp");
+ TeCurveAnim2<TeLayout, TeVector3f32> *dialogAnimDown = _gui.layoutAnchorLinearAnimation("dialogAnimationDown");
if (!dialogAnimUp || !dialogAnimDown)
error("Dialog2::load: didn't get dialogAnimUp or dialogAnimationDown");
@@ -152,9 +152,9 @@ bool Dialog2::onMinimumTimeTimer() {
}
bool Dialog2::onSkipButton() {
- const TeCurveAnim2<TeLayout,TeVector3f32> *dialogAnimUp = _gui.layoutAnchorLinearAnimation("dialogAnimationUp");
+ const TeCurveAnim2<TeLayout, TeVector3f32> *dialogAnimUp = _gui.layoutAnchorLinearAnimation("dialogAnimationUp");
if (!dialogAnimUp->_runTimer.running()) {
- const TeCurveAnim2<TeLayout,TeVector3f32> *dialogAnimDown = _gui.layoutAnchorLinearAnimation("dialogAnimationDown");
+ const TeCurveAnim2<TeLayout, TeVector3f32> *dialogAnimDown = _gui.layoutAnchorLinearAnimation("dialogAnimationDown");
if (!dialogAnimDown->_runTimer.running()) {
startDownAnimation();
_music.stop();
@@ -198,16 +198,16 @@ void Dialog2::pushDialog(const Common::String &name, const Common::String &textV
void Dialog2::startDownAnimation() {
_minimumTimeTimer.stop();
- TeCurveAnim2<TeLayout,TeVector3f32> *dialogAnimDown = _gui.layoutAnchorLinearAnimation("dialogAnimationDown");
+ TeCurveAnim2<TeLayout, TeVector3f32> *dialogAnimDown = _gui.layoutAnchorLinearAnimation("dialogAnimationDown");
dialogAnimDown->play();
}
void Dialog2::unload() {
if (!_gui.loaded())
return;
- TeCurveAnim2<TeLayout,TeVector3f32> *dialogAnimUp = _gui.layoutAnchorLinearAnimation("dialogAnimationUp");
+ TeCurveAnim2<TeLayout, TeVector3f32> *dialogAnimUp = _gui.layoutAnchorLinearAnimation("dialogAnimationUp");
dialogAnimUp->stop();
- TeCurveAnim2<TeLayout,TeVector3f32> *dialogAnimDown = _gui.layoutAnchorLinearAnimation("dialogAnimationDown");
+ TeCurveAnim2<TeLayout, TeVector3f32> *dialogAnimDown = _gui.layoutAnchorLinearAnimation("dialogAnimationDown");
dialogAnimDown->stop();
_music.close();
_gui.unload();
diff --git a/engines/tetraedge/game/documents_browser.cpp b/engines/tetraedge/game/documents_browser.cpp
index 73e2881e1e8..badd29b8a6e 100644
--- a/engines/tetraedge/game/documents_browser.cpp
+++ b/engines/tetraedge/game/documents_browser.cpp
@@ -193,8 +193,8 @@ void DocumentsBrowser::showDocument(const Common::String &docName, long startPag
TeVector2s32 spriteSize = sprite->_tiledSurfacePtr->_tiledTexture->_totalSize;
sprite->setSizeType(RELATIVE_TO_PARENT);
TeVector3f32 winSize = app->getMainWindow().size();
- sprite->setSize(TeVector3f32(1.0, (4.0 / (winSize.y() / winSize.x() * 4.0)) *
- ((float)spriteSize._y / (float)spriteSize._x), 0.0));
+ sprite->setSize(TeVector3f32(1.0f, (4.0f / (winSize.y() / winSize.x() * 4.0f)) *
+ ((float)spriteSize._y / (float)spriteSize._x), 0.0f));
TeScrollingLayout *scroll = _gui1.scrollingLayout("scroll");
if (!scroll)
error("DocumentsBrowser::showDocument Couldn't fetch scroll object");
@@ -225,9 +225,8 @@ void DocumentsBrowser::unload() {
TeLayout *slot = _gui1.layout(pageSlotName);
if (!slot)
break;
- for (unsigned int i = 0; i < slot->childCount(); i++) {
- Te3DObject2 *child = slot->child(i);
- Document *doc = dynamic_cast<Document *>(child);
+ for (long i = 0; i < slot->childCount(); i++) {
+ Document *doc = dynamic_cast<Document *>(slot->child(i));
if (doc)
delete doc;
}
diff --git a/engines/tetraedge/game/gallery_menu.cpp b/engines/tetraedge/game/gallery_menu.cpp
index 7403f62ec18..2276481ab6c 100644
--- a/engines/tetraedge/game/gallery_menu.cpp
+++ b/engines/tetraedge/game/gallery_menu.cpp
@@ -43,10 +43,10 @@ bool GalleryMenu::onSkipVideoButtonValidated() {
Game *game = g_engine->getGame();
game->stopSound(AMBIENT_SND_BIKE);
- game->playSound(AMBIENT_SND_BIKE, -1, 0.1);
+ game->playSound(AMBIENT_SND_BIKE, -1, 0.1f);
game->stopSound(AMBIENT_SND_ENGR);
- game->playSound(AMBIENT_SND_ENGR, -1, 0.09);
+ game->playSound(AMBIENT_SND_ENGR, -1, 0.09f);
TeSpriteLayout *video = spriteLayoutChecked("video");
video->stop();
@@ -86,10 +86,10 @@ void GalleryMenu::enter() {
app->_frontLayout.addChild(menu);
game->stopSound(AMBIENT_SND_BIKE);
- game->playSound(AMBIENT_SND_BIKE, -1, 0.1);
+ game->playSound(AMBIENT_SND_BIKE, -1, 0.1f);
game->stopSound(AMBIENT_SND_ENGR);
- game->playSound(AMBIENT_SND_ENGR, -1, 0.09);
+ game->playSound(AMBIENT_SND_ENGR, -1, 0.09f);
TeButtonLayout *btn = buttonLayoutChecked("quitButton");
btn->onMouseClickValidated().add(this, &GalleryMenu::onQuitButton);
diff --git a/engines/tetraedge/game/game.cpp b/engines/tetraedge/game/game.cpp
index e50ba5db78d..7da4d3f43b4 100644
--- a/engines/tetraedge/game/game.cpp
+++ b/engines/tetraedge/game/game.cpp
@@ -52,7 +52,7 @@ _sceneCharacterVisibleFromLoad(false), _isCharacterWalking(false),
_lastCharMoveMousePos(0.0f, 0.0f), _randomSoundFinished(false),
_previousMousePos(-1, -1), _markersVisible(true), _saveRequested(false),
_gameLoadState(0), _luaShowOwnerError(false), _score(0), _warped(false),
-_firstInventory(true), _loadName("save.xml"), _randomSource("SyberiaGameRandom") {
+_firstInventory(true), _randomSource("SyberiaGameRandom") {
for (int i = 0; i < NUM_OBJECTS_TAKEN_IDS; i++) {
_objectsTakenBits[i] = false;
}
@@ -213,7 +213,7 @@ bool Game::changeWarp2(const Common::String &zone, const Common::String &scene,
_warped = false;
_movePlayerCharacterDisabled = false;
_sceneCharacterVisibleFromLoad = false;
- // TODO: set another field here (0x3f40 = -1)
+ // TODO? _charMoveMouseEventNo = -1?
_isCharacterIdle = true;
_isCharacterWalking = false;
Common::Path luapath("scenes");
@@ -278,11 +278,11 @@ void Game::enter(bool newgame) {
_score = 0;
Application *app = g_engine->getApplication();
app->visualFade().init();
- // FIXME: Original puts this click handler at -10000.. but then it never gets hit?
+ // TODO: Original puts this click handler at -10000.. but then it never gets hit?
Common::SharedPtr<TeCallback1Param<Game, const Common::Point &>> callbackptr(new TeCallback1Param<Game, const Common::Point &>(this, &Game::onMouseClick, 10000.0f));
g_engine->getInputMgr()->_mouseLUpSignal.push_back(callbackptr);
_movePlayerCharacterDisabled = false;
- // TODO? Set character mouse move event no to -1
+ // TODO? Set _charMoveMouseEventNo = -1
_isCharacterIdle = true;
_sceneCharacterVisibleFromLoad = false;
Character::loadSettings("models/ModelsSettings.xml");
@@ -352,11 +352,14 @@ void Game::enter(bool newgame) {
_notifier.load();
}
-/*static*/ TeI3DObject2 *Game::findLayoutByName(TeLayout *parent, const Common::String &name) {
- error("TODO: Implement Game::findLayoutByName - although maybe never used?");
+/*static*/
+TeI3DObject2 *Game::findLayoutByName(TeLayout *parent, const Common::String &name) {
+ // Seems like this is never used?
+ error("TODO: Implement Game::findLayoutByName");
}
-/*static*/ TeSpriteLayout *Game::findSpriteLayoutByName(TeLayout *parent, const Common::String &name) {
+/*static*/
+TeSpriteLayout *Game::findSpriteLayoutByName(TeLayout *parent, const Common::String &name) {
if (!parent)
return nullptr;
@@ -380,7 +383,9 @@ void Game::finishFreemium() {
void Game::finishGame() {
Application *app = g_engine->getApplication();
- app->_finishedGame = true;
+ // FIXME: The original sets this, but then Application::run immediately
+ // returns to the menu.. how does the original wait for the credits to end??
+ //app->_finishedGame = true;
_playedTimer.stop();
/* Game does this but does nothing with result?
if (app->difficulty() == 2) {
@@ -569,8 +574,8 @@ bool Game::initWarp(const Common::String &zone, const Common::String &scene, boo
TeSpriteLayout *video = _inGameGui.spriteLayout("video");
video->setVisible(false);
- video->_tiledSurfacePtr->_frameAnim.onFinished().remove(this, &Game::onVideoFinished);
- video->_tiledSurfacePtr->_frameAnim.onFinished().add(this, &Game::onVideoFinished);
+ video->_tiledSurfacePtr->_frameAnim.onStop().remove(this, &Game::onVideoFinished);
+ video->_tiledSurfacePtr->_frameAnim.onStop().add(this, &Game::onVideoFinished);
TeButtonLayout *invbtn = _inGameGui.buttonLayout("inventoryButton");
invbtn->onMouseClickValidated().remove(this, &Game::onInventoryButtonValidated);
@@ -579,9 +584,9 @@ bool Game::initWarp(const Common::String &zone, const Common::String &scene, boo
const TeVector3f32 winSize = app->getMainWindow().size();
if (g_engine->getCore()->fileFlagSystemFlag("definition") == "SD") {
- invbtn->setSize(TeVector3f32(0.12, (4.0 / ((winSize.y() / winSize.x()) * 4.0)) * 0.12, 0.0));
+ invbtn->setSize(TeVector3f32(0.12f, (4.0f / ((winSize.y() / winSize.x()) * 4.0f)) * 0.12f, 0.0));
} else {
- invbtn->setSize(TeVector3f32(0.08, (4.0 / ((winSize.y() / winSize.x()) * 4.0)) * 0.08, 0.0));
+ invbtn->setSize(TeVector3f32(0.08f, (4.0f / ((winSize.y() / winSize.x()) * 4.0f)) * 0.08f, 0.0));
}
TeCheckboxLayout *markersCheckbox = _inGameGui.checkboxLayout("markersVisibleButton");
@@ -688,20 +693,42 @@ static const char *DIALOG_IDS[20] = {
bool Game::launchDialog(const Common::String &dname, uint param_2, const Common::String &charname,
const Common::String &animfile, float animblend) {
Application *app = g_engine->getApplication();
- const Common::String *locdname = app->_loc.value(dname);
- if (!locdname)
- locdname = &dname;
+ const Common::String *locstring = app->_loc.value(dname);
+
+ if (!locstring)
+ locstring = &dname;
- if (!locdname)
+ if (!locstring) // shouldn't happen?
return false;
+ Common::String dstring = *locstring;
+
+ //
+ // WORKAROUND: Fix some errors in en version strings
+ //
+ if (g_engine->getCore()->language() == "en") {
+ if (dname == "C_OK_tel03_09") {
+ size_t rloc = dstring.find("pleased to here");
+ if (rloc != Common::String::npos)
+ dstring.replace(rloc + 11, 4, "hear");
+ } else if (dname == "B_diapo04") {
+ size_t rloc = dstring.find("little imagination ? he draws");
+ if (rloc != Common::String::npos)
+ dstring.replace(rloc + 19, 1, "-");
+ } else if (dname == "V_NK_lettre_01") {
+ size_t rloc = dstring.find("you now ? my brother");
+ if (rloc != Common::String::npos)
+ dstring.replace(rloc + 8, 1, "-");
+ }
+ }
+
for (unsigned int i = 0; i < ARRAYSIZE(DIALOG_IDS); i++) {
if (dname.contains(Common::String::format("_%s_", DIALOG_IDS[i])))
_dialogsTold++;
}
const Common::String sndfile = dname + ".ogg";
- _dialog2.pushDialog(dname, *locdname, sndfile, charname, animfile, animblend);
+ _dialog2.pushDialog(dname, dstring, sndfile, charname, animfile, animblend);
return true;
}
@@ -1061,7 +1088,8 @@ bool Game::onMouseClick(const Common::Point &pt) {
_lastCharMoveMousePos = pt;
}
}
- // FIXME: The original never checks for empty/null curve here.. why?
+ // FIXME: The original never checks for empty/null curve here..
+ // but it seems our curve can possibly become null.
if (_scene.curve() && _scene.curve()->length()) {
TeVector3f32 lastPoint = _scene.curve()->controlPoints().back();
character->setAnimation(character->walkAnim(Character::WalkPart_Loop), true);
@@ -1317,7 +1345,8 @@ void Game::playSound(const Common::String &name, int repeats, float volume) {
if (!sound->play()) {
game->luaScript().execute("OnFreeSoundFinished", name);
game->luaScript().execute("OnCellFreeSoundFinished", name);
- // TODO: original seems to leak sound here??
+ // Note: original leaks sound here, don't do that..
+ delete sound;
} else {
sound->onStopSignal().add(sound, &GameSound::onSoundStopped);
sound->setRetain(true);
@@ -1396,10 +1425,13 @@ void Game::resumeMovie() {
}
void Game::saveBackup(const Common::String &saveName) {
+ Application *app = g_engine->getApplication();
+ app->showLoadingIcon(true);
if (saveName == "save.xml")
g_engine->saveAutosaveIfEnabled();
else
warning("TODO: Implemet Game::saveBackup %s", saveName.c_str());
+ app->showLoadingIcon(false);
}
bool Game::setBackground(const Common::String &name) {
@@ -1419,7 +1451,7 @@ void Game::setCurrentObjectSprite(const Common::Path &spritePath) {
bool Game::showMarkers(bool val) {
TeLayout *bg = _forGui.layoutChecked("background");
- for (unsigned int i = 0; i < bg->childCount(); i++) {
+ for (long i = 0; i < bg->childCount(); i++) {
const InGameScene::TeMarker *marker = _scene.findMarker(bg->child(i)->name());
if (marker)
bg->child(i)->setVisible(!val);
@@ -1516,7 +1548,7 @@ void Game::update() {
if (!_entered)
return;
- TeTextLayout *debugTimeTextLayout = _inGameGui.textLayout("debugTimeText1");
+ TeITextLayout *debugTimeTextLayout = _inGameGui.textLayout("debugTimeText1");
if (debugTimeTextLayout) {
warning("TODO: Game::update: Fill out debugTimeTextLayout");
}
diff --git a/engines/tetraedge/game/game.h b/engines/tetraedge/game/game.h
index 2208b0d6b99..36979202b83 100644
--- a/engines/tetraedge/game/game.h
+++ b/engines/tetraedge/game/game.h
@@ -198,6 +198,7 @@ public:
void setExitZone(const Common::String &zone) { _exitZone = zone; }
Common::RandomSource &randomSource() { return _randomSource; }
void setLoadName(const Common::String &loadName) { _loadName = loadName; }
+ bool hasLoadName() const { return !_loadName.empty(); }
private:
bool _luaShowOwnerError;
diff --git a/engines/tetraedge/game/global_bonus_menu.cpp b/engines/tetraedge/game/global_bonus_menu.cpp
index dfabd6a27dc..8bcbec1598b 100644
--- a/engines/tetraedge/game/global_bonus_menu.cpp
+++ b/engines/tetraedge/game/global_bonus_menu.cpp
@@ -39,25 +39,25 @@ void GlobalBonusMenu::enter() {
// Original checks each layout's existence
TeButtonLayout *btn;
- btn = buttonLayoutChecked("Val");
+ btn = buttonLayout("Val");
if (btn)
btn->onMouseClickValidated().add(this, &GlobalBonusMenu::onValButtonValidated);
- btn = buttonLayoutChecked("Bar");
+ btn = buttonLayout("Bar");
if (btn)
btn->onMouseClickValidated().add(this, &GlobalBonusMenu::onBarButtonValidated);
- btn = buttonLayoutChecked("Cit");
+ btn = buttonLayout("Cit");
if (btn)
btn->onMouseClickValidated().add(this, &GlobalBonusMenu::onCitButtonValidated);
- btn = buttonLayoutChecked("Ara");
+ btn = buttonLayout("Ara");
if (btn)
btn->onMouseClickValidated().add(this, &GlobalBonusMenu::onAraButtonValidated);
- btn = buttonLayoutChecked("Syb2");
+ btn = buttonLayout("Syb2");
if (btn)
btn->onMouseClickValidated().add(this, &GlobalBonusMenu::onSyb2ButtonValidated);
- btn = buttonLayoutChecked("Syb3");
+ btn = buttonLayout("Syb3");
if (btn)
btn->onMouseClickValidated().add(this, &GlobalBonusMenu::onSyb3ButtonValidated);
- btn = buttonLayoutChecked("Back");
+ btn = buttonLayout("Back");
if (btn)
btn->onMouseClickValidated().add(this, &GlobalBonusMenu::onQuitButton);
}
diff --git a/engines/tetraedge/game/how_to.cpp b/engines/tetraedge/game/how_to.cpp
index e0448d47923..e313a081f4f 100644
--- a/engines/tetraedge/game/how_to.cpp
+++ b/engines/tetraedge/game/how_to.cpp
@@ -19,7 +19,10 @@
*
*/
+#include "tetraedge/tetraedge.h"
+
#include "tetraedge/game/how_to.h"
+#include "tetraedge/game/application.h"
namespace Tetraedge {
@@ -27,10 +30,20 @@ HowTo::HowTo() : _entered(false) {
}
void HowTo::leave() {
- error("TODO: Implement HowTo::leave");
+ Application *app = g_engine->getApplication();
+ app->captureFade();
+ unload();
+ //app->helpOptionMenu().enter();
+ app->fade();
+ _entered = false;
+ error("TODO: Finish HowTo::leave - need app->helpOptionMenu");
}
void HowTo::enter() {
+ if (_entered)
+ return;
+
+ _entered = true;
error("TODO: Implement HowTo::enter");
}
diff --git a/engines/tetraedge/game/in_game_scene.cpp b/engines/tetraedge/game/in_game_scene.cpp
index 8ee2628edff..082230582b7 100644
--- a/engines/tetraedge/game/in_game_scene.cpp
+++ b/engines/tetraedge/game/in_game_scene.cpp
@@ -113,9 +113,9 @@ bool InGameScene::addMarker(const Common::String &markerName, const Common::Stri
const TeVector3f32 winSize = g_engine->getApplication()->getMainWindow().size();
if (g_engine->getCore()->fileFlagSystemFlag("definition") == "SD") {
- markerSprite->setSize(TeVector3f32(0.07, (4.0 / ((winSize.y() / winSize.x()) * 4.0)) * 0.07, 0.0));
+ markerSprite->setSize(TeVector3f32(0.07f, (4.0f / ((winSize.y() / winSize.x()) * 4.0f)) * 0.07f, 0.0));
} else {
- markerSprite->setSize(TeVector3f32(0.04, (4.0 / ((winSize.y() / winSize.x()) * 4.0)) * 0.04, 0.0));
+ markerSprite->setSize(TeVector3f32(0.04f, (4.0f / ((winSize.y() / winSize.x()) * 4.0f)) * 0.04f, 0.0));
}
markerSprite->setVisible(game->markersVisible());
markerSprite->_tiledSurfacePtr->_frameAnim._loopCount = -1;
@@ -137,13 +137,11 @@ bool InGameScene::addMarker(const Common::String &markerName, const Common::Stri
/*static*/
float InGameScene::angularDistance(float a1, float a2) {
- float result;
-
- result = a2 - a1;
- if (result >= -3.141593 && result > 3.141593) {
- result = result + -6.283185;
+ float result = a2 - a1;
+ if (result >= -M_PI && result > M_PI) {
+ result = result + -(M_PI * 2);
} else {
- result = result + 6.283185;
+ result = result + (M_PI * 2);
}
return result;
}
@@ -489,9 +487,9 @@ float InGameScene::getHeadHorizontalRotation(Character *cter, const TeVector3f32
zvec.rotate(cter->_model->rotation());
float angle = atan2f(-pos.x(), pos.z()) - atan2f(-zvec.x(), zvec.z());
if (angle < -M_PI)
- angle += (M_PI * 2);
+ angle += (float)(M_PI * 2);
else if (angle > M_PI)
- angle -= (M_PI * 2);
+ angle -= (float)(M_PI * 2);
return angle;
}
@@ -1117,11 +1115,11 @@ void InGameScene::update() {
targetpos.y() += 17;
TeVector2f32 headRot(getHeadHorizontalRotation(_character, targetpos),
getHeadVerticalRotation(_character, targetpos));
- float hangle = headRot.getX() * 180.0 / M_PI;
+ float hangle = headRot.getX() * 180.0f / M_PI;
if (hangle > 90.0f)
- headRot.setX(M_PI_2);
+ headRot.setX((float)M_PI_2);
else if (hangle < -90.0f)
- headRot.setX(-M_PI_2);
+ headRot.setX((float)-M_PI_2);
_character->setHeadRotation(headRot);
_character->setHasAnchor(true);
}
@@ -1133,11 +1131,11 @@ void InGameScene::update() {
targetpos.y() += 17;
TeVector2f32 headRot(getHeadHorizontalRotation(c, targetpos),
getHeadVerticalRotation(c, targetpos));
- float hangle = headRot.getX() * 180.0 / M_PI;
+ float hangle = headRot.getX() * 180.0f / M_PI;
if (hangle > 90)
- headRot.setX(M_PI_2);
+ headRot.setX((float)M_PI_2);
else if (hangle < -90)
- headRot.setX(-M_PI_2);
+ headRot.setX((float)-M_PI_2);
c->setHeadRotation(headRot);
c->setHasAnchor(true);
}
diff --git a/engines/tetraedge/game/inventory.cpp b/engines/tetraedge/game/inventory.cpp
index a70d7738648..05169ca366d 100644
--- a/engines/tetraedge/game/inventory.cpp
+++ b/engines/tetraedge/game/inventory.cpp
@@ -199,10 +199,10 @@ bool Inventory::addObject(InventoryObject *obj) {
TeLayout *slot = _gui.layout(Common::String::format("page%dSlot%d", pageNo, slotNo));
if (!slot)
break;
- for (unsigned int c = 0; c < slot->childCount(); c++) {
+ for (long c = 0; c < slot->childCount(); c++) {
Te3DObject2 *child = slot->child(c);
- InventoryObject *obj = dynamic_cast<InventoryObject *>(child);
- if (obj) {
+ InventoryObject *iobj = dynamic_cast<InventoryObject *>(child);
+ if (iobj) {
slot->removeChild(child);
c--;
}
@@ -215,7 +215,7 @@ bool Inventory::addObject(InventoryObject *obj) {
int pageno = 0;
unsigned int totalSlots = 0;
- bool retval;
+ bool retval = false;
const Common::String newObjName = obj->name();
auto invObjIter = _invObjects.begin();
bool finished = false;
@@ -238,8 +238,8 @@ bool Inventory::addObject(InventoryObject *obj) {
TeTextLayout *newText = new TeTextLayout();
newText->setSizeType(CoordinatesType::RELATIVE_TO_PARENT);
- newText->setPosition(TeVector3f32(1.0,1.0,0.0));
- newText->setSize(TeVector3f32(1.0,1.0,0.0));
+ newText->setPosition(TeVector3f32(1.0, 1.0, 0.0));
+ newText->setSize(TeVector3f32(1.0, 1.0, 0.0));
newText->setTextSizeType(1);
newText->setTextSizeProportionalToWidth(200);
newText->setText(_gui.value("textAttributs").toString() + objectName((*invObjIter)->name()));
@@ -426,7 +426,7 @@ void Inventory::selectedObject(InventoryObject *obj) {
_gui.buttonLayoutChecked("lire")->setEnable(isDocument(objId));
game->setCurrentObjectSprite(obj->spritePath());
TeLayout *textObj = _gui.layout("textObject");
- for (unsigned int i = 0; i < textObj->childCount(); i++) {
+ for (long i = 0; i < textObj->childCount(); i++) {
if (textObj->child(i)->name() == obj->name()) {
textObj->setVisible(true);
textObj->child(i)->setVisible(true);
diff --git a/engines/tetraedge/game/loc_file.h b/engines/tetraedge/game/loc_file.h
index 31c49104be6..861229b22e4 100644
--- a/engines/tetraedge/game/loc_file.h
+++ b/engines/tetraedge/game/loc_file.h
@@ -37,9 +37,6 @@ public:
void load(const Common::Path &path);
const Common::String *value(const Common::String &key);
-private:
- // TODO add private members
-
};
} // end namespace Tetraedge
diff --git a/engines/tetraedge/game/main_menu.cpp b/engines/tetraedge/game/main_menu.cpp
index fec813c658a..243b736fd61 100644
--- a/engines/tetraedge/game/main_menu.cpp
+++ b/engines/tetraedge/game/main_menu.cpp
@@ -118,7 +118,7 @@ void MainMenu::enter() {
}
}
setCenterButtonsVisibility(true);
- TeTextLayout *versionNum = textLayout("versionNumber");
+ TeITextLayout *versionNum = textLayout("versionNumber");
if (versionNum) {
const Common::String versionSectionStr("<section style=\"left\" /><color r=\"255\" g=\"255\" b=\"255\"/><font file=\"Common/Fonts/arial.ttf\" size=\"12\" />");
versionNum->setText(versionSectionStr + app->getVersionString());
@@ -222,7 +222,12 @@ bool MainMenu::onEnterGameRotateAnimFinished() {
}
bool MainMenu::onGalleryButtonValidated() {
- error("TODO: Implement MainMenu::onGalleryButtonValidated");
+ Application *app = g_engine->getApplication();
+ app->captureFade();
+ leave();
+ app->globalBonusMenu().enter();
+ app->fade();
+ return false;
}
bool MainMenu::onHowToButtonValidated() {
diff --git a/engines/tetraedge/game/notifier.cpp b/engines/tetraedge/game/notifier.cpp
index bd5085f2123..c8dd1c53f4d 100644
--- a/engines/tetraedge/game/notifier.cpp
+++ b/engines/tetraedge/game/notifier.cpp
@@ -55,7 +55,7 @@ void Notifier::launchNextnotifier() {
TeVariant textformat = _gui.value("textFormat");
Common::String formattedName = Common::String::format(textformat.toString().c_str(), _notifierDataArray[0]._name.c_str());
- TeTextLayout *text = _gui.textLayout("text");
+ TeITextLayout *text = _gui.textLayout("text");
text->setText(formattedName);
if (!_notifierDataArray[0]._imgpath.empty()) {
diff --git a/engines/tetraedge/game/objectif.cpp b/engines/tetraedge/game/objectif.cpp
index acc0f042e87..1f73149148d 100644
--- a/engines/tetraedge/game/objectif.cpp
+++ b/engines/tetraedge/game/objectif.cpp
@@ -180,7 +180,7 @@ void Objectif::update() {
}
}
- float z = 0.1;
+ float z = 0.1f;
for (Te3DObject2 *child : tasks->childList()) {
TeTextLayout *text = dynamic_cast<TeTextLayout *>(child);
/*TeVector3f32 size =*/
diff --git a/engines/tetraedge/game/question2.h b/engines/tetraedge/game/question2.h
index 7582f06920d..bc171484aae 100644
--- a/engines/tetraedge/game/question2.h
+++ b/engines/tetraedge/game/question2.h
@@ -48,7 +48,7 @@ public:
void enter();
void leave();
void load();
- bool onBackgroundClick() {}
+ bool onBackgroundClick() { return false; }
bool onAnswerValidated(Answer &answer);
void pushAnswer(const Common::String &name, const Common::String &unk, const Common::String &path);
void unload();
diff --git a/engines/tetraedge/game/scene_lights_xml_parser.cpp b/engines/tetraedge/game/scene_lights_xml_parser.cpp
index d2f1505568a..81043ac87a7 100644
--- a/engines/tetraedge/game/scene_lights_xml_parser.cpp
+++ b/engines/tetraedge/game/scene_lights_xml_parser.cpp
@@ -39,7 +39,7 @@ bool SceneLightsXmlParser::parseCol(ParserNode *node, TeColor &colout) {
else
a = 0xff;
- if (r > 255 || g > 255 || b > 255 | a > 255) {
+ if (r > 255 || g > 255 || b > 255 || a > 255) {
parserError("Invalid color values");
return false;
}
@@ -47,7 +47,6 @@ bool SceneLightsXmlParser::parseCol(ParserNode *node, TeColor &colout) {
return true;
}
-
bool SceneLightsXmlParser::parserCallback_Ambient(ParserNode *node) {
// can appear under either global or light
TeColor col;
diff --git a/engines/tetraedge/game/splash_screens.cpp b/engines/tetraedge/game/splash_screens.cpp
index 96773bf6d47..28dad2adcf4 100644
--- a/engines/tetraedge/game/splash_screens.cpp
+++ b/engines/tetraedge/game/splash_screens.cpp
@@ -25,6 +25,7 @@
#include "tetraedge/tetraedge.h"
#include "tetraedge/game/application.h"
+#include "tetraedge/game/game.h"
#include "tetraedge/game/splash_screens.h"
namespace Tetraedge {
@@ -87,7 +88,11 @@ bool SplashScreens::onQuitSplash() {
app->captureFade();
TeLuaGUI::unload();
_entered = false;
- app->mainMenu().enter();
+ if (!g_engine->getGame()->hasLoadName()) {
+ app->mainMenu().enter();
+ } else {
+ app->startGame(false, 1);
+ }
app->fade();
return false;
}
diff --git a/engines/tetraedge/metaengine.cpp b/engines/tetraedge/metaengine.cpp
index d4d1fb4b9e7..f88e5240f60 100644
--- a/engines/tetraedge/metaengine.cpp
+++ b/engines/tetraedge/metaengine.cpp
@@ -39,12 +39,12 @@ bool TetraedgeMetaEngine::hasFeature(MetaEngineFeature f) const {
(f == kSupportsListSaves) ||
(f == kSupportsDeleteSave) ||
(f == kSavesSupportMetaInfo) ||
- // (f == kSavesSupportThumbnail) || // TODO: support save thumbnail
+ (f == kSavesSupportThumbnail) ||
(f == kSupportsLoadingDuringStartup);
}
void TetraedgeMetaEngine::getSavegameThumbnail(Graphics::Surface &thumb) {
- thumb.create(320, 200, Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24));
+ Tetraedge::TetraedgeEngine::getSavegameThumbnail(thumb);
}
diff --git a/engines/tetraedge/module.mk b/engines/tetraedge/module.mk
index bdb10afc5c1..12de439554e 100644
--- a/engines/tetraedge/module.mk
+++ b/engines/tetraedge/module.mk
@@ -59,6 +59,7 @@ MODULE_OBJS := \
te/te_i_3d_object2.o \
te/te_i_layout.o \
te/te_i_loc.o \
+ te/te_i_text_layout.o \
te/te_image.o \
te/te_images_sequence.o \
te/te_input_mgr.o \
diff --git a/engines/tetraedge/te/te_3d_texture.cpp b/engines/tetraedge/te/te_3d_texture.cpp
index bd9ee1b3575..28fb1cdb3cb 100644
--- a/engines/tetraedge/te/te_3d_texture.cpp
+++ b/engines/tetraedge/te/te_3d_texture.cpp
@@ -64,6 +64,15 @@ void Te3DTexture::copyCurrentRender(uint xoffset, uint yoffset, uint x, uint y)
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, xoffset, yoffset, x, y, _texWidth, _texHeight);
}
+void Te3DTexture::writeTo(Graphics::Surface &surf) {
+ Graphics::Surface fullTex;
+ fullTex.create(_texWidth, _texHeight, Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24));
+ glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, fullTex.getPixels());
+ surf.create(_width, _height, Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24));
+ surf.copyRectToSurface(fullTex, 0, 0, Common::Rect(_width, _height));
+ fullTex.free();
+}
+
void Te3DTexture::create() {
_flipY = false;
_leftBorder = _btmBorder = _texWidth = _texHeight = 0;
diff --git a/engines/tetraedge/te/te_3d_texture.h b/engines/tetraedge/te/te_3d_texture.h
index bba5ad26975..2a37d0ad7c6 100644
--- a/engines/tetraedge/te/te_3d_texture.h
+++ b/engines/tetraedge/te/te_3d_texture.h
@@ -59,6 +59,8 @@ public:
bool unload();
void update(const TeImage &img, uint xoff, uint yoff);
+ void writeTo(Graphics::Surface &surf);
+
int _numFrames;
int _frameRate;
uint _width;
diff --git a/engines/tetraedge/te/te_button_layout.cpp b/engines/tetraedge/te/te_button_layout.cpp
index 93db4cc9fc7..1b935322932 100644
--- a/engines/tetraedge/te/te_button_layout.cpp
+++ b/engines/tetraedge/te/te_button_layout.cpp
@@ -39,21 +39,24 @@ public:
float _pri;
};
-/*static*/ bool TeButtonLayout::_mousePositionChangedCatched = false;
-/*static*/ TeTimer *TeButtonLayout::_doubleValidationProtectionTimer = nullptr;
+/*static*/
+bool TeButtonLayout::_mousePositionChangedCatched = false;
+/*static*/
+TeTimer *TeButtonLayout::_doubleValidationProtectionTimer = nullptr;
-/*static*/ TeTimer *TeButtonLayout::getDoubleValidationProtectionTimer() {
+/*static*/
+TeTimer *TeButtonLayout::getDoubleValidationProtectionTimer() {
if (!_doubleValidationProtectionTimer) {
_doubleValidationProtectionTimer = new TeTimer();
}
return _doubleValidationProtectionTimer;
}
-TeButtonLayout::TeButtonLayout() :
-_currentState(BUTTON_STATE_UP), _clickPassThrough(false), _validationSoundVolume(1.0),
-_ignoreMouseEvents(false), _doubleValidationProtectionEnabled(true), _upLayout(nullptr),
-_downLayout(nullptr), _rolloverLayout(nullptr), _disabledLayout(nullptr),
-_hitZoneLayout(nullptr)
+TeButtonLayout::TeButtonLayout() : _currentState(BUTTON_STATE_UP),
+_clickPassThrough(false), _validationSoundVolume(1.0),
+_ignoreMouseEvents(false), _doubleValidationProtectionEnabled(true),
+_upLayout(nullptr), _downLayout(nullptr), _rolloverLayout(nullptr),
+_disabledLayout(nullptr), _hitZoneLayout(nullptr)
{
_onMousePositionChangedMaxPriorityCallback.reset(new TeCallback1Param<TeButtonLayout, const Common::Point &>(this, &TeButtonLayout::onMousePositionChangedMaxPriority, FLT_MAX));
diff --git a/engines/tetraedge/te/te_button_layout.h b/engines/tetraedge/te/te_button_layout.h
index 908e73ff1ab..66c3b03481e 100644
--- a/engines/tetraedge/te/te_button_layout.h
+++ b/engines/tetraedge/te/te_button_layout.h
@@ -86,6 +86,7 @@ public:
}
void setState(State newState);
+ State state() const { return _currentState; };
TeSignal0Param &onMouseClickValidated() { return _onMouseClickValidatedSignal; };
TeSignal0Param &onButtonChangedToStateUpSignal() { return _onButtonChangedToStateUpSignal; };
diff --git a/engines/tetraedge/te/te_camera.cpp b/engines/tetraedge/te/te_camera.cpp
index eee6d0af931..969aff846a9 100644
--- a/engines/tetraedge/te/te_camera.cpp
+++ b/engines/tetraedge/te/te_camera.cpp
@@ -214,14 +214,14 @@ TeMatrix4x4 TeCamera::transformationMatrix() {
return Te3DObject2::transformationMatrix();
TeMatrix4x4 retval;
- warning("TODO: TeCamera::transformationMatrix Implement me.");
+ warning("TODO: Implement TeCamera::transformationMatrix");
retval.setToIdentity();
return retval;
}
TeVector3f32 TeCamera::transformCoord(const TeVector3f32 &pt) {
- warning("TODO: TeCamera::transformCoord Implement me.");
+ warning("TODO: Implement TeCamera::transformCoord");
return pt;
}
diff --git a/engines/tetraedge/te/te_core.cpp b/engines/tetraedge/te/te_core.cpp
index f85f50ac040..cc925988fbe 100644
--- a/engines/tetraedge/te/te_core.cpp
+++ b/engines/tetraedge/te/te_core.cpp
@@ -85,17 +85,17 @@ void TeCore::fileFlagSystemSetFlag(const Common::String &name, const Common::Str
}
bool TeCore::fileFlagSystemFlagsContains(const Common::String &name) const {
- // TODO: Implement me
+ error("TODO: Implement TeCore::fileFlagSystemFlagsContains");
return false;
}
Common::Array<Common::String> TeCore::fileFlagSystemPossibleFlags() {
- // TODO: Implement me
+ error("TODO: Implement TeCore::fileFlagSystemPossibleFlags");
return Common::Array<Common::String>();
}
bool TeCore::fileFlagSystemPossibleFlagsContains(const Common::String &name) const {
- // TODO: Implement me
+ error("TODO: Implement TeCore::fileFlagSystemPossibleFlagsContains");
return false;
}
@@ -108,7 +108,7 @@ void TeCore::language(const Common::String &val) {
}
bool TeCore::onActivityTrackingAlarm() {
- error("TODO: Implement me");
+ error("TODO: Implement TeCore::onActivityTrackingAlarm");
}
@@ -147,16 +147,32 @@ Common::Path TeCore::findFile(const Common::Path &path) {
"de-es-fr-it-en"
};
+ // Note: the audio files for a few videos have a weird path
+ // structure where the language is first, followed by some other
+ // part names, followed by the file.
+ // Dialogs have part stuff followed by lang, so we have to try
+ // adding language before *and* after the suffix.
+
for (int langtype = 0; langtype < ARRAYSIZE(langs); langtype++) {
+ const Common::Path &lang = langs[langtype];
for (int i = 0; i < ARRAYSIZE(pathSuffixes); i++) {
- Common::Path testPath = dir.join(pathSuffixes[i]);
- if (!langs[langtype].empty()) {
- testPath.joinInPlace(langs[langtype]);
- }
+ const Common::Path &suffix = pathSuffixes[i];
+
+ Common::Path testPath = dir;
+ if (!suffix.empty())
+ testPath.joinInPlace(suffix);
+ if (!lang.empty())
+ testPath.joinInPlace(lang);
testPath.joinInPlace(fname);
- //debug("check for %s", testPath.toString());
if (Common::File::exists(testPath) || Common::FSNode(testPath).exists())
return testPath;
+
+ // also try the other way around
+ if (!lang.empty() && !suffix.empty()) {
+ testPath = dir.join(lang).joinInPlace(suffix).join(fname);
+ if (Common::File::exists(testPath) || Common::FSNode(testPath).exists())
+ return testPath;
+ }
}
}
diff --git a/engines/tetraedge/te/te_extended_text_layout.cpp b/engines/tetraedge/te/te_extended_text_layout.cpp
index d355b761fb8..8ee803d92ec 100644
--- a/engines/tetraedge/te/te_extended_text_layout.cpp
+++ b/engines/tetraedge/te/te_extended_text_layout.cpp
@@ -24,6 +24,26 @@
namespace Tetraedge {
TeExtendedTextLayout::TeExtendedTextLayout() {
+ _textLayout.setSizeType(RELATIVE_TO_PARENT);
+ _textLayout.setAnchor(TeVector3f32(0.5, 0.0, 0.0));
+ _textLayout.setPosition(TeVector3f32(0.5, 0.0, 0.0));
+ const TeVector3f32 usersz = userSize();
+ _textLayout.setSize(TeVector3f32(1.0, 1.0, usersz.z()));
+ _scrollingLayout.setContentLayout(&_textLayout);
+ _scrollingLayout.setSizeType(RELATIVE_TO_PARENT);
+ _scrollingLayout.setSize(TeVector3f32(1.0, 1.0, usersz.z()));
+ _scrollingLayout.setDirection(TeVector3f32(0.0, 1.0, 0.0));
+ _scrollingLayout.setMouseControl(false);
+ _scrollingLayout.setEnclose(true);
+ _scrollingLayout.setAutoScrollLoop(1);
+ _scrollingLayout.setAutoScrollDelay(4000);
+ _scrollingLayout.setAutoScrollAnimation1Enabled(true);
+ _scrollingLayout.setAutoScrollAnimation1Delay(0);
+ _scrollingLayout.setAutoScrollAnimation1Speed(0.1f);
+ _scrollingLayout.setAutoScrollAnimation2Enabled(false);
+ _scrollingLayout.setAutoScrollAnimation2Delay(0);
+ _scrollingLayout.setAutoScrollAnimation2Speed(0.1f);
+ addChild(&_scrollingLayout);
}
void TeExtendedTextLayout::setAutoScrollDelay(int val) {
@@ -35,5 +55,38 @@ void TeExtendedTextLayout::setAutoScrollSpeed(float val) {
_scrollingLayout.setAutoScrollAnimation2Speed(val);
}
+void TeExtendedTextLayout::setText(const Common::String &val) {
+ _textLayout.setText(val);
+ _scrollingLayout.resetScrollPosition();
+ _scrollingLayout.playAutoScroll();
+}
+
+void TeExtendedTextLayout::setInterLine(float val) {
+ _textLayout.setInterLine(val);
+}
+
+void TeExtendedTextLayout::setWrapMode(TeTextBase2::WrapMode mode) {
+ if (mode == TeTextBase2::WrapModeFixed) {
+ _textLayout.setAnchor(TeVector3f32(0.5f, 0.0f, 0.0f));
+ _textLayout.setPosition(TeVector3f32(0.5f, 0.0f, 0.0f));
+ _scrollingLayout.setDirection(TeVector3f32(0.0, 1.0, 0.0));
+ } else {
+ _textLayout.setAnchor(TeVector3f32(0.0f, 0.5f, 0.0f));
+ _textLayout.setPosition(TeVector3f32(0.0f, 0.5f, 0.0f));
+ _scrollingLayout.setDirection(TeVector3f32(1.0, 0.0, 0.0));
+ }
+ _scrollingLayout.setContentLayout(nullptr);
+ _scrollingLayout.setContentLayout(&_textLayout);
+ _textLayout.setWrapMode(mode);
+}
+
+void TeExtendedTextLayout::setTextSizeType(int type) {
+ _textLayout.setTextSizeType(type);
+}
+
+void TeExtendedTextLayout::setTextSizeProportionalToWidth(int val) {
+ _textLayout.setTextSizeProportionalToWidth(val);
+}
+
} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_extended_text_layout.h b/engines/tetraedge/te/te_extended_text_layout.h
index 12fdd8a4f0a..82091ddf13c 100644
--- a/engines/tetraedge/te/te_extended_text_layout.h
+++ b/engines/tetraedge/te/te_extended_text_layout.h
@@ -22,24 +22,28 @@
#ifndef TETRAEDGE_TE_TE_EXTENDED_TEXT_LAYOUT_H
#define TETRAEDGE_TE_TE_EXTENDED_TEXT_LAYOUT_H
+#include "tetraedge/te/te_i_text_layout.h"
#include "tetraedge/te/te_text_layout.h"
#include "tetraedge/te/te_scrolling_layout.h"
namespace Tetraedge {
-class TeExtendedTextLayout : public TeTextLayout {
+class TeExtendedTextLayout : public TeITextLayout {
public:
TeExtendedTextLayout();
void setAutoScrollDelay(int val);
void setAutoScrollSpeed(float val);
- // TODO add public members
+ void setText(const Common::String &val) override;
+ void setInterLine(float val) override;
+ void setWrapMode(TeTextBase2::WrapMode mode) override;
+ void setTextSizeType(int type) override;
+ void setTextSizeProportionalToWidth(int val) override;
private:
TeScrollingLayout _scrollingLayout;
- // TODO add private members
-
+ TeTextLayout _textLayout;
};
} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_font3.cpp b/engines/tetraedge/te/te_font3.cpp
index 9c6e33a221f..718084a7978 100644
--- a/engines/tetraedge/te/te_font3.cpp
+++ b/engines/tetraedge/te/te_font3.cpp
@@ -133,10 +133,10 @@ void TeFont3::draw(TeImage &destImage, const Common::String &str, int fontSize,
case AlignRight:
talign = Graphics::kTextAlignRight;
break;
+ // Note: we don't support justify.. just center. (justify is not used anyway)
case AlignJustify:
- talign = Graphics::kTextAlignCenter;
- break;
case AlignCenter:
+ default:
talign = Graphics::kTextAlignCenter;
break;
}
@@ -187,7 +187,7 @@ float TeFont3::ascender(unsigned int pxSize) {
}
float TeFont3::descender(unsigned int pxSize) {
- error("TeFont3::descender: Implement me.");
+ error("TODO: Implement TeFont3::descender");
}
float TeFont3::height(unsigned int pxSize) {
diff --git a/engines/tetraedge/te/te_free_move_zone.cpp b/engines/tetraedge/te/te_free_move_zone.cpp
index 81e769b2680..212827f9c75 100644
--- a/engines/tetraedge/te/te_free_move_zone.cpp
+++ b/engines/tetraedge/te/te_free_move_zone.cpp
@@ -147,7 +147,7 @@ void TeFreeMoveZone::clear() {
_projectedPointsDirty = true;
_transformedVerticies.clear();
_borders.clear();
- // TODO: Some other point vector here.
+ // TODO: Clear some other TeVector2f32 list here (field_0x178)
_gridDirty = true;
_graph->_flags.clear();
_graph->_size = TeVector2s32(0, 0);
@@ -327,7 +327,7 @@ static int segmentIntersection(const TeVector2f32 &s1start, const TeVector2f32 &
}
-bool TeFreeMoveZone::hasBlockerIntersection(const TeVector2s32 &pt) {
+byte TeFreeMoveZone::hasBlockerIntersection(const TeVector2s32 &pt) {
TeVector2f32 borders[4];
const float gridOffsetX = _gridOffsetSomething.getX();
diff --git a/engines/tetraedge/te/te_free_move_zone.h b/engines/tetraedge/te/te_free_move_zone.h
index 9f6dcc6442a..ec8cde052e4 100644
--- a/engines/tetraedge/te/te_free_move_zone.h
+++ b/engines/tetraedge/te/te_free_move_zone.h
@@ -76,7 +76,7 @@ public:
void draw() override;
TeVector3f32 findNearestPointOnBorder(const TeVector2f32 &pt);
- bool hasBlockerIntersection(const TeVector2s32 &pt);
+ byte hasBlockerIntersection(const TeVector2s32 &pt);
bool hasCellBorderIntersection(const TeVector2s32 &pt);
TeActZone *isInZone(const TeVector3f32 &pt);
@@ -99,7 +99,7 @@ public:
void setVertex(unsigned int offset, const TeVector3f32 &vertex);
TeVector3f32 transformAStarGridInWorldSpace(const TeVector2s32 &gridpt);
float transformHeightMin(float minval);
- TeVector3f32 transformVectorInWorldSpace(float param_3,float param_4);
+ TeVector3f32 transformVectorInWorldSpace(float param_3, float param_4);
void updateBorders();
void updateGrid(bool force);
void updatePickMesh();
diff --git a/engines/tetraedge/te/te_i_3d_object2.cpp b/engines/tetraedge/te/te_i_3d_object2.cpp
index 457b316b15a..6ae88f59c61 100644
--- a/engines/tetraedge/te/te_i_3d_object2.cpp
+++ b/engines/tetraedge/te/te_i_3d_object2.cpp
@@ -26,6 +26,4 @@ namespace Tetraedge {
TeI3DObject2::TeI3DObject2() {
}
-// TODO: Add more functions here.
-
} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_i_3d_object2.h b/engines/tetraedge/te/te_i_3d_object2.h
index de922feb320..d5373828025 100644
--- a/engines/tetraedge/te/te_i_3d_object2.h
+++ b/engines/tetraedge/te/te_i_3d_object2.h
@@ -29,12 +29,6 @@ public:
TeI3DObject2();
virtual ~TeI3DObject2() {}
-
- // TODO add public members
-
-private:
- // TODO add private members
-
};
} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_i_text_layout.cpp b/engines/tetraedge/te/te_i_text_layout.cpp
new file mode 100644
index 00000000000..abf312df3a2
--- /dev/null
+++ b/engines/tetraedge/te/te_i_text_layout.cpp
@@ -0,0 +1,31 @@
+/* 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 "tetraedge/te/te_i_text_layout.h"
+
+namespace Tetraedge {
+
+TeITextLayout::TeITextLayout() {
+}
+
+// TODO: Add more functions here.
+
+} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_i_text_layout.h b/engines/tetraedge/te/te_i_text_layout.h
new file mode 100644
index 00000000000..bdb987f150a
--- /dev/null
+++ b/engines/tetraedge/te/te_i_text_layout.h
@@ -0,0 +1,44 @@
+/* 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 TETRAEDGE_TE_TE_I_TEXT_LAYOUT_H
+#define TETRAEDGE_TE_TE_I_TEXT_LAYOUT_H
+
+#include "tetraedge/te/te_layout.h"
+#include "tetraedge/te/te_text_base2.h"
+
+namespace Tetraedge {
+
+class TeITextLayout : public TeLayout {
+public:
+ TeITextLayout();
+
+ virtual void setText(const Common::String &val) = 0;
+ virtual void setInterLine(float val) = 0;
+ virtual void setWrapMode(TeTextBase2::WrapMode mode) = 0;
+ virtual void setTextSizeType(int type) = 0;
+ virtual void setTextSizeProportionalToWidth(int val) = 0;
+
+};
+
+} // end namespace Tetraedge
+
+#endif // TETRAEDGE_TE_TE_I_TEXT_LAYOUT_H
diff --git a/engines/tetraedge/te/te_image.cpp b/engines/tetraedge/te/te_image.cpp
index c25def49905..49deda8b37e 100644
--- a/engines/tetraedge/te/te_image.cpp
+++ b/engines/tetraedge/te/te_image.cpp
@@ -32,15 +32,15 @@ TeImage::TeImage() : ManagedSurface(), _format(INVALID) {
}
TeImage::TeImage(const TeImage &other) {
- error("TODO: TeImage:: copy constructor Implement me.");
+ error("TODO: Implement TeImage::TeImage copy constructor");
}
void TeImage::copy(TeImage &dest, const TeVector2s32 &vec1, const TeVector2s32 &vec2, const TeVector2s32 &vec3) const {
- error("TODO: TeImage::copy Implement me.");
+ error("TODO: Implement TeImage::copy");
}
unsigned long TeImage::countPixelsOfColor(const TeColor &col) const {
- error("TODO: TeImage: Implement me.");
+ error("TODO: Implement TeImage::countPixelsOfColor");
}
void TeImage::create() {
@@ -59,7 +59,7 @@ void TeImage::create(uint xsize, uint ysize, Common::SharedPtr<TePalette> &pal,
}
void TeImage::deserialize(Common::ReadStream &stream) {
- error("TODO: TeImage: Implement me.");
+ error("TODO: Implement TeImage::deserialize");
}
void TeImage::destroy() {
@@ -68,11 +68,11 @@ void TeImage::destroy() {
}
void TeImage::drawPlot(void *outbuf, int x, int y, const TeVector2s32 &bufsize, const TeColor &col) {
- error("TODO: TeImage: Implement me.");
+ error("TODO: Implement TeImage::drawPlot");
}
void TeImage::fill(byte val) {
- error("TODO: TeImage: Implement me.");
+ error("TODO: Implement TeImage::fill");
}
void TeImage::fill(byte r, byte g, byte b, byte a) {
@@ -83,11 +83,11 @@ void TeImage::fill(byte r, byte g, byte b, byte a) {
}
void TeImage::getBuff(uint x, uint y, byte *pout, uint w_, uint h_) {
- error("TODO: TeImage: Implement me.");
+ error("TODO: Implement TeImage::getBuff");
}
bool TeImage::isExtensionSupported(const Common::Path &path) {
- error("TODO: TeImage: Implement me.");
+ error("TODO: Implement TeImage::isExtensionSupported");
}
bool TeImage::load(const Common::Path &path) {
@@ -108,15 +108,15 @@ bool TeImage::load(const Common::Path &path) {
}
bool TeImage::load(Common::ReadStream &stream, const Common::Path &path) {
- error("TODO: TeImage::load Implement me.");
+ error("TODO: Implement TeImage::load");
}
bool TeImage::save(const Common::Path &path, enum Type type) {
- error("TODO: TeImage::save Implement me.");
+ error("TODO: Implement TeImage::save");
}
int TeImage::serialize(Common::WriteStream &stream) {
- error("TODO: TeImage::serialize Implement me.");
+ error("TODO: Implement TeImage::serialize");
}
} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_layout.cpp b/engines/tetraedge/te/te_layout.cpp
index f8e4e406e8b..3fde8410e1b 100644
--- a/engines/tetraedge/te/te_layout.cpp
+++ b/engines/tetraedge/te/te_layout.cpp
@@ -396,7 +396,7 @@ void TeLayout::updateSize() {
newSize.x() = _ratio * newSize.y();
else
newSize.y() = newSize.x() / _ratio;
- }
+ }
}
_size.x() = newSize.x();
diff --git a/engines/tetraedge/te/te_light.cpp b/engines/tetraedge/te/te_light.cpp
index 55d42947e30..74544399728 100644
--- a/engines/tetraedge/te/te_light.cpp
+++ b/engines/tetraedge/te/te_light.cpp
@@ -76,7 +76,7 @@ void TeLight::draw(TeCamera &camera) {
error("TODO: Finish TeLight::draw");
}
-void TeLight::transformDirPoint(const TeVector3f32 &pt1,TeVector3f32 &pt2) {
+void TeLight::transformDirPoint(const TeVector3f32 &pt1, TeVector3f32 &pt2) {
const TeQuaternion q1 = TeQuaternion::fromAxisAndAngle(TeVector3f32(0, 1, 0), _positionRadial.getX() + M_PI);
const TeQuaternion q2 = TeQuaternion::fromAxisAndAngle(TeVector3f32(0, 0, -1), -_positionRadial.getY());
pt2.rotate(q2);
@@ -95,39 +95,29 @@ void TeLight::transformSpotPoint(TeVector3f32 &pt) {
void TeLight::update(uint lightno) {
if (lightno > GL_MAX_LIGHTS)
error("Invalid light no %d", lightno);
- float col[4];
const uint glLight = _toGlLight(lightno);
- col[0] = _colAmbient.r() / 255.0f;
- col[1] = _colAmbient.g() / 255.0f;
- col[2] = _colAmbient.b() / 255.0f;
- col[3] = 1.0;
- glLightfv(glLight, GL_AMBIENT, col);
-
- col[0] = _colDiffuse.r() / 255.0f;
- col[1] = _colDiffuse.g() / 255.0f;
- col[2] = _colDiffuse.b() / 255.0f;
- col[3] = 1.0;
- glLightfv(glLight, GL_DIFFUSE, col);
+
+ const float ambient[4] = {_colAmbient.r() / 255.0f, _colAmbient.g() / 255.0f,
+ _colAmbient.b() / 255.0f, 1.0};
+ glLightfv(glLight, GL_AMBIENT, ambient);
+
+ const float diff[4] = {_colDiffuse.r() / 255.0f, _colDiffuse.g() / 255.0f,
+ _colDiffuse.b() / 255.0f, 1.0};
+ glLightfv(glLight, GL_DIFFUSE, diff);
// WORKAROUND: Original game sets 0.01 as threshold here to avoid enabling
- // the "shadow" light. However, CitStation/31130 has shadowlight with values
- // 4,0,0 which means it gets enabled.
+ // the "shadow" light. However, Syberia CitStation/31130 has shadowlight with
+ // values (4, 0, 0) which means it gets enabled and everything is dark.
- if (col[0] < 0.02f && col[1] < 0.02f && col[2] < 0.02f)
+ if (diff[0] < 0.02f && diff[1] < 0.02f && diff[2] < 0.02f)
glDisable(glLight);
- col[0] = _colSpecular.r() / 255.0f;
- col[1] = _colSpecular.g() / 255.0f;
- col[2] = _colSpecular.b() / 255.0f;
- col[3] = 1.0;
- glLightfv(glLight, GL_SPECULAR, col);
+ const float spec[4] = {_colSpecular.r() / 255.0f, _colSpecular.g() / 255.0f,
+ _colSpecular.b() / 255.0f, 1.0};
+ glLightfv(glLight, GL_SPECULAR, spec);
if (_type == LightTypeSpot || _type == LightTypePoint) {
- float pos[4];
- pos[0] = _position3d.x();
- pos[1] = _position3d.y();
- pos[2] = _position3d.z();
- pos[3] = 1.0f;
+ const float pos[4] = {_position3d.x(), _position3d.y(), _position3d.z(), 1.0f};
glLightfv(glLight, GL_POSITION, pos);
glLightf(glLight, GL_CONSTANT_ATTENUATION, _constAtten);
glLightf(glLight, GL_LINEAR_ATTENUATION, _linearAtten);
@@ -135,28 +125,20 @@ void TeLight::update(uint lightno) {
}
if (_type == LightTypeDirectional) {
- float pos[4];
float cosx = cosf(_positionRadial.getX());
float cosy = cosf(_positionRadial.getY());
float sinx = sinf(_positionRadial.getX());
float siny = sinf(_positionRadial.getY());
- pos[0] = cosx * cosy;
- pos[1] = siny;
- pos[2] = sinx * cosy;
- pos[3] = 0.0;
+ const float pos[4] = {cosx * cosy, siny, sinx * cosy, 0.0f};
glLightfv(glLight, GL_POSITION, pos);
}
if (_type == LightTypeSpot) {
- float pos[4];
float cosx = cosf(_positionRadial.getX());
float cosy = cosf(_positionRadial.getY());
float sinx = sinf(_positionRadial.getX());
float siny = sinf(_positionRadial.getY());
- pos[0] = cosx * cosy;
- pos[1] = siny;
- pos[2] = sinx * cosy;
- pos[3] = 0.0;
+ const float pos[4] = {cosx * cosy, siny, sinx * cosy, 0.0f};
glLightfv(glLight, GL_SPOT_DIRECTION, pos);
glLightf(glLight, GL_SPOT_CUTOFF, (_cutoff * 180.0) / M_PI);
glLightf(glLight, GL_SPOT_EXPONENT, _exponent);
@@ -167,11 +149,8 @@ void TeLight::update(uint lightno) {
/*static*/
void TeLight::updateGlobal() {
- float col[4];
- col[0] = _globalAmbientColor.r() / 255.0f;
- col[1] = _globalAmbientColor.g() / 255.0f;
- col[2] = _globalAmbientColor.b() / 255.0f;
- col[3] = 1.0;
+ const float col[4] = {_globalAmbientColor.r() / 255.0f,
+ _globalAmbientColor.g() / 255.0f, _globalAmbientColor.b() / 255.0f, 1.0};
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, col);
}
diff --git a/engines/tetraedge/te/te_list_layout.cpp b/engines/tetraedge/te/te_list_layout.cpp
index 9b109879a49..9678ff8928b 100644
--- a/engines/tetraedge/te/te_list_layout.cpp
+++ b/engines/tetraedge/te/te_list_layout.cpp
@@ -26,6 +26,4 @@ namespace Tetraedge {
TeListLayout::TeListLayout() {
}
-// TODO: Add more functions here.
-
} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_lua_context.cpp b/engines/tetraedge/te/te_lua_context.cpp
index 15b7c8b880c..c7a928cfe12 100644
--- a/engines/tetraedge/te/te_lua_context.cpp
+++ b/engines/tetraedge/te/te_lua_context.cpp
@@ -33,7 +33,7 @@ namespace Tetraedge {
static int luaPanicFunction(lua_State *state) {
const char *msg = lua_tolstring(state, -1, nullptr);
- warning("Lua: %s",msg);
+ warning("Lua: %s", msg);
lua_settop(state, -2);
return 1;
}
@@ -69,7 +69,7 @@ TeVariant TeLuaContext::global(const Common::String &name) {
TeVariant retval;
int type = lua_type(_luaState, -1);
if (type == LUA_TBOOLEAN) {
- int result = lua_toboolean(_luaState,-1);
+ int result = lua_toboolean(_luaState, -1);
lua_settop(_luaState, -2);
return TeVariant(result > 0);
} else if (type == LUA_TNUMBER) {
diff --git a/engines/tetraedge/te/te_lua_gui.cpp b/engines/tetraedge/te/te_lua_gui.cpp
index 26e60c63ee5..84d30ee5c4a 100644
--- a/engines/tetraedge/te/te_lua_gui.cpp
+++ b/engines/tetraedge/te/te_lua_gui.cpp
@@ -110,7 +110,7 @@ TeCurveAnim2<TeLayout, TeVector3f32> *TeLuaGUI::layoutAnchorLinearAnimation(cons
return _layoutAnchorLinearAnimations.getVal(name);
}
-TeCurveAnim2<TeI3DObject2, TeVector3f32> *TeLuaGUI::layoutPositionLinearAnimation(const Common::String &name) {
+TeCurveAnim2<TeLayout, TeVector3f32> *TeLuaGUI::layoutPositionLinearAnimation(const Common::String &name) {
return _layoutPositionLinearAnimations.getVal(name);
}
@@ -122,7 +122,7 @@ TeListLayout *TeLuaGUI::listLayout(const Common::String &name) {
}
TeCurveAnim2<TeI3DObject2, TeQuaternion> *TeLuaGUI::rotationLinearAnimation(const Common::String &name) {
- error("TODO: Implement me.");
+ error("TODO: Implement TeLuaGUI::rotationLinearAnimation.");
return nullptr;
}
@@ -140,7 +140,7 @@ TeSpriteLayout *TeLuaGUI::spriteLayout(const Common::String &name) {
return nullptr;
}
-TeTextLayout *TeLuaGUI::textLayout(const Common::String &name) {
+TeITextLayout *TeLuaGUI::textLayout(const Common::String &name) {
StringMap<TeTextLayout *>::iterator iter = _textLayouts.find(name);
if (iter != _textLayouts.end())
return iter->_value;
@@ -206,7 +206,7 @@ bool TeLuaGUI::load(const Common::Path &path_) {
_luaContext.registerCFunction("TeRotationLinearAnimation", rotationLinearAnimationBindings);
_luaContext.registerCFunction("TeScrollingLayout", scrollingLayoutBindings);
_luaContext.registerCFunction("TeExtendedTextLayout", extendedTextLayoutBindings);
- _luaContext.setInRegistry("__TeLuaGUIThis",this);
+ _luaContext.setInRegistry("__TeLuaGUIThis", this);
_luaScript.attachToContext(&_luaContext);
_luaScript.load(path);
_luaScript.execute();
diff --git a/engines/tetraedge/te/te_lua_gui.h b/engines/tetraedge/te/te_lua_gui.h
index 54e272f57a9..d5eccc4efbf 100644
--- a/engines/tetraedge/te/te_lua_gui.h
+++ b/engines/tetraedge/te/te_lua_gui.h
@@ -33,6 +33,7 @@
#include "tetraedge/te/te_extended_text_layout.h"
#include "tetraedge/te/te_i_3d_object2.h"
#include "tetraedge/te/te_i_layout.h"
+#include "tetraedge/te/te_i_text_layout.h"
#include "tetraedge/te/te_layout.h"
#include "tetraedge/te/te_list_layout.h"
#include "tetraedge/te/te_lua_context.h"
@@ -64,12 +65,12 @@ public:
TeCurveAnim2<Te3DObject2, TeColor> *colorLinearAnimation(const Common::String &name);
TeExtendedTextLayout *extendedTextLayout(const Common::String &name);
TeCurveAnim2<TeLayout, TeVector3f32> *layoutAnchorLinearAnimation(const Common::String &name);
- TeCurveAnim2<TeI3DObject2, TeVector3f32> *layoutPositionLinearAnimation(const Common::String &name);
+ TeCurveAnim2<TeLayout, TeVector3f32> *layoutPositionLinearAnimation(const Common::String &name);
TeListLayout *listLayout(const Common::String &name);
TeCurveAnim2<TeI3DObject2, TeQuaternion> *rotationLinearAnimation(const Common::String &name);
TeScrollingLayout *scrollingLayout(const Common::String &name);
TeSpriteLayout *spriteLayout(const Common::String &name);
- TeTextLayout *textLayout(const Common::String &name);
+ TeITextLayout *textLayout(const Common::String &name);
// Same as the above functions, but call error() if the result is null.
TeLayout *layoutChecked(const Common::String &name);
@@ -94,7 +95,7 @@ public:
StringMap<TeClipLayout *> &clipLayouts() { return _clipLayouts; }
StringMap<TeExtendedTextLayout *> &extendedTextLayouts() { return _extendedTextLayouts; }
StringMap<TeCurveAnim2<TeLayout, TeVector3f32> *> &layoutAnchorLinearAnimations() { return _layoutAnchorLinearAnimations; }
- StringMap<TeCurveAnim2<TeI3DObject2, TeVector3f32> *> &layoutPositionLinearAnimations() { return _layoutPositionLinearAnimations; }
+ StringMap<TeCurveAnim2<TeLayout, TeVector3f32> *> &layoutPositionLinearAnimations() { return _layoutPositionLinearAnimations; }
StringMap<TeCurveAnim2<Te3DObject2, TeColor> *> &colorLinearAnimations() { return _colorLinearAnimations; }
bool loaded() const { return _loaded; }
@@ -119,7 +120,7 @@ private:
StringMap<TeClipLayout *> _clipLayouts;
StringMap<TeExtendedTextLayout *> _extendedTextLayouts;
StringMap<TeCurveAnim2<TeLayout, TeVector3f32> *> _layoutAnchorLinearAnimations;
- StringMap<TeCurveAnim2<TeI3DObject2, TeVector3f32> *> _layoutPositionLinearAnimations;
+ StringMap<TeCurveAnim2<TeLayout, TeVector3f32> *> _layoutPositionLinearAnimations;
StringMap<TeCurveAnim2<Te3DObject2, TeColor> *> _colorLinearAnimations;
};
diff --git a/engines/tetraedge/te/te_lua_gui_lua_callbacks.cpp b/engines/tetraedge/te/te_lua_gui_lua_callbacks.cpp
index c922904da83..84cc5a90c54 100644
--- a/engines/tetraedge/te/te_lua_gui_lua_callbacks.cpp
+++ b/engines/tetraedge/te/te_lua_gui_lua_callbacks.cpp
@@ -74,7 +74,7 @@ static float TeLuaToF32(lua_State *L, int index) {
}
}
-static bool TeLuaToBool(lua_State *L,int index) {
+static bool TeLuaToBool(lua_State *L, int index) {
if (lua_type(L, index) != LUA_TBOOLEAN) {
warning("TeLuaToBool:: not a bool");
return false;
@@ -107,7 +107,7 @@ static TeColor TeLuaToTeColor(lua_State *L, int index) {
lua_settop(L, -2);
lua_pushinteger(L, 3);
- lua_gettable(L,index);
+ lua_gettable(L, index);
if (lua_isnumber(L, -1)) {
retval.b() = TeLuaToU32(L, -1);
}
@@ -209,7 +209,7 @@ static bool loadCommonLayoutItems(lua_State *L, const char *s, TeLayout *layout)
}
-// TODO: Fix this.
+// TODO: Fix this widescreen flag
static bool _g_bWidescreen = false;
int layoutBindings(lua_State *L) {
@@ -229,7 +229,7 @@ int layoutBindings(lua_State *L) {
} else if (!strcmp(s, "consoleNoStretch")) {
warning("TODO: Handle _g_bWidescreen");
if (_g_bWidescreen) {
- layout->setScale(TeVector3f32(0.7500001f, 1.0f ,1.0f));
+ layout->setScale(TeVector3f32(0.7500001f, 1.0f, 1.0f));
}
} else {
warning("[TeLuaGUI.layoutBindings] Unreconized attribute : %s", s);
@@ -246,7 +246,7 @@ int layoutBindings(lua_State *L) {
}
lua_pushstring(L, "__TeLuaGUIThis");
lua_gettable(L, LUA_REGISTRYINDEX);
- TeLuaGUI *gui = TeLuaTo<TeLuaGUI*>(L,-1);
+ TeLuaGUI *gui = TeLuaTo<TeLuaGUI*>(L, -1);
TeLuaGUI::StringMap<TeLayout *> &layouts = gui->layouts();
if (!layouts.contains(layout->name())) {
layouts.setVal(layout->name(), layout);
@@ -289,7 +289,7 @@ int listLayoutBindings(lua_State *L) {
} else if (!strcmp(s, "consoleNoStretch")) {
warning("TODO: Handle _g_bWidescreen");
if (_g_bWidescreen) {
- layout->setScale(TeVector3f32(0.7500001f, 1.0f ,1.0f));
+ layout->setScale(TeVector3f32(0.7500001f, 1.0f, 1.0f));
}
} else {
warning("[TeLuaGUI.layoutBindings] Unreconized attribute : %s", s);
@@ -306,7 +306,7 @@ int listLayoutBindings(lua_State *L) {
}
lua_pushstring(L, "__TeLuaGUIThis");
lua_gettable(L, LUA_REGISTRYINDEX);
- TeLuaGUI *gui = TeLuaTo<TeLuaGUI*>(L,-1);
+ TeLuaGUI *gui = TeLuaTo<TeLuaGUI*>(L, -1);
TeLuaGUI::StringMap<TeListLayout *> &layouts = gui->listLayouts();
if (!layouts.contains(layout->name())) {
layouts.setVal(layout->name(), layout);
@@ -376,7 +376,7 @@ int spriteLayoutBindings(lua_State *L) {
} else if (!strcmp(s, "consoleNoStretch")) {
warning("TODO: Handle _g_bWidescreen");
if (_g_bWidescreen) {
- layout->setScale(TeVector3f32(0.7500001,1.0,1.0));
+ layout->setScale(TeVector3f32(0.7500001f, 1.0f, 1.0f));
}
} else {
warning("[TeLuaGUI.layoutBindings] Unreconized attribute : %s", s);
@@ -470,7 +470,7 @@ int buttonLayoutBindings(lua_State *L) {
} else if (!strcmp(s, "consoleNoStretch")) {
warning("TODO: Handle _g_bWidescreen");
if (_g_bWidescreen) {
- layout->setScale(TeVector3f32(0.7500001,1.0,1.0));
+ layout->setScale(TeVector3f32(0.7500001f, 1.0f, 1.0f));
}
} else {
warning("[TeLuaGUI.buttonLayoutBindings] Unreconized attribute : %s", s);
@@ -490,7 +490,7 @@ int buttonLayoutBindings(lua_State *L) {
lua_pushstring(L, "__TeLuaGUIThis");
lua_gettable(L, LUA_REGISTRYINDEX);
- TeLuaGUI *gui = TeLuaTo<TeLuaGUI*>(L,-1);
+ TeLuaGUI *gui = TeLuaTo<TeLuaGUI*>(L, -1);
TeLuaGUI::StringMap<TeButtonLayout *> &blayouts = gui->buttonLayouts();
if (!blayouts.contains(layout->name())) {
blayouts.setVal(layout->name(), layout);
@@ -540,7 +540,7 @@ int checkboxLayoutBindings(lua_State *L) {
} else if (!strcmp(s, "consoleNoStretch")) {
warning("TODO: Handle _g_bWidescreen");
if (_g_bWidescreen) {
- layout->setScale(TeVector3f32(0.7500001,1.0,1.0));
+ layout->setScale(TeVector3f32(0.7500001f, 1.0f, 1.0f));
}
} else {
warning("[TeLuaGUI.checkboxLayoutBindings] Unreconized attribute : %s", s);
@@ -560,7 +560,7 @@ int checkboxLayoutBindings(lua_State *L) {
lua_pushstring(L, "__TeLuaGUIThis");
lua_gettable(L, LUA_REGISTRYINDEX);
- TeLuaGUI *gui = TeLuaTo<TeLuaGUI*>(L,-1);
+ TeLuaGUI *gui = TeLuaTo<TeLuaGUI*>(L, -1);
TeLuaGUI::StringMap<TeCheckboxLayout *> &blayouts = gui->checkboxLayouts();
if (!blayouts.contains(layout->name())) {
blayouts.setVal(layout->name(), layout);
@@ -579,7 +579,53 @@ int layoutPositionLinearAnimationBindings(lua_State *L) {
return 0;
}
- error("TODO: Implement layoutPositionLinearAnimationBindings.");
+ TeCurveAnim2<TeLayout, TeVector3f32> *anim = new TeCurveAnim2<TeLayout, TeVector3f32>();
+ lua_pushnil(L);
+ Common::String name;
+ while (lua_next(L, -2) != 0) {
+ int type = lua_type(L, -2);
+ if (type == LUA_TSTRING) {
+ const char *s = lua_tolstring(L, -2, nullptr);
+ if (!strcmp(s, "name")) {
+ name = TeLuaToTeString(L, -1);
+ } else if (!strcmp(s, "duration")) {
+ anim->_duration = TeLuaToF32(L, -1);
+ } else if (!strcmp(s, "startValue")) {
+ static const TeVector3f32 defaultStart(0.0f, 0.0f, 0.0f);
+ anim->_startVal = TeLuaToTeVector3f32(L, -1, defaultStart);
+ } else if (!strcmp(s, "endValue")) {
+ static const TeVector3f32 defaultEnd(0.0f, 0.0f, 0.0f);
+ anim->_endVal = TeLuaToTeVector3f32(L, -1, defaultEnd);
+ } else if (!strcmp(s, "layout")) {
+ // skip.
+ } else if (!strcmp(s, "curve")) {
+ const Common::Array<float> curve = TeLuaToFloatArray(L, -1);
+ anim->setCurve(curve);
+ } else {
+ error("[TeLuaGUI.layoutPositionLinearAnimationBindings] Unreconized attribute : %s", s);
+ }
+ lua_settop(L, -2);
+ }
+ }
+
+ if (name.empty()) {
+ name = Common::String::format("%p", (void *)anim);
+ }
+ anim->_callbackMethod = &TeLayout::setPosition;
+ lua_pushstring(L, "__TeLuaGUIThis");
+ lua_gettable(L, LUA_REGISTRYINDEX);
+ TeLuaGUI *gui = TeLuaTo<TeLuaGUI*>(L, -1);
+ TeLuaGUI::StringMap<TeCurveAnim2<TeLayout, TeVector3f32> *> &anims = gui->layoutPositionLinearAnimations();
+ if (!anims.contains(name)) {
+ anims.setVal(name, anim);
+ lua_pushlightuserdata(L, (void *)(anim));
+ return true;
+ } else {
+ warning("layoutPositionLinearAnimationBindings:: multiple objects with name %s", name.c_str());
+ delete anim;
+ return false;
+ }
+ return true;
}
int layoutAnchorLinearAnimationBindings(lua_State *L) {
@@ -588,7 +634,7 @@ int layoutAnchorLinearAnimationBindings(lua_State *L) {
return 0;
}
- TeCurveAnim2<TeLayout,TeVector3f32> *anim = new TeCurveAnim2<TeLayout,TeVector3f32>();
+ TeCurveAnim2<TeLayout, TeVector3f32> *anim = new TeCurveAnim2<TeLayout, TeVector3f32>();
lua_pushnil(L);
Common::String name;
while (lua_next(L, -2) != 0) {
@@ -613,7 +659,7 @@ int layoutAnchorLinearAnimationBindings(lua_State *L) {
} else {
error("[TeLuaGUI.layoutAnchorLinearAnimationBindings] Unreconized attribute : %s", s);
}
- lua_settop(L,-2);
+ lua_settop(L, -2);
}
}
@@ -623,7 +669,7 @@ int layoutAnchorLinearAnimationBindings(lua_State *L) {
anim->_callbackMethod = &TeLayout::setAnchor;
lua_pushstring(L, "__TeLuaGUIThis");
lua_gettable(L, LUA_REGISTRYINDEX);
- TeLuaGUI *gui = TeLuaTo<TeLuaGUI*>(L,-1);
+ TeLuaGUI *gui = TeLuaTo<TeLuaGUI*>(L, -1);
TeLuaGUI::StringMap<TeCurveAnim2<TeLayout, TeVector3f32> *> &anims = gui->layoutAnchorLinearAnimations();
if (!anims.contains(name)) {
anims.setVal(name, anim);
@@ -664,7 +710,7 @@ int textLayoutBindings(lua_State *L) {
} else if (!strcmp(s, "consoleNoStretch")) {
warning("TODO: Handle _g_bWidescreen");
if (_g_bWidescreen) {
- layout->setScale(TeVector3f32(0.7500001,1.0,1.0));
+ layout->setScale(TeVector3f32(0.7500001f, 1.0f, 1.0f));
}
} else {
warning("[TeLuaGUI.textLayoutBindings] Unreconized attribute : %s", s);
@@ -682,7 +728,7 @@ int textLayoutBindings(lua_State *L) {
lua_pushstring(L, "__TeLuaGUIThis");
lua_gettable(L, LUA_REGISTRYINDEX);
- TeLuaGUI *gui = TeLuaTo<TeLuaGUI*>(L,-1);
+ TeLuaGUI *gui = TeLuaTo<TeLuaGUI*>(L, -1);
TeLuaGUI::StringMap<TeTextLayout *> &layouts = gui->textLayouts();
if (!layouts.contains(layout->name())) {
layouts.setVal(layout->name(), layout);
@@ -710,7 +756,7 @@ int colorLinearAnimationBindings(lua_State *L) {
return 0;
}
- TeCurveAnim2<Te3DObject2,TeColor> *anim = new TeCurveAnim2<Te3DObject2, TeColor>();
+ TeCurveAnim2<Te3DObject2, TeColor> *anim = new TeCurveAnim2<Te3DObject2, TeColor>();
lua_pushnil(L);
Common::String name;
while (lua_next(L, -2) != 0) {
@@ -732,7 +778,7 @@ int colorLinearAnimationBindings(lua_State *L) {
} else {
error("[TeLuaGUI.colorLinearAnimationBindings] Unreconized attribute : %s", s);
}
- lua_settop(L,-2);
+ lua_settop(L, -2);
}
}
@@ -742,7 +788,7 @@ int colorLinearAnimationBindings(lua_State *L) {
anim->_callbackMethod = &Te3DObject2::setColor;
lua_pushstring(L, "__TeLuaGUIThis");
lua_gettable(L, LUA_REGISTRYINDEX);
- TeLuaGUI *gui = TeLuaTo<TeLuaGUI*>(L,-1);
+ TeLuaGUI *gui = TeLuaTo<TeLuaGUI*>(L, -1);
TeLuaGUI::StringMap<TeCurveAnim2<Te3DObject2, TeColor> *> &anims = gui->colorLinearAnimations();
if (!anims.contains(name)) {
anims.setVal(name, anim);
@@ -782,7 +828,7 @@ int scrollingLayoutBindings(lua_State *L) {
} else if (!strcmp(s, "inertiaAnimationDuration")) {
layout->setInertiaAnimationDuration(TeLuaToU32(L, -1));
} else if (!strcmp(s, "inertiaAnimationCurve")) {
- layout->setInertiaAnimationCurve(TeLuaToFloatArray(L ,-1));
+ layout->setInertiaAnimationCurve(TeLuaToFloatArray(L, -1));
} else if (!strcmp(s, "direction")) {
TeVector3f32 newdir = TeLuaToTeVector3f32(L, -1, layout->direction());
layout->setDirection(newdir);
@@ -815,7 +861,7 @@ int scrollingLayoutBindings(lua_State *L) {
} else if (!strcmp(s, "consoleNoStretch")) {
warning("TODO: Handle _g_bWidescreen");
if (_g_bWidescreen) {
- layout->setScale(TeVector3f32(0.7500001,1.0,1.0));
+ layout->setScale(TeVector3f32(0.7500001f, 1.0f, 1.0f));
}
} else {
warning("[TeLuaGUI.scrollingLayoutBindings] Unreconized attribute : %s", s);
@@ -833,7 +879,7 @@ int scrollingLayoutBindings(lua_State *L) {
lua_pushstring(L, "__TeLuaGUIThis");
lua_gettable(L, LUA_REGISTRYINDEX);
- TeLuaGUI *gui = TeLuaTo<TeLuaGUI*>(L,-1);
+ TeLuaGUI *gui = TeLuaTo<TeLuaGUI*>(L, -1);
TeLuaGUI::StringMap<TeScrollingLayout *> &layouts = gui->scrollingLayouts();
if (!layouts.contains(layout->name())) {
layouts.setVal(layout->name(), layout);
@@ -869,7 +915,7 @@ int extendedTextLayoutBindings(lua_State *L) {
} else if (!strcmp(s, "autoScrollDelay")) {
layout->setAutoScrollDelay(TeLuaToS32(L, -1));
} else if (!strcmp(s, "autoScrollSpeed")) {
- layout->setAutoScrollSpeed(TeLuaToS32(L, -1));
+ layout->setAutoScrollSpeed(TeLuaToF32(L, -1));
} else if (!strcmp(s, "textSizeType")) {
layout->setTextSizeType(TeLuaToS32(L, -1));
} else if (!strcmp(s, "textSizeProportionalToWidth")) {
@@ -877,7 +923,7 @@ int extendedTextLayoutBindings(lua_State *L) {
} else if (!strcmp(s, "consoleNoStretch")) {
warning("TODO: Handle _g_bWidescreen");
if (_g_bWidescreen) {
- layout->setScale(TeVector3f32(0.7500001,1.0,1.0));
+ layout->setScale(TeVector3f32(0.7500001f, 1.0f, 1.0f));
}
} else {
warning("[TeLuaGUI.textLayoutBindings] Unreconized attribute : %s", s);
@@ -895,7 +941,7 @@ int extendedTextLayoutBindings(lua_State *L) {
lua_pushstring(L, "__TeLuaGUIThis");
lua_gettable(L, LUA_REGISTRYINDEX);
- TeLuaGUI *gui = TeLuaTo<TeLuaGUI*>(L,-1);
+ TeLuaGUI *gui = TeLuaTo<TeLuaGUI*>(L, -1);
TeLuaGUI::StringMap<TeExtendedTextLayout *> &layouts = gui->extendedTextLayouts();
if (!layouts.contains(layout->name())) {
layouts.setVal(layout->name(), layout);
diff --git a/engines/tetraedge/te/te_material.cpp b/engines/tetraedge/te/te_material.cpp
index 2f740f45ea4..af940165a7a 100644
--- a/engines/tetraedge/te/te_material.cpp
+++ b/engines/tetraedge/te/te_material.cpp
@@ -91,7 +91,7 @@ void TeMaterial::apply() const {
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_CONSTANT);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
} else {
- glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE, GL_MODULATE);
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
if (_mode != MaterialMode1) {
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER, 0.5);
diff --git a/engines/tetraedge/te/te_matrix4x4.cpp b/engines/tetraedge/te/te_matrix4x4.cpp
index db6440047a5..c9fe992bb65 100644
--- a/engines/tetraedge/te/te_matrix4x4.cpp
+++ b/engines/tetraedge/te/te_matrix4x4.cpp
@@ -151,7 +151,7 @@ TeVector3f32 TeMatrix4x4::operator*(const TeVector3f32 &mul) const {
const float *d = getData();
float w = d[3] * x + d[7] * y + d[11] * z + d[15];
if (w == 0.0)
- w = 1e-09;
+ w = 1e-09f;
return TeVector3f32
((d[0] * x + d[4] * y + d[8] * z + d[12]) / w,
diff --git a/engines/tetraedge/te/te_model_vertex_animation.cpp b/engines/tetraedge/te/te_model_vertex_animation.cpp
index 5b90be781c3..17479130bdc 100644
--- a/engines/tetraedge/te/te_model_vertex_animation.cpp
+++ b/engines/tetraedge/te/te_model_vertex_animation.cpp
@@ -25,7 +25,7 @@
namespace Tetraedge {
TeModelVertexAnimation::TeModelVertexAnimation() : _lastMillis(0.0f), _modelAnim(nullptr) {
- _rot.fromAxisAndAngle(TeVector3f32(0.0f, 1.0f, 0.0f), -M_PI_2);
+ _rot.fromAxisAndAngle(TeVector3f32(0.0f, 1.0f, 0.0f), (float)-M_PI_2);
}
void TeModelVertexAnimation::bind(TeIntrusivePtr<TeModel> &model) {
diff --git a/engines/tetraedge/te/te_music.cpp b/engines/tetraedge/te/te_music.cpp
index c7ba5010e9a..b3fbd96f681 100644
--- a/engines/tetraedge/te/te_music.cpp
+++ b/engines/tetraedge/te/te_music.cpp
@@ -148,11 +148,11 @@ byte TeMusic::currentData() {
return retval;
}
-/*
- This is probably not needed - it's the thread function
- which is handled by the mixer in ScummVM */
+
+// This is probably not needed - it's the thread function
+// which is handled by the mixer in ScummVM
void TeMusic::entry() {
- error("TODO: Implement me");
+ error("TODO: Implement TeMusic::entry");
}
bool TeMusic::isPlaying() {
diff --git a/engines/tetraedge/te/te_palette.cpp b/engines/tetraedge/te/te_palette.cpp
index 778608c4706..47b6816dd64 100644
--- a/engines/tetraedge/te/te_palette.cpp
+++ b/engines/tetraedge/te/te_palette.cpp
@@ -26,6 +26,4 @@ namespace Tetraedge {
TePalette::TePalette() {
}
-// TODO: Add more functions here.
-
} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_ray_intersection.cpp b/engines/tetraedge/te/te_ray_intersection.cpp
index 6fcdad15a17..fd645bf1c37 100644
--- a/engines/tetraedge/te/te_ray_intersection.cpp
+++ b/engines/tetraedge/te/te_ray_intersection.cpp
@@ -110,54 +110,6 @@ int intersect(const TeVector3f32 &rayPos, const TeVector3f32 &rayDir, const TeVe
}
*/
-/*
-bool testIntersection(const TeVector3f32 &v1, const TeVector3f32 &v2, const TeVector3f32 &v3, const TeVector3f32 &orig, TeVector3f32 &dir) {
- TeVector3f32 qvec,tvec;
-
- TeVector3f32 e1 = v2 - v1;
- TeVector3f32 e2 = v3 - v1;
-
- TeVector3f32 pvec = TeVector3f32::crossProduct(dir, e2);
-
- dir.normalize();
- float det = pvec.dotProduct(e1);
-//#ifdef TEST_CULL
- if (det < FLT_EPSILON)
- return false;
-
- tvec = orig - v1;
- float u = tvec.dotProduct(pvec);
- if (u < 0.0 || u > det) {
- return false;
- }
- CROSS(qvec,tvec,e1);
- float v = dir.dotProduct(qvec);
- if (v < 0.0f || v + u > det) {
- return false;
- }
-#else
- if (det < FLT_EPSILON && det > -FLT_EPSILON ) {
- return false;
- }
-
- float invDet = 1.0f / det;
- tvec = orig - v1;
- // NORMALIZE(tvec);
- float u = invDet * tvec.dotProduct(pvec);
- if (u <0.0f || u > 1.0f) {
- return false;
- }
-
- qvec = TeVector3f32::crossProduct(tvec, e1);
- float v = invDet * qvec.dotProduct(dir);
- if (v < 0.0f || u+v > 1.0f) {
- return false;
- }
-#endif
- return true;
-}
-*/
-
} // end namespace TeRayIntersection
} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_renderer.cpp b/engines/tetraedge/te/te_renderer.cpp
index 0ac997fbebe..518b8578e31 100644
--- a/engines/tetraedge/te/te_renderer.cpp
+++ b/engines/tetraedge/te/te_renderer.cpp
@@ -225,7 +225,7 @@ void TeRenderer::disableZBuffer() {
}
void TeRenderer::drawLine(const TeVector3f32 &from, const TeVector3f32 &to) {
- error("TODO: TeRenderer::drawLine Implement me.");
+ error("TODO: Implement TeRenderer::drawLine");
}
void TeRenderer::enableTexture() {
@@ -494,15 +494,15 @@ void TeRenderer::reset() {
}
void TeRenderer::rotate(const TeQuaternion &rot) {
- error("TODO: TeRenderer::rotate Implement me.");
+ _matriciesStacks[_matrixMode].rotate(rot);
}
-void TeRenderer::rotate(float f1, float f2, float f3, float f4) {
- error("TODO: TeRenderer::rotate Implement me.");
+void TeRenderer::rotate(float angle, float rx, float ry, float rz) {
+ _matriciesStacks[_matrixMode].rotate(angle, TeVector3f32(rx, ry, rz));
}
void TeRenderer::scale(float xs, float ys, float zs) {
- error("TODO: TeRenderer::scale Implement me.");
+ _matriciesStacks[_matrixMode].scale(TeVector3f32(xs, ys, zs));
}
void TeRenderer::setClearColor(const TeColor &col) {
@@ -564,7 +564,7 @@ void TeRenderer::shadowMode(enum ShadowMode mode) {
}
void TeRenderer::translate(float x, float y, float z) {
- error("TODO: TeRenderer::translate Implement me.");
+ _matriciesStacks[_matrixMode].translate(TeVector3f32(x, y, z));
}
Common::String TeRenderer::vendor() {
diff --git a/engines/tetraedge/te/te_renderer.h b/engines/tetraedge/te/te_renderer.h
index 03ccb7ed28b..61cb82a5904 100644
--- a/engines/tetraedge/te/te_renderer.h
+++ b/engines/tetraedge/te/te_renderer.h
@@ -95,7 +95,7 @@ public:
void renderTransparentMeshes();
void reset();
void rotate(const TeQuaternion &rot);
- void rotate(float f1, float f2, float f3, float f4);
+ void rotate(float angle, float rx, float ry, float rz);
void scale(float xs, float ys, float zs);
bool scissorEnabled() const { return _scissorEnabled; }
int scissorHeight() const { return _scissorHeight; }
diff --git a/engines/tetraedge/te/te_scrolling_layout.cpp b/engines/tetraedge/te/te_scrolling_layout.cpp
index 01522966b52..bd15fffc8a8 100644
--- a/engines/tetraedge/te/te_scrolling_layout.cpp
+++ b/engines/tetraedge/te/te_scrolling_layout.cpp
@@ -21,14 +21,54 @@
#include "tetraedge/te/te_scrolling_layout.h"
+#include "tetraedge/tetraedge.h"
+#include "tetraedge/te/te_input_mgr.h"
+
+#include "common/math.h"
+
namespace Tetraedge {
TeScrollingLayout::TeScrollingLayout() : _contentLayout(nullptr),
_enclose(true), _mouseControl(true), _autoScrollLoop(-1), _autoScrollDelay(1500),
_autoScrollAnimation1Enabled(true), _autoScrollAnimation2Enabled(true),
- _autoScrollAnimation1Speed(0.1), _autoScrollAnimation2Speed(0.1),
- _autoScrollAnimation1Delay(1000), _autoScrollAnimation2Delay(1000)
+ _autoScrollAnimation1Speed(0.1f), _autoScrollAnimation2Speed(0.1f),
+ _autoScrollAnimation1Delay(1000), _autoScrollAnimation2Delay(1000),
+ _currentScrollLoopNo(0), _inertiaAnimationDuration(500),
+ _mouseMoveThreshold(30.0), _insideMouseThreshold(true),
+ _direction(0.0, 1.0, 0.0)
{
+ setSizeType(RELATIVE_TO_PARENT);
+ setSize(TeVector3f32(1.0, 1.0, 1.0));
+ // TODO: original does addChild on something here.
+ // FIXME: This doesn't seem right...
+ //onWorldTransformationMatrixChanged().add(this, &TeScrollingLayout::onSlideButtonDown);
+ Common::Array<float> curve;
+ curve.push_back(0.0f);
+ curve.push_back(1.0f);
+ _autoScrollAnimation1Curve = curve;
+ _autoScrollAnimation2Curve = curve;
+ _autoScrollDelayTimer.alarmSignal().add(this, &TeScrollingLayout::onAutoScrollDelayTimer);
+ _autoScrollAnimation1Timer.alarmSignal().add(this, &TeScrollingLayout::onAutoScrollAnimation1DelayTimer);
+ _autoScrollAnimation2Timer.alarmSignal().add(this, &TeScrollingLayout::onAutoScrollAnimation2DelayTimer);
+ _autoScrollAnimation1.onFinished().add(this, &TeScrollingLayout::onAutoScrollAnimation1Finished);
+ _autoScrollAnimation2.onFinished().add(this, &TeScrollingLayout::onAutoScrollAnimation2Finished);
+ Common::Array<float> curve2;
+ curve2.push_back(0.0f);
+ curve2.push_back(0.35f);
+ curve2.push_back(0.68f);
+ curve2.push_back(0.85f);
+ curve2.push_back(0.93f);
+ curve2.push_back(0.97f);
+ curve2.push_back(1.0f);
+ _inertiaAnimationCurve = curve2;
+ _scrollTimer.start();
+ playAutoScroll();
+}
+
+TeScrollingLayout::~TeScrollingLayout() {
+ TeInputMgr *inputmgr = g_engine->getInputMgr();
+ inputmgr->_mouseMoveSignal.remove<TeScrollingLayout>(this, &TeScrollingLayout::onMouseMove);
+ inputmgr->_mouseLUpSignal.remove<TeScrollingLayout>(this, &TeScrollingLayout::onMouseLeftUp);
}
void TeScrollingLayout::setContentLayout(TeLayout *layout) {
@@ -43,16 +83,316 @@ void TeScrollingLayout::setContentLayout(TeLayout *layout) {
}
}
+void TeScrollingLayout::setSpeed(const TeVector3f32 &speed) {
+ _speed = speed;
+ TeVector3f32 newpos = scrollPosition() + _speed * (float)(_scrollTimer.timeElapsed() / 1000000.0);
+ setScrollPosition(newpos);
+}
+
+void TeScrollingLayout::setScrollPosition(const TeVector3f32 &scrPos) {
+ if (!_contentLayout)
+ return;
+
+ TeVector3f32 pos = scrPos;
+ pos.x() = CLIP(pos.x(), 0.0f, 1.0f);
+ pos.y() = CLIP(pos.y(), 0.0f, 1.0f);
+
+ const TeVector3f32 thisSize(xSize(), ySize(), 1.0);
+ const TeVector3f32 contentSize(_contentLayout->xSize(), _contentLayout->ySize(), 1.0);
+ TeVector3f32 sizeRatio;
+
+ if (thisSize.x() == 0.0 || thisSize.y() == 0.0) {
+ sizeRatio = TeVector3f32(1.0, 1.0, 1.0);
+ } else {
+ sizeRatio = contentSize / thisSize;
+ }
+
+ TeVector3f32 posToSet = _contentLayout->userPosition();
+ const TeVector3f32 contentAnchor = _contentLayout->anchor();
+ if (!_enclose) {
+ if (thisSize.x() < contentSize.x()) {
+ float offset = (sizeRatio.x() + 1.0) * pos.x();
+ posToSet.x() = contentAnchor.x() * sizeRatio.x() + (1.0 - offset);
+ }
+ if (thisSize.y() < contentSize.y()) {
+ float offset = (sizeRatio.y() + 1.0) * pos.y();
+ posToSet.y() = contentAnchor.y() * sizeRatio.y() + (1.0 - offset);
+ }
+ } else {
+ if (thisSize.x() < contentSize.x()) {
+ float offset = (sizeRatio.x() - 1.0) * pos.x();
+ posToSet.x() = contentAnchor.x() * sizeRatio.x() - offset;
+ }
+ if (thisSize.y() < contentSize.y()) {
+ float offset = (sizeRatio.y() - 1.0) * pos.y();
+ posToSet.y() = contentAnchor.y() * sizeRatio.y() - offset;
+ }
+ }
+
+ _contentLayout->setPosition(posToSet);
+ _posUpdatedSignal.call();
+}
+
+TeVector3f32 TeScrollingLayout::scrollPosition() {
+ if (!_contentLayout)
+ return TeVector3f32();
+
+ const TeVector3f32 thisSize(xSize(), ySize(), 1.0);
+ const TeVector3f32 contentSize(_contentLayout->xSize(), _contentLayout->ySize(), 1.0);
+
+ TeVector3f32 sizeRatio;
+ if (thisSize.x() == 0.0 || thisSize.y() == 0.0) {
+ sizeRatio = TeVector3f32(1.0, 1.0, 1.0);
+ } else {
+ sizeRatio = contentSize / thisSize;
+ }
+
+ TeVector3f32 result(0.0, 0.0, 0.0);
+ if (_enclose) {
+ TeVector3f32 contentAnchor = _contentLayout->anchor();
+ TeVector3f32 contentPos = _contentLayout->userPosition();
+ if (sizeRatio.x() > 1.0) {
+ result.x() = (-(int)(contentPos.x() - contentAnchor.x() * sizeRatio.x())) / (sizeRatio.x() - 1.0);
+ }
+ if (sizeRatio.y() > 1.0) {
+ result.y() = (-(int)(contentPos.y() - contentAnchor.y() * sizeRatio.y())) / (sizeRatio.y() - 1.0);
+ }
+ } else {
+ TeVector3f32 offsetPos = _contentLayout->position() - TeVector3f32(1.0, 1.0, 1.0);
+ result = ((_contentLayout->anchor() * sizeRatio) - offsetPos) / (sizeRatio + TeVector3f32(1.0, 1.0, 1.0));
+ }
+ return result;
+}
+
+bool TeScrollingLayout::onAutoScrollDelayTimer() {
+ _autoScrollDelayTimer.stop();
+ playAutoScrollAnimation1();
+ return false;
+}
+
+bool TeScrollingLayout::onAutoScrollAnimation1DelayTimer() {
+ _autoScrollAnimation1Timer.stop();
+ _autoScrollAnimation1.setCurve(_autoScrollAnimation1Curve);
+ const TeVector3f32 startPos = scrollPosition();
+ _autoScrollAnimation1._startVal = startPos;
+ TeVector3f32 endPos = startPos + TeVector3f32(1.0, 1.0, 0.0) * _direction;
+ endPos.x() = CLIP(endPos.x(), 0.0f, 1.0f);
+ endPos.y() = CLIP(endPos.y(), 0.0f, 1.0f);
+ _autoScrollAnimation1._endVal = endPos;
+
+ TeVector3f32 sizeRatio(1.0, 1.0, 0.0);
+ if (_contentLayout) {
+ sizeRatio = _contentLayout->userSize() / size();
+ }
+
+ float duration = 0.0;
+ if (_autoScrollAnimation1Speed != 0.0) {
+ const TeVector3f32 dist = endPos - startPos;
+ if (_enclose) {
+ sizeRatio = dist * (sizeRatio - TeVector3f32(1.0, 1.0, 0.0));
+ } else {
+ sizeRatio = dist * (sizeRatio + TeVector3f32(1.0, 1.0, 0.0));
+ }
+ duration = (sizeRatio * _direction).length() / (_autoScrollAnimation1Speed / 1000.0);
+ }
+
+ _autoScrollAnimation1._duration = duration;
+ _autoScrollAnimation1._callbackObj = this;
+ _autoScrollAnimation1._callbackMethod = &TeScrollingLayout::setScrollPosition;
+ _autoScrollAnimation1.play();
+ return false;
+}
+
+bool TeScrollingLayout::onAutoScrollAnimation2DelayTimer() {
+ _autoScrollAnimation2Timer.stop();
+ _autoScrollAnimation2.setCurve(_autoScrollAnimation2Curve);
+ const TeVector3f32 startPos = scrollPosition();
+ _autoScrollAnimation2._startVal = startPos;
+ // Note: this is the only real difference between this and the "1" version
+ // of the function.. - instead of +
+ TeVector3f32 endPos = startPos - TeVector3f32(1.0, 1.0, 0.0) * _direction;
+ endPos.x() = CLIP(endPos.x(), 0.0f, 1.0f);
+ endPos.y() = CLIP(endPos.y(), 0.0f, 1.0f);
+ _autoScrollAnimation2._endVal = endPos;
+
+ TeVector3f32 sizeRatio(1.0, 1.0, 0.0);
+ if (_contentLayout) {
+ sizeRatio = _contentLayout->size() / size();
+ }
+
+ float duration = 0.0;
+ if (_autoScrollAnimation2Speed != 0.0) {
+ const TeVector3f32 dist = endPos - startPos;
+ if (_enclose) {
+ sizeRatio = dist * (sizeRatio - TeVector3f32(1.0, 1.0, 0.0));
+ } else {
+ sizeRatio = dist * (sizeRatio + TeVector3f32(1.0, 1.0, 0.0));
+ }
+ duration = (sizeRatio * _direction).length() / (_autoScrollAnimation2Speed / 1000.0);
+ }
+
+ _autoScrollAnimation2._duration = duration;
+ _autoScrollAnimation2._callbackObj = this;
+ _autoScrollAnimation2._callbackMethod = &TeScrollingLayout::setScrollPosition;
+ _autoScrollAnimation2.play();
+ return false;
+}
+
+bool TeScrollingLayout::onAutoScrollAnimation1Finished() {
+ playAutoScrollAnimation2();
+ return false;
+}
+
+bool TeScrollingLayout::onAutoScrollAnimation2Finished() {
+ _currentScrollLoopNo++;
+ playAutoScrollAnimation1();
+ return false;
+}
+
+bool TeScrollingLayout::onMouseMove(const Common::Point &pt) {
+ _inertiaAnimation.stop();
+ const TeVector3f32 scrollPos = scrollPosition();
+ TeVector3f32 offset;
+ TeInputMgr *inputmgr = g_engine->getInputMgr();
+ if (_contentLayout) {
+ const TeVector3f32 thisUserSz = userSize();
+ const TeVector3f32 contentUserSz = _contentLayout->userSize();
+ if (contentUserSz.y() <= thisUserSz.y())
+ return false;
+
+ const TeVector2s32 lastMouse = inputmgr->lastMousePos();
+ if (!_enclose) {
+ offset.x() = (-(int)(_direction.x() * (lastMouse._x - _slideDownMousePos._x))) /
+ (xSize() + _contentLayout->xSize());
+ offset.y() = ((lastMouse._y - _slideDownMousePos._y) * _direction.y()) / (ySize() + _contentLayout->ySize());
+ } else {
+ float xdiff = xSize() - _contentLayout->xSize();
+ if (xdiff)
+ offset.x() = (-(int)(_direction.x() * (lastMouse._x - _slideDownMousePos._x))) / xdiff;
+ float ydiff = ySize() - _contentLayout->ySize();
+ if (ydiff)
+ offset.y() = ((lastMouse._y - _slideDownMousePos._y) * _direction.y()) / ydiff;
+ }
+ }
+
+ setScrollPosition(scrollPos + offset);
+ _slideDownMousePos = inputmgr->lastMousePos();
+ TeVector3f32 nowMousePos(inputmgr->lastMousePos());
+ _insideMouseThreshold = (_lastMouseDownPos - nowMousePos).length() <= _mouseMoveThreshold;
+ long elapsed = _scrollTimer.timeElapsed();
+ if (elapsed > 0) {
+ _speed = offset / (float)(elapsed / 1000000.0);
+ }
+ return false;
+}
+
+bool TeScrollingLayout::onMouseLeftUp(const Common::Point &pt) {
+ _inertiaAnimation.stop();
+ if (_contentLayout) {
+ _inertiaAnimation.setCurve(_inertiaAnimationCurve);
+ _inertiaAnimation._duration = _inertiaAnimationDuration;
+ _inertiaAnimation._startVal = _speed;
+ _inertiaAnimation._endVal = TeVector3f32(0.0, 0.0, 0.0);
+ _inertiaAnimation._callbackObj = this;
+ _inertiaAnimation._callbackMethod = &TeScrollingLayout::setSpeed;
+ _inertiaAnimation.play();
+ }
+
+ TeInputMgr *inputmgr = g_engine->getInputMgr();
+ inputmgr->_mouseMoveSignal.remove<TeScrollingLayout>(this, &TeScrollingLayout::onMouseMove);
+ inputmgr->_mouseLUpSignal.remove<TeScrollingLayout>(this, &TeScrollingLayout::onMouseLeftUp);
+
+ if (_autoScrollLoop == -1 || _currentScrollLoopNo < _autoScrollLoop) {
+ _autoScrollDelayTimer.start();
+ _autoScrollDelayTimer.setAlarmIn(_autoScrollDelay * 1000);
+ }
+ return false;
+}
+
+bool TeScrollingLayout::onSlideButtonDown() {
+ _currentScrollLoopNo = 0;
+ _inertiaAnimation.stop();
+ _autoScrollDelayTimer.stop();
+ _autoScrollAnimation1Timer.stop();
+ _autoScrollAnimation2Timer.stop();
+ _autoScrollAnimation1.stop();
+ _autoScrollAnimation2.stop();
+
+ _slideDownMousePos = g_engine->getInputMgr()->lastMousePos();
+
+ _lastMouseDownPos = TeVector3f32(_slideDownMousePos);
+ _insideMouseThreshold = true;
+
+ TeInputMgr *inputmgr = g_engine->getInputMgr();
+
+ Common::SharedPtr<TeCallback1Param<TeScrollingLayout, const Common::Point &>> callback;
+
+ inputmgr->_mouseMoveSignal.remove(this, &TeScrollingLayout::onMouseMove);
+ callback.reset(new TeCallback1Param<TeScrollingLayout, const Common::Point &>(
+ this, &TeScrollingLayout::onMouseMove, FLT_MAX));
+ inputmgr->_mouseMoveSignal.push_back(callback);
+
+ inputmgr->_mouseLUpSignal.remove(this, &TeScrollingLayout::onMouseLeftUp);
+ callback.reset(new TeCallback1Param<TeScrollingLayout, const Common::Point &>(
+ this, &TeScrollingLayout::onMouseLeftUp, FLT_MAX));
+ inputmgr->_mouseLUpSignal.push_back(callback);
+ return false;
+}
+
+void TeScrollingLayout::playAutoScrollAnimation1() {
+ if (!_autoScrollAnimation1Enabled) {
+ playAutoScrollAnimation2();
+ return;
+ }
+
+ if (_autoScrollLoop != -1 && _currentScrollLoopNo >= _autoScrollLoop)
+ return;
+
+ _autoScrollAnimation1Timer.start();
+ _autoScrollAnimation1Timer.setAlarmIn(_autoScrollAnimation1Delay * 1000);
+ return;
+}
+
+void TeScrollingLayout::playAutoScrollAnimation2() {
+ if (!_autoScrollAnimation2Enabled) {
+ _currentScrollLoopNo++;
+ playAutoScrollAnimation1();
+ return;
+ }
+
+ if (_autoScrollLoop != -1 && _currentScrollLoopNo >= _autoScrollLoop)
+ return;
+
+ _autoScrollAnimation2Timer.start();
+ _autoScrollAnimation2Timer.setAlarmIn(_autoScrollAnimation2Delay * 1000);
+}
+
void TeScrollingLayout::resetScrollPosition() {
if (!_contentLayout)
return;
- warning("TODO: Implement TeScrollingLayout::resetScrollPosition");
+
+ _inertiaAnimation.stop();
+ _autoScrollDelayTimer.stop();
+ _autoScrollAnimation1Timer.stop();
+ _autoScrollAnimation2Timer.stop();
+ _autoScrollAnimation1.stop();
+ _autoScrollAnimation2.stop();
+ _contentLayout->setPosition(_contentLayoutUserPos);
+ _posUpdatedSignal.call();
}
void TeScrollingLayout::playAutoScroll() {
- warning("TODO: Implement TeScrollingLayout::playAutoScroll");
+ _currentScrollLoopNo = 0;
+ if (_autoScrollLoop < 1 && _autoScrollLoop != -1)
+ return;
+ _inertiaAnimation.stop();
+ _autoScrollDelayTimer.stop();
+ _autoScrollAnimation1Timer.stop();
+ _autoScrollAnimation2Timer.stop();
+ _autoScrollAnimation1.stop();
+ _autoScrollAnimation2.stop();
+ _autoScrollDelayTimer.start();
+ _autoScrollDelayTimer.setAlarmIn(_autoScrollDelay * 1000);
}
-// TODO: Add more functions here.
-
} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_scrolling_layout.h b/engines/tetraedge/te/te_scrolling_layout.h
index ba64168cf57..528019bf8c4 100644
--- a/engines/tetraedge/te/te_scrolling_layout.h
+++ b/engines/tetraedge/te/te_scrolling_layout.h
@@ -22,13 +22,18 @@
#ifndef TETRAEDGE_TE_TE_SCROLLING_LAYOUT_H
#define TETRAEDGE_TE_TE_SCROLLING_LAYOUT_H
+#include "tetraedge/te/te_animation.h"
+#include "tetraedge/te/te_curve_anim2.h"
#include "tetraedge/te/te_layout.h"
+#include "tetraedge/te/te_timer.h"
+#include "tetraedge/te/te_signal.h"
namespace Tetraedge {
class TeScrollingLayout : public TeLayout {
public:
TeScrollingLayout();
+ virtual ~TeScrollingLayout();
void setInertiaAnimationDuration(int duration) {
_inertiaAnimationDuration = duration;
@@ -79,28 +84,64 @@ public:
_enclose = val;
}
void setContentLayout(TeLayout *layout);
+ void setSpeed(const TeVector3f32 &speed);
+
+ bool onAutoScrollDelayTimer();
+ bool onAutoScrollAnimation1DelayTimer();
+ bool onAutoScrollAnimation2DelayTimer();
+ bool onAutoScrollAnimation1Finished();
+ bool onAutoScrollAnimation2Finished();
+ bool onMouseMove(const Common::Point &pt);
+ bool onSlideButtonDown();
+ bool onMouseLeftUp(const Common::Point &pt);
+
+ void playAutoScrollAnimation1();
+ void playAutoScrollAnimation2();
void resetScrollPosition();
void playAutoScroll();
+ TeVector3f32 scrollPosition();
+ void setScrollPosition(const TeVector3f32 &newpos);
private:
int _inertiaAnimationDuration;
Common::Array<float> _inertiaAnimationCurve;
- uint _autoScrollDelay;
+ TeCurveAnim2<TeScrollingLayout, TeVector3f32> _inertiaAnimation;
+
int _autoScrollLoop;
+ int _currentScrollLoopNo;
+
+ uint _autoScrollDelay;
+ TeTimer _autoScrollDelayTimer;
+
float _autoScrollAnimation1Speed;
float _autoScrollAnimation2Speed;
bool _autoScrollAnimation1Enabled;
bool _autoScrollAnimation2Enabled;
int _autoScrollAnimation1Delay;
int _autoScrollAnimation2Delay;
+ TeTimer _autoScrollAnimation1Timer;
+ TeTimer _autoScrollAnimation2Timer;
Common::Array<float> _autoScrollAnimation1Curve;
Common::Array<float> _autoScrollAnimation2Curve;
+ TeCurveAnim2<TeScrollingLayout, TeVector3f32> _autoScrollAnimation1;
+ TeCurveAnim2<TeScrollingLayout, TeVector3f32> _autoScrollAnimation2;
+
TeVector3f32 _direction;
+ TeVector3f32 _speed;
+ TeTimer _scrollTimer;
bool _mouseControl;
bool _enclose;
TeLayout *_contentLayout;
TeVector3f32 _contentLayoutUserPos;
+
+ TeVector2s32 _slideDownMousePos;
+ float _mouseMoveThreshold;
+
+ TeVector3f32 _lastMouseDownPos;
+ bool _insideMouseThreshold;
+
+ TeSignal0Param _posUpdatedSignal;
};
} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_sprite_layout.cpp b/engines/tetraedge/te/te_sprite_layout.cpp
index 29819cf05cd..b3f30780fa1 100644
--- a/engines/tetraedge/te/te_sprite_layout.cpp
+++ b/engines/tetraedge/te/te_sprite_layout.cpp
@@ -29,11 +29,10 @@ namespace Tetraedge {
TeSpriteLayout::TeSpriteLayout() : _tiledSurfacePtr(new TeTiledSurface()), _sizeSet(false) {
_tiledSurfacePtr->setColor(TeColor(255, 255, 255, 255));
//_tiledSurfacePtr->_shouldDraw = true // should already be true..
- // TODO: set some other flag in _tiledSurfacePtr?
+
updateMesh();
}
-
int TeSpriteLayout::bufferSize() {
return _tiledSurfacePtr->bufferSize();
}
diff --git a/engines/tetraedge/te/te_text_base2.cpp b/engines/tetraedge/te/te_text_base2.cpp
index deefe76c733..b78c8721d1a 100644
--- a/engines/tetraedge/te/te_text_base2.cpp
+++ b/engines/tetraedge/te/te_text_base2.cpp
@@ -55,10 +55,20 @@ void TeTextBase2::build() {
_size = TeVector2s32(0, 0);
_wrappedLines.clear();
- if (_text.find(' ') != Common::String::npos)
- font->wordWrapText(_text, _fontSize, _drawRect._x, _wrappedLines);
- else
- _wrappedLines.push_back(_text);
+ Common::Array<uint32> endPts = _lineBreaks;
+ uint32 npos = Common::String::npos;
+ endPts.push_back(npos);
+ uint32 start = 0;
+ for (uint32 end : endPts) {
+ Common::Array<Common::String> lines;
+ Common::String txt = _text.substr(start, end - start);
+ if (txt.find(' ') != Common::String::npos)
+ font->wordWrapText(txt, _fontSize, _drawRect._x, lines);
+ else
+ lines.push_back(txt);
+ _wrappedLines.push_back(lines);
+ start = end;
+ }
Common::Array<float> lineoffsets;
float lineHeight = font->getHeight(_fontSize);
@@ -95,7 +105,7 @@ void TeTextBase2::build() {
#if DUMP_RENDERED_FONTS
Common::DumpFile dumpFile;
- dumpFile.open(Common::String::format("/Users/stauff/tmp/%04d.png", dumpCount));
+ dumpFile.open(Common::String::format("/tmp/rendered-font-dump-%04d.png", dumpCount));
dumpCount++;
Image::writePNG(dumpFile, img);
#endif
@@ -125,7 +135,7 @@ void TeTextBase2::build() {
_mesh.setIndex(1, 1);
_mesh.setIndex(2, 3);
_mesh.setIndex(3, 2);
- //_mesh.setHasAlpha(true);
+ _mesh.setHasAlpha(true);
}
void TeTextBase2::clear() {
diff --git a/engines/tetraedge/te/te_text_base2.h b/engines/tetraedge/te/te_text_base2.h
index fe92f0bac4b..3033669b7ff 100644
--- a/engines/tetraedge/te/te_text_base2.h
+++ b/engines/tetraedge/te/te_text_base2.h
@@ -98,7 +98,7 @@ private:
Common::Array<Common::String> _wrappedLines;
- Common::Array<unsigned int> _lineBreaks;
+ Common::Array<uint32> _lineBreaks;
Common::HashMap<unsigned int, TeColor> _colors;
Common::HashMap<unsigned int, TeIntrusivePtr<TeFont3>> _fonts;
};
diff --git a/engines/tetraedge/te/te_text_layout.cpp b/engines/tetraedge/te/te_text_layout.cpp
index 77750a593cd..b448b96144f 100644
--- a/engines/tetraedge/te/te_text_layout.cpp
+++ b/engines/tetraedge/te/te_text_layout.cpp
@@ -71,6 +71,7 @@ static TeFont3::AlignStyle _alignNameToEnum(const Common::String &name) {
void TeTextLayout::setText(const Common::String &val) {
if (!val.size()) {
clear();
+ _sizeChanged = true;
return;
}
@@ -89,6 +90,16 @@ void TeTextLayout::setText(const Common::String &val) {
bstart = replaced.find("$(", bstart + 1);
}
+ //
+ // WORKAROUND: The Syberia credits xml has an unmatched "</t>" at the end..
+ // just delete it.
+ //
+ // Note there is another workaround for the credits xml in the parser.
+ //
+ size_t tagstart = replaced.find("</t>");
+ if (tagstart != Common::String::npos)
+ replaced.replace(tagstart, 4, " ");
+
const Common::String xmlDocStr = Common::String::format("<?xml version=\"1.0\" encoding=\"UTF-8\"?><document>%s</document>", replaced.c_str());
TeTextLayoutXmlParser parser;
@@ -116,6 +127,7 @@ void TeTextLayout::setText(const Common::String &val) {
_base.setAlignStyle(_alignNameToEnum(parser.style()));
for (unsigned int offset : parser.lineBreaks())
_base.insertNewLine(offset);
+ _sizeChanged = true;
}
void TeTextLayout::setTextSizeType(int type) {
@@ -158,15 +170,15 @@ void TeTextLayout::updateSize() {
TeLayout::updateSize();
- TeMatrix4x4 transform = worldTransformationMatrix();
+ const TeMatrix4x4 transform = worldTransformationMatrix();
const TeVector3f32 v1 = transform * TeVector3f32(0, 0, 0);
const TeVector3f32 v2 = transform * TeVector3f32(1, 0, 0);
const TeVector3f32 v3 = transform * TeVector3f32(0, 1, 0);
- const TeVector3f32 newSize((v2 - v1).length(), (v3 - v1).length(), 1.0);
+ const TeVector3f32 transformVec((v2 - v1).length(), (v3 - v1).length(), 1.0);
const TeVector3f32 thisSize = size();
- const TeVector3f32 textSize = thisSize * newSize;
+ const TeVector3f32 textSize = thisSize * transformVec;
const TeVector2s32 textSizeI(textSize.x(), textSize.y());
_base.setRect(textSizeI);
@@ -177,15 +189,29 @@ void TeTextLayout::updateSize() {
newFontSize = (thisSize.x() / _textSizeProportionalToWidth) * _baseFontSize;
}
- newFontSize *= newSize.y();
+ newFontSize *= transformVec.y();
_base.setFontSize(newFontSize);
_base.build();
- //TeVector2s32 renderedSize = _base.size();
- /*const TeVector3f32 thisUserSize = */TeLayout::userSize();
+ TeVector3f32 userSz = userSize();
+ const TeVector2s32 baseSz = _base.size();
+
+ if (sizeType() == RELATIVE_TO_PARENT && parent()) {
+ if (wrapMode() != TeTextBase2::WrapModeFixed) {
+ if (parent()->xSize() != 0.0)
+ userSz.x() = ((float)baseSz._x / transformVec.y()) / parent()->xSize();
+ }
+ if (parent()->ySize() != 0.0)
+ userSz.y() = ((float)baseSz._y / transformVec.y()) / parent()->ySize();
+ } else if (sizeType() == ABSOLUTE) {
+ if (wrapMode() != TeTextBase2::WrapModeFixed) {
+ userSz.x() = baseSz._x / transformVec.y();
+ }
+ userSz.y() = baseSz._y / transformVec.y();
+ }
- //warning("TODO: finish the last bit of TeTextLayout::updateSize");
+ setSize(userSz);
}
} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_text_layout.h b/engines/tetraedge/te/te_text_layout.h
index d889f0d8d63..0992dbc7676 100644
--- a/engines/tetraedge/te/te_text_layout.h
+++ b/engines/tetraedge/te/te_text_layout.h
@@ -23,11 +23,12 @@
#define TETRAEDGE_TE_TE_TEXT_LAYOUT_H
#include "tetraedge/te/te_layout.h"
+#include "tetraedge/te/te_i_text_layout.h"
#include "tetraedge/te/te_text_base2.h"
namespace Tetraedge {
-class TeTextLayout : public TeLayout {
+class TeTextLayout : public TeITextLayout {
public:
TeTextLayout();
@@ -38,11 +39,11 @@ public:
}
void draw() override;
- void setText(const Common::String &val);
- void setInterLine(float val);
- void setWrapMode(TeTextBase2::WrapMode mode);
- void setTextSizeType(int type);
- void setTextSizeProportionalToWidth(int val);
+ void setText(const Common::String &val) override;
+ void setInterLine(float val) override;
+ void setWrapMode(TeTextBase2::WrapMode mode) override;
+ void setTextSizeType(int type) override;
+ void setTextSizeProportionalToWidth(int val) override;
void strikethrough(bool val);
bool strikethrough() const;
const Common::String &text() const;
diff --git a/engines/tetraedge/te/te_text_layout_xml_parser.cpp b/engines/tetraedge/te/te_text_layout_xml_parser.cpp
index f71b05f5152..cc3d11cb591 100644
--- a/engines/tetraedge/te/te_text_layout_xml_parser.cpp
+++ b/engines/tetraedge/te/te_text_layout_xml_parser.cpp
@@ -52,4 +52,13 @@ bool TeTextLayoutXmlParser::parserCallback_br(ParserNode *node) {
return true;
}
+bool TeTextLayoutXmlParser::parserCallback_b(ParserNode *node) {
+ //
+ // WORKAROUND: There is a <b /> in the The Syberia credits text xml.
+ // It's almost certainly a typo for <br />, bold fonts are not supported.
+ //
+ _lineBreaks.push_back(_textContent.size());
+ return true;
+}
+
} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_text_layout_xml_parser.h b/engines/tetraedge/te/te_text_layout_xml_parser.h
index 4bab07863b6..c913b0c92cd 100644
--- a/engines/tetraedge/te/te_text_layout_xml_parser.h
+++ b/engines/tetraedge/te/te_text_layout_xml_parser.h
@@ -49,6 +49,8 @@ public:
KEY_END()
XML_KEY(br)
KEY_END()
+ XML_KEY(b)
+ KEY_END()
KEY_END()
} PARSER_END()
@@ -59,6 +61,7 @@ private:
bool parserCallback_color(ParserNode *node);
bool parserCallback_font(ParserNode *node);
bool parserCallback_br(ParserNode *node);
+ bool parserCallback_b(ParserNode *node);
virtual bool textCallback(const Common::String &str) override;
diff --git a/engines/tetraedge/te/te_theora.cpp b/engines/tetraedge/te/te_theora.cpp
index 47c9b985e79..a8cbbffa42e 100644
--- a/engines/tetraedge/te/te_theora.cpp
+++ b/engines/tetraedge/te/te_theora.cpp
@@ -99,8 +99,11 @@ float TeTheora::frameRate() {
bool TeTheora::update(unsigned long i, TeImage &imgout) {
// TODO: Should this seek to frame i? Currently just continues.
- const Graphics::Surface *frame = _decoder->decodeNextFrame();
- if (frame) {
+ const Graphics::Surface *frame = nullptr;
+ while (_decoder->getCurFrame() < (int)i && !_decoder->endOfVideo())
+ frame = _decoder->decodeNextFrame();
+
+ if (frame && frame->getPixels()) {
//debug("TeTheora: %s %ld", _path.toString().c_str(), i);
imgout.copyFrom(*frame);
return true;
diff --git a/engines/tetraedge/te/te_tiled_surface.cpp b/engines/tetraedge/te/te_tiled_surface.cpp
index f2c123fe550..6c7554f1f7f 100644
--- a/engines/tetraedge/te/te_tiled_surface.cpp
+++ b/engines/tetraedge/te/te_tiled_surface.cpp
@@ -25,9 +25,15 @@
#include "tetraedge/te/te_frame_anim.h"
#include "tetraedge/te/te_resource_manager.h"
+//#define DUMP_LOADED_IMAGES 1
+
+#ifdef DUMP_LOADED_IMAGES
+#include "image/png.h"
+#endif
+
namespace Tetraedge {
-static void getRangeIntersection(float start1,float end1,float start2,float end2,float *pstart,float *pend) {
+static void getRangeIntersection(float start1, float end1, float start2, float end2, float *pstart, float *pend) {
*pstart = MAX(start1, start2);
*pend = MIN(end1, end2);
}
@@ -61,8 +67,6 @@ bool TeTiledSurface::load(const Common::Path &path) {
_path = path;
TeIntrusivePtr<TeTiledTexture> texture;
- if (path.toString() == "menus/inGame/Inventory.png")
- debug("loading inventory from path");
if (resmgr->exists(path.append(".tt"))) {
texture = resmgr->getResourceNoSearch<TeTiledTexture>(path.append(".tt"));
// we don't own this one..
@@ -102,6 +106,13 @@ bool TeTiledSurface::load(const Common::Path &path) {
img.create(_codec->width(), _codec->height(), nullpal, _imgFormat, bufx, bufy);
if (_codec->update(0, img)) {
+#if DUMP_LOADED_IMAGES
+ static int dumpCount = 0;
+ Common::DumpFile dumpFile;
+ dumpFile.open(Common::String::format("/tmp/dump-tiledsurf-%s-%04d.png", name().c_str(), dumpCount));
+ dumpCount++;
+ Image::writePNG(dumpFile, img);
+#endif
texture->load(img);
}
} else {
@@ -114,7 +125,7 @@ bool TeTiledSurface::load(const Common::Path &path) {
}
bool TeTiledSurface::load(const TeImage &image) {
- error("TODO: Implement me TeTiledSurface::load(image)");
+ error("TODO: Implement TeTiledSurface::load(image)");
}
bool TeTiledSurface::load(const TeIntrusivePtr<Te3DTexture> &texture) {
@@ -124,8 +135,6 @@ bool TeTiledSurface::load(const TeIntrusivePtr<Te3DTexture> &texture) {
TeIntrusivePtr<TeTiledTexture> tiledTexture;
const Common::Path ttPath = texture->getAccessName().append(".tt");
- if (ttPath.toString() == "menus/inGame/Inventory.png.tt")
- debug("loading inventory from texture");
if (resmgr->exists(ttPath)) {
tiledTexture = resmgr->getResourceNoSearch<TeTiledTexture>(ttPath);
diff --git a/engines/tetraedge/te/te_visual_fade.h b/engines/tetraedge/te/te_visual_fade.h
index 307c2d95983..6a9f363b610 100644
--- a/engines/tetraedge/te/te_visual_fade.h
+++ b/engines/tetraedge/te/te_visual_fade.h
@@ -50,6 +50,8 @@ public:
TeCurveAnim2<Te3DObject2, TeColor> blackFadeCurveAnim() { return _blackFadeCurveAnim; }
+ TeIntrusivePtr<Te3DTexture> texture() { return _texturePtr; }
+
private:
TeIntrusivePtr<Te3DTexture> _texturePtr;
diff --git a/engines/tetraedge/tetraedge.cpp b/engines/tetraedge/tetraedge.cpp
index 811384ffa42..5b8276b160f 100644
--- a/engines/tetraedge/tetraedge.cpp
+++ b/engines/tetraedge/tetraedge.cpp
@@ -223,4 +223,10 @@ void TetraedgeEngine::openConfigDialog() {
syncSoundSettings();
}
+/*static*/
+void TetraedgeEngine::getSavegameThumbnail(Graphics::Surface &thumb) {
+ g_engine->getApplication()->getSavegameThumbnail(thumb);
+}
+
+
} // namespace Tetraedge
diff --git a/engines/tetraedge/tetraedge.h b/engines/tetraedge/tetraedge.h
index f942697df21..0e2c6de5ab0 100644
--- a/engines/tetraedge/tetraedge.h
+++ b/engines/tetraedge/tetraedge.h
@@ -106,6 +106,8 @@ public:
Common::Serializer s(nullptr, stream);
return syncGame(s);
}
+
+ static void getSavegameThumbnail(Graphics::Surface &thumb);
Common::Error loadGameState(int slot) override;
Common::Error loadGameStream(Common::SeekableReadStream *stream) override;
diff --git a/engines/tetraedge/to_lua.cpp b/engines/tetraedge/to_lua.cpp
index ffc930156a2..a8b57973000 100644
--- a/engines/tetraedge/to_lua.cpp
+++ b/engines/tetraedge/to_lua.cpp
@@ -28,6 +28,8 @@ namespace Tetraedge {
namespace ToLua {
+// Also see the tolua copyright notice in to_lua.h.
+
static char toluaname[128] = "tolua.";
static void tolua_push_globals_table(lua_State *L) {
@@ -41,76 +43,76 @@ static void tolua_push_globals_table(lua_State *L) {
}
static int class_index_event(lua_State *L) {
- error ("TODO: Implement ToLua::class_index_event");
+ error("TODO: Implement ToLua::class_index_event");
}
static int class_newindex_event(lua_State *L) {
- error ("TODO: Implement ToLua::class_newindex_event");
+ error("TODO: Implement ToLua::class_newindex_event");
}
static int class_add_event(lua_State *L) {
- error ("TODO: Implement ToLua::class_add_event");
+ error("TODO: Implement ToLua::class_add_event");
}
static int class_sub_event(lua_State *L) {
- error ("TODO: Implement ToLua::class_sub_event");
+ error("TODO: Implement ToLua::class_sub_event");
}
static int class_mul_event(lua_State *L) {
- error ("TODO: Implement ToLua::class_mul_event");
+ error("TODO: Implement ToLua::class_mul_event");
}
static int class_div_event(lua_State *L) {
- error ("TODO: Implement ToLua::class_div_event");
+ error("TODO: Implement ToLua::class_div_event");
}
static int class_lt_event(lua_State *L) {
- error ("TODO: Implement ToLua::class_lt_event");
+ error("TODO: Implement ToLua::class_lt_event");
}
static int class_le_event(lua_State *L) {
- error ("TODO: Implement ToLua::class_le_event");
+ error("TODO: Implement ToLua::class_le_event");
}
static int class_eq_event(lua_State *L) {
- error ("TODO: Implement ToLua::class_eq_event");
+ error("TODO: Implement ToLua::class_eq_event");
}
static int class_gc_event(lua_State *L) {
- error ("TODO: Implement ToLua::class_gc_event");
+ error("TODO: Implement ToLua::class_gc_event");
}
static void tolua_classevents(lua_State *L) {
- lua_pushstring(L,"__index");
- lua_pushcclosure(L,class_index_event,0);
- lua_rawset(L,-3);
- lua_pushstring(L,"__newindex");
- lua_pushcclosure(L,class_newindex_event,0);
- lua_rawset(L,-3);
- lua_pushstring(L,"__add");
- lua_pushcclosure(L,class_add_event,0);
- lua_rawset(L,-3);
- lua_pushstring(L,"__sub");
- lua_pushcclosure(L,class_sub_event,0);
- lua_rawset(L,-3);
- lua_pushstring(L,"__mul");
- lua_pushcclosure(L,class_mul_event,0);
- lua_rawset(L,-3);
- lua_pushstring(L,"__div");
- lua_pushcclosure(L,class_div_event,0);
- lua_rawset(L,-3);
- lua_pushstring(L,"__lt");
- lua_pushcclosure(L,class_lt_event,0);
- lua_rawset(L,-3);
- lua_pushstring(L,"__le");
- lua_pushcclosure(L,class_le_event,0);
- lua_rawset(L,-3);
- lua_pushstring(L,"__eq");
- lua_pushcclosure(L,class_eq_event,0);
- lua_rawset(L,-3);
- lua_pushstring(L,"__gc");
- lua_pushcclosure(L,class_gc_event,0);
- lua_rawset(L,-3);
+ lua_pushstring(L, "__index");
+ lua_pushcclosure(L, class_index_event, 0);
+ lua_rawset(L, -3);
+ lua_pushstring(L, "__newindex");
+ lua_pushcclosure(L, class_newindex_event, 0);
+ lua_rawset(L, -3);
+ lua_pushstring(L, "__add");
+ lua_pushcclosure(L, class_add_event, 0);
+ lua_rawset(L, -3);
+ lua_pushstring(L, "__sub");
+ lua_pushcclosure(L, class_sub_event, 0);
+ lua_rawset(L, -3);
+ lua_pushstring(L, "__mul");
+ lua_pushcclosure(L, class_mul_event, 0);
+ lua_rawset(L, -3);
+ lua_pushstring(L, "__div");
+ lua_pushcclosure(L, class_div_event, 0);
+ lua_rawset(L, -3);
+ lua_pushstring(L, "__lt");
+ lua_pushcclosure(L, class_lt_event, 0);
+ lua_rawset(L, -3);
+ lua_pushstring(L, "__le");
+ lua_pushcclosure(L, class_le_event, 0);
+ lua_rawset(L, -3);
+ lua_pushstring(L, "__eq");
+ lua_pushcclosure(L, class_eq_event, 0);
+ lua_rawset(L, -3);
+ lua_pushstring(L, "__gc");
+ lua_pushcclosure(L, class_gc_event, 0);
+ lua_rawset(L, -3);
}
static void tolua_newmetatable(lua_State *L, const char *name) {
@@ -154,7 +156,7 @@ static const char* tolua_typename(lua_State *L, int lo) {
lua_concat(L, 2);
}
}
- return lua_tostring(L,-1);
+ return lua_tostring(L, -1);
}
static int tolua_bnd_type(lua_State *L) {
@@ -167,8 +169,8 @@ static void *tolua_clone(lua_State *L, void *dest, lua_CFunction fn) {
lua_rawget(L, LUA_REGISTRYINDEX);
lua_pushlightuserdata(L, dest);
lua_pushcclosure(L, fn, 0);
- lua_rawset(L,-3);
- lua_settop(L,-2);
+ lua_rawset(L, -3);
+ lua_settop(L, -2);
return dest;
}
@@ -177,12 +179,12 @@ static int tolua_bnd_takeownership(lua_State *L) {
lua_CFunction fn = nullptr;
if (lua_isuserdata(L, 1)) {
if (lua_getmetatable(L, 1)) {
- lua_pushstring(L,".collector");
- lua_rawget(L,-2);
- if (lua_iscfunction(L,-1)) {
+ lua_pushstring(L, ".collector");
+ lua_rawget(L, -2);
+ if (lua_iscfunction(L, -1)) {
fn = lua_tocfunction(L, -1);
}
- lua_settop(L,-3);
+ lua_settop(L, -3);
void *data = lua_touserdata(L, 1);
tolua_clone(L, data, fn);
}
@@ -230,7 +232,7 @@ static int tolua_bnd_cast(lua_State *L) {
}
static void tolua_release(lua_State *L, void *p) {
- lua_pushstring(L,"tolua_ubox");
+ lua_pushstring(L, "tolua_ubox");
lua_rawget(L, LUA_REGISTRYINDEX);
lua_pushlightuserdata(L, p);
lua_rawget(L, -2);
@@ -431,7 +433,7 @@ void *tolua_tousertype(lua_State *L, int narg, void* def) {
}
int tolua_toboolean(lua_State *L, int narg, int def) {
- return lua_gettop(L) < abs(narg) ? def : lua_toboolean(L,narg);
+ return lua_gettop(L) < abs(narg) ? def : lua_toboolean(L, narg);
}
void tolua_pushboolean(lua_State *L, bool val) {
Commit: 9dab12cf3ccef9cbf348a01d3a313370cb1eb6fa
https://github.com/scummvm/scummvm/commit/9dab12cf3ccef9cbf348a01d3a313370cb1eb6fa
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2023-01-16T17:36:43+01:00
Commit Message:
TETRAEDGE: Misc code cleanups. Less public members.
Changed paths:
R engines/tetraedge/game/loading_menu.cpp
R engines/tetraedge/game/loading_menu.h
R engines/tetraedge/te/te_screen.cpp
R engines/tetraedge/te/te_screen.h
R engines/tetraedge/te/te_sfx.cpp
R engines/tetraedge/te/te_sfx.h
engines/tetraedge/credits.pl
engines/tetraedge/game/application.cpp
engines/tetraedge/game/application.h
engines/tetraedge/game/billboard.cpp
engines/tetraedge/game/bonus_menu.cpp
engines/tetraedge/game/cellphone.cpp
engines/tetraedge/game/character.cpp
engines/tetraedge/game/characters_shadow.cpp
engines/tetraedge/game/confirm.cpp
engines/tetraedge/game/confirm.h
engines/tetraedge/game/credits.cpp
engines/tetraedge/game/documents_browser.cpp
engines/tetraedge/game/gallery_menu.cpp
engines/tetraedge/game/game.cpp
engines/tetraedge/game/game_achievements.h
engines/tetraedge/game/global_bonus_menu.cpp
engines/tetraedge/game/in_game_scene.cpp
engines/tetraedge/game/in_game_scene.h
engines/tetraedge/game/loc_file.cpp
engines/tetraedge/game/loc_file.h
engines/tetraedge/game/lua_binds.cpp
engines/tetraedge/game/main_menu.cpp
engines/tetraedge/game/object3d.cpp
engines/tetraedge/game/objectif.cpp
engines/tetraedge/game/owner_error_menu.cpp
engines/tetraedge/game/question2.cpp
engines/tetraedge/game/question2.h
engines/tetraedge/game/splash_screens.cpp
engines/tetraedge/game/splash_screens.h
engines/tetraedge/module.mk
engines/tetraedge/te/te_3d_texture.cpp
engines/tetraedge/te/te_3d_texture.h
engines/tetraedge/te/te_act_zone.cpp
engines/tetraedge/te/te_animation.h
engines/tetraedge/te/te_button_layout.h
engines/tetraedge/te/te_camera.h
engines/tetraedge/te/te_checkbox_layout.h
engines/tetraedge/te/te_clip_layout.cpp
engines/tetraedge/te/te_clip_layout.h
engines/tetraedge/te/te_core.h
engines/tetraedge/te/te_font3.h
engines/tetraedge/te/te_frame_anim.h
engines/tetraedge/te/te_free_move_zone.cpp
engines/tetraedge/te/te_i_loc.cpp
engines/tetraedge/te/te_i_loc.h
engines/tetraedge/te/te_image.cpp
engines/tetraedge/te/te_image.h
engines/tetraedge/te/te_list_layout.h
engines/tetraedge/te/te_lua_gui_lua_callbacks.cpp
engines/tetraedge/te/te_material.h
engines/tetraedge/te/te_model.cpp
engines/tetraedge/te/te_model.h
engines/tetraedge/te/te_palette.h
engines/tetraedge/te/te_real_timer.h
engines/tetraedge/te/te_renderer.cpp
engines/tetraedge/te/te_sprite_layout.cpp
engines/tetraedge/te/te_tiled_surface.cpp
engines/tetraedge/te/te_tiled_surface.h
engines/tetraedge/te/te_tiled_texture.cpp
engines/tetraedge/te/te_tiled_texture.h
engines/tetraedge/te/te_timer.cpp
engines/tetraedge/tetraedge.h
diff --git a/engines/tetraedge/credits.pl b/engines/tetraedge/credits.pl
index a14c198dbb6..c5d7254ef82 100644
--- a/engines/tetraedge/credits.pl
+++ b/engines/tetraedge/credits.pl
@@ -1,3 +1,3 @@
begin_section("Tetraedge");
- add_person("Matthew Duggan", "Handle 1", "");
+ add_person("Matthew Duggan", "stauff", "");
end_section();
diff --git a/engines/tetraedge/game/application.cpp b/engines/tetraedge/game/application.cpp
index e05f2bcbd40..493a24fdfd8 100644
--- a/engines/tetraedge/game/application.cpp
+++ b/engines/tetraedge/game/application.cpp
@@ -88,11 +88,10 @@ void Application::create() {
// See TeMainWindowBase::initCamera
_mainWindowCamera.reset(new TeCamera());
_mainWindowCamera->setName("_mainWinCam");
- _mainWindowCamera->_projectionMatrixType = 4;
+ _mainWindowCamera->setProjMatrixType(4);
_mainWindowCamera->viewport(0, 0, winWidth, winHeight);
_mainWindowCamera->orthogonalParams(winWidth * -0.5f, winWidth * 0.5f, winHeight * 0.5f, winHeight * -0.5f);
- _mainWindowCamera->_orthNearVal = -2048.0f;
- _mainWindowCamera->_orthFarVal = 2048.0f;
+ _mainWindowCamera->setOrthoPlanes(-2048.0f, 2048.0f);
_mainWindow.setSize(TeVector3f32(winWidth, winHeight, 0.0));
_mainWindow.setSizeType(TeILayout::ABSOLUTE);
@@ -421,10 +420,10 @@ void Application::performRender() {
TeRenderer *renderer = g_engine->getRenderer();
if (_drawShadows && game->running() && game->scene()._character
- && game->scene()._shadowLightNo != -1
- && game->scene()._charactersShadow != nullptr) {
+ && game->scene().shadowLightNo() != -1
+ && game->scene().charactersShadow() != nullptr) {
renderer->shadowMode(TeRenderer::ShadowMode1);
- game->scene()._charactersShadow->createTexture(&game->scene());
+ game->scene().charactersShadow()->createTexture(&game->scene());
renderer->shadowMode(TeRenderer::ShadowMode0);
}
@@ -434,13 +433,13 @@ void Application::performRender() {
renderer->clearBuffer(GL_ACCUM);
if (game->running()) {
if (_drawShadows && game->scene()._character
- && game->scene()._shadowLightNo != -1
- && game->scene()._charactersShadow != nullptr) {
+ && game->scene().shadowLightNo() != -1
+ && game->scene().charactersShadow() != nullptr) {
TeIntrusivePtr<TeCamera> currentCamera = game->scene().currentCamera();
if (currentCamera) {
currentCamera->apply();
renderer->shadowMode(TeRenderer::ShadowMode2);
- game->scene()._charactersShadow->draw(&game->scene());
+ game->scene().charactersShadow()->draw(&game->scene());
renderer->shadowMode(TeRenderer::ShadowMode0);
}
}
@@ -489,8 +488,7 @@ void Application::getSavegameThumbnail(Graphics::Surface &thumb) {
Graphics::Surface screen;
_visFade.texture()->writeTo(screen);
screen.flipVertical(Common::Rect(screen.w, screen.h));
- Common::ScopedPtr<Graphics::Surface> scaledScreen(screen.scale(kThumbnailWidth, kThumbnailHeight2, true));
- //scaledScreen->convertToInPlace(Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0));
+ Common::ScopedPtr<Graphics::Surface> scaledScreen(screen.scale(kThumbnailWidth, kThumbnailHeight2));
thumb.copyFrom(*scaledScreen);
screen.free();
scaledScreen->free();
diff --git a/engines/tetraedge/game/application.h b/engines/tetraedge/game/application.h
index 9d88c203c76..37afa2d40e0 100644
--- a/engines/tetraedge/game/application.h
+++ b/engines/tetraedge/game/application.h
@@ -104,20 +104,20 @@ public:
int &difficulty() { return _difficulty; }
bool &tutoActivated() { return _tutoActivated; }
- // TODO: Add accessors for these and make them private.
+ void setFinishedGame(bool val) { _finishedGame = val; }
+ void setFinishedFremium(bool val) { _finishedFremium = val; }
+ const Common::String &firstWarpPath() { return _firstWarpPath; }
+ const Common::String &firstZone() { return _firstZone; }
+ const Common::String &firstScene() { return _firstScene; }
+ TeLayout &frontLayout() { return _frontLayout; };
+ TeLayout &frontOrientationLayout() { return _frontOrientationLayout; }
+ TeLayout &backLayout() { return _backLayout; }
+ LocFile &loc() { return _loc; }
+
+private:
bool _finishedGame;
bool _finishedFremium;
- TeLayout _frontLayout;
- TeLayout _frontOrientationLayout;
- TeLayout _backLayout;
- TeButtonLayout _lockCursorButton;
- TeButtonLayout _lockCursorFromActionButton;
- LocFile _loc;
- Common::String _firstWarpPath;
- Common::String _firstZone;
- Common::String _firstScene;
-private:
TeVisualFade _visFade;
TeMusic _music;
TeSpriteLayout _appSpriteLayout;
@@ -125,8 +125,20 @@ private:
TeSpriteLayout _autoSaveIcon1;
TeSpriteLayout _autoSaveIcon2;
+ TeButtonLayout _lockCursorButton;
+ TeButtonLayout _lockCursorFromActionButton;
+
+ TeLayout _frontLayout;
+ TeLayout _frontOrientationLayout;
+ TeLayout _backLayout;
+
+ LocFile _loc;
+
Common::String _applicationTitle;
Common::String _versionString;
+ Common::String _firstWarpPath;
+ Common::String _firstZone;
+ Common::String _firstScene;
Common::Array<Common::String> _unrecalAnims;
diff --git a/engines/tetraedge/game/billboard.cpp b/engines/tetraedge/game/billboard.cpp
index 0d37ac6dcec..d3c8f002568 100644
--- a/engines/tetraedge/game/billboard.cpp
+++ b/engines/tetraedge/game/billboard.cpp
@@ -70,22 +70,22 @@ void Billboard::calcVertex() {
fx = _pos.x();
fy = _pos.y();
meshVertex = camTotalInverse * TeVector3f32(fx + fx - 1.0f, fy + fy - 1.0f, posvec.z());
- _model->_meshes[0].setVertex(0, meshVertex);
+ _model->meshes()[0].setVertex(0, meshVertex);
fx = _pos.x();
fy = _pos.y() + _size.getY();
meshVertex = camTotalInverse * TeVector3f32(fx + fx - 1.0f, fy + fy - 1.0f, posvec.z());
- _model->_meshes[0].setVertex(1, meshVertex);
+ _model->meshes()[0].setVertex(1, meshVertex);
fx = _pos.x() + _size.getX();
fy = _pos.y();
meshVertex = camTotalInverse * TeVector3f32(fx + fx - 1.0f, fy + fy - 1.0f, posvec.z());
- _model->_meshes[0].setVertex(2, meshVertex);
+ _model->meshes()[0].setVertex(2, meshVertex);
fx = _pos.x() + _size.getX();
fy = _pos.y() + _size.getY();
meshVertex = camTotalInverse * TeVector3f32(fx + fx - 1.0f, fy + fy - 1.0f, posvec.z());
- _model->_meshes[0].setVertex(3, meshVertex);
+ _model->meshes()[0].setVertex(3, meshVertex);
}
void Billboard::position(const TeVector3f32 &pos) {
diff --git a/engines/tetraedge/game/bonus_menu.cpp b/engines/tetraedge/game/bonus_menu.cpp
index f0ccb12b348..4dc9bdfb12c 100644
--- a/engines/tetraedge/game/bonus_menu.cpp
+++ b/engines/tetraedge/game/bonus_menu.cpp
@@ -36,7 +36,7 @@ void BonusMenu::enter(const Common::String &scriptName) {
if (!loaded)
error("BonusMenu::enter: failed to load %s", scriptName.c_str());
Application *app = g_engine->getApplication();
- app->_frontLayout.addChild(layoutChecked("menu"));
+ app->frontLayout().addChild(layoutChecked("menu"));
buttonLayoutChecked("quitButton")->onMouseClickValidated().add(this, &BonusMenu::onQuitButton);
@@ -149,7 +149,7 @@ bool BonusMenu::onPictureButton() {
Application *app = g_engine->getApplication();
TeSpriteLayout *pictureLayout = spriteLayoutChecked("fullScreenPictureLayout");
- app->_frontLayout.removeChild(pictureLayout);
+ app->frontLayout().removeChild(pictureLayout);
pictureLayout->setVisible(true);
return true;
diff --git a/engines/tetraedge/game/cellphone.cpp b/engines/tetraedge/game/cellphone.cpp
index f2a47e2c330..1fbc2a719ef 100644
--- a/engines/tetraedge/game/cellphone.cpp
+++ b/engines/tetraedge/game/cellphone.cpp
@@ -47,7 +47,7 @@ bool Cellphone::addNumber(const Common::String &num) {
layout->setTextSizeType(1);
layout->setTextSizeProportionalToWidth(46);
Common::String val("Unknown");
- Common::String *locNum = g_engine->getCore()->loc()->text(num);
+ const Common::String *locNum = g_engine->getCore()->loc()->text(num);
if (locNum)
val = *locNum;
diff --git a/engines/tetraedge/game/character.cpp b/engines/tetraedge/game/character.cpp
index 7827158b957..2ba77527a05 100644
--- a/engines/tetraedge/game/character.cpp
+++ b/engines/tetraedge/game/character.cpp
@@ -346,8 +346,8 @@ bool Character::loadModel(const Common::String &mname, bool unused) {
return false;
_characterSettings = _globalCharacterSettings->getVal(mname);
- _model->_texturePath = Common::Path("models/Textures");
- _model->_enableLights = true;
+ _model->setTexturePath("models/Textures");
+ _model->setEnableLights(true);
Common::Path modelPath("models");
modelPath.joinInPlace(_characterSettings._modelFileName);
if (!_model->load(modelPath))
@@ -356,8 +356,9 @@ bool Character::loadModel(const Common::String &mname, bool unused) {
_model->setName(mname);
_model->setScale(_characterSettings._defaultScale);
- for (auto &mesh : _model->_meshes)
+ for (auto &mesh : _model->meshes())
mesh.setVisible(true);
+
// Set all mouthes not visible by default
_model->setVisibleByName("_B_", false);
// Set all eyes not visible by default
@@ -744,10 +745,10 @@ float Character::speedFromAnim(double msFromStart) {
return 0.0f;
TeIntrusivePtr<TeModelAnimation> modelAnim;
- if (_model->_boneBlenders.empty()) {
+ if (_model->boneBlenders().empty()) {
modelAnim = _model->anim();
} else {
- modelAnim = _model->_boneBlenders.back()->_anim;
+ modelAnim = _model->boneBlenders().back()->_anim;
}
if (!modelAnim)
diff --git a/engines/tetraedge/game/characters_shadow.cpp b/engines/tetraedge/game/characters_shadow.cpp
index 5bde6f4dc9c..e422b41def9 100644
--- a/engines/tetraedge/game/characters_shadow.cpp
+++ b/engines/tetraedge/game/characters_shadow.cpp
@@ -42,8 +42,8 @@ void CharactersShadow::create(InGameScene *scene) {
TeRenderer *renderer = g_engine->getRenderer();
renderer->enableTexture();
_camera = new TeCamera();
- _camera->_projectionMatrixType = 2;
- _camera->_somePerspectiveVal = 1.0;
+ _camera->setProjMatrixType(2);
+ _camera->setPerspectiveVal(1.0);
_camera->setName("_shadowCam");
_camera->viewport(0, 0, _texSize, _texSize);
Te3DTexture::unbind();
@@ -67,9 +67,8 @@ void CharactersShadow::createTexture(InGameScene *scene) {
_camera->setRotation(q2 * q1);
_camera->setPosition(light->position3d());
}
- _camera->_fov = scene->shadowFov() * M_PI / 180.0;
- _camera->_orthNearVal = scene->shadowNearPlane();
- _camera->_orthFarVal = scene->shadowFarPlane();
+ _camera->setFov((float)(scene->shadowFov() * M_PI / 180.0));
+ _camera->setOrthoPlanes(scene->shadowNearPlane(), scene->shadowFarPlane());
_camera->apply();
glClearColor(0.0, 0.0, 0.0, 0.0);
@@ -154,10 +153,10 @@ void CharactersShadow::draw(InGameScene *scene) {
renderer->setCurrentColor(scene->shadowColor());
for (TeIntrusivePtr<TeModel> model : scene->zoneModels()) {
- if (model->_meshes.size() > 0 && model->_meshes[0].materials().empty()) {
- model->_meshes[0].defaultMaterial(TeIntrusivePtr<Te3DTexture>());
- model->_meshes[0].materials()[0]._enableSomethingDefault0 = true;
- model->_meshes[0].materials()[0]._diffuseColor = scene->shadowColor();
+ if (model->meshes().size() > 0 && model->meshes()[0].materials().empty()) {
+ model->meshes()[0].defaultMaterial(TeIntrusivePtr<Te3DTexture>());
+ model->meshes()[0].materials()[0]._enableSomethingDefault0 = true;
+ model->meshes()[0].materials()[0]._diffuseColor = scene->shadowColor();
}
model->draw();
}
diff --git a/engines/tetraedge/game/confirm.cpp b/engines/tetraedge/game/confirm.cpp
index c535e0a7c73..ff1bbdf6da4 100644
--- a/engines/tetraedge/game/confirm.cpp
+++ b/engines/tetraedge/game/confirm.cpp
@@ -39,7 +39,7 @@ void Confirm::enter(const Common::String &guiPath, const Common::String &y) {
Application *app = g_engine->getApplication();
TeButtonLayout *confirmButtonLayout = _gui.buttonLayout("confirm");
- app->_frontOrientationLayout.addChild(confirmButtonLayout);
+ app->frontOrientationLayout().addChild(confirmButtonLayout);
TeButtonLayout *yesButtonLayout = _gui.buttonLayout("yes");
if (yesButtonLayout)
@@ -53,11 +53,11 @@ void Confirm::enter(const Common::String &guiPath, const Common::String &y) {
if (textLayout) {
const Common::String textAttributs = _gui.value("textAttributs").toString();
const Common::String textAttributsDown = _gui.value("textAttributsDown").toString();
- const Common::String *okButtonLoc = app->_loc.value("okButton");
- const Common::String *cancelButtonLoc = app->_loc.value("cancelButton");
+ const Common::String *okButtonLoc = app->loc().value("okButton");
+ const Common::String *cancelButtonLoc = app->loc().value("cancelButton");
TeTextLayout *textTextLayout = dynamic_cast<TeTextLayout *>(textLayout->child(0));
- textTextLayout->setText(textAttributs + *app->_loc.value(textTextLayout->name()));
+ textTextLayout->setText(textAttributs + *app->loc().value(textTextLayout->name()));
if (!okButtonLoc || !cancelButtonLoc) {
error("Missing translations for ok and cancel");
@@ -89,8 +89,8 @@ void Confirm::enter(const Common::String &guiPath, const Common::String &y) {
}
// Make sure the mouse cursor is back on top.
- app->_frontOrientationLayout.removeChild(&app->mouseCursorLayout());
- app->_frontOrientationLayout.addChild(&app->mouseCursorLayout());
+ app->frontOrientationLayout().removeChild(&app->mouseCursorLayout());
+ app->frontOrientationLayout().addChild(&app->mouseCursorLayout());
if (ConfMan.get("skip_confirm") == "true") {
onButtonYes();
@@ -101,7 +101,7 @@ void Confirm::leave() {
Application *app = g_engine->getApplication();
TeButtonLayout *confirmButtonLayout = _gui.buttonLayout("confirm");
if (confirmButtonLayout) {
- app->_frontLayout.removeChild(confirmButtonLayout);
+ app->frontLayout().removeChild(confirmButtonLayout);
}
_gui.unload();
}
diff --git a/engines/tetraedge/game/confirm.h b/engines/tetraedge/game/confirm.h
index af21e62d15c..7e3e5a4a1ff 100644
--- a/engines/tetraedge/game/confirm.h
+++ b/engines/tetraedge/game/confirm.h
@@ -39,9 +39,13 @@ public:
bool onButtonNo();
bool onButtonYes();
+ TeSignal0Param &onButtonNoSignal() { return _onButtonNoSignal; }
+ TeSignal0Param &onButtonYesSignal() { return _onButtonYesSignal; }
+
+private:
+ TeLuaGUI _gui;
TeSignal0Param _onButtonNoSignal;
TeSignal0Param _onButtonYesSignal;
- TeLuaGUI _gui;
};
} // end namespace Tetraedge
diff --git a/engines/tetraedge/game/credits.cpp b/engines/tetraedge/game/credits.cpp
index b726fdb4294..ce784ad63be 100644
--- a/engines/tetraedge/game/credits.cpp
+++ b/engines/tetraedge/game/credits.cpp
@@ -37,7 +37,7 @@ void Credits::enter(bool returnToOptions) {
// TODO: set _field0x50 = 0;
_gui.load("menus/credits/credits.lua");
Application *app = g_engine->getApplication();
- app->_frontLayout.addChild(_gui.layoutChecked("menu"));
+ app->frontLayout().addChild(_gui.layoutChecked("menu"));
Common::String musicPath = _gui.value("musicPath").toString();
if (!app->music().isPlaying() || app->music().path() != musicPath) {
@@ -117,7 +117,7 @@ void Credits::leave() {
if (_gui.loaded()) {
Application *app = g_engine->getApplication();
app->captureFade();
- app->_frontLayout.removeChild(_gui.layoutChecked("menu"));
+ app->frontLayout().removeChild(_gui.layoutChecked("menu"));
_timer.stop();
_gui.unload();
if (_returnToOptions)
diff --git a/engines/tetraedge/game/documents_browser.cpp b/engines/tetraedge/game/documents_browser.cpp
index badd29b8a6e..a99f231c728 100644
--- a/engines/tetraedge/game/documents_browser.cpp
+++ b/engines/tetraedge/game/documents_browser.cpp
@@ -190,7 +190,7 @@ void DocumentsBrowser::showDocument(const Common::String &docName, long startPag
TeSpriteLayout *sprite = _gui1.spriteLayoutChecked("zoomedSprite");
//sprite->setSizeType(ABSOLUTE);
sprite->load(docPath);
- TeVector2s32 spriteSize = sprite->_tiledSurfacePtr->_tiledTexture->_totalSize;
+ TeVector2s32 spriteSize = sprite->_tiledSurfacePtr->tiledTexture()->totalSize();
sprite->setSizeType(RELATIVE_TO_PARENT);
TeVector3f32 winSize = app->getMainWindow().size();
sprite->setSize(TeVector3f32(1.0f, (4.0f / (winSize.y() / winSize.x() * 4.0f)) *
diff --git a/engines/tetraedge/game/gallery_menu.cpp b/engines/tetraedge/game/gallery_menu.cpp
index 2276481ab6c..d18e76147e5 100644
--- a/engines/tetraedge/game/gallery_menu.cpp
+++ b/engines/tetraedge/game/gallery_menu.cpp
@@ -83,7 +83,7 @@ void GalleryMenu::enter() {
load("menus/galleryMenu/galleryMenu.lua");
TeLayout *menu = layoutChecked("galleryMenu");
- app->_frontLayout.addChild(menu);
+ app->frontLayout().addChild(menu);
game->stopSound(AMBIENT_SND_BIKE);
game->playSound(AMBIENT_SND_BIKE, -1, 0.1f);
diff --git a/engines/tetraedge/game/game.cpp b/engines/tetraedge/game/game.cpp
index 7da4d3f43b4..fc631015e28 100644
--- a/engines/tetraedge/game/game.cpp
+++ b/engines/tetraedge/game/game.cpp
@@ -144,7 +144,7 @@ void Game::addNoScaleChildren() {
_noScaleLayout->addChild(&_question2);
Application *app = g_engine->getApplication();
- app->_frontLayout.addChild(&_dialog2);
+ app->frontLayout().addChild(&_dialog2);
_noScaleLayout->addChild(&_inventory);
_noScaleLayout->addChild(&_inventoryMenu);
@@ -377,8 +377,8 @@ TeSpriteLayout *Game::findSpriteLayoutByName(TeLayout *parent, const Common::Str
void Game::finishFreemium() {
Application *app = g_engine->getApplication();
- app->_finishedGame = true;
- app->_finishedFremium = true;
+ app->setFinishedGame(true);
+ app->setFinishedFremium(true);
}
void Game::finishGame() {
@@ -408,9 +408,9 @@ void Game::initLoadedBackupData() {
g_engine->setTotalPlayTime(header.playtime);
}
} else {
- firstWarpPath = app->_firstWarpPath;
- _currentScene = app->_firstScene;
- _currentZone = app->_firstZone;
+ firstWarpPath = app->firstWarpPath();
+ _currentScene = app->firstScene();
+ _currentZone = app->firstZone();
_playedTimer.start();
_objectsTakenVal = 0;
for (int i = 0; i < ARRAYSIZE(_objectsTakenBits); i++) {
@@ -534,13 +534,13 @@ bool Game::initWarp(const Common::String &zone, const Common::String &scene, boo
_forGui.load(forLuaPath);
TeLayout *bg = _forGui.layoutChecked("background");
bg->setRatioMode(TeILayout::RATIO_MODE_NONE);
- app->_frontLayout.addChild(bg);
+ app->frontLayout().addChild(bg);
// Note: Game also adds cellphone to both frontLayout *and* noScaleLayout2,
// so we reproduce the broken behavior exactly.
TeLayout *cellbg = _inventory.cellphone()->gui().buttonLayoutChecked("background");
- app->_frontLayout.removeChild(cellbg);
- app->_frontLayout.addChild(cellbg);
- _objectif.reattachLayout(&app->_frontLayout);
+ app->frontLayout().removeChild(cellbg);
+ app->frontLayout().addChild(cellbg);
+ _objectif.reattachLayout(&app->frontLayout());
}
if (intLuaExists) {
@@ -595,17 +595,17 @@ bool Game::initWarp(const Common::String &zone, const Common::String &scene, boo
initNoScale();
removeNoScale2Children();
- app->_frontLayout.removeChild(_noScaleLayout2);
+ app->frontLayout().removeChild(_noScaleLayout2);
TeLayout *vidLayout = _inGameGui.layout("videoLayout");
- app->_frontLayout.removeChild(vidLayout);
+ app->frontLayout().removeChild(vidLayout);
removeNoScaleChildren();
- app->_frontLayout.removeChild(_noScaleLayout);
+ app->frontLayout().removeChild(_noScaleLayout);
- app->_frontLayout.addChild(_noScaleLayout);
+ app->frontLayout().addChild(_noScaleLayout);
addNoScaleChildren();
- app->_frontLayout.addChild(vidLayout);
- app->_frontLayout.addChild(_noScaleLayout2);
+ app->frontLayout().addChild(vidLayout);
+ app->frontLayout().addChild(_noScaleLayout2);
addNoScale2Children();
if (!fadeFlag) {
if (_inventory.selectedObject().size()) {
@@ -618,11 +618,11 @@ bool Game::initWarp(const Common::String &zone, const Common::String &scene, boo
loadScene("save.xml");
}
- app->_backLayout.addChild(_scene.background());
+ app->backLayout().addChild(_scene.background());
if (markerLuaExists) {
TeLayout *bg = _scene.markerGui().layout("background");
- app->_frontLayout.addChild(bg);
+ app->frontLayout().addChild(bg);
}
Common::String camname = Common::String("Camera") + scene;
@@ -693,7 +693,7 @@ static const char *DIALOG_IDS[20] = {
bool Game::launchDialog(const Common::String &dname, uint param_2, const Common::String &charname,
const Common::String &animfile, float animblend) {
Application *app = g_engine->getApplication();
- const Common::String *locstring = app->_loc.value(dname);
+ const Common::String *locstring = app->loc().value(dname);
if (!locstring)
locstring = &dname;
@@ -787,8 +787,8 @@ void Game::leave(bool flag) {
_enteredFlag2 = false;
Application *app = g_engine->getApplication();
- app->_lockCursorButton.setVisible(false);
- app->_lockCursorFromActionButton.setVisible(false);
+ app->lockCursor(false);
+ app->lockCursorFromAction(false);
// TODO: Set some inputmgr flag here?
Character::animCacheFreeAll();
}
@@ -1033,7 +1033,7 @@ bool Game::onMouseClick(const Common::Point &pt) {
}
}
- if (!app->_frontLayout.isMouseIn(pt))
+ if (!app->frontLayout().isMouseIn(pt))
return false;
Common::String nearestMeshName = "None";
@@ -1280,7 +1280,7 @@ void Game::playMovie(const Common::String &vidPath, const Common::String &musicP
// Stop the movie and sound early for testing if skip_videos set
if (ConfMan.get("skip_videos") == "true") {
- videoSpriteLayout->_tiledSurfacePtr->_frameAnim._nbFrames = 10;
+ videoSpriteLayout->_tiledSurfacePtr->_frameAnim.setNbFrames(10);
music.stop();
}
@@ -1408,7 +1408,7 @@ void Game::removeNoScaleChildren() {
return;
_noScaleLayout->removeChild(&_question2);
Application *app = g_engine->getApplication();
- app->_frontLayout.removeChild(&_dialog2);
+ app->frontLayout().removeChild(&_dialog2);
_noScaleLayout->removeChild(&_inventory);
_noScaleLayout->removeChild(&_inventoryMenu);
_noScaleLayout->removeChild(&_documentsBrowser);
@@ -1450,6 +1450,9 @@ void Game::setCurrentObjectSprite(const Common::Path &spritePath) {
}
bool Game::showMarkers(bool val) {
+ if (!_forGui.loaded())
+ return false;
+
TeLayout *bg = _forGui.layoutChecked("background");
for (long i = 0; i < bg->childCount(); i++) {
const InGameScene::TeMarker *marker = _scene.findMarker(bg->child(i)->name());
@@ -1462,8 +1465,8 @@ bool Game::showMarkers(bool val) {
bool Game::startAnimation(const Common::String &animName, int loopcount, bool reversed) {
TeSpriteLayout *layout = _scene.bgGui().spriteLayout(animName);
if (layout) {
- layout->_tiledSurfacePtr->_frameAnim._loopCount = loopcount;
- layout->_tiledSurfacePtr->_frameAnim._reversed = reversed;
+ layout->_tiledSurfacePtr->_frameAnim.setLoopCount(loopcount);
+ layout->_tiledSurfacePtr->_frameAnim.setReversed(reversed);
layout->_tiledSurfacePtr->play();
}
return layout != nullptr;
@@ -1565,7 +1568,7 @@ void Game::update() {
if (_scene._character) {
if (!_scene._character->_model->visible())
- app->_lockCursorButton.setVisible(false);
+ app->lockCursor(false);
}
TeButtonLayout *invbtn = _inGameGui.buttonLayout("inventoryButton");
diff --git a/engines/tetraedge/game/game_achievements.h b/engines/tetraedge/game/game_achievements.h
index c9cf6b9e75d..b1f3ba98567 100644
--- a/engines/tetraedge/game/game_achievements.h
+++ b/engines/tetraedge/game/game_achievements.h
@@ -32,10 +32,6 @@ public:
GameAchievements();
static void registerAchievements(TeLuaContext &context);
- // TODO add public members
-
-private:
- // TODO add private members
};
diff --git a/engines/tetraedge/game/global_bonus_menu.cpp b/engines/tetraedge/game/global_bonus_menu.cpp
index 8bcbec1598b..d92e78aaf3a 100644
--- a/engines/tetraedge/game/global_bonus_menu.cpp
+++ b/engines/tetraedge/game/global_bonus_menu.cpp
@@ -35,7 +35,7 @@ void GlobalBonusMenu::enter() {
_entered = true;
load("menus/bonusmenu/GlobalBonusMenu.lua");
TeLayout *menu = layoutChecked("menu");
- app->_frontLayout.addChild(menu);
+ app->frontLayout().addChild(menu);
// Original checks each layout's existence
TeButtonLayout *btn;
diff --git a/engines/tetraedge/game/in_game_scene.cpp b/engines/tetraedge/game/in_game_scene.cpp
index 082230582b7..ec3d32449dd 100644
--- a/engines/tetraedge/game/in_game_scene.cpp
+++ b/engines/tetraedge/game/in_game_scene.cpp
@@ -102,7 +102,7 @@ bool InGameScene::addMarker(const Common::String &markerName, const Common::Stri
TeVector3f32 newPos;
if (locType == "PERCENT") {
Application *app = g_engine->getApplication();
- TeVector3f32 frontLayoutSize = app->_frontLayout.userSize();
+ TeVector3f32 frontLayoutSize = app->frontLayout().userSize();
newPos.x() = frontLayoutSize.x() * (x / 100.0);
newPos.y() = frontLayoutSize.y() * (y / 100.0);
} else {
@@ -118,7 +118,7 @@ bool InGameScene::addMarker(const Common::String &markerName, const Common::Stri
markerSprite->setSize(TeVector3f32(0.04f, (4.0f / ((winSize.y() / winSize.x()) * 4.0f)) * 0.04f, 0.0));
}
markerSprite->setVisible(game->markersVisible());
- markerSprite->_tiledSurfacePtr->_frameAnim._loopCount = -1;
+ markerSprite->_tiledSurfacePtr->_frameAnim.setLoopCount(-1);
markerSprite->play();
TeMarker newMarker;
@@ -220,17 +220,17 @@ void InGameScene::close() {
void InGameScene::convertPathToMesh(TeFreeMoveZone *zone) {
TeIntrusivePtr<TeModel> model = new TeModel();
- model->_meshes.resize(1);
+ model->meshes().resize(1);
model->setName("shadowReceiving");
model->setPosition(zone->position());
model->setRotation(zone->rotation());
model->setScale(zone->scale());
unsigned long nverticies = zone->verticies().size();
- model->_meshes[0].setConf(nverticies, nverticies, TeMesh::MeshMode_Triangles, 0, 0);
+ model->meshes()[0].setConf(nverticies, nverticies, TeMesh::MeshMode_Triangles, 0, 0);
for (unsigned int i = 0; i < nverticies; i++) {
- model->_meshes[0].setIndex(i, i);
- model->_meshes[0].setVertex(i, zone->verticies()[i]);
- model->_meshes[0].setNormal(i, TeVector3f32(0, 0, 1));
+ model->meshes()[0].setIndex(i, i);
+ model->meshes()[0].setVertex(i, zone->verticies()[i]);
+ model->meshes()[0].setNormal(i, TeVector3f32(0, 0, 1));
}
_zoneModels.push_back(model);
}
@@ -277,16 +277,15 @@ void InGameScene::deleteMarker(const Common::String &markerName) {
}
void InGameScene::deserializeCam(Common::ReadStream &stream, TeIntrusivePtr<TeCamera> &cam) {
- cam->_projectionMatrixType = 2;
+ cam->setProjMatrixType(2);
cam->viewport(0, 0, _viewportSize.getX(), _viewportSize.getY());
// load name/position/rotation/scale
Te3DObject2::deserialize(stream, *cam);
- cam->_fov = stream.readFloatLE();
- cam->_somePerspectiveVal = stream.readFloatLE();
- cam->_orthNearVal = stream.readFloatLE();
- // Original loads the val then ignores it and sets 3000.
+ cam->setFov(stream.readFloatLE());
+ cam->setPerspectiveVal(stream.readFloatLE());
+ // Original loads the second val then ignores it and sets 3000.
+ cam->setOrthoPlanes(stream.readFloatLE(), 3000.0);
stream.readFloatLE();
- cam->_orthFarVal = 3000.0;
}
void InGameScene::deserializeModel(Common::ReadStream &stream, TeIntrusivePtr<TeModel> &model, TePickMesh2 *pickmesh) {
@@ -755,7 +754,7 @@ bool InGameScene::loadObjectMaterials(const Common::String &name) {
if (img.load(mpath)) {
Te3DTexture *tex = new Te3DTexture();
tex->load(img);
- obj._model->_meshes[0].defaultMaterial(tex);
+ obj._model->meshes()[0].defaultMaterial(tex);
retval = true;
}
}
@@ -858,7 +857,7 @@ void InGameScene::loadBackground(const Common::Path &path) {
root->setRatioMode(TeILayout::RATIO_MODE_NONE);
TeCamera *wincam = g_engine->getApplication()->mainWindowCamera();
bg->disableAutoZ();
- bg->setZPosition(wincam->_orthNearVal);
+ bg->setZPosition(wincam->orthoNearPlane());
for (auto layoutEntry : _bgGui.spriteLayouts()) {
AnimObject *animobj = new AnimObject();
@@ -976,7 +975,7 @@ void InGameScene::setImagePathMarker(const Common::String &markerName, const Com
TeSpriteLayout *sprite = dynamic_cast<TeSpriteLayout *>(child);
if (sprite) {
sprite->load(path);
- sprite->_tiledSurfacePtr->_frameAnim._loopCount = -1;
+ sprite->_tiledSurfacePtr->_frameAnim.setLoopCount(-1);
sprite->play();
}
}
diff --git a/engines/tetraedge/game/in_game_scene.h b/engines/tetraedge/game/in_game_scene.h
index 7fb5318b2ed..2d6fdc46eb0 100644
--- a/engines/tetraedge/game/in_game_scene.h
+++ b/engines/tetraedge/game/in_game_scene.h
@@ -186,9 +186,9 @@ public:
float shadowNearPlane() const { return _shadowNearPlane; }
float shadowFov() const { return _shadowFov; }
const TeColor &shadowColor() const { return _shadowColor; }
+ int shadowLightNo() const { return _shadowLightNo; }
+ CharactersShadow *charactersShadow() { return _charactersShadow; }
- int _shadowLightNo;
- CharactersShadow *_charactersShadow;
TeIntrusivePtr<TeBezierCurve> curve() { return _curve; }
void setCurve(TeIntrusivePtr<TeBezierCurve> &c) { _curve = c; }
Common::Array<TeIntrusivePtr<TeModel>> &zoneModels() { return _zoneModels; }
@@ -199,7 +199,10 @@ public:
TeTimer &waitTimeTimer() { return _waitTimeTimer; }
Common::Array<TeLight> &lights() { return _lights; }
+
private:
+ int _shadowLightNo;
+ CharactersShadow *_charactersShadow;
TeColor _shadowColor;
float _shadowFarPlane;
float _shadowNearPlane;
diff --git a/engines/tetraedge/game/loading_menu.cpp b/engines/tetraedge/game/loading_menu.cpp
deleted file mode 100644
index d8bc4a53afb..00000000000
--- a/engines/tetraedge/game/loading_menu.cpp
+++ /dev/null
@@ -1,31 +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 "tetraedge/game/loading_menu.h"
-
-namespace Tetraedge {
-
-LoadingMenu::LoadingMenu() {
-}
-
-// TODO: Add more functions here.
-
-} // end namespace Tetraedge
diff --git a/engines/tetraedge/game/loading_menu.h b/engines/tetraedge/game/loading_menu.h
deleted file mode 100644
index 34021f76d43..00000000000
--- a/engines/tetraedge/game/loading_menu.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 TETRAEDGE_GAME_LOADING_MENU_H
-#define TETRAEDGE_GAME_LOADING_MENU_H
-
-namespace Tetraedge {
-
-class LoadingMenu {
-public:
- LoadingMenu();
-
- // TODO add public members
-
-private:
- // TODO add private members
-
-};
-
-} // end namespace Tetraedge
-
-#endif // TETRAEDGE_GAME_LOADING_MENU_H
diff --git a/engines/tetraedge/game/loc_file.cpp b/engines/tetraedge/game/loc_file.cpp
index 89b43242403..c89f69502d9 100644
--- a/engines/tetraedge/game/loc_file.cpp
+++ b/engines/tetraedge/game/loc_file.cpp
@@ -54,7 +54,7 @@ void LocFile::load(const Common::Path &path) {
_map = parser.getMap();
}
-const Common::String *LocFile::value(const Common::String &key) {
+const Common::String *LocFile::value(const Common::String &key) const {
return text(key);
}
diff --git a/engines/tetraedge/game/loc_file.h b/engines/tetraedge/game/loc_file.h
index 861229b22e4..77051a5b2f4 100644
--- a/engines/tetraedge/game/loc_file.h
+++ b/engines/tetraedge/game/loc_file.h
@@ -35,7 +35,7 @@ public:
//const Common::String *avatar(const Common::String &key);
void load(const Common::Path &path);
- const Common::String *value(const Common::String &key);
+ const Common::String *value(const Common::String &key) const;
};
diff --git a/engines/tetraedge/game/lua_binds.cpp b/engines/tetraedge/game/lua_binds.cpp
index b06f6c3e2fe..52156f6c68d 100644
--- a/engines/tetraedge/game/lua_binds.cpp
+++ b/engines/tetraedge/game/lua_binds.cpp
@@ -1304,7 +1304,7 @@ static int tolua_ExportedFunctions_LaunchDialogAndWaitForEnd00(lua_State *L) {
static void PushAnswer(const Common::String &val, const Common::String &gui) {
Application *app = g_engine->getApplication();
- const Common::String *locVal = app->_loc.value(val);
+ const Common::String *locVal = app->loc().value(val);
Common::String locValStr;
if (locVal) {
locValStr = *locVal;
diff --git a/engines/tetraedge/game/main_menu.cpp b/engines/tetraedge/game/main_menu.cpp
index 243b736fd61..a3deb90f071 100644
--- a/engines/tetraedge/game/main_menu.cpp
+++ b/engines/tetraedge/game/main_menu.cpp
@@ -41,10 +41,10 @@ namespace Tetraedge {
static const char *LAST_SAVE_CONF = "lastSaveSlot";
MainMenu::MainMenu() : _entered(false), _confirmingTuto(false) {
- _newGameConfirm._onButtonYesSignal.add(this, &MainMenu::onNewGameConfirmed);
- _tutoConfirm._onButtonYesSignal.add(this, &MainMenu::onActivedTuto);
- _tutoConfirm._onButtonNoSignal.add(this, &MainMenu::onDisabledTuto);
- _quitConfirm._onButtonYesSignal.add(this, &MainMenu::onQuit);
+ _newGameConfirm.onButtonYesSignal().add(this, &MainMenu::onNewGameConfirmed);
+ _tutoConfirm.onButtonYesSignal().add(this, &MainMenu::onActivedTuto);
+ _tutoConfirm.onButtonNoSignal().add(this, &MainMenu::onDisabledTuto);
+ _quitConfirm.onButtonYesSignal().add(this, &MainMenu::onQuit);
onFacebookLoggedSignal.add(this, &MainMenu::onFacebookLogged);
}
@@ -54,7 +54,7 @@ void MainMenu::enter() {
appSpriteLayout.setVisible(true);
if (!appSpriteLayout._tiledSurfacePtr->_frameAnim._runTimer.running()) {
appSpriteLayout.load("menus/menu.ogv");
- appSpriteLayout._tiledSurfacePtr->_frameAnim._loopCount = -1;
+ appSpriteLayout._tiledSurfacePtr->_frameAnim.setLoopCount(-1);
appSpriteLayout._tiledSurfacePtr->play();
}
app->captureFade();
diff --git a/engines/tetraedge/game/object3d.cpp b/engines/tetraedge/game/object3d.cpp
index 493a4280b7d..4006e12ee71 100644
--- a/engines/tetraedge/game/object3d.cpp
+++ b/engines/tetraedge/game/object3d.cpp
@@ -48,7 +48,7 @@ bool Object3D::loadModel(const Common::String &name) {
if (settings != _objectSettings->end()) {
_modelFileName = settings->_value._modelFileName;
_defaultScale = settings->_value._defaultScale;
- _modelPtr->_texturePath = Common::Path("objects/Textures");
+ _modelPtr->setTexturePath("objects/Textures");
bool loaded = _modelPtr->load(Common::Path("objects").join(_modelFileName));
if (loaded) {
_modelPtr->setName(name);
diff --git a/engines/tetraedge/game/objectif.cpp b/engines/tetraedge/game/objectif.cpp
index 1f73149148d..6d274095cb0 100644
--- a/engines/tetraedge/game/objectif.cpp
+++ b/engines/tetraedge/game/objectif.cpp
@@ -61,7 +61,7 @@ void Objectif::load() {
_gui2.load("menus/helpButton.lua");
TeButtonLayout *btn = _gui2.buttonLayoutChecked("helpButton");
- app->_frontLayout.addChild(btn);
+ app->frontLayout().addChild(btn);
btn->setVisible(true);
_helpButtonVisible = true;
btn->onMouseClickValidated().add(this, &Objectif::onHelpButtonValidated);
diff --git a/engines/tetraedge/game/owner_error_menu.cpp b/engines/tetraedge/game/owner_error_menu.cpp
index ecb12101a99..4694698a4b5 100644
--- a/engines/tetraedge/game/owner_error_menu.cpp
+++ b/engines/tetraedge/game/owner_error_menu.cpp
@@ -38,9 +38,9 @@ void OwnerErrorMenu::enter() {
load(luaPath);
Application *app = g_engine->getApplication();
TeLayout *menuLayout = layoutChecked("menu");
- app->_frontLayout.addChild(menuLayout);
+ app->frontLayout().addChild(menuLayout);
TeTextLayout *txt = dynamic_cast<TeTextLayout*>(layoutChecked("ownerMenuText"));
- const Common::String *locname = app->_loc.value(txt->name());
+ const Common::String *locname = app->loc().value(txt->name());
txt->setText(value("textAttributs").toString() + (locname ? *locname : txt->name()));
}
diff --git a/engines/tetraedge/game/question2.cpp b/engines/tetraedge/game/question2.cpp
index 09ce43b64ad..29e17670877 100644
--- a/engines/tetraedge/game/question2.cpp
+++ b/engines/tetraedge/game/question2.cpp
@@ -115,11 +115,10 @@ void Question2::pushAnswer(const Common::String &name, const Common::String &loc
xpos = 0.15f;
}
blayout->setPosition(TeVector3f32(xpos, _answers.size() * 0.08f + 0.06f, 1.0f));
-
- blayout->_upLayout->setSizeType(RELATIVE_TO_PARENT);
- blayout->_upLayout->setSize(TeVector3f32(1.0f, 1.0f, 1.0f));
- blayout->_downLayout->setSizeType(RELATIVE_TO_PARENT);
- blayout->_downLayout->setSize(TeVector3f32(1.0f, 1.0f, 1.0f));
+ blayout->upLayout()->setSizeType(RELATIVE_TO_PARENT);
+ blayout->upLayout()->setSize(TeVector3f32(1.0f, 1.0f, 1.0f));
+ blayout->downLayout()->setSizeType(RELATIVE_TO_PARENT);
+ blayout->downLayout()->setSize(TeVector3f32(1.0f, 1.0f, 1.0f));
TeSpriteLayout *calepinLayout = _gui.spriteLayoutChecked("Calepin");
calepinLayout->addChild(blayout);
@@ -142,7 +141,7 @@ void Question2::Answer::load(const Common::String &name, const Common::String &l
TeButtonLayout *answerButton = _gui.buttonLayout("answer");
if (answerButton) {
answerButton->onMouseClickValidated().add(this, &Question2::Answer::onButtonValidated);
- answerButton->_ignoreMouseEvents = false;
+ answerButton->setIgnoreMouseEvents(false);
}
}
diff --git a/engines/tetraedge/game/question2.h b/engines/tetraedge/game/question2.h
index bc171484aae..86201e499d5 100644
--- a/engines/tetraedge/game/question2.h
+++ b/engines/tetraedge/game/question2.h
@@ -56,8 +56,8 @@ public:
TeSignal1Param<const Common::String &> &onAnswerSignal() { return _onAnswerSignal; }
private:
- TeLuaGUI _gui;
Common::Array<Answer *> _answers;
+ TeLuaGUI _gui;
TeSignal1Param<const Common::String &> _onAnswerSignal;
};
diff --git a/engines/tetraedge/game/splash_screens.cpp b/engines/tetraedge/game/splash_screens.cpp
index 28dad2adcf4..22c88aed33d 100644
--- a/engines/tetraedge/game/splash_screens.cpp
+++ b/engines/tetraedge/game/splash_screens.cpp
@@ -43,7 +43,7 @@ void SplashScreens::enter() {
TeLuaGUI::load(scriptPath.toString());
Application *app = g_engine->getApplication();
TeLayout *splash = layout("splash");
- app->_frontLayout.addChild(splash);
+ app->frontLayout().addChild(splash);
app->performRender();
}
onAlarm();
@@ -72,7 +72,7 @@ bool SplashScreens::onAlarm() {
btnLayout->onMouseClickValidated().add(this, &SplashScreens::onQuitSplash);
TeLayout *splash = layout("splash");
- app->_frontLayout.addChild(splash);
+ app->frontLayout().addChild(splash);
_timer.start();
_timer.setAlarmIn(1500000);
diff --git a/engines/tetraedge/game/splash_screens.h b/engines/tetraedge/game/splash_screens.h
index b393dca3991..b89025eb8e1 100644
--- a/engines/tetraedge/game/splash_screens.h
+++ b/engines/tetraedge/game/splash_screens.h
@@ -41,8 +41,8 @@ public:
private:
bool _entered;
- TeTimer _timer;
int _splashNo;
+ TeTimer _timer;
};
} // end namespace Tetraedge
diff --git a/engines/tetraedge/module.mk b/engines/tetraedge/module.mk
index 12de439554e..01df59acb24 100644
--- a/engines/tetraedge/module.mk
+++ b/engines/tetraedge/module.mk
@@ -27,7 +27,6 @@ MODULE_OBJS := \
game/inventory_menu.o \
game/inventory_object.o \
game/inventory_objects_xml_parser.o \
- game/loading_menu.o \
game/loc_file.o \
game/lua_binds.o \
game/main_menu.o \
@@ -94,10 +93,8 @@ MODULE_OBJS := \
te/te_resource.o \
te/te_resource_manager.o \
te/te_scene.o \
- te/te_screen.o \
te/te_scrolling_layout.o \
te/te_scummvm_codec.o \
- te/te_sfx.o \
te/te_sound_manager.o \
te/te_sprite_layout.o \
te/te_text_base2.o \
diff --git a/engines/tetraedge/te/te_3d_texture.cpp b/engines/tetraedge/te/te_3d_texture.cpp
index 28fb1cdb3cb..a40b475343d 100644
--- a/engines/tetraedge/te/te_3d_texture.cpp
+++ b/engines/tetraedge/te/te_3d_texture.cpp
@@ -154,7 +154,7 @@ bool Te3DTexture::load(const TeImage &img) {
_width = img.w;
_height = img.h;
- _format = img._format;
+ _format = img.teFormat();
// TODO? set some other fields from the image here.
// for now just set some good defaults.
diff --git a/engines/tetraedge/te/te_3d_texture.h b/engines/tetraedge/te/te_3d_texture.h
index 2a37d0ad7c6..b217d8cf6b8 100644
--- a/engines/tetraedge/te/te_3d_texture.h
+++ b/engines/tetraedge/te/te_3d_texture.h
@@ -61,12 +61,14 @@ public:
void writeTo(Graphics::Surface &surf);
- int _numFrames;
- int _frameRate;
- uint _width;
- uint _height;
+ uint width() const { return _width; }
+ uint height() const { return _height; }
private:
+ uint _width;
+ uint _height;
+ int _numFrames;
+ int _frameRate;
TeImage::Format _format;
bool _createdTexture;
bool _loaded;
diff --git a/engines/tetraedge/te/te_act_zone.cpp b/engines/tetraedge/te/te_act_zone.cpp
index e6ec2ca3b09..092717f4441 100644
--- a/engines/tetraedge/te/te_act_zone.cpp
+++ b/engines/tetraedge/te/te_act_zone.cpp
@@ -26,6 +26,4 @@ namespace Tetraedge {
TeActZone::TeActZone() {
}
-// TODO: Add more functions here.
-
} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_animation.h b/engines/tetraedge/te/te_animation.h
index 41ee20eec7e..576b0688776 100644
--- a/engines/tetraedge/te/te_animation.h
+++ b/engines/tetraedge/te/te_animation.h
@@ -55,9 +55,9 @@ public:
TeTimer _runTimer;
int _repeatCount;
- bool _dontRepeat;
protected:
+ bool _dontRepeat;
TeSignal0Param _onStopSignal;
TeSignal0Param _onFinishedSignal;
diff --git a/engines/tetraedge/te/te_button_layout.h b/engines/tetraedge/te/te_button_layout.h
index 66c3b03481e..74abb0d398e 100644
--- a/engines/tetraedge/te/te_button_layout.h
+++ b/engines/tetraedge/te/te_button_layout.h
@@ -93,16 +93,18 @@ public:
TeSignal0Param &onButtonChangedToStateDownSignal() { return _onButtonChangedToStateDownSignal; };
TeSignal0Param &onButtonChangedToStateRolloverSignal() { return _onButtonChangedToStateRolloverSignal; };
- bool _ignoreMouseEvents;
- TeLayout *_upLayout;
- TeLayout *_downLayout;
+ TeLayout *upLayout() { return _upLayout; }
+ TeLayout *downLayout() { return _downLayout; }
+ void setIgnoreMouseEvents(bool val) { _ignoreMouseEvents = val; }
private:
static bool _mousePositionChangedCatched;
- bool _doubleValidationProtectionEnabled;
static TeTimer *getDoubleValidationProtectionTimer();
static TeTimer *_doubleValidationProtectionTimer;
+ bool _doubleValidationProtectionEnabled;
+ bool _ignoreMouseEvents;
+
State _currentState;
bool _clickPassThrough;
Common::String _validationSound;
@@ -119,6 +121,8 @@ private:
TeLayout *_rolloverLayout;
TeLayout *_disabledLayout;
TeLayout *_hitZoneLayout;
+ TeLayout *_upLayout;
+ TeLayout *_downLayout;
TeSignal0Param _onMouseClickValidatedSignal;
TeSignal0Param _onButtonChangedToStateUpSignal;
diff --git a/engines/tetraedge/te/te_camera.h b/engines/tetraedge/te/te_camera.h
index 43d8e4ae854..0d73a0a1859 100644
--- a/engines/tetraedge/te/te_camera.h
+++ b/engines/tetraedge/te/te_camera.h
@@ -64,20 +64,32 @@ public:
TeMatrix4x4 transformationMatrix();
TeVector3f32 transformCoord(const TeVector3f32 &pt);
TeVector3f32 transformPoint2Dto3D(const TeVector3f32 &pt);
- void updateProjectionMatrix();
void viewport(int x, int y, uint width, uint height);
TeVector2f32 viewportSize() const { return TeVector2f32(_viewportW, _viewportH); }
TeSignal0Param &onViewportChangedSignal() { return _onViewportChangedSignal; }
- int _projectionMatrixType;
+ void setFov(float fov) { _fov = fov; }
+ void setOrthoPlanes(float near, float far) {
+ _orthFarVal = far;
+ _orthNearVal = near;
+ }
+ void setProjMatrixType(int matrixType) { _projectionMatrixType = matrixType; }
+ int projMatrixType() const { return _projectionMatrixType; }
+ void setPerspectiveVal(float val) { _somePerspectiveVal = val; }
+ float orthoNearPlane() const { return _orthNearVal; }
+ float orthoFarPlane() const { return _orthNearVal; }
+
+private:
+ void updateProjectionMatrix();
+
+ int _projectionMatrixType; // TODO: Should be an enum.
float _orthNearVal;
float _orthFarVal;
float _fov;
float _somePerspectiveVal;
-private:
int _viewportX;
int _viewportY;
uint _viewportW;
diff --git a/engines/tetraedge/te/te_checkbox_layout.h b/engines/tetraedge/te/te_checkbox_layout.h
index 11cb9def573..c5352a98a8a 100644
--- a/engines/tetraedge/te/te_checkbox_layout.h
+++ b/engines/tetraedge/te/te_checkbox_layout.h
@@ -70,6 +70,7 @@ private:
TeLayout *_activeRollOverLayout;
TeLayout *_unactiveRollOverLayout;
TeLayout *_hitZone;
+
bool _clickPassThrough;
Common::String _activationSound;
Common::String _unactivationSound;
diff --git a/engines/tetraedge/te/te_clip_layout.cpp b/engines/tetraedge/te/te_clip_layout.cpp
index e5a3e42cbf2..c3bb6ee8454 100644
--- a/engines/tetraedge/te/te_clip_layout.cpp
+++ b/engines/tetraedge/te/te_clip_layout.cpp
@@ -26,6 +26,4 @@ namespace Tetraedge {
TeClipLayout::TeClipLayout() {
}
-// TODO: Add more functions here.
-
} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_clip_layout.h b/engines/tetraedge/te/te_clip_layout.h
index 6d788adb44a..3df4d741f80 100644
--- a/engines/tetraedge/te/te_clip_layout.h
+++ b/engines/tetraedge/te/te_clip_layout.h
@@ -26,15 +26,11 @@
namespace Tetraedge {
+// Not used in Syberia1
class TeClipLayout : public TeLayout {
public:
TeClipLayout();
- // TODO add public members
-
-private:
- // TODO add private members
-
};
} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_core.h b/engines/tetraedge/te/te_core.h
index 8785a29f040..ec0f518d981 100644
--- a/engines/tetraedge/te/te_core.h
+++ b/engines/tetraedge/te/te_core.h
@@ -64,6 +64,7 @@ public:
Common::Path findFile(const Common::Path &path);
bool _coreNotReady;
+
private:
TeILoc *_loc;
diff --git a/engines/tetraedge/te/te_font3.h b/engines/tetraedge/te/te_font3.h
index 7350d355049..e30918d66f1 100644
--- a/engines/tetraedge/te/te_font3.h
+++ b/engines/tetraedge/te/te_font3.h
@@ -56,7 +56,6 @@ public:
AlignCenter
};
- class FontSizeData {};
struct GlyphData {
uint32 _charcode;
Common::Rect _bitmapSize;
@@ -65,7 +64,6 @@ public:
bool load(const Common::Path &path);
void unload();
- void init();
GlyphData glyph(unsigned int size, unsigned int charcode);
@@ -77,13 +75,15 @@ public:
return _fontSizeData[size];
}
- int wordWrapText(const Common::String &str, int fontSize, int maxWidth, Common::Array<Common::String> &lines);
Common::Rect getBoundingBox(const Common::String &str, int fontSize);
int getHeight(int fontSize);
void draw(TeImage &destImage, const Common::String &str, int fontSize, int yoff, const TeColor &col, AlignStyle alignMode);
+ int wordWrapText(const Common::String &str, int fontSize, int maxWidth, Common::Array<Common::String> &lines);
+
private:
+ void init();
Graphics::Font *getAtSize(unsigned int size);
Common::File _fontFile;
diff --git a/engines/tetraedge/te/te_frame_anim.h b/engines/tetraedge/te/te_frame_anim.h
index ca717ee6588..cfe2cb5fc54 100644
--- a/engines/tetraedge/te/te_frame_anim.h
+++ b/engines/tetraedge/te/te_frame_anim.h
@@ -36,20 +36,31 @@ public:
TeSignal0Param &frameChangedSignal() { return _frameChangedSignal; };
- int _nbFrames;
+ void setFrameRate(float rate) { _frameRate = rate; }
+ void setNbFrames(int frames) { _nbFrames = frames; }
+ void setLoopCount(int count) { _loopCount = count; }
+ void setReversed(bool reverse) { _reversed = reverse; }
+
+ void setStartTime(double start) { _startTime = start; }
+ void setEndTime(double end) { _endTime = end; }
+
+ int lastFrameShown() const { return _lastFrameShown; }
+
+private:
float _frameRate;
int _loopCount;
+ int _nbFrames;
+ int _numFramesToShow;
+
bool _reversed;
+
int _lastFrameShown;
int _minFrame;
- int _numFramesToShow;
double _startTime;
double _endTime;
-private:
TeSignal0Param _frameChangedSignal;
-
};
} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_free_move_zone.cpp b/engines/tetraedge/te/te_free_move_zone.cpp
index 212827f9c75..77b5be41363 100644
--- a/engines/tetraedge/te/te_free_move_zone.cpp
+++ b/engines/tetraedge/te/te_free_move_zone.cpp
@@ -807,7 +807,7 @@ TePickMesh2 *TeFreeMoveZone::findNearestMesh(TeIntrusivePtr<TeCamera> &camera, c
Common::Array<TePickMesh2*> &pickMeshes, TeVector3f32 *outloc, bool lastHitFirst) {
TeVector3f32 closestLoc;
TePickMesh2 *nearestMesh = nullptr;
- float closestDist = camera->_orthFarVal;
+ float closestDist = camera->orthoFarPlane();
Math::Ray camRay;
for (unsigned int i = 0; i < pickMeshes.size(); i++) {
TePickMesh2 *mesh = pickMeshes[i];
@@ -825,7 +825,7 @@ TePickMesh2 *TeFreeMoveZone::findNearestMesh(TeIntrusivePtr<TeCamera> &camera, c
TeVector3f32 intersectLoc;
float intersectDist;
bool intResult = camRay.intersectTriangle(v1, v2, v3, intersectLoc, intersectDist);
- if (intResult && intersectDist < closestDist && intersectDist >= camera->_orthNearVal)
+ if (intResult && intersectDist < closestDist && intersectDist >= camera->orthoNearPlane())
return mesh;
}
for (unsigned int tri = 0; tri < mesh->verticies().size() / 3; tri++) {
@@ -841,7 +841,7 @@ TePickMesh2 *TeFreeMoveZone::findNearestMesh(TeIntrusivePtr<TeCamera> &camera, c
TeVector3f32(camRay.getDirection()).dump().c_str(),
v1.dump().c_str(), v2.dump().c_str(), v3.dump().c_str(),
intResult ? "hit!" : "no hit");*/
- if (intResult && intersectDist < closestDist && intersectDist >= camera->_orthNearVal) {
+ if (intResult && intersectDist < closestDist && intersectDist >= camera->orthoNearPlane()) {
mesh->setLastTriangleHit(tri);
closestLoc = intersectLoc;
closestDist = intersectDist;
diff --git a/engines/tetraedge/te/te_i_loc.cpp b/engines/tetraedge/te/te_i_loc.cpp
index 4857660beff..54fc157b5f6 100644
--- a/engines/tetraedge/te/te_i_loc.cpp
+++ b/engines/tetraedge/te/te_i_loc.cpp
@@ -26,7 +26,7 @@ namespace Tetraedge {
TeILoc::TeILoc() {
}
-Common::String *TeILoc::text(const Common::String &key) {
+const Common::String *TeILoc::text(const Common::String &key) const {
if (!_map.contains(key)) {
return nullptr;
}
diff --git a/engines/tetraedge/te/te_i_loc.h b/engines/tetraedge/te/te_i_loc.h
index 3293520332f..3296a5b74e4 100644
--- a/engines/tetraedge/te/te_i_loc.h
+++ b/engines/tetraedge/te/te_i_loc.h
@@ -32,7 +32,7 @@ public:
TeILoc();
virtual ~TeILoc() {};
- virtual Common::String *text(const Common::String &key);
+ virtual const Common::String *text(const Common::String &key) const;
protected:
Common::StringMap _map;
diff --git a/engines/tetraedge/te/te_image.cpp b/engines/tetraedge/te/te_image.cpp
index 49deda8b37e..01d5a638eaf 100644
--- a/engines/tetraedge/te/te_image.cpp
+++ b/engines/tetraedge/te/te_image.cpp
@@ -28,7 +28,7 @@
namespace Tetraedge {
-TeImage::TeImage() : ManagedSurface(), _format(INVALID) {
+TeImage::TeImage() : ManagedSurface(), _teFormat(INVALID) {
}
TeImage::TeImage(const TeImage &other) {
@@ -50,7 +50,7 @@ void TeImage::create() {
void TeImage::create(uint xsize, uint ysize, Common::SharedPtr<TePalette> &pal,
Format teformat, uint bufxsize, uint bufysize) {
- _format = teformat;
+ _teFormat = teformat;
Graphics::PixelFormat pxformat = ((teformat == TeImage::RGB8) ?
Graphics::PixelFormat(3, 8, 8, 8, 0, 16, 8, 0, 0) : Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24));
@@ -64,7 +64,7 @@ void TeImage::deserialize(Common::ReadStream &stream) {
void TeImage::destroy() {
Graphics::ManagedSurface::free();
- _format = INVALID;
+ _teFormat = INVALID;
}
void TeImage::drawPlot(void *outbuf, int x, int y, const TeVector2s32 &bufsize, const TeColor &col) {
diff --git a/engines/tetraedge/te/te_image.h b/engines/tetraedge/te/te_image.h
index 16dacc6e9ae..e363ef3d574 100644
--- a/engines/tetraedge/te/te_image.h
+++ b/engines/tetraedge/te/te_image.h
@@ -80,13 +80,10 @@ public:
TeVector2s32 bufSize() const {
return TeVector2s32(pitch / format.bytesPerPixel, h);
}
-
- Format _format;
+ Format teFormat() const { return _teFormat; }
private:
-
- // No private members?
-
+ Format _teFormat;
};
} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_list_layout.h b/engines/tetraedge/te/te_list_layout.h
index b631891c8b3..15d10a60540 100644
--- a/engines/tetraedge/te/te_list_layout.h
+++ b/engines/tetraedge/te/te_list_layout.h
@@ -30,11 +30,18 @@ class TeListLayout : public TeLayout {
public:
TeListLayout();
+ void setMinimumMargin(const TeVector3f32 &val) { _minimumMargin = val; }
+ void setMaximumMargin(const TeVector3f32 &val) { _maximumMargin = val; }
+ void setDirection(const TeVector3f32 &val) { _direction = val; }
+
+ const TeVector3f32 &minimumMargin() { return _minimumMargin; }
+ const TeVector3f32 &maximumMargin() { return _maximumMargin; }
+ const TeVector3f32 &direction() { return _direction; }
+
+private:
TeVector3f32 _minimumMargin;
TeVector3f32 _maximumMargin;
TeVector3f32 _direction;
-private:
- // TODO add private members
};
diff --git a/engines/tetraedge/te/te_lua_gui_lua_callbacks.cpp b/engines/tetraedge/te/te_lua_gui_lua_callbacks.cpp
index 84cc5a90c54..c76e1316041 100644
--- a/engines/tetraedge/te/te_lua_gui_lua_callbacks.cpp
+++ b/engines/tetraedge/te/te_lua_gui_lua_callbacks.cpp
@@ -47,7 +47,7 @@ static Common::String TeLuaToTeString(lua_State *L, int index) {
}
}
-long TeLuaToS32(lua_State *L, int index) {
+static long TeLuaToS32(lua_State *L, int index) {
if (!lua_isnumber(L, index)) {
warning("TeLuaToS32:: not a number");
return 0;
@@ -83,7 +83,6 @@ static bool TeLuaToBool(lua_State *L, int index) {
}
}
-
static TeColor TeLuaToTeColor(lua_State *L, int index) {
TeColor retval(255, 255, 255, 255);
if (lua_type(L, index) != LUA_TTABLE) {
@@ -124,7 +123,6 @@ static TeColor TeLuaToTeColor(lua_State *L, int index) {
return retval;
}
-
static TeVector3f32 TeLuaToTeVector3f32(lua_State *L, int index, TeVector3f32 defaultVal) {
TeVector3f32 retval = defaultVal;
if (lua_type(L, index) != LUA_TTABLE) {
@@ -173,6 +171,7 @@ static Common::Array<float> TeLuaToFloatArray(lua_State *L, int index) {
return result;
}
+
static bool loadCommonLayoutItems(lua_State *L, const char *s, TeLayout *layout) {
if (!strcmp(s, "name")) {
layout->setName(TeLuaToTeString(L, -1));
@@ -229,7 +228,7 @@ int layoutBindings(lua_State *L) {
} else if (!strcmp(s, "consoleNoStretch")) {
warning("TODO: Handle _g_bWidescreen");
if (_g_bWidescreen) {
- layout->setScale(TeVector3f32(0.7500001f, 1.0f, 1.0f));
+ layout->setScale(TeVector3f32(0.75f, 1.0f, 1.0f));
}
} else {
warning("[TeLuaGUI.layoutBindings] Unreconized attribute : %s", s);
@@ -275,21 +274,21 @@ int listLayoutBindings(lua_State *L) {
if (loadCommonLayoutItems(L, s, layout)) {
// do nothing.
} else if (!strcmp(s, "direction")) {
- const TeVector3f32 lastDirection = layout->_direction;
+ const TeVector3f32 lastDirection = layout->direction();
const TeVector3f32 direction = TeLuaToTeVector3f32(L, -1, lastDirection);
- layout->_direction = direction;
+ layout->setDirection(direction);
} else if (!strcmp(s, "minimumMargin")) {
- const TeVector3f32 lastMinimumMargin = layout->_minimumMargin;
+ const TeVector3f32 lastMinimumMargin = layout->minimumMargin();
const TeVector3f32 minimumMargin = TeLuaToTeVector3f32(L, -1, lastMinimumMargin);
- layout->_minimumMargin = minimumMargin;
+ layout->setMinimumMargin(minimumMargin);
} else if (!strcmp(s, "maximumMargin")) {
- const TeVector3f32 lastMaximumMargin = layout->_maximumMargin;
+ const TeVector3f32 lastMaximumMargin = layout->maximumMargin();
const TeVector3f32 maximumMargin = TeLuaToTeVector3f32(L, -1, lastMaximumMargin);
- layout->_maximumMargin = maximumMargin;
+ layout->setMaximumMargin(maximumMargin);
} else if (!strcmp(s, "consoleNoStretch")) {
warning("TODO: Handle _g_bWidescreen");
if (_g_bWidescreen) {
- layout->setScale(TeVector3f32(0.7500001f, 1.0f, 1.0f));
+ layout->setScale(TeVector3f32(0.75f, 1.0f, 1.0f));
}
} else {
warning("[TeLuaGUI.layoutBindings] Unreconized attribute : %s", s);
@@ -364,11 +363,11 @@ int spriteLayoutBindings(lua_State *L) {
} else if (!strcmp(s, "bottomCropping")) {
layout->_tiledSurfacePtr->setBottomCropping(TeLuaToF32(L, -1));
} else if (!strcmp(s, "loopCount")) {
- layout->_tiledSurfacePtr->_frameAnim._loopCount = TeLuaToS32(L, -1);
+ layout->_tiledSurfacePtr->_frameAnim.setLoopCount(TeLuaToS32(L, -1));
} else if (!strcmp(s, "play")) {
playNow = TeLuaToBool(L, -1);
} else if (!strcmp(s, "reversed")) {
- layout->_tiledSurfacePtr->_frameAnim._reversed = TeLuaToBool(L, -1);
+ layout->_tiledSurfacePtr->_frameAnim.setReversed(TeLuaToBool(L, -1));
} else if (!strcmp(s, "startingFrame")) {
startingFrame = TeLuaToU32(L, -1);
} else if (!strcmp(s, "endingFrame")) {
@@ -376,7 +375,7 @@ int spriteLayoutBindings(lua_State *L) {
} else if (!strcmp(s, "consoleNoStretch")) {
warning("TODO: Handle _g_bWidescreen");
if (_g_bWidescreen) {
- layout->setScale(TeVector3f32(0.7500001f, 1.0f, 1.0f));
+ layout->setScale(TeVector3f32(0.75f, 1.0f, 1.0f));
}
} else {
warning("[TeLuaGUI.layoutBindings] Unreconized attribute : %s", s);
@@ -412,14 +411,14 @@ int spriteLayoutBindings(lua_State *L) {
layout->stop();
}
- TeICodec *codec = layout->_tiledSurfacePtr->_codec;
+ TeICodec *codec = layout->_tiledSurfacePtr->codec();
if (codec) {
float frameRate = codec->frameRate();
- layout->_tiledSurfacePtr->_frameAnim._startTime = (startingFrame / frameRate) * 1000.0 * 1000.0;
+ layout->_tiledSurfacePtr->_frameAnim.setStartTime((startingFrame / frameRate) * 1000.0 * 1000.0);
if (endingFrame == -1) {
- layout->_tiledSurfacePtr->_frameAnim._endTime = FLT_MAX;
+ layout->_tiledSurfacePtr->_frameAnim.setEndTime(FLT_MAX);
} else {
- layout->_tiledSurfacePtr->_frameAnim._endTime = (endingFrame / frameRate) * 1000.0 * 1000.0;
+ layout->_tiledSurfacePtr->_frameAnim.setEndTime((endingFrame / frameRate) * 1000.0 * 1000.0);
}
}
@@ -470,7 +469,7 @@ int buttonLayoutBindings(lua_State *L) {
} else if (!strcmp(s, "consoleNoStretch")) {
warning("TODO: Handle _g_bWidescreen");
if (_g_bWidescreen) {
- layout->setScale(TeVector3f32(0.7500001f, 1.0f, 1.0f));
+ layout->setScale(TeVector3f32(0.75f, 1.0f, 1.0f));
}
} else {
warning("[TeLuaGUI.buttonLayoutBindings] Unreconized attribute : %s", s);
@@ -540,7 +539,7 @@ int checkboxLayoutBindings(lua_State *L) {
} else if (!strcmp(s, "consoleNoStretch")) {
warning("TODO: Handle _g_bWidescreen");
if (_g_bWidescreen) {
- layout->setScale(TeVector3f32(0.7500001f, 1.0f, 1.0f));
+ layout->setScale(TeVector3f32(0.75f, 1.0f, 1.0f));
}
} else {
warning("[TeLuaGUI.checkboxLayoutBindings] Unreconized attribute : %s", s);
@@ -710,7 +709,7 @@ int textLayoutBindings(lua_State *L) {
} else if (!strcmp(s, "consoleNoStretch")) {
warning("TODO: Handle _g_bWidescreen");
if (_g_bWidescreen) {
- layout->setScale(TeVector3f32(0.7500001f, 1.0f, 1.0f));
+ layout->setScale(TeVector3f32(0.75f, 1.0f, 1.0f));
}
} else {
warning("[TeLuaGUI.textLayoutBindings] Unreconized attribute : %s", s);
@@ -861,7 +860,7 @@ int scrollingLayoutBindings(lua_State *L) {
} else if (!strcmp(s, "consoleNoStretch")) {
warning("TODO: Handle _g_bWidescreen");
if (_g_bWidescreen) {
- layout->setScale(TeVector3f32(0.7500001f, 1.0f, 1.0f));
+ layout->setScale(TeVector3f32(0.75f, 1.0f, 1.0f));
}
} else {
warning("[TeLuaGUI.scrollingLayoutBindings] Unreconized attribute : %s", s);
@@ -923,7 +922,7 @@ int extendedTextLayoutBindings(lua_State *L) {
} else if (!strcmp(s, "consoleNoStretch")) {
warning("TODO: Handle _g_bWidescreen");
if (_g_bWidescreen) {
- layout->setScale(TeVector3f32(0.7500001f, 1.0f, 1.0f));
+ layout->setScale(TeVector3f32(0.75f, 1.0f, 1.0f));
}
} else {
warning("[TeLuaGUI.textLayoutBindings] Unreconized attribute : %s", s);
diff --git a/engines/tetraedge/te/te_material.h b/engines/tetraedge/te/te_material.h
index 4758d1f5df8..7e0f3eec87d 100644
--- a/engines/tetraedge/te/te_material.h
+++ b/engines/tetraedge/te/te_material.h
@@ -64,9 +64,8 @@ public:
TeColor _specularColor;
TeColor _emissionColor;
float _shininess;
- bool _enableLights;
bool _enableSomethingDefault0;
-private:
+ bool _enableLights;
};
} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_model.cpp b/engines/tetraedge/te/te_model.cpp
index c5b1d4b67cc..f2c1460302f 100644
--- a/engines/tetraedge/te/te_model.cpp
+++ b/engines/tetraedge/te/te_model.cpp
@@ -58,7 +58,7 @@ void TeModel::blendMesh(const Common::String &s1, const Common::String &s2, floa
_meshBlenders.push_back(new MeshBlender(s1, s2, amount, this));
}
-int TeModel::checkFileType(Common::SeekableReadStream &instream) {
+int TeModel::checkFileType(Common::SeekableReadStream &instream) const {
char buf[4];
instream.seek(0);
int sz = instream.read(buf, 4);
diff --git a/engines/tetraedge/te/te_model.h b/engines/tetraedge/te/te_model.h
index ab27bb06384..ef9cf6da215 100644
--- a/engines/tetraedge/te/te_model.h
+++ b/engines/tetraedge/te/te_model.h
@@ -86,7 +86,7 @@ public:
void blendAnim(TeIntrusivePtr<TeModelAnimation>& anim, float amount, bool repeat);
void blendMesh(const Common::String &s1, const Common::String &s2, float amount);
- int checkFileType(Common::SeekableReadStream &instream);
+ int checkFileType(Common::SeekableReadStream &instream) const;
void create();
void destroy();
@@ -97,7 +97,6 @@ public:
int findOrAddWeights(const Common::Array<weightElement> &weights);
void forceMatrix(const TeMatrix4x4 &matrix);
TeTRS getBone(TeIntrusivePtr<TeModelAnimation> anim, unsigned int num);
- TeMatrix4x4 lerpElementsMatrix(unsigned int weightNum, const Common::Array<TeMatrix4x4> &matricies);
/* Align the stream to the nearest 4 byte boudary*/
static void loadAlign(Common::SeekableReadStream &stream);
@@ -109,9 +108,8 @@ public:
bool loadWeights(Common::ReadStream &stream, Common::Array<weightElement> &weights);
bool loadMesh(Common::SeekableReadStream &stream, TeMesh &mesh);
- void optimize();
- void update();
void removeAnim();
+ void update();
void saveBone(Common::SeekableWriteStream &stream, unsigned long boneno);
void saveMesh(Common::SeekableWriteStream &stream, const TeMesh &mesh);
@@ -126,27 +124,36 @@ public:
TeMatrix4x4 skinOffset(unsigned long boneno) const;
+ static Common::SeekableReadStream *tryLoadZlibStream(Common::SeekableReadStream &instr);
+
TeSignal2Param<const Common::String &, TeMatrix4x4 &> &bonesUpdatedSignal() { return _bonesUpdatedSignal; }
+ Common::Array<BonesBlender *> &boneBlenders() { return _boneBlenders; }
+ Common::Array<TeMesh> &meshes() { return _meshes; }
+ TeIntrusivePtr<TeTiledTexture> tiledTexture() { return _tiledTexture; }
- static Common::SeekableReadStream *tryLoadZlibStream(Common::SeekableReadStream &instr);
- TeIntrusivePtr<TeTiledTexture> _tiledTexture;
+ void setEnableLights(bool val) { _enableLights = val; }
+ void setTexturePath(const Common::Path &path) { _texturePath = path; }
+
+protected:
+ TeMatrix4x4 lerpElementsMatrix(unsigned int weightNum, const Common::Array<TeMatrix4x4> &matricies);
+ void optimize();
Common::Path _texturePath;
+ TeIntrusivePtr<TeTiledTexture> _tiledTexture;
+
bool _enableLights;
+ bool _matrixForced;
bool _skipSkinOffsets;
- Common::Array<TeMesh> _meshes;
- Common::Array<BonesBlender *> _boneBlenders;
-
-protected:
- bool _matrixForced;
TeMatrix4x4 _forcedMatrix;
+ Common::Array<BonesBlender *> _boneBlenders;
Common::Array<MeshBlender *> _meshBlenders;
Common::Array<bone> _bones;
Common::Array<TeMatrix4x4> _skinOffsets;
Common::Array<TeMatrix4x4> _boneMatricies;
Common::Array<TeMatrix4x4> _lerpedElements;
Common::Array<Common::Array<weightElement>> _weightElements;
+ Common::Array<TeMesh> _meshes;
TeQuaternion _boneRotation;
diff --git a/engines/tetraedge/te/te_palette.h b/engines/tetraedge/te/te_palette.h
index 4a93ab09e6b..816b4e305ff 100644
--- a/engines/tetraedge/te/te_palette.h
+++ b/engines/tetraedge/te/te_palette.h
@@ -28,11 +28,6 @@ class TePalette {
public:
TePalette();
- // TODO add public members
-
-private:
- // TODO add private members
-
};
} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_real_timer.h b/engines/tetraedge/te/te_real_timer.h
index 184e29c182a..78020556952 100644
--- a/engines/tetraedge/te/te_real_timer.h
+++ b/engines/tetraedge/te/te_real_timer.h
@@ -39,14 +39,14 @@ public:
unsigned long timeElapsed();
unsigned long timeFromLastTimeElapsed();
- bool _paused;
+ bool isPaused() const { return _paused; }
private:
+ bool _paused;
unsigned long _startTime;
unsigned long _startTime2;
unsigned long _pausedTime;
unsigned long _maxTimeSeen;
- // TODO add private members
};
diff --git a/engines/tetraedge/te/te_renderer.cpp b/engines/tetraedge/te/te_renderer.cpp
index 518b8578e31..0716a62e5e4 100644
--- a/engines/tetraedge/te/te_renderer.cpp
+++ b/engines/tetraedge/te/te_renderer.cpp
@@ -34,7 +34,7 @@ _numTransparentMeshes(0), _pendingTransparentMeshProperties(0) {
}
void TeRenderer::addTransparentMesh(const TeMesh &mesh, unsigned long i1, unsigned long tricount, unsigned long materialno) {
- const float orthNearVal = _currentCamera->_orthNearVal;
+ const float orthNearVal = _currentCamera->orthoNearPlane();
const TeMesh::Mode meshMode = mesh.getMode();
if (!tricount) {
if (meshMode == TeMesh::MeshMode_TriangleStrip) {
@@ -123,9 +123,9 @@ void TeRenderer::addTransparentMesh(const TeMesh &mesh, unsigned long i1, unsign
midpoint.z() -= orthNearVal;
float zOrder;
- if (_currentCamera->_projectionMatrixType < 4) {
+ if (_currentCamera->projMatrixType() < 4) {
zOrder = -midpoint.squaredLength();
- } else if (_currentCamera->_projectionMatrixType == 4) {
+ } else if (_currentCamera->projMatrixType() == 4) {
zOrder = midpoint.z() * midpoint.z();
} else {
zOrder = midpoint.squaredLength();
@@ -165,9 +165,9 @@ void TeRenderer::addTransparentMesh(const TeMesh &mesh, unsigned long i1, unsign
midpoint.z() -= orthNearVal;
float zOrder;
- if (_currentCamera->_projectionMatrixType < 4) {
+ if (_currentCamera->projMatrixType() < 4) {
zOrder = -midpoint.squaredLength();
- } else if (_currentCamera->_projectionMatrixType == 4) {
+ } else if (_currentCamera->projMatrixType() == 4) {
zOrder = midpoint.z() * midpoint.z();
} else {
zOrder = midpoint.squaredLength();
diff --git a/engines/tetraedge/te/te_screen.cpp b/engines/tetraedge/te/te_screen.cpp
deleted file mode 100644
index 34f4a4de4b2..00000000000
--- a/engines/tetraedge/te/te_screen.cpp
+++ /dev/null
@@ -1,31 +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 "tetraedge/te/te_screen.h"
-
-namespace Tetraedge {
-
-TeScreen::TeScreen() {
-}
-
-// TODO: Add more functions here.
-
-} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_screen.h b/engines/tetraedge/te/te_screen.h
deleted file mode 100644
index b00bc539664..00000000000
--- a/engines/tetraedge/te/te_screen.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 TETRAEDGE_TE_TE_SCREEN_H
-#define TETRAEDGE_TE_TE_SCREEN_H
-
-namespace Tetraedge {
-
-class TeScreen {
-public:
- TeScreen();
-
- // TODO add public members
-
-private:
- // TODO add private members
-
-};
-
-} // end namespace Tetraedge
-
-#endif // TETRAEDGE_TE_TE_SCREEN_H
diff --git a/engines/tetraedge/te/te_sfx.cpp b/engines/tetraedge/te/te_sfx.cpp
deleted file mode 100644
index cfb507ca39a..00000000000
--- a/engines/tetraedge/te/te_sfx.cpp
+++ /dev/null
@@ -1,31 +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 "tetraedge/te/te_sfx.h"
-
-namespace Tetraedge {
-
-TeSFX::TeSFX() {
-}
-
-// TODO: Add more functions here.
-
-} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_sfx.h b/engines/tetraedge/te/te_sfx.h
deleted file mode 100644
index c8d7eaa8361..00000000000
--- a/engines/tetraedge/te/te_sfx.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 TETRAEDGE_TE_TE_S_F_X_H
-#define TETRAEDGE_TE_TE_S_F_X_H
-
-namespace Tetraedge {
-
-class TeSFX {
-public:
- TeSFX();
-
- // TODO add public members
-
-private:
- // TODO add private members
-
-};
-
-} // end namespace Tetraedge
-
-#endif // TETRAEDGE_TE_TE_S_F_X_H
diff --git a/engines/tetraedge/te/te_sprite_layout.cpp b/engines/tetraedge/te/te_sprite_layout.cpp
index b3f30780fa1..6826cca91c2 100644
--- a/engines/tetraedge/te/te_sprite_layout.cpp
+++ b/engines/tetraedge/te/te_sprite_layout.cpp
@@ -82,7 +82,7 @@ bool TeSpriteLayout::load(const Common::Path &path) {
unload();
if (_tiledSurfacePtr->load(path)) {
- const TeVector2s32 texSize = _tiledSurfacePtr->_tiledTexture->_totalSize;
+ const TeVector2s32 texSize = _tiledSurfacePtr->tiledTexture()->totalSize();
if (texSize._y <= 0) {
setRatio(1.0);
} else {
@@ -102,7 +102,7 @@ bool TeSpriteLayout::load(TeIntrusivePtr<Te3DTexture> &texture) {
unload();
if (_tiledSurfacePtr->load(texture)) {
- const TeVector2s32 tiledTexSize = _tiledSurfacePtr->_tiledTexture->_totalSize;
+ const TeVector2s32 tiledTexSize = _tiledSurfacePtr->tiledTexture()->totalSize();
if (tiledTexSize._y <= 0) {
setRatio(1.0);
} else {
@@ -124,7 +124,7 @@ bool TeSpriteLayout::load(TeImage &img) {
unload();
if (_tiledSurfacePtr->load(img)) {
- const TeVector2s32 tiledTexSize = _tiledSurfacePtr->_tiledTexture->_totalSize;
+ const TeVector2s32 tiledTexSize = _tiledSurfacePtr->tiledTexture()->totalSize();
if (tiledTexSize._y <= 0) {
setRatio(1.0);
} else {
diff --git a/engines/tetraedge/te/te_tiled_surface.cpp b/engines/tetraedge/te/te_tiled_surface.cpp
index 6c7554f1f7f..5f60feec8b3 100644
--- a/engines/tetraedge/te/te_tiled_surface.cpp
+++ b/engines/tetraedge/te/te_tiled_surface.cpp
@@ -169,7 +169,7 @@ bool TeTiledSurface::onFrameAnimCurrentFrameChanged() {
Common::SharedPtr<TePalette> nullPal;
img.create(vidSize._x, vidSize._y, nullPal, _imgFormat, bufxsize, bufysize);
- if (_codec->update(_frameAnim._lastFrameShown, img))
+ if (_codec->update(_frameAnim.lastFrameShown(), img))
update(img);
return _codec->isAtEnd();
}
@@ -180,8 +180,8 @@ void TeTiledSurface::pause() {
void TeTiledSurface::play() {
if (_codec) {
- _frameAnim._nbFrames = _codec->nbFrames();
- _frameAnim._frameRate = _codec->frameRate();
+ _frameAnim.setNbFrames(_codec->nbFrames());
+ _frameAnim.setFrameRate(_codec->frameRate());
_frameAnim.play();
}
}
diff --git a/engines/tetraedge/te/te_tiled_surface.h b/engines/tetraedge/te/te_tiled_surface.h
index 85e54ead249..d9c9d14e9e7 100644
--- a/engines/tetraedge/te/te_tiled_surface.h
+++ b/engines/tetraedge/te/te_tiled_surface.h
@@ -86,7 +86,8 @@ public:
const Common::Path &path() const { return _path; }
TeFrameAnim _frameAnim;
- TeICodec *_codec;
+
+ TeICodec *codec() { return _codec; }
private:
float _bottomCrop;
@@ -94,6 +95,8 @@ private:
float _rightCrop;
float _topCrop;
+ TeICodec *_codec;
+
TeColor _colorKey;
bool _colorKeyActive;
float _colorKeyTolerence;
diff --git a/engines/tetraedge/te/te_tiled_texture.cpp b/engines/tetraedge/te/te_tiled_texture.cpp
index 839cacdde03..b6438ea57b1 100644
--- a/engines/tetraedge/te/te_tiled_texture.cpp
+++ b/engines/tetraedge/te/te_tiled_texture.cpp
@@ -83,7 +83,7 @@ bool TeTiledTexture::load(const TeImage &img) {
const TeImage *tileimage;
if (newTileSize != _totalSize) {
- TeImage *optimizedimg = optimisedTileImage(imgArray, newTileSize, Common::SharedPtr<TePalette>(), img._format);
+ TeImage *optimizedimg = optimisedTileImage(imgArray, newTileSize, Common::SharedPtr<TePalette>(), img.teFormat());
img.copy(*optimizedimg, TeVector2s32(0, 0), TeVector2s32(_tileSize._x * row, _tileSize._y * col), newTileSize);
//optimizedimg->_flipY = img._flipY;
Common::String accessName = Common::String::format("%s.Tile%dx%d", img.getAccessName().toString().c_str(), row, col);
@@ -98,9 +98,9 @@ bool TeTiledTexture::load(const TeImage &img) {
tiledata->_texture = new Te3DTexture();
tiledata->_texture->load(*tileimage);
tiledata->_vec2 = TeVector3f32
- ((float)tiledata->_texture->_width / (float)_totalSize._x,
- (float)tiledata->_texture->_height / (float)_totalSize._y, 0.0);
- _somethingSize += TeVector2s32(tiledata->_texture->_width, tiledata->_texture->_height);
+ ((float)tiledata->_texture->width() / (float)_totalSize._x,
+ (float)tiledata->_texture->height() / (float)_totalSize._y, 0.0);
+ _somethingSize += TeVector2s32(tiledata->_texture->width(), tiledata->_texture->height());
} else {
tiledata->_texture.release();
tiledata->_vec2 = TeVector3f32(0.0, 0.0, 0.0);
@@ -122,8 +122,8 @@ bool TeTiledTexture::load(const TeImage &img) {
bool TeTiledTexture::load(const TeIntrusivePtr<Te3DTexture> &texture) {
release();
- _tileSize._x = texture->_width;
- _tileSize._y = texture->_height;
+ _tileSize._x = texture->width();
+ _tileSize._y = texture->height();
_totalSize = _tileSize;
_tileArray.resize(1);
Tile *tileData = tile(TeVector2s32(0, 0));
@@ -146,7 +146,7 @@ long TeTiledTexture::numberOfRow() const {
TeImage *TeTiledTexture::optimisedTileImage(Common::Array<TeImage> &images, const TeVector2s32 &size,
const Common::SharedPtr<TePalette> &pal, enum TeImage::Format format) {
for (TeImage &image : images) {
- if (image.w == size._x && image.h == size._y && image._format == format) {
+ if (image.w == size._x && image.h == size._y && image.teFormat() == format) {
return ℑ
}
}
diff --git a/engines/tetraedge/te/te_tiled_texture.h b/engines/tetraedge/te/te_tiled_texture.h
index 8b2aa599af0..402a6d1aa21 100644
--- a/engines/tetraedge/te/te_tiled_texture.h
+++ b/engines/tetraedge/te/te_tiled_texture.h
@@ -52,7 +52,7 @@ public:
long numberOfColumns() const;
long numberOfRow() const;
- /*static*/ TeImage *optimisedTileImage(Common::Array<TeImage> &images, const TeVector2s32 &size,
+ TeImage *optimisedTileImage(Common::Array<TeImage> &images, const TeVector2s32 &size,
const Common::SharedPtr<TePalette> &pal, enum TeImage::Format format);
void release();
@@ -60,9 +60,10 @@ public:
Tile *tile(const TeVector2s32 &loc);
void update(const TeImage &image);
- TeVector2s32 _totalSize;
+ TeVector2s32 totalSize() const { return _totalSize; }
private:
+ TeVector2s32 _totalSize;
Common::Array<Tile> _tileArray;
TeVector2s32 _tileSize;
TeVector2s32 _somethingSize;
diff --git a/engines/tetraedge/te/te_timer.cpp b/engines/tetraedge/te/te_timer.cpp
index 7ca28da0095..97e62ec6a21 100644
--- a/engines/tetraedge/te/te_timer.cpp
+++ b/engines/tetraedge/te/te_timer.cpp
@@ -33,7 +33,7 @@ namespace Tetraedge {
TeTimer::TeTimer() : _stopped(true), _pausable(true), _alarmTime(0),
_startTime(0), _lastTimeElapsed(0), _startTimeOffset(0), _updated(false) {
- if (realTimer()->_paused) {
+ if (realTimer()->isPaused()) {
realTimer()->start();
_realTime = realTimer()->getTimeFromStart();
}
diff --git a/engines/tetraedge/tetraedge.h b/engines/tetraedge/tetraedge.h
index 0e2c6de5ab0..0afb7ec4cdc 100644
--- a/engines/tetraedge/tetraedge.h
+++ b/engines/tetraedge/tetraedge.h
@@ -106,7 +106,7 @@ public:
Common::Serializer s(nullptr, stream);
return syncGame(s);
}
-
+
static void getSavegameThumbnail(Graphics::Surface &thumb);
Common::Error loadGameState(int slot) override;
@@ -128,7 +128,6 @@ public:
private:
void configureSearchPaths();
-
};
extern TetraedgeEngine *g_engine;
Commit: 0d981983fceb19781888d241a4660e1a3f874fad
https://github.com/scummvm/scummvm/commit/0d981983fceb19781888d241a4660e1a3f874fad
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2023-01-16T17:36:43+01:00
Commit Message:
TETRAEDGE: add ability to save/load any time
Changed paths:
engines/tetraedge/tetraedge.cpp
engines/tetraedge/tetraedge.h
diff --git a/engines/tetraedge/tetraedge.cpp b/engines/tetraedge/tetraedge.cpp
index 5b8276b160f..32c0e25af12 100644
--- a/engines/tetraedge/tetraedge.cpp
+++ b/engines/tetraedge/tetraedge.cpp
@@ -175,6 +175,17 @@ int TetraedgeEngine::getDefaultScreenHeight() const {
return 600;
}
+bool TetraedgeEngine::onKeyUp(const Common::KeyState &state) {
+ if (state.keycode == Common::KEYCODE_l) {
+ if (loadGameDialog())
+ _game->initLoadedBackupData();
+ } else if (state.keycode == Common::KEYCODE_s) {
+ saveGameDialog();
+ }
+
+ return false;
+}
+
Common::Error TetraedgeEngine::run() {
initGraphics3d(getDefaultScreenWidth(), getDefaultScreenHeight());
@@ -189,12 +200,13 @@ Common::Error TetraedgeEngine::run() {
// Set the engine's debugger console
setDebugger(new Console());
+ getInputMgr()->_keyUpSignal.add(this, &TetraedgeEngine::onKeyUp);
+
// If a savegame was selected from the launcher, load it
int saveSlot = ConfMan.getInt("save_slot");
if (saveSlot != -1)
(void)loadGameState(saveSlot);
- // Simple event handling loop
Common::Event e;
while (!shouldQuit()) {
diff --git a/engines/tetraedge/tetraedge.h b/engines/tetraedge/tetraedge.h
index 0afb7ec4cdc..290638adbc5 100644
--- a/engines/tetraedge/tetraedge.h
+++ b/engines/tetraedge/tetraedge.h
@@ -25,6 +25,7 @@
#include "common/scummsys.h"
#include "common/system.h"
#include "common/error.h"
+#include "common/events.h"
#include "common/fs.h"
#include "common/hash-str.h"
#include "common/random.h"
@@ -123,6 +124,7 @@ public:
TeInputMgr *getInputMgr();
void openConfigDialog();
+ bool onKeyUp(const Common::KeyState &state);
static Common::StringArray splitString(const Common::String &text, char c);
Commit: 87bbf9660e409615d49551a1a2738d6b579aa2c9
https://github.com/scummvm/scummvm/commit/87bbf9660e409615d49551a1a2738d6b579aa2c9
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2023-01-16T17:36:43+01:00
Commit Message:
TETRAEDGE: Reduce dependency on OpenGL headers
Changed paths:
engines/tetraedge/game/application.cpp
engines/tetraedge/te/te_mesh.cpp
engines/tetraedge/te/te_mesh.h
engines/tetraedge/te/te_renderer.cpp
engines/tetraedge/te/te_renderer.h
engines/tetraedge/te/te_text_base2.cpp
engines/tetraedge/tetraedge.cpp
diff --git a/engines/tetraedge/game/application.cpp b/engines/tetraedge/game/application.cpp
index 493a24fdfd8..98ed7325b04 100644
--- a/engines/tetraedge/game/application.cpp
+++ b/engines/tetraedge/game/application.cpp
@@ -25,7 +25,6 @@
#include "common/util.h"
#include "common/events.h"
-#include "graphics/opengl/system_headers.h"
#include "graphics/scaler.h"
#include "tetraedge/tetraedge.h"
@@ -430,7 +429,7 @@ void Application::performRender() {
drawBack();
renderer->renderTransparentMeshes();
- renderer->clearBuffer(GL_ACCUM);
+ renderer->clearBuffer(TeRenderer::DepthBuffer);
if (game->running()) {
if (_drawShadows && game->scene()._character
&& game->scene().shadowLightNo() != -1
@@ -447,7 +446,7 @@ void Application::performRender() {
}
renderer->renderTransparentMeshes();
- renderer->clearBuffer(GL_ACCUM);
+ renderer->clearBuffer(TeRenderer::DepthBuffer);
drawFront();
renderer->renderTransparentMeshes();
game->scene().drawPath();
diff --git a/engines/tetraedge/te/te_mesh.cpp b/engines/tetraedge/te/te_mesh.cpp
index 66186576662..c368fc5501b 100644
--- a/engines/tetraedge/te/te_mesh.cpp
+++ b/engines/tetraedge/te/te_mesh.cpp
@@ -248,6 +248,10 @@ void TeMesh::resizeUpdatedTables(unsigned long newSize) {
_updatedNormals.resize(newSize);
}
+void TeMesh::setglTexEnvBlend() {
+ _gltexEnvMode = GL_BLEND;
+}
+
void TeMesh::setColor(const TeColor &col) {
Te3DObject2::setColor(col);
diff --git a/engines/tetraedge/te/te_mesh.h b/engines/tetraedge/te/te_mesh.h
index f09fb8bdb10..1399d88f858 100644
--- a/engines/tetraedge/te/te_mesh.h
+++ b/engines/tetraedge/te/te_mesh.h
@@ -108,10 +108,10 @@ public:
uint numIndexes() const { return _indexes.size(); }
uint numVerticies() const { return _verticies.size(); }
bool shouldDrawMaybe() const { return _shouldDraw; }
- uint gltexEnvMode() const { return _gltexEnvMode; }
+ uint32 gltexEnvMode() const { return _gltexEnvMode; }
void setShouldDraw(bool val) { _shouldDraw = val; }
- void setglTexEnv(unsigned int val) { _gltexEnvMode = val; }
+ void setglTexEnvBlend();
void setHasAlpha(bool val) { _hasAlpha = val; }
Common::Array<TeMaterial> &materials() { return _materials; }
@@ -143,7 +143,7 @@ private:
bool _drawWires;
bool _shouldDraw;
- unsigned int _gltexEnvMode;
+ uint32 _gltexEnvMode;
};
diff --git a/engines/tetraedge/te/te_renderer.cpp b/engines/tetraedge/te/te_renderer.cpp
index 0716a62e5e4..3da806d02d5 100644
--- a/engines/tetraedge/te/te_renderer.cpp
+++ b/engines/tetraedge/te/te_renderer.cpp
@@ -195,7 +195,14 @@ void TeRenderer::addTransparentMesh(const TeMesh &mesh, unsigned long i1, unsign
}
void TeRenderer::clearBuffer(TeRenderer::Buffer buf) {
- glClear(buf);
+ GLenum glBuf = 0;
+ if (buf & StencilBuffer)
+ glBuf |= GL_STENCIL_BUFFER_BIT;
+ if (buf & DepthBuffer)
+ glBuf |= GL_DEPTH_BUFFER_BIT;
+ if (buf & ColorBuffer)
+ glBuf |= GL_COLOR_BUFFER_BIT;
+ glClear(glBuf);
}
void TeRenderer::create() {
diff --git a/engines/tetraedge/te/te_renderer.h b/engines/tetraedge/te/te_renderer.h
index 61cb82a5904..752e29b8f55 100644
--- a/engines/tetraedge/te/te_renderer.h
+++ b/engines/tetraedge/te/te_renderer.h
@@ -55,7 +55,7 @@ public:
TeMaterial _material;
- uint _glTexEnvMode;
+ uint32 _glTexEnvMode;
uint _sourceTransparentMesh;
bool _hasColor;
float _zOrder;
@@ -67,7 +67,11 @@ public:
bool _shouldDraw;
};
- typedef uint32 Buffer;
+ enum Buffer {
+ DepthBuffer = 1,
+ ColorBuffer = 2,
+ StencilBuffer = 4
+ };
void addTransparentMesh(const TeMesh &mesh, unsigned long i1, unsigned long i2, unsigned long i3);
void checkError(const Common::String &str) {};
diff --git a/engines/tetraedge/te/te_text_base2.cpp b/engines/tetraedge/te/te_text_base2.cpp
index b78c8721d1a..19794a82b44 100644
--- a/engines/tetraedge/te/te_text_base2.cpp
+++ b/engines/tetraedge/te/te_text_base2.cpp
@@ -26,14 +26,13 @@
#endif
#include "tetraedge/te/te_text_base2.h"
-#include "graphics/opengl/system_headers.h"
namespace Tetraedge {
TeTextBase2::TeTextBase2() : _drawRect(0, 0), _size(0, 0),
_alignStyle(TeFont3::AlignLeft), _interLine(0.0f), _globalColor(0xff, 0xff, 0xff, 0xff),
_wrapMode(WrapModeFixed), _strikethrough(false), _fontSize(10), _valueWasSet(true) {
- _mesh.setglTexEnv(GL_BLEND);
+ _mesh.setglTexEnvBlend();
_mesh.setShouldDraw(true);
}
@@ -112,7 +111,7 @@ void TeTextBase2::build() {
_mesh.setConf(4, 4, TeMesh::MeshMode_TriangleStrip, 0, 0);
_mesh.defaultMaterial(texture);
- _mesh.setglTexEnv(GL_BLEND);
+ _mesh.setglTexEnvBlend();
_mesh.setShouldDraw(true);
_mesh.setColor(_globalColor);
_mesh.setVertex(0, TeVector3f32(_size._x * -0.5f, _size._y * -0.5f, 0.0f));
diff --git a/engines/tetraedge/tetraedge.cpp b/engines/tetraedge/tetraedge.cpp
index 32c0e25af12..d2afbf479a6 100644
--- a/engines/tetraedge/tetraedge.cpp
+++ b/engines/tetraedge/tetraedge.cpp
@@ -41,8 +41,6 @@
#include "tetraedge/te/te_sound_manager.h"
#include "tetraedge/te/te_input_mgr.h"
-#include "graphics/opengl/system_headers.h"
-
namespace Tetraedge {
TetraedgeEngine *g_engine;
Commit: 48015aa751d94e2e2ec05aa24ea1791bae9c2ccd
https://github.com/scummvm/scummvm/commit/48015aa751d94e2e2ec05aa24ea1791bae9c2ccd
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2023-01-16T17:36:43+01:00
Commit Message:
TETRAEDGE: Small fixes.
Changed paths:
engines/tetraedge/game/application.cpp
engines/tetraedge/game/game.cpp
engines/tetraedge/game/game.h
engines/tetraedge/game/main_menu.cpp
engines/tetraedge/te/te_camera.h
engines/tetraedge/te/te_free_move_zone.cpp
engines/tetraedge/te/te_text_base2.cpp
engines/tetraedge/tetraedge.cpp
diff --git a/engines/tetraedge/game/application.cpp b/engines/tetraedge/game/application.cpp
index 98ed7325b04..284cd0a6c90 100644
--- a/engines/tetraedge/game/application.cpp
+++ b/engines/tetraedge/game/application.cpp
@@ -299,7 +299,7 @@ void Application::startGame(bool newGame, int difficulty) {
_appSpriteLayout.unload();
if (newGame)
_difficulty = difficulty;
- g_engine->getGame()->enter(newGame);
+ g_engine->getGame()->enter();
}
void Application::resume() {
diff --git a/engines/tetraedge/game/game.cpp b/engines/tetraedge/game/game.cpp
index fc631015e28..8b66666b570 100644
--- a/engines/tetraedge/game/game.cpp
+++ b/engines/tetraedge/game/game.cpp
@@ -271,7 +271,7 @@ void Game::draw() {
}
}
-void Game::enter(bool newgame) {
+void Game::enter() {
_enteredFlag2 = true;
_entered = true;
_luaShowOwnerError = false;
@@ -339,7 +339,7 @@ void Game::enter(bool newgame) {
_inventory.cellphone()->onCallNumber().add(this, &Game::onCallNumber);
- if (!newgame) {
+ if (hasLoadName()) {
loadBackup(_loadName);
} else {
_gameLoadState = 1;
@@ -1016,6 +1016,10 @@ bool Game::onMouseClick(const Common::Point &pt) {
if (app->isFading())
return true;
+ // In case we capture a click during a video..
+ if (!_scene.currentCamera())
+ return false;
+
_posPlayer = TeVector3f32(-1.0f, -1.0f, -1.0f);
if (_previousMousePos == TeVector2s32(-1, -1)) {
_previousMousePos = pt;
diff --git a/engines/tetraedge/game/game.h b/engines/tetraedge/game/game.h
index 36979202b83..9674923b5e5 100644
--- a/engines/tetraedge/game/game.h
+++ b/engines/tetraedge/game/game.h
@@ -101,7 +101,7 @@ public:
void deleteNoScale();
void draw();
- void enter(bool newgame);
+ void enter(); // will load game if _loadName is set.
// Note: game uses ILayouts here..
static TeI3DObject2 *findLayoutByName(TeLayout *parent, const Common::String &name);
static TeSpriteLayout *findSpriteLayoutByName(TeLayout *parent, const Common::String &name);
diff --git a/engines/tetraedge/game/main_menu.cpp b/engines/tetraedge/game/main_menu.cpp
index a3deb90f071..9a02a952ac0 100644
--- a/engines/tetraedge/game/main_menu.cpp
+++ b/engines/tetraedge/game/main_menu.cpp
@@ -124,7 +124,9 @@ void MainMenu::enter() {
versionNum->setText(versionSectionStr + app->getVersionString());
}
- if (ConfMan.get("skip_mainmenu") == "true") {
+ // Skip the menu if we are loading.
+ Game *game = g_engine->getGame();
+ if (game->hasLoadName() || ConfMan.get("skip_mainmenu") == "true") {
onNewGameConfirmed();
}
}
diff --git a/engines/tetraedge/te/te_camera.h b/engines/tetraedge/te/te_camera.h
index 0d73a0a1859..1afc99d426c 100644
--- a/engines/tetraedge/te/te_camera.h
+++ b/engines/tetraedge/te/te_camera.h
@@ -79,7 +79,7 @@ public:
int projMatrixType() const { return _projectionMatrixType; }
void setPerspectiveVal(float val) { _somePerspectiveVal = val; }
float orthoNearPlane() const { return _orthNearVal; }
- float orthoFarPlane() const { return _orthNearVal; }
+ float orthoFarPlane() const { return _orthFarVal; }
private:
void updateProjectionMatrix();
diff --git a/engines/tetraedge/te/te_free_move_zone.cpp b/engines/tetraedge/te/te_free_move_zone.cpp
index 77b5be41363..ba4dd874364 100644
--- a/engines/tetraedge/te/te_free_move_zone.cpp
+++ b/engines/tetraedge/te/te_free_move_zone.cpp
@@ -807,6 +807,8 @@ TePickMesh2 *TeFreeMoveZone::findNearestMesh(TeIntrusivePtr<TeCamera> &camera, c
Common::Array<TePickMesh2*> &pickMeshes, TeVector3f32 *outloc, bool lastHitFirst) {
TeVector3f32 closestLoc;
TePickMesh2 *nearestMesh = nullptr;
+ if (!camera)
+ return nullptr;
float closestDist = camera->orthoFarPlane();
Math::Ray camRay;
for (unsigned int i = 0; i < pickMeshes.size(); i++) {
diff --git a/engines/tetraedge/te/te_text_base2.cpp b/engines/tetraedge/te/te_text_base2.cpp
index 19794a82b44..ed5015a16c7 100644
--- a/engines/tetraedge/te/te_text_base2.cpp
+++ b/engines/tetraedge/te/te_text_base2.cpp
@@ -214,7 +214,9 @@ void TeTextBase2::drawEmptyChar(unsigned int offset) {
void TeTextBase2::drawLine(TeImage &img, const Common::String &str, int yoffset) {
TeIntrusivePtr<TeFont3> font = _fonts[0];
- font->draw(img, str, _fontSize, yoffset, _globalColor, _alignStyle);
+ // Note: We draw this with black because the global color will be applied on
+ // the mesh.
+ font->draw(img, str, _fontSize, yoffset, TeColor(0, 0, 0, 255), _alignStyle);
}
unsigned int TeTextBase2::endOfWord(unsigned int offset) const {
diff --git a/engines/tetraedge/tetraedge.cpp b/engines/tetraedge/tetraedge.cpp
index d2afbf479a6..05bf6b71680 100644
--- a/engines/tetraedge/tetraedge.cpp
+++ b/engines/tetraedge/tetraedge.cpp
@@ -148,7 +148,7 @@ Common::Error TetraedgeEngine::loadGameState(int slot) {
return Common::kReadingFailed;
// The game will reopen the file and do the loading, see Game::initLoadedBackupData
- _game->setLoadName(saveStateName);
+ getGame()->setLoadName(saveStateName);
delete saveFile;
return Common::kNoError;
@@ -193,18 +193,22 @@ Common::Error TetraedgeEngine::run() {
_renderer = new TeRenderer();
_renderer->init();
_renderer->reset();
- _application->create();
// Set the engine's debugger console
setDebugger(new Console());
getInputMgr()->_keyUpSignal.add(this, &TetraedgeEngine::onKeyUp);
- // If a savegame was selected from the launcher, load it
+ // If a savegame was selected from the launcher, load it.
+ // Should be before application->create() because it only
+ // sets the game name to load inside the Game object. It will
+ // actually be loaded when the application is created.
int saveSlot = ConfMan.getInt("save_slot");
if (saveSlot != -1)
(void)loadGameState(saveSlot);
+ _application->create();
+
Common::Event e;
while (!shouldQuit()) {
Commit: d0d67e91f8b0479dda8a76c9e43374ad3b46932b
https://github.com/scummvm/scummvm/commit/d0d67e91f8b0479dda8a76c9e43374ad3b46932b
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2023-01-16T17:36:43+01:00
Commit Message:
TETRAEDGE: Reduce movement janks and accidental moves
Changed paths:
engines/tetraedge/game/character.cpp
engines/tetraedge/game/dialog2.cpp
engines/tetraedge/game/game.cpp
engines/tetraedge/game/question2.cpp
engines/tetraedge/game/question2.h
engines/tetraedge/te/te_button_layout.cpp
diff --git a/engines/tetraedge/game/character.cpp b/engines/tetraedge/game/character.cpp
index 2ba77527a05..757f9282216 100644
--- a/engines/tetraedge/game/character.cpp
+++ b/engines/tetraedge/game/character.cpp
@@ -174,7 +174,7 @@ float Character::animLength(const TeModelAnimation &modelanim, long bone, long l
lastframe = last;
int first = modelanim.firstFrame();
const TeVector3f32 starttrans = translationVectorFromAnim(modelanim, bone, first);
- const TeVector3f32 endtrans = translationVectorFromAnim(modelanim, bone, last);
+ const TeVector3f32 endtrans = translationVectorFromAnim(modelanim, bone, lastframe);
const TeVector3f32 secondtrans = translationVectorFromAnim(modelanim, bone, first + 1);
return ((endtrans.z() - starttrans.z()) + secondtrans.z()) - starttrans.z();
}
@@ -970,7 +970,7 @@ void Character::walkTo(float curveEnd, bool walkFlag) {
uint framecounts[4];
if (repeats == 0)
- framecounts[0] = UINT_MAX;
+ framecounts[0] = INT_MAX;
else
framecounts[0] = (repeats - 1) * _walkLoopAnimFrameCount + 29;
@@ -1011,7 +1011,7 @@ void Character::walkTo(float curveEnd, bool walkFlag) {
play();
return; // NOTE: early return here.
} else {
- // NPC walk
+ // Run or NPC walk
double intpart;
double remainder = modf(nloops, &intpart);
if (remainder >= 0.5) {
diff --git a/engines/tetraedge/game/dialog2.cpp b/engines/tetraedge/game/dialog2.cpp
index 159f076eb23..dd0e0f9a0d3 100644
--- a/engines/tetraedge/game/dialog2.cpp
+++ b/engines/tetraedge/game/dialog2.cpp
@@ -108,9 +108,7 @@ void Dialog2::load() {
TeButtonLayout *dialogBtn = _gui.buttonLayoutChecked("dialog");
- // WORKAROUND: Ensure this is always above the Game (which is set to pri 10000)
- Common::SharedPtr<TeCallback0Param<Dialog2>> callbackptr(new TeCallback0Param<Dialog2>(this, &Dialog2::onSkipButton, 20000.0f));
- dialogBtn->onMouseClickValidated().push_back(callbackptr);
+ dialogBtn->onMouseClickValidated().add(this, &Dialog2::onSkipButton);
TeCurveAnim2<TeLayout, TeVector3f32> *dialogAnimUp = _gui.layoutAnchorLinearAnimation("dialogAnimationUp");
TeCurveAnim2<TeLayout, TeVector3f32> *dialogAnimDown = _gui.layoutAnchorLinearAnimation("dialogAnimationDown");
@@ -160,7 +158,8 @@ bool Dialog2::onSkipButton() {
_music.stop();
}
}
- return false;
+ // Divergence from original: don't let clicks through on skip operation.
+ return true;
}
bool Dialog2::onSoundFinished() {
diff --git a/engines/tetraedge/game/game.cpp b/engines/tetraedge/game/game.cpp
index 8b66666b570..fa7ccca400c 100644
--- a/engines/tetraedge/game/game.cpp
+++ b/engines/tetraedge/game/game.cpp
@@ -1016,8 +1016,8 @@ bool Game::onMouseClick(const Common::Point &pt) {
if (app->isFading())
return true;
- // In case we capture a click during a video..
- if (!_scene.currentCamera())
+ // In case we capture a click during a video or dialog (shouldn't happen?)
+ if (!_scene.currentCamera() || _dialog2.isDialogPlaying() || _question2.isEntered())
return false;
_posPlayer = TeVector3f32(-1.0f, -1.0f, -1.0f);
diff --git a/engines/tetraedge/game/question2.cpp b/engines/tetraedge/game/question2.cpp
index 29e17670877..0d7394df0de 100644
--- a/engines/tetraedge/game/question2.cpp
+++ b/engines/tetraedge/game/question2.cpp
@@ -26,7 +26,7 @@
namespace Tetraedge {
-Question2::Question2() {
+Question2::Question2() : _entered(false) {
}
Question2::~Question2() {
@@ -40,9 +40,11 @@ void Question2::enter() {
TeButtonLayout *backgroundButton = _gui.buttonLayoutChecked("background");
backgroundButton->setVisible(true);
g_engine->getGame()->showMarkers(true);
+ _entered = true;
}
void Question2::leave() {
+ _entered = false;
TeLayout *background = _gui.layout("background");
if (!background)
return;
@@ -78,10 +80,6 @@ void Question2::load() {
if (backgroundButton) {
addChild(backgroundButton);
backgroundButton->setVisible(false);
-
- // WORKAROUND: Block clicks going to the Game (which is set to pri 10000)
- Common::SharedPtr<TeCallback0Param<Question2>> callbackptr(new TeCallback0Param<Question2>(this, &Question2::onBackgroundClick, 20000.0f));
- backgroundButton->onMouseClickValidated().push_back(callbackptr);
}
size();
}
diff --git a/engines/tetraedge/game/question2.h b/engines/tetraedge/game/question2.h
index 86201e499d5..4a2e9ad0f04 100644
--- a/engines/tetraedge/game/question2.h
+++ b/engines/tetraedge/game/question2.h
@@ -48,7 +48,7 @@ public:
void enter();
void leave();
void load();
- bool onBackgroundClick() { return false; }
+ bool isEntered() const { return _entered; }
bool onAnswerValidated(Answer &answer);
void pushAnswer(const Common::String &name, const Common::String &unk, const Common::String &path);
void unload();
@@ -56,6 +56,7 @@ public:
TeSignal1Param<const Common::String &> &onAnswerSignal() { return _onAnswerSignal; }
private:
+ bool _entered;
Common::Array<Answer *> _answers;
TeLuaGUI _gui;
TeSignal1Param<const Common::String &> _onAnswerSignal;
diff --git a/engines/tetraedge/te/te_button_layout.cpp b/engines/tetraedge/te/te_button_layout.cpp
index 1b935322932..39f11995cd9 100644
--- a/engines/tetraedge/te/te_button_layout.cpp
+++ b/engines/tetraedge/te/te_button_layout.cpp
@@ -158,8 +158,8 @@ bool TeButtonLayout::onMouseLeftUp(const Common::Point &pt) {
sndMgr->playFreeSound(_validationSound, _validationSoundVolume, "sfx");
}
setState(newState);
- _onMouseClickValidatedSignal.call();
- return !_clickPassThrough;
+ bool stopProcessing = _onMouseClickValidatedSignal.call();
+ return !_clickPassThrough || stopProcessing;
}
break;
case BUTTON_STATE_ROLLOVER:
Commit: 9cdfb0deee3d3c8c4815fb497b3b217d85ff9107
https://github.com/scummvm/scummvm/commit/9cdfb0deee3d3c8c4815fb497b3b217d85ff9107
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2023-01-16T17:36:43+01:00
Commit Message:
TETRAEDGE: Clean up includes
Changed paths:
engines/tetraedge/detection.cpp
diff --git a/engines/tetraedge/detection.cpp b/engines/tetraedge/detection.cpp
index 938be16631e..e019e66eb61 100644
--- a/engines/tetraedge/detection.cpp
+++ b/engines/tetraedge/detection.cpp
@@ -19,13 +19,6 @@
*
*/
-#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 "tetraedge/detection.h"
#include "tetraedge/detection_tables.h"
Commit: c4869ff02ffb3659172e1f1c0077770696cd342c
https://github.com/scummvm/scummvm/commit/c4869ff02ffb3659172e1f1c0077770696cd342c
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2023-01-16T17:36:43+01:00
Commit Message:
TETRAEDGE: Fix whitespace and use uint consistently
Changed paths:
engines/tetraedge/game/application.cpp
engines/tetraedge/game/cellphone.cpp
engines/tetraedge/game/character.cpp
engines/tetraedge/game/characters_shadow.cpp
engines/tetraedge/game/documents_browser.cpp
engines/tetraedge/game/game.cpp
engines/tetraedge/game/game_sound.cpp
engines/tetraedge/game/in_game_scene.cpp
engines/tetraedge/game/inventory.cpp
engines/tetraedge/game/lua_binds.cpp
engines/tetraedge/game/main_menu.cpp
engines/tetraedge/game/objectif.cpp
engines/tetraedge/metaengine.cpp
engines/tetraedge/te/micropather.cpp
engines/tetraedge/te/micropather.h
engines/tetraedge/te/te_3d_object2.cpp
engines/tetraedge/te/te_3d_object2.h
engines/tetraedge/te/te_3d_texture.cpp
engines/tetraedge/te/te_animation.cpp
engines/tetraedge/te/te_bezier_curve.cpp
engines/tetraedge/te/te_bezier_curve.h
engines/tetraedge/te/te_button_layout.h
engines/tetraedge/te/te_camera.cpp
engines/tetraedge/te/te_color.h
engines/tetraedge/te/te_core.cpp
engines/tetraedge/te/te_font3.cpp
engines/tetraedge/te/te_font3.h
engines/tetraedge/te/te_free_move_zone.cpp
engines/tetraedge/te/te_free_move_zone.h
engines/tetraedge/te/te_images_sequence.h
engines/tetraedge/te/te_layout.cpp
engines/tetraedge/te/te_lua_context.cpp
engines/tetraedge/te/te_lua_gui_lua_callbacks.cpp
engines/tetraedge/te/te_lua_thread.cpp
engines/tetraedge/te/te_matrix4x4.cpp
engines/tetraedge/te/te_mesh.cpp
engines/tetraedge/te/te_mesh.h
engines/tetraedge/te/te_model.cpp
engines/tetraedge/te/te_model.h
engines/tetraedge/te/te_model_animation.cpp
engines/tetraedge/te/te_model_animation.h
engines/tetraedge/te/te_model_vertex_animation.cpp
engines/tetraedge/te/te_model_vertex_animation.h
engines/tetraedge/te/te_music.cpp
engines/tetraedge/te/te_name_val_xml_parser.cpp
engines/tetraedge/te/te_pick_mesh2.cpp
engines/tetraedge/te/te_pick_mesh2.h
engines/tetraedge/te/te_ray_intersection.h
engines/tetraedge/te/te_renderer.cpp
engines/tetraedge/te/te_renderer.h
engines/tetraedge/te/te_scrolling_layout.cpp
engines/tetraedge/te/te_scrolling_layout.h
engines/tetraedge/te/te_text_base2.cpp
engines/tetraedge/te/te_text_base2.h
engines/tetraedge/te/te_text_layout.cpp
engines/tetraedge/te/te_text_layout_xml_parser.h
engines/tetraedge/te/te_tiled_surface.cpp
engines/tetraedge/te/te_tiled_texture.cpp
engines/tetraedge/te/te_tiled_texture.h
engines/tetraedge/tetraedge.h
diff --git a/engines/tetraedge/game/application.cpp b/engines/tetraedge/game/application.cpp
index 284cd0a6c90..bd0b9e3e526 100644
--- a/engines/tetraedge/game/application.cpp
+++ b/engines/tetraedge/game/application.cpp
@@ -345,9 +345,9 @@ bool Application::run() {
finalGui.unload();
}
_finishedGame = false;
- }
- InGameScene::updateScroll();
- TeObject::deleteNow();
+ }
+ InGameScene::updateScroll();
+ TeObject::deleteNow();
}
return true;
}
@@ -487,10 +487,10 @@ void Application::getSavegameThumbnail(Graphics::Surface &thumb) {
Graphics::Surface screen;
_visFade.texture()->writeTo(screen);
screen.flipVertical(Common::Rect(screen.w, screen.h));
- Common::ScopedPtr<Graphics::Surface> scaledScreen(screen.scale(kThumbnailWidth, kThumbnailHeight2));
- thumb.copyFrom(*scaledScreen);
- screen.free();
- scaledScreen->free();
+ Common::ScopedPtr<Graphics::Surface> scaledScreen(screen.scale(kThumbnailWidth, kThumbnailHeight2));
+ thumb.copyFrom(*scaledScreen);
+ screen.free();
+ scaledScreen->free();
}
bool Application::isFading() {
diff --git a/engines/tetraedge/game/cellphone.cpp b/engines/tetraedge/game/cellphone.cpp
index 1fbc2a719ef..bcfeb661b2e 100644
--- a/engines/tetraedge/game/cellphone.cpp
+++ b/engines/tetraedge/game/cellphone.cpp
@@ -128,7 +128,7 @@ bool Cellphone::onCloseButtonValidated() {
}
bool Cellphone::onNextNumber() {
- unsigned int numoffset = _nextNumber + 1;
+ uint numoffset = _nextNumber + 1;
if (numoffset < _textLayoutArray.size()) {
currentPage(numoffset);
}
@@ -137,9 +137,8 @@ bool Cellphone::onNextNumber() {
bool Cellphone::onPreviousNumber() {
int numoffset = _nextNumber - 1;
- if (numoffset >= 0) {
- currentPage(numoffset);
- }
+ if (numoffset >= 0)
+ currentPage(numoffset);
return false;
}
@@ -158,10 +157,10 @@ void Cellphone::unload() {
Common::Error Cellphone::syncState(Common::Serializer &s) {
Common::Array<Common::String> numbers = _addedNumbers;
- unsigned int numElems = numbers.size();
+ uint numElems = numbers.size();
s.syncAsUint32LE(numElems);
numbers.resize(numElems);
- for (unsigned int i = 0; i < numElems; i++) {
+ for (uint i = 0; i < numElems; i++) {
s.syncString(numbers[i]);
}
if (s.isLoading()) {
diff --git a/engines/tetraedge/game/character.cpp b/engines/tetraedge/game/character.cpp
index 757f9282216..ae9600d3edc 100644
--- a/engines/tetraedge/game/character.cpp
+++ b/engines/tetraedge/game/character.cpp
@@ -77,15 +77,15 @@ Character::~Character() {
deleteAnim();
Game *game = g_engine->getGame();
Common::Array<TeIntrusivePtr<TeModel>> &models = game->scene().models();
- for (unsigned int i = 0; i < models.size(); i++) {
+ for (uint i = 0; i < models.size(); i++) {
if (models[i] == _model) {
models.remove_at(i);
break;
}
}
removeAnim();
- for (unsigned int s = 0; s < 2; s++) {
- for (unsigned int i = 0; i < models.size(); i++) {
+ for (uint s = 0; s < 2; s++) {
+ for (uint i = 0; i < models.size(); i++) {
if (models[i] == _shadowModel[s]) {
models.remove_at(i);
break;
@@ -120,7 +120,7 @@ void Character::addCallback(const Common::String &animKey, const Common::String
if (fnName == "ChangeClef" && c->_triggerFrame == 31)
c->_triggerFrame = 15;
- const Common::Path animPath = _model->anim()->_loadedPath;
+ const Common::Path animPath = _model->anim()->loadedPath();
// Another difference.. the original messes with paths a bit - just
// use the file name, since it's already limited by character.
@@ -185,7 +185,7 @@ float Character::animLengthFromFile(const Common::String &animname, uint32 *pfra
return 0.0f;
}
TeIntrusivePtr<TeModelAnimation> anim = _model->anim();
- if (!anim->_loadedPath.toString().contains(animname)) {
+ if (!anim->loadedPath().toString().contains(animname)) {
Common::Path animpath("models/Anims");
animpath.joinInPlace(animname);
anim = animCacheLoad(animpath);
@@ -264,12 +264,12 @@ void Character::deleteAnim() {
void Character::deleteCallback(const Common::String &key, const Common::String &fnName, float f) {
_callbacksChanged = true;
assert(_model->anim());
- Common::String animFile = _model->anim()->_loadedPath.getLastComponent().toString();
+ Common::String animFile = _model->anim()->loadedPath().getLastComponent().toString();
if (!_callbacks.contains(animFile))
return;
Common::Array<Callback *> &cbs = _callbacks.getVal(animFile);
- for (unsigned int i = 0; i < cbs.size(); i++) {
+ for (uint i = 0; i < cbs.size(); i++) {
if (fnName.empty()) {
delete cbs[i];
// don't remove from array, clear at the end.
@@ -309,7 +309,7 @@ bool Character::isFramePassed(int frameno) {
}
bool Character::isWalkEnd() {
- const Common::String animFile = _model->anim()->_loadedPath.getLastComponent().toString();
+ const Common::String animFile = _model->anim()->loadedPath().getLastComponent().toString();
for (const auto & walkSettings : _characterSettings._walkSettings) {
if (walkSettings._value._walkParts[WalkPart_EndD]._file.contains(animFile)
|| walkSettings._value._walkParts[WalkPart_EndG]._file.contains(animFile))
@@ -446,7 +446,7 @@ bool Character::onBonesUpdate(const Common::String &boneName, TeMatrix4x4 &boneM
Game *game = g_engine->getGame();
if (boneName == "Pere") {
- const Common::String animfile = _model->anim()->_loadedPath.getLastComponent().toString();
+ const Common::String animfile = _model->anim()->loadedPath().getLastComponent().toString();
bool resetX = false;
if (game->scene()._character == this) {
for (const auto &walkSettings : _characterSettings._walkSettings) {
@@ -547,7 +547,7 @@ bool Character::onModelAnimationFinished() {
if (!_model->anim())
return false;
- const Common::Path loadedPath = _model->anim()->_loadedPath;
+ const Common::Path loadedPath = _model->anim()->loadedPath();
const Common::String animfile = loadedPath.getLastComponent().toString();
bool shouldAdjust = true;
@@ -619,7 +619,7 @@ bool Character::onModelAnimationFinished() {
void Character::permanentUpdate() {
assert(_model->anim());
- const Common::Path animPath = _model->anim()->_loadedPath;
+ const Common::Path &animPath = _model->anim()->loadedPath();
int curFrame = _model->anim()->curFrame2();
Game *game = g_engine->getGame();
_callbacksChanged = false;
@@ -892,14 +892,13 @@ void Character::update(double msFromStart) {
if (!endGAnim.empty() && _curAnimName == walkAnim(WalkPart_Loop) &&
((_curModelAnim->speed() * (msFromStart / 1000.0)) >= _walkTotalFrames)) {
if (_walkToFlag) {
- _walkToFlag = false;
- endMove();
+ _walkToFlag = false;
+ endMove();
} else {
- if (_walkEndAnimG) {
- setAnimation(walkAnim(WalkPart_EndG), false);
- } else {
- setAnimation(walkAnim(WalkPart_EndD), false);
- }
+ if (_walkEndAnimG)
+ setAnimation(walkAnim(WalkPart_EndG), false);
+ else
+ setAnimation(walkAnim(WalkPart_EndD), false);
}
}
@@ -990,20 +989,21 @@ void Character::walkTo(float curveEnd, bool walkFlag) {
switch(minoffset) {
case 0:
- remainder = 29;
- _walkEndAnimG = true;
- repeats--;
- break;
+ remainder = 29;
+ _walkEndAnimG = true;
+ repeats--;
+ break;
case 1:
- remainder = 13;
- break;
+ remainder = 13;
+ break;
case 2:
- remainder = 29;
- _walkEndAnimG = true;
- break;
+ remainder = 29;
+ _walkEndAnimG = true;
+ break;
case 3:
- remainder = 13;
- repeats++;
+ remainder = 13;
+ repeats++;
+ break;
}
_walkTotalFrames = _walkLoopAnimFrameCount * repeats + _walkStartAnimFrameCount + remainder;
const float loopAnimLen = animLengthFromFile(walkAnim(WalkPart_Loop), &remainder, remainder);
diff --git a/engines/tetraedge/game/characters_shadow.cpp b/engines/tetraedge/game/characters_shadow.cpp
index e422b41def9..3593488eedb 100644
--- a/engines/tetraedge/game/characters_shadow.cpp
+++ b/engines/tetraedge/game/characters_shadow.cpp
@@ -72,7 +72,7 @@ void CharactersShadow::createTexture(InGameScene *scene) {
_camera->apply();
glClearColor(0.0, 0.0, 0.0, 0.0);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ renderer->clearBuffer(TeRenderer::ColorAndDepth);
for (Character *character : scene->_characters) {
character->_model->draw();
@@ -81,7 +81,7 @@ void CharactersShadow::createTexture(InGameScene *scene) {
Te3DTexture::unbind();
glBindTexture(GL_TEXTURE_2D, _glTex);
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, _texSize, _texSize);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ renderer->clearBuffer(TeRenderer::ColorAndDepth);
TeCamera::restore();
TeCamera::restore();
@@ -124,25 +124,25 @@ void CharactersShadow::draw(InGameScene *scene) {
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
float f[4];
- for (unsigned int i = 0; i < 4; i++)
+ for (uint i = 0; i < 4; i++)
f[i] = matrix(i, 0);
glTexGenfv(GL_S, GL_EYE_PLANE, f);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
- for (unsigned int i = 0; i < 4; i++)
+ for (uint i = 0; i < 4; i++)
f[i] = matrix(i, 1);
glTexGenfv(GL_T, GL_EYE_PLANE, f);
glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
- for (unsigned int i = 0; i < 4; i++)
+ for (uint i = 0; i < 4; i++)
f[i] = matrix(i, 2);
glTexGenfv(GL_R, GL_EYE_PLANE, f);
glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
- for (unsigned int i = 0; i < 4; i++)
+ for (uint i = 0; i < 4; i++)
f[i] = matrix(i, 3);
glTexGenfv(GL_Q, GL_EYE_PLANE, f);
diff --git a/engines/tetraedge/game/documents_browser.cpp b/engines/tetraedge/game/documents_browser.cpp
index a99f231c728..a876feda3a0 100644
--- a/engines/tetraedge/game/documents_browser.cpp
+++ b/engines/tetraedge/game/documents_browser.cpp
@@ -54,7 +54,7 @@ void DocumentsBrowser::hideDocument() {
bool callFn = true;
Common::Array<Game::YieldedCallback> &yieldedcallbacks = game->yieldedCallbacks();
- for (unsigned int i = 0; i < yieldedcallbacks.size(); i++) {
+ for (uint i = 0; i < yieldedcallbacks.size(); i++) {
if (yieldedcallbacks[i]._luaFnName == "OnDocumentClosed" &&
yieldedcallbacks[i]._luaParam == docName) {
yieldedcallbacks.remove_at(i);
@@ -194,7 +194,7 @@ void DocumentsBrowser::showDocument(const Common::String &docName, long startPag
sprite->setSizeType(RELATIVE_TO_PARENT);
TeVector3f32 winSize = app->getMainWindow().size();
sprite->setSize(TeVector3f32(1.0f, (4.0f / (winSize.y() / winSize.x() * 4.0f)) *
- ((float)spriteSize._y / (float)spriteSize._x), 0.0f));
+ ((float)spriteSize._y / (float)spriteSize._x), 0.0f));
TeScrollingLayout *scroll = _gui1.scrollingLayout("scroll");
if (!scroll)
error("DocumentsBrowser::showDocument Couldn't fetch scroll object");
diff --git a/engines/tetraedge/game/game.cpp b/engines/tetraedge/game/game.cpp
index fa7ccca400c..ec45dbf41e4 100644
--- a/engines/tetraedge/game/game.cpp
+++ b/engines/tetraedge/game/game.cpp
@@ -389,7 +389,7 @@ void Game::finishGame() {
_playedTimer.stop();
/* Game does this but does nothing with result?
if (app->difficulty() == 2) {
- _playedTimer.getTimeFromStart();
+ _playedTimer.getTimeFromStart();
} */
app->credits().enter(false);
}
@@ -648,7 +648,7 @@ bool Game::initWarp(const Common::String &zone, const Common::String &scene, boo
_luaScript.execute("OnSelectedObject", _inventory.selectedObject());
}
- for (unsigned int i = 0; i < _gameSounds.size(); i++) {
+ for (uint i = 0; i < _gameSounds.size(); i++) {
if (_gameSounds[i]->retain())
continue;
_gameSounds[i]->stop();
@@ -691,7 +691,7 @@ static const char *DIALOG_IDS[20] = {
"KFJ", "KM", "KN", "KFM"};
bool Game::launchDialog(const Common::String &dname, uint param_2, const Common::String &charname,
- const Common::String &animfile, float animblend) {
+ const Common::String &animfile, float animblend) {
Application *app = g_engine->getApplication();
const Common::String *locstring = app->loc().value(dname);
@@ -722,7 +722,7 @@ bool Game::launchDialog(const Common::String &dname, uint param_2, const Common:
}
}
- for (unsigned int i = 0; i < ARRAYSIZE(DIALOG_IDS); i++) {
+ for (uint i = 0; i < ARRAYSIZE(DIALOG_IDS); i++) {
if (dname.contains(Common::String::format("_%s_", DIALOG_IDS[i])))
_dialogsTold++;
}
@@ -851,7 +851,7 @@ bool Game::onCharacterAnimationFinished(const Common::String &charName) {
if (!_scene._character)
return false;
- for (unsigned int i = 0; i < _yieldedCallbacks.size(); i++) {
+ for (uint i = 0; i < _yieldedCallbacks.size(); i++) {
YieldedCallback &cb = _yieldedCallbacks[i];
if (cb._luaFnName == "OnCharacterAnimationFinished" && cb._luaParam == charName) {
TeLuaThread *lua = cb._luaThread;
@@ -872,7 +872,7 @@ bool Game::onCharacterAnimationPlayerFinished(const Common::String &anim) {
return false;
bool callScripts = true;
- for (unsigned int i = 0; i < _yieldedCallbacks.size(); i++) {
+ for (uint i = 0; i < _yieldedCallbacks.size(); i++) {
YieldedCallback &cb = _yieldedCallbacks[i];
if (cb._luaFnName == "OnCharacterAnimationFinished" && cb._luaParam == "Kate") {
TeLuaThread *lua = cb._luaThread;
@@ -920,7 +920,7 @@ bool Game::onCharacterAnimationPlayerFinished(const Common::String &anim) {
}
bool Game::onDialogFinished(const Common::String &val) {
- for (unsigned int i = 0; i < _yieldedCallbacks.size(); i++) {
+ for (uint i = 0; i < _yieldedCallbacks.size(); i++) {
YieldedCallback &cb = _yieldedCallbacks[i];
if (cb._luaFnName == "OnDialogFinished" && cb._luaParam == val) {
TeLuaThread *lua = cb._luaThread;
@@ -952,7 +952,7 @@ bool Game::onDisplacementFinished() {
TeLuaThread *thread = nullptr;
- for (unsigned int i = 0; i < _yieldedCallbacks.size(); i++) {
+ for (uint i = 0; i < _yieldedCallbacks.size(); i++) {
YieldedCallback &cb = _yieldedCallbacks[i];
if (cb._luaFnName == "OnDisplacementFinished") {
thread = cb._luaThread;
@@ -1186,7 +1186,7 @@ bool Game::onMouseMove() {
bool checkedCursor = false;
if (!skipFullSearch && _scene.gui2().loaded()) {
TeLayout *bglayout = _scene.gui2().layoutChecked("background");
- for (unsigned int i = 0; i < bglayout->childCount(); i++) {
+ for (uint i = 0; i < bglayout->childCount(); i++) {
TeLayout *childlayout = dynamic_cast<TeLayout *>(bglayout->child(i));
if (childlayout && childlayout->isMouseIn(mouseLoc) && childlayout->visible()) {
for (int i = 0; i < ARRAYSIZE(cursorsTable); i++) {
@@ -1235,7 +1235,7 @@ bool Game::onVideoFinished() {
_music.stop();
_running = true;
bool resumed = false;
- for (unsigned int i = 0; i < _yieldedCallbacks.size(); i++) {
+ for (uint i = 0; i < _yieldedCallbacks.size(); i++) {
YieldedCallback &cb = _yieldedCallbacks[i];
if (cb._luaFnName == "OnMovieFinished" && cb._luaParam == vidPath) {
TeLuaThread *lua = cb._luaThread;
@@ -1317,7 +1317,7 @@ void Game::playRandomSound(const Common::String &name) {
}
int r = _randomSource.getRandomNumber(RAND_MAX);
float total2 = 0.0;
- unsigned int i = 0;
+ uint i = 0;
while (i < sndlist.size() && total2 <= r * 4.656613e-10 * total) {
total2 += sndlist[i]->_f1;
i++;
@@ -1445,11 +1445,10 @@ bool Game::setBackground(const Common::String &name) {
void Game::setCurrentObjectSprite(const Common::Path &spritePath) {
TeSpriteLayout *currentSprite = _inGameGui.spriteLayout("currentObjectSprite");
if (currentSprite) {
- if (spritePath.empty()) {
+ if (spritePath.empty())
currentSprite->unload();
- } else {
+ else
currentSprite->load(spritePath);
- }
}
}
@@ -1477,7 +1476,7 @@ bool Game::startAnimation(const Common::String &animName, int loopcount, bool re
}
void Game::stopSound(const Common::String &name) {
- for (unsigned int i = 0; i < _gameSounds.size(); i++) {
+ for (uint i = 0; i < _gameSounds.size(); i++) {
GameSound *sound = _gameSounds[i];
if (sound->rawPath() == name) {
sound->stop();
@@ -1504,7 +1503,7 @@ Common::Error Game::syncGame(Common::Serializer &s) {
_playedTimer.stop();
_playedTimer.start();
s.syncAsUint32LE(_objectsTakenVal);
- for (unsigned int i = 0; i < ARRAYSIZE(_objectsTakenBits); i++)
+ for (uint i = 0; i < ARRAYSIZE(_objectsTakenBits); i++)
s.syncAsByte(_objectsTakenBits[i]);
s.syncAsUint32LE(_dialogsTold);
s.syncString(_prevSceneName);
@@ -1524,7 +1523,7 @@ bool Game::unloadCharacter(const Common::String &charname) {
if (!c)
return false;
- for (unsigned int i = 0; i < _scene.models().size(); i++) {
+ for (uint i = 0; i < _scene.models().size(); i++) {
if (_scene.models()[i] == c->_model) {
_scene.models().remove_at(i);
break;
diff --git a/engines/tetraedge/game/game_sound.cpp b/engines/tetraedge/game/game_sound.cpp
index 16a86615ce3..b7f45c3cee1 100644
--- a/engines/tetraedge/game/game_sound.cpp
+++ b/engines/tetraedge/game/game_sound.cpp
@@ -36,7 +36,7 @@ bool GameSound::onSoundStopped() {
return false;
Common::Array<Game::YieldedCallback> &callbacks = game->yieldedCallbacks();
- for (unsigned int i = 0; i < callbacks.size(); i++) {
+ for (uint i = 0; i < callbacks.size(); i++) {
if (callbacks[i]._luaFnName == "OnFreeSoundFinished" && callbacks[i]._luaParam == _name) {
TeLuaThread *thread = callbacks[i]._luaThread;
callbacks.remove_at(i);
diff --git a/engines/tetraedge/game/in_game_scene.cpp b/engines/tetraedge/game/in_game_scene.cpp
index ec3d32449dd..4270975a61e 100644
--- a/engines/tetraedge/game/in_game_scene.cpp
+++ b/engines/tetraedge/game/in_game_scene.cpp
@@ -227,7 +227,7 @@ void InGameScene::convertPathToMesh(TeFreeMoveZone *zone) {
model->setScale(zone->scale());
unsigned long nverticies = zone->verticies().size();
model->meshes()[0].setConf(nverticies, nverticies, TeMesh::MeshMode_Triangles, 0, 0);
- for (unsigned int i = 0; i < nverticies; i++) {
+ for (uint i = 0; i < nverticies; i++) {
model->meshes()[0].setIndex(i, i);
model->meshes()[0].setVertex(i, zone->verticies()[i]);
model->meshes()[0].setNormal(i, TeVector3f32(0, 0, 1));
@@ -257,7 +257,7 @@ void InGameScene::deleteMarker(const Common::String &markerName) {
if (!isMarker(markerName))
return;
- for (unsigned int i = 0; i < _markers.size(); i++) {
+ for (uint i = 0; i < _markers.size(); i++) {
if (_markers[i]._name == markerName) {
_markers.remove_at(i);
break;
@@ -313,28 +313,28 @@ void InGameScene::deserializeModel(Common::ReadStream &stream, TeIntrusivePtr<Te
error("InGameScene::deserializeModel: Unxpected counts %d %d", indexcount, vertexcount);
mesh.setConf(vertexcount, indexcount, TeMesh::MeshMode_Triangles, 0, 0);
- for (unsigned int i = 0; i < indexcount; i++)
+ for (uint i = 0; i < indexcount; i++)
mesh.setIndex(i, stream.readUint32LE());
- for (unsigned int i = 0; i < vertexcount; i++) {
+ for (uint i = 0; i < vertexcount; i++) {
TeVector3f32::deserialize(stream, vec);
mesh.setVertex(i, vec);
}
- for (unsigned int i = 0; i < vertexcount; i++) {
+ for (uint i = 0; i < vertexcount; i++) {
TeVector3f32::deserialize(stream, vec);
mesh.setNormal(i, vec);
}
- for (unsigned int i = 0; i < vertexcount; i++) {
+ for (uint i = 0; i < vertexcount; i++) {
TeVector2f32::deserialize(stream, vec2);
mesh.setTextureUV(i, vec2);
}
- for (unsigned int i = 0; i < vertexcount; i++) {
+ for (uint i = 0; i < vertexcount; i++) {
col.deserialize(stream);
mesh.setColor(i, col);
}
pickmesh->setNbTriangles(indexcount / 3);
- for (unsigned int i = 0; i < indexcount; i++) {
+ for (uint i = 0; i < indexcount; i++) {
vec = mesh.vertex(mesh.index(i));
pickmesh->verticies()[i] = vec;
}
@@ -367,7 +367,7 @@ void InGameScene::draw() {
#endif
TeLight::updateGlobal();
- for (unsigned int i = 0; i < _lights.size(); i++)
+ for (uint i = 0; i < _lights.size(); i++)
_lights[i].update(i);
TeCamera::restore();
@@ -380,7 +380,7 @@ void InGameScene::drawPath() {
currentCamera()->apply();
g_engine->getRenderer()->disableZBuffer();
- for (unsigned int i = 0; i < _freeMoveZones.size(); i++)
+ for (uint i = 0; i < _freeMoveZones.size(); i++)
_freeMoveZones[i]->draw();
g_engine->getRenderer()->enableZBuffer();
@@ -545,7 +545,7 @@ bool InGameScene::load(const Common::Path &path) {
if (count > 1000000)
error("Improbable number of actzones %d", count);
_actZones.resize(count);
- for (unsigned int i = 0; i < _actZones.size(); i++) {
+ for (uint i = 0; i < _actZones.size(); i++) {
_actZones[i].s1 = Te3DObject2::deserializeString(actzonefile);
_actZones[i].s2 = Te3DObject2::deserializeString(actzonefile);
for (int j = 0; j < 4; j++)
@@ -557,7 +557,7 @@ bool InGameScene::load(const Common::Path &path) {
}
if (!_lights.empty()) {
TeLight::disableAll();
- for (unsigned int i = 0; i < _lights.size(); i++) {
+ for (uint i = 0; i < _lights.size(); i++) {
_lights[i].disable(i);
}
_lights.clear();
@@ -580,7 +580,7 @@ bool InGameScene::load(const Common::Path &path) {
uint32 ncameras = scenefile.readUint32LE();
if (ncameras > 1024)
error("Improbable number of cameras %d", ncameras);
- for (unsigned int i = 0; i < ncameras; i++) {
+ for (uint i = 0; i < ncameras; i++) {
TeIntrusivePtr<TeCamera> cam = new TeCamera();
deserializeCam(scenefile, cam);
cameras().push_back(cam);
@@ -589,7 +589,7 @@ bool InGameScene::load(const Common::Path &path) {
uint32 nobjects = scenefile.readUint32LE();
if (nobjects > 1024)
error("Improbable number of objects %d", nobjects);
- for (unsigned int i = 0; i < nobjects; i++) {
+ for (uint i = 0; i < nobjects; i++) {
TeIntrusivePtr<TeModel> model = new TeModel();
const Common::String modelname = Te3DObject2::deserializeString(scenefile);
model->setName(modelname);
@@ -624,7 +624,7 @@ bool InGameScene::load(const Common::Path &path) {
uint32 nfreemovezones = scenefile.readUint32LE();
if (nfreemovezones > 1024)
error("Improbable number of free move zones %d", nfreemovezones);
- for (unsigned int i = 0; i < nfreemovezones; i++) {
+ for (uint i = 0; i < nfreemovezones; i++) {
TeFreeMoveZone *zone = new TeFreeMoveZone();
TeFreeMoveZone::deserialize(scenefile, *zone, &_blockers, &_rectBlockers, &_actZones);
_freeMoveZones.push_back(zone);
@@ -634,7 +634,7 @@ bool InGameScene::load(const Common::Path &path) {
uint32 ncurves = scenefile.readUint32LE();
if (ncurves > 1024)
error("Improbable number of curves %d", ncurves);
- for (unsigned int i = 0; i < ncurves; i++) {
+ for (uint i = 0; i < ncurves; i++) {
TeIntrusivePtr<TeBezierCurve> curve = new TeBezierCurve();
TeBezierCurve::deserialize(scenefile, *curve);
curve->setVisible(true);
@@ -644,7 +644,7 @@ bool InGameScene::load(const Common::Path &path) {
uint32 ndummies = scenefile.readUint32LE();
if (ndummies > 1024)
error("Improbable number of dummies %d", ndummies);
- for (unsigned int i = 0; i < ndummies; i++) {
+ for (uint i = 0; i < ndummies; i++) {
InGameScene::Dummy dummy;
TeVector3f32 vec;
TeQuaternion rot;
@@ -702,7 +702,7 @@ bool InGameScene::loadLights(const Common::Path &path) {
_shadowFov = parser.getShadowFov();
TeLight::enableAll();
- for (unsigned int i = 0; i < _lights.size(); i++) {
+ for (uint i = 0; i < _lights.size(); i++) {
_lights[i].enable(i);
}
@@ -710,7 +710,7 @@ bool InGameScene::loadLights(const Common::Path &path) {
debug("--- Scene lights ---");
debug("Shadow: %s no:%d far:%.02f near:%.02f fov:%.02f", _shadowColor.dump().c_str(), _shadowLightNo, _shadowFarPlane, _shadowNearPlane, _shadowFov);
debug("Global: %s", TeLight::globalAmbient().dump().c_str());
- for (unsigned int i = 0; i < _lights.size(); i++) {
+ for (uint i = 0; i < _lights.size(); i++) {
debug("%s", _lights[i].dump().c_str());
}
debug("--- end lights ---");
@@ -827,7 +827,7 @@ void InGameScene::loadBlockers() {
if (nblockers > 1024)
error("Improbable number of blockers %d", nblockers);
_blockers.resize(nblockers);
- for (unsigned int i = 0; i < nblockers; i++) {
+ for (uint i = 0; i < nblockers; i++) {
_blockers[i]._s = Te3DObject2::deserializeString(blockersfile);
TeVector2f32::deserialize(blockersfile, _blockers[i]._pts[0]);
TeVector2f32::deserialize(blockersfile, _blockers[i]._pts[1]);
@@ -839,9 +839,9 @@ void InGameScene::loadBlockers() {
if (nrectblockers > 1024)
error("Improbable number of rectblockers %d", nrectblockers);
_rectBlockers.resize(nrectblockers);
- for (unsigned int i = 0; i < nrectblockers; i++) {
+ for (uint i = 0; i < nrectblockers; i++) {
_rectBlockers[i]._s = Te3DObject2::deserializeString(blockersfile);
- for (unsigned int j = 0; j < 4l; j++) {
+ for (uint j = 0; j < 4l; j++) {
TeVector2f32::deserialize(blockersfile, _rectBlockers[i]._pts[j]);
}
_rectBlockers[i]._enabled = true;
@@ -925,7 +925,7 @@ void InGameScene::onMainWindowSizeChanged() {
TeCamera *mainWinCam = g_engine->getApplication()->mainWindowCamera();
_viewportSize = mainWinCam->viewportSize();
Common::Array<TeIntrusivePtr<TeCamera>> &cams = cameras();
- for (unsigned int i = 0; i < cams.size(); i++) {
+ for (uint i = 0; i < cams.size(); i++) {
cams[i]->viewport(0, 0, _viewportSize.getX(), _viewportSize.getY());
}
}
@@ -1048,7 +1048,7 @@ void InGameScene::unloadCharacter(const Common::String &name) {
// TODO: deleteLater() something here..
_character = nullptr;
}
- for (unsigned int i = 0; i < _characters.size(); i++) {
+ for (uint i = 0; i < _characters.size(); i++) {
Character *c = _characters[i];
if (c && c->_model->name() == name) {
c->removeAnim();
@@ -1065,10 +1065,10 @@ void InGameScene::unloadCharacter(const Common::String &name) {
}
void InGameScene::unloadObject(const Common::String &name) {
- for (unsigned int i = 0; i < _object3Ds.size(); i++) {
+ for (uint i = 0; i < _object3Ds.size(); i++) {
if (_object3Ds[i]->model()->name() == name) {
// Remove from the scene models.
- for (unsigned int j = 0; j < models().size(); j++) {
+ for (uint j = 0; j < models().size(); j++) {
if (models()[j] == _object3Ds[i]->model()) {
models().remove_at(j);
break;
@@ -1154,7 +1154,7 @@ void InGameScene::update() {
_waitTime = -1.0;
_waitTimeTimer.stop();
bool resumed = false;
- for (unsigned int i = 0; i < game->yieldedCallbacks().size(); i++) {
+ for (uint i = 0; i < game->yieldedCallbacks().size(); i++) {
Game::YieldedCallback &yc = game->yieldedCallbacks()[i];
if (yc._luaFnName == "OnWaitFinished") {
TeLuaThread *thread = yc._luaThread;
@@ -1184,7 +1184,7 @@ void InGameScene::update() {
bool InGameScene::AnimObject::onFinished() {
Game *game = g_engine->getGame();
- for (unsigned int i = 0; i < game->yieldedCallbacks().size(); i++) {
+ for (uint i = 0; i < game->yieldedCallbacks().size(); i++) {
Game::YieldedCallback &yc = game->yieldedCallbacks()[i];
if (yc._luaFnName == "OnFinishedAnim" && yc._luaParam == _name) {
TeLuaThread *thread = yc._luaThread;
diff --git a/engines/tetraedge/game/inventory.cpp b/engines/tetraedge/game/inventory.cpp
index 05169ca366d..2a2be4ec074 100644
--- a/engines/tetraedge/game/inventory.cpp
+++ b/engines/tetraedge/game/inventory.cpp
@@ -211,10 +211,10 @@ bool Inventory::addObject(InventoryObject *obj) {
}
pageNo++;
}
- }
+ }
int pageno = 0;
- unsigned int totalSlots = 0;
+ uint totalSlots = 0;
bool retval = false;
const Common::String newObjName = obj->name();
auto invObjIter = _invObjects.begin();
@@ -498,13 +498,13 @@ bool Inventory::updateLayout() {
//#define DEBUG_SAVELOAD 1
Common::Error Inventory::syncState(Common::Serializer &s) {
- unsigned int nitems = _invObjects.size();
+ uint nitems = _invObjects.size();
s.syncAsUint32LE(nitems);
if (s.isLoading()) {
#if DEBUG_SAVELOAD
debug("Inventory::syncState: --- Loading %d inventory items: ---", nitems);
#endif
- for (unsigned int i = 0; i < nitems; i++) {
+ for (uint i = 0; i < nitems; i++) {
Common::String objname;
s.syncString(objname);
addObject(objname);
diff --git a/engines/tetraedge/game/lua_binds.cpp b/engines/tetraedge/game/lua_binds.cpp
index 52156f6c68d..01a57c56126 100644
--- a/engines/tetraedge/game/lua_binds.cpp
+++ b/engines/tetraedge/game/lua_binds.cpp
@@ -1551,7 +1551,7 @@ static int tolua_ExportedFunctions_Random00(lua_State *L) {
tolua_Error err;
if (tolua_isnumber(L, 1, 0, &err) && tolua_isnoobj(L, 2, &err)) {
double d1 = tolua_tonumber(L, 1, 0.0);
- unsigned int result = Random(d1);
+ uint result = Random(d1);
tolua_pushnumber(L, result);
return 1;
}
@@ -2111,7 +2111,7 @@ void LuaOpenBinds(lua_State *L) {
tolua_ExportedFunctions_MoveCharacterToAndWaitForEnd00);
tolua_function(L, "MoveCharacterPlayerTo", tolua_ExportedFunctions_MoveCharacterPlayerTo00);
// tolua_function(L, "MoveCharacterPlayerToAndWaitForEnd",
- // tolua_ExportedFunctions_MoveCharacterPlayerToAndWaitForEnd00); // Unused
+ // tolua_ExportedFunctions_MoveCharacterPlayerToAndWaitForEnd00); // Unused
// tolua_function(L, "MoveCharacterPlayerAtTo", tolua_ExportedFunctions_MoveCharacterPlayerAtTo00); // Unused
tolua_function(L, "SetCharacterPosition", tolua_ExportedFunctions_SetCharacterPosition00);
tolua_function(L, "PlaceCharacterOnDummy", tolua_ExportedFunctions_PlaceCharacterOnDummy00);
diff --git a/engines/tetraedge/game/main_menu.cpp b/engines/tetraedge/game/main_menu.cpp
index 9a02a952ac0..a996edf9263 100644
--- a/engines/tetraedge/game/main_menu.cpp
+++ b/engines/tetraedge/game/main_menu.cpp
@@ -199,7 +199,7 @@ bool MainMenu::onContinueGameButtonValidated() {
tryDisableButton("quitButton");
if (_confirmingTuto)
- return false;
+ return false;
app->captureFade();
leave();
diff --git a/engines/tetraedge/game/objectif.cpp b/engines/tetraedge/game/objectif.cpp
index 6d274095cb0..42a93841cb7 100644
--- a/engines/tetraedge/game/objectif.cpp
+++ b/engines/tetraedge/game/objectif.cpp
@@ -166,7 +166,7 @@ void Objectif::update() {
removeChildren();
int last_i = -1;
- for (unsigned int i = 0; i < _tasks.size(); i++) {
+ for (uint i = 0; i < _tasks.size(); i++) {
if (!_tasks[i]._taskFlag)
continue;
if (last_i != -1 && _tasks[i]._headTask == _tasks[last_i]._headTask)
@@ -174,7 +174,7 @@ void Objectif::update() {
last_i = i;
createChildLayout(tasks, _tasks[i]._headTask, false);
// Creating the subtasks for this head
- for (unsigned int j = 0; j < _tasks.size(); j++) {
+ for (uint j = 0; j < _tasks.size(); j++) {
if (_tasks[j]._taskFlag && _tasks[j]._headTask == _tasks[i]._headTask && _tasks[j]._subTask != "")
createChildLayout(tasks, _tasks[j]._subTask, true);
}
diff --git a/engines/tetraedge/metaengine.cpp b/engines/tetraedge/metaengine.cpp
index f88e5240f60..10d7d9cd0d7 100644
--- a/engines/tetraedge/metaengine.cpp
+++ b/engines/tetraedge/metaengine.cpp
@@ -36,11 +36,11 @@ bool TetraedgeMetaEngine::hasFeature(MetaEngineFeature f) const {
return
(f == kSavesUseExtendedFormat) ||
(f == kSimpleSavesNames) ||
- (f == kSupportsListSaves) ||
- (f == kSupportsDeleteSave) ||
- (f == kSavesSupportMetaInfo) ||
- (f == kSavesSupportThumbnail) ||
- (f == kSupportsLoadingDuringStartup);
+ (f == kSupportsListSaves) ||
+ (f == kSupportsDeleteSave) ||
+ (f == kSavesSupportMetaInfo) ||
+ (f == kSavesSupportThumbnail) ||
+ (f == kSupportsLoadingDuringStartup);
}
void TetraedgeMetaEngine::getSavegameThumbnail(Graphics::Surface &thumb) {
diff --git a/engines/tetraedge/te/micropather.cpp b/engines/tetraedge/te/micropather.cpp
index 2e469d6791f..4ad0c1af493 100644
--- a/engines/tetraedge/te/micropather.cpp
+++ b/engines/tetraedge/te/micropather.cpp
@@ -367,7 +367,7 @@ unsigned PathNodePool::Hash( void* voidval )
// public domain.
MP_UPTR val = (MP_UPTR)(voidval);
const unsigned char *p = (unsigned char *)(&val);
- unsigned int h = 2166136261;
+ uint h = 2166136261;
for( size_t i=0; i<sizeof(MP_UPTR); ++i, ++p ) {
h ^= *p;
@@ -704,20 +704,20 @@ void MicroPather::DumpStats()
void MicroPather::StatesInPool( Common::Array< void* >* stateVec )
{
- stateVec->clear();
+ stateVec->clear();
pathNodePool.AllStates( frame, stateVec );
}
void PathNodePool::AllStates( unsigned frame, Common::Array< void* >* stateVec )
{
- for ( Block* b=blocks; b; b=b->nextBlock )
- {
- for( unsigned i=0; i<allocate; ++i )
- {
- if ( b->pathNode[i].frame == frame )
- stateVec->push_back( b->pathNode[i].state );
- }
+ for ( Block* b=blocks; b; b=b->nextBlock )
+ {
+ for( unsigned i=0; i<allocate; ++i )
+ {
+ if ( b->pathNode[i].frame == frame )
+ stateVec->push_back( b->pathNode[i].state );
+ }
}
}
diff --git a/engines/tetraedge/te/micropather.h b/engines/tetraedge/te/micropather.h
index fa4fe3052ec..f4804f1a78a 100644
--- a/engines/tetraedge/te/micropather.h
+++ b/engines/tetraedge/te/micropather.h
@@ -107,7 +107,7 @@ namespace micropather
*/
class Graph
{
- public:
+ public:
virtual ~Graph() {}
/**
@@ -150,7 +150,7 @@ namespace micropather
*/
class PathNode
{
- public:
+ public:
void Init( unsigned _frame,
void* _state,
float _costFromStart,
@@ -210,7 +210,7 @@ namespace micropather
totalCost = FLT_MAX;
}
- private:
+ private:
void operator=( const PathNode& );
};
@@ -311,7 +311,7 @@ namespace micropather
unsigned Hash() const {
const unsigned char *p = (const unsigned char *)(&start);
- unsigned int h = 2166136261U;
+ uint h = 2166136261U;
for( unsigned i=0; i<sizeof(void*)*2; ++i, ++p ) {
h ^= *p;
@@ -363,7 +363,7 @@ namespace micropather
{
friend class micropather::PathNode;
- public:
+ public:
enum
{
SOLVED,
@@ -388,7 +388,7 @@ namespace micropather
would be set to 8x8 (64)
- If your map is large, something like 1/4 the number of possible
states is good.
- - If your state space is huge, use a multiple (5-10x) of the normal
+ - If your state space is huge, use a multiple (5-10x) of the normal
path. "Occasionally" call Reset() to free unused memory.
@param typicalAdjacent Used to determine cache size. The typical number of adjacent states
to a given state. (On a chessboard, 8.) Higher values use a little
@@ -431,7 +431,7 @@ namespace micropather
void StatesInPool( Common::Array< void* >* stateVec );
void GetCacheData( CacheData* data );
- private:
+ private:
MicroPather( const MicroPather& ); // undefined and unsupported
void operator=( const MicroPather ); // undefined and unsupported
diff --git a/engines/tetraedge/te/te_3d_object2.cpp b/engines/tetraedge/te/te_3d_object2.cpp
index 7519441900e..5f96a047c37 100644
--- a/engines/tetraedge/te/te_3d_object2.cpp
+++ b/engines/tetraedge/te/te_3d_object2.cpp
@@ -345,17 +345,17 @@ void Te3DObject2::deserializeVectorArray(Common::ReadStream &stream, Common::Arr
if (nentries > 1000000)
error("TeFreeMoveZone improbable number of vectors %d", nentries);
dest.resize(nentries);
- for (unsigned int i = 0; i < nentries; i++)
+ for (uint i = 0; i < nentries; i++)
TeVector3f32::deserialize(stream, dest[i]);
}
/*static*/
-void Te3DObject2::deserializeUintArray(Common::ReadStream &stream, Common::Array<unsigned int> &dest) {
+void Te3DObject2::deserializeUintArray(Common::ReadStream &stream, Common::Array<uint> &dest) {
uint32 nentries = stream.readUint32LE();
if (nentries > 1000000)
error("TeFreeMoveZone improbable number of ints %d", nentries);
dest.resize(nentries);
- for (unsigned int i = 0; i < nentries; i++)
+ for (uint i = 0; i < nentries; i++)
dest[i] = stream.readUint32LE();
}
diff --git a/engines/tetraedge/te/te_3d_object2.h b/engines/tetraedge/te/te_3d_object2.h
index 3c5e090888a..c094957c0d0 100644
--- a/engines/tetraedge/te/te_3d_object2.h
+++ b/engines/tetraedge/te/te_3d_object2.h
@@ -144,7 +144,7 @@ public:
static bool loadAndCheckFourCC(Common::ReadStream &stream, const char *str);
static Common::String deserializeString(Common::ReadStream &stream);
static void deserializeVectorArray(Common::ReadStream &stream, Common::Array<TeVector3f32> &dest);
- static void deserializeUintArray(Common::ReadStream &stream, Common::Array<unsigned int> &dest);
+ static void deserializeUintArray(Common::ReadStream &stream, Common::Array<uint> &dest);
protected:
TeVector3f32 _size;
diff --git a/engines/tetraedge/te/te_3d_texture.cpp b/engines/tetraedge/te/te_3d_texture.cpp
index a40b475343d..8d4e7a9a00d 100644
--- a/engines/tetraedge/te/te_3d_texture.cpp
+++ b/engines/tetraedge/te/te_3d_texture.cpp
@@ -55,10 +55,8 @@ void Te3DTexture::copyCurrentRender(uint xoffset, uint yoffset, uint x, uint y)
const TeVector3f32 offset((float)_leftBorder / _width, (float)_btmBorder / _height, 0.0);
_matrix.translate(offset);
const TeVector3f32 borderScale(
- 1.0 - (float)(_rightBorder + _leftBorder) /
- (float)_width,
- 1.0 - (float)(_topBorder + _btmBorder) /
- (float)_height, 1.0);
+ 1.0 - (float)(_rightBorder + _leftBorder) / (float)_width,
+ 1.0 - (float)(_topBorder + _btmBorder) / (float)_height, 1.0);
_matrix.scale(borderScale);
bind();
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, xoffset, yoffset, x, y, _texWidth, _texHeight);
@@ -96,7 +94,7 @@ void Te3DTexture::create() {
void Te3DTexture::destroy() {
if (_createdTexture) {
- glDeleteTextures(1, &_glTexture);
+ glDeleteTextures(1, &_glTexture);
}
_createdTexture = false;
_loaded = false;
@@ -200,7 +198,7 @@ bool Te3DTexture::load(const TeImage &img) {
_matrix.scale(TeVector3f32((float)_width / _texWidth, (float)_height / _texHeight, 1.0f));
_matrix.translate(TeVector3f32((float)_leftBorder / _width, (float)_btmBorder / _height, 0.0f));
_matrix.scale(TeVector3f32(1.0 - (float)(_rightBorder + _leftBorder) / _width,
- 1.0 - (float)(_topBorder + _btmBorder) / _height, 1.0f));
+ 1.0 - (float)(_topBorder + _btmBorder) / _height, 1.0f));
if (_flipY) {
_matrix.translate(TeVector3f32(0.0f, 1.0f, 0.0f));
_matrix.scale(TeVector3f32(1.0f, -1.0f, 1.0f));
diff --git a/engines/tetraedge/te/te_animation.cpp b/engines/tetraedge/te/te_animation.cpp
index 5256ce11d5f..7048112b137 100644
--- a/engines/tetraedge/te/te_animation.cpp
+++ b/engines/tetraedge/te/te_animation.cpp
@@ -113,7 +113,7 @@ void TeAnimation::updateAll() {
Common::Array<TeAnimation *> &anims = *animations();
// Note: update can cause events which cascade into animtaions
// getting deleted, so be careful about the numbers.
- for (unsigned int i = 0; i < anims.size(); i++) {
+ for (uint i = 0; i < anims.size(); i++) {
if (anims[i]->_runTimer.running()) {
float msFromStart = anims[i]->_runTimer.getTimeFromStart() / 1000.0;
anims[i]->update(msFromStart);
diff --git a/engines/tetraedge/te/te_bezier_curve.cpp b/engines/tetraedge/te/te_bezier_curve.cpp
index 400fbd1fc55..b92a6f9df98 100644
--- a/engines/tetraedge/te/te_bezier_curve.cpp
+++ b/engines/tetraedge/te/te_bezier_curve.cpp
@@ -44,18 +44,18 @@ void TeBezierCurve::draw() {
if (!worldVisible() || _controlPoints.empty())
return;
- TeMesh mesh1;
- TeMesh mesh2;
- unsigned int npoints = _controlPoints.size();
+ TeMesh mesh1;
+ TeMesh mesh2;
+ uint npoints = _controlPoints.size();
mesh1.setConf(npoints, npoints, TeMesh::MeshMode_Points, 0, 0);
- for (unsigned int i = 0; i < npoints; i++) {
+ for (uint i = 0; i < npoints; i++) {
mesh1.setVertex(i, _controlPoints[i]);
mesh1.setIndex(i, i);
}
mesh2.setConf(npoints, npoints, TeMesh::MeshMode_LineStrip, 0, 0);
- for (unsigned int i = 0; i < npoints; i++) {
+ for (uint i = 0; i < npoints; i++) {
mesh2.setVertex(i, _controlPoints[i]);
mesh2.setNormal(i, TeVector3f32(0.0f, 1.0f, 0.0));
mesh2.setIndex(i, i);
@@ -81,7 +81,7 @@ float TeBezierCurve::length() {
TeVector3f32 lastpt = _controlPoints[0];
lastpt.y() = 0;
- for (unsigned int i = 0; i < _numIterations; i++) {
+ for (uint i = 0; i < _numIterations; i++) {
float amount = (float)i / _numIterations;
TeVector3f32 pt = retrievePoint(amount);
pt.y() = 0;
@@ -111,7 +111,7 @@ float TeBezierCurve::rawLength() {
_rawLength = 0.0;
_rawLengths.clear();
_rawLengths.push_back(0.0);
- for (unsigned int i = 1; i < _controlPoints.size(); i++) {
+ for (uint i = 1; i < _controlPoints.size(); i++) {
const TeVector3f32 diff = _controlPoints[i] - _controlPoints[i - 1];
_rawLength += diff.length();
_rawLengths.push_back(_rawLength);
@@ -200,7 +200,7 @@ void TeBezierCurve::deserialize(Common::ReadStream &stream, TeBezierCurve &curve
if (npoints > 1000000)
error("TeBezierCurve::deserialize improbable number of control ponts %d", npoints);
- for (unsigned int i = 0; i < npoints; i++) {
+ for (uint i = 0; i < npoints; i++) {
TeVector3f32 vec;
TeVector3f32::deserialize(stream, vec);
curve._controlPoints.push_back(vec);
diff --git a/engines/tetraedge/te/te_bezier_curve.h b/engines/tetraedge/te/te_bezier_curve.h
index 358edb65a81..1626cb931f0 100644
--- a/engines/tetraedge/te/te_bezier_curve.h
+++ b/engines/tetraedge/te/te_bezier_curve.h
@@ -52,10 +52,10 @@ public:
static void deserialize(Common::ReadStream &stream, TeBezierCurve &curve);
const Common::Array<TeVector3f32> &controlPoints() { return _controlPoints; }
- unsigned int numIterations() const { return _numIterations; }
+ uint numIterations() const { return _numIterations; }
private:
- unsigned int _numIterations;
+ uint _numIterations;
float _length;
float _rawLength;
bool _lengthNeedsUpdate;
diff --git a/engines/tetraedge/te/te_button_layout.h b/engines/tetraedge/te/te_button_layout.h
index 74abb0d398e..240123ece2e 100644
--- a/engines/tetraedge/te/te_button_layout.h
+++ b/engines/tetraedge/te/te_button_layout.h
@@ -110,7 +110,7 @@ private:
Common::String _validationSound;
float _validationSoundVolume;
- Common::Array<unsigned int> _intArr;
+ Common::Array<uint> _intArr;
TeICallback1ParamPtr<const Common::Point &> _onMousePositionChangedMaxPriorityCallback;
TeICallback1ParamPtr<const Common::Point &> _onMousePositionChangedCallback;
diff --git a/engines/tetraedge/te/te_camera.cpp b/engines/tetraedge/te/te_camera.cpp
index 969aff846a9..3183ab78b5e 100644
--- a/engines/tetraedge/te/te_camera.cpp
+++ b/engines/tetraedge/te/te_camera.cpp
@@ -68,15 +68,15 @@ void TeCamera::applyTransformations() {
void TeCamera::buildOrthoMatrix() {
float widthNorm = FLT_MAX;
if ((_orthogonalParamR - _orthogonalParamL) != 0.0) {
- widthNorm = 1.0 / (_orthogonalParamR - _orthogonalParamL);
+ widthNorm = 1.0 / (_orthogonalParamR - _orthogonalParamL);
}
float heightNorm = FLT_MAX;
if (_orthogonalParamB - _orthogonalParamT != 0.0) {
- heightNorm = 1.0 / (_orthogonalParamB - _orthogonalParamT);
+ heightNorm = 1.0 / (_orthogonalParamB - _orthogonalParamT);
}
float depthNorm = FLT_MAX;
if ((_orthFarVal - _orthNearVal) != 0.0) {
- depthNorm = 1.0 / (_orthFarVal - _orthNearVal);
+ depthNorm = 1.0 / (_orthFarVal - _orthNearVal);
}
_projectionMatrix.setValue(0, 0, widthNorm * 2.0f);
diff --git a/engines/tetraedge/te/te_color.h b/engines/tetraedge/te/te_color.h
index 9e65d9e5435..99704bca302 100644
--- a/engines/tetraedge/te/te_color.h
+++ b/engines/tetraedge/te/te_color.h
@@ -59,7 +59,7 @@ public:
Common::String dump() const {
return Common::String::format("TeColor(%d %d %d %d)",
- _c[0], _c[1], _c[2], _c[3]);
+ _c[0], _c[1], _c[2], _c[3]);
}
private:
diff --git a/engines/tetraedge/te/te_core.cpp b/engines/tetraedge/te/te_core.cpp
index cc925988fbe..bb6b76e292d 100644
--- a/engines/tetraedge/te/te_core.cpp
+++ b/engines/tetraedge/te/te_core.cpp
@@ -168,7 +168,7 @@ Common::Path TeCore::findFile(const Common::Path &path) {
return testPath;
// also try the other way around
- if (!lang.empty() && !suffix.empty()) {
+ if (!lang.empty() && !suffix.empty()) {
testPath = dir.join(lang).joinInPlace(suffix).join(fname);
if (Common::File::exists(testPath) || Common::FSNode(testPath).exists())
return testPath;
diff --git a/engines/tetraedge/te/te_font3.cpp b/engines/tetraedge/te/te_font3.cpp
index 718084a7978..18c03a031cc 100644
--- a/engines/tetraedge/te/te_font3.cpp
+++ b/engines/tetraedge/te/te_font3.cpp
@@ -75,7 +75,7 @@ TeFont3::~TeFont3() {
unload();
}
-Graphics::Font *TeFont3::getAtSize(unsigned int size) {
+Graphics::Font *TeFont3::getAtSize(uint size) {
if (_fonts.contains(size))
return _fonts.getVal(size);
@@ -94,7 +94,7 @@ Graphics::Font *TeFont3::getAtSize(unsigned int size) {
return newFont;
}
-TeFont3::GlyphData TeFont3::glyph(unsigned int pxSize, unsigned int charcode) {
+TeFont3::GlyphData TeFont3::glyph(uint pxSize, uint charcode) {
Graphics::Font *font = getAtSize(pxSize);
Common::Rect bbox = font->getBoundingBox(charcode);
TeImage *img = new TeImage();
@@ -181,21 +181,21 @@ void TeFont3::unload() {
void TeFont3::init() {
}
-float TeFont3::ascender(unsigned int pxSize) {
+float TeFont3::ascender(uint pxSize) {
Graphics::Font *font = getAtSize(pxSize);
return font->getFontAscent();
}
-float TeFont3::descender(unsigned int pxSize) {
+float TeFont3::descender(uint pxSize) {
error("TODO: Implement TeFont3::descender");
}
-float TeFont3::height(unsigned int pxSize) {
+float TeFont3::height(uint pxSize) {
Graphics::Font *font = getAtSize(pxSize);
return font->getFontHeight();
}
-TeVector3f32 TeFont3::kerning(unsigned int pxSize, unsigned int isocode1, unsigned int isocode2) {
+TeVector3f32 TeFont3::kerning(uint pxSize, uint isocode1, uint isocode2) {
uint32 uni1 = getUnicodeFromISO(isocode1);
uint32 uni2 = getUnicodeFromISO(isocode2);
Graphics::Font *font = getAtSize(pxSize);
diff --git a/engines/tetraedge/te/te_font3.h b/engines/tetraedge/te/te_font3.h
index e30918d66f1..44876c3393c 100644
--- a/engines/tetraedge/te/te_font3.h
+++ b/engines/tetraedge/te/te_font3.h
@@ -65,12 +65,12 @@ public:
bool load(const Common::Path &path);
void unload();
- GlyphData glyph(unsigned int size, unsigned int charcode);
+ GlyphData glyph(uint size, uint charcode);
- float ascender(unsigned int pxSize);
- float descender(unsigned int pxSize);
- float height(unsigned int pxSize);
- TeVector3f32 kerning(unsigned int pxSize, unsigned int isocode1, unsigned int isocode2);
+ float ascender(uint pxSize);
+ float descender(uint pxSize);
+ float height(uint pxSize);
+ TeVector3f32 kerning(uint pxSize, uint isocode1, uint isocode2);
TeIntrusivePtr<Te3DTexture> getFontSizeData(int size) const {
return _fontSizeData[size];
}
@@ -84,12 +84,12 @@ public:
private:
void init();
- Graphics::Font *getAtSize(unsigned int size);
+ Graphics::Font *getAtSize(uint size);
Common::File _fontFile;
- Common::HashMap<unsigned int, Graphics::Font *> _fonts;
+ Common::HashMap<uint, Graphics::Font *> _fonts;
Common::Path _loadedPath;
- Common::HashMap<unsigned int, TeIntrusivePtr<Te3DTexture>> _fontSizeData;
+ Common::HashMap<uint, TeIntrusivePtr<Te3DTexture>> _fontSizeData;
};
} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_free_move_zone.cpp b/engines/tetraedge/te/te_free_move_zone.cpp
index ba4dd874364..9302d69c309 100644
--- a/engines/tetraedge/te/te_free_move_zone.cpp
+++ b/engines/tetraedge/te/te_free_move_zone.cpp
@@ -236,7 +236,7 @@ TeIntrusivePtr<TeBezierCurve> TeFreeMoveZone::curve(const TeVector3f32 &startpt,
/*static*/
void TeFreeMoveZone::deserialize(Common::ReadStream &stream, TeFreeMoveZone &dest, Common::Array<TeBlocker> *blockers,
- Common::Array<TeRectBlocker> *rectblockers, Common::Array<TeActZone> *actzones) {
+ Common::Array<TeRectBlocker> *rectblockers, Common::Array<TeActZone> *actzones) {
dest.clear();
TePickMesh2::deserialize(stream, dest);
TeVector2f32::deserialize(stream, dest._gridOffsetSomething);
@@ -276,7 +276,7 @@ void TeFreeMoveZone::draw() {
TePickMesh2::draw();
TeMesh mesh;
mesh.setConf(_borders.size(), _borders.size(), TeMesh::MeshMode_Lines, 0, 0);
- for (unsigned int i = 0; i < _borders.size(); i++) {
+ for (uint i = 0; i < _borders.size(); i++) {
mesh.setIndex(i, i);
mesh.setVertex(i, verticies()[_borders[i]]);
}
@@ -300,7 +300,7 @@ TeVector3f32 TeFreeMoveZone::findNearestPointOnBorder(const TeVector2f32 &pt) {
static int segmentIntersection(const TeVector2f32 &s1start, const TeVector2f32 &s1end,
const TeVector2f32 &s2start, const TeVector2f32 &s2end,
- TeVector2f32 *sout, float *fout1, float *fout2) {
+ TeVector2f32 *sout, float *fout1, float *fout2) {
TeVector2f32 s1len = s1end - s1start;
TeVector2f32 s2len = s2end - s2start;
float squarelen = s1len.getX() * s2len.getX() + s1len.getY() * s2len.getY();
@@ -309,11 +309,11 @@ static int segmentIntersection(const TeVector2f32 &s1start, const TeVector2f32 &
result = 1;
float intersection1 = -((s1len.getY() * s1start.getX() +
(s1len.getX() * s2start.getY() - s1len.getX() * s1start.getY())) -
- s1len.getY() * s2start.getX()) / squarelen;
+ s1len.getY() * s2start.getX()) / squarelen;
if (intersection1 >= 0.0f && intersection1 <= 1.0f) {
float intersection2 = -((s2len.getY() * s2start.getY() +
(s2len.getX() * s1start.getX() - s2len.getX() * s2start.getX())) -
- s2len.getY() * s1start.getY()) / squarelen;
+ s2len.getY() * s1start.getY()) / squarelen;
if (intersection2 >= 0.0f && intersection2 <= 1.0f) {
result = 2;
if (sout || fout1 || fout2) {
@@ -333,35 +333,35 @@ byte TeFreeMoveZone::hasBlockerIntersection(const TeVector2s32 &pt) {
const float gridOffsetX = _gridOffsetSomething.getX();
const float gridOffsetY = _gridOffsetSomething.getX();
borders[0] = TeVector2f32(pt._x * gridOffsetX + _someGridVec1.getX(),
- pt._y * gridOffsetY + _someGridVec1.getY());
+ pt._y * gridOffsetY + _someGridVec1.getY());
borders[1] = TeVector2f32(pt._x * gridOffsetX + _someGridVec1.getX() + gridOffsetX,
- pt._y * gridOffsetY + _someGridVec1.getY());
+ pt._y * gridOffsetY + _someGridVec1.getY());
borders[2] = TeVector2f32(pt._x * gridOffsetX + _someGridVec1.getX(),
- pt._y * gridOffsetY + _someGridVec1.getY() + gridOffsetY);
+ pt._y * gridOffsetY + _someGridVec1.getY() + gridOffsetY);
borders[3] = TeVector2f32(pt._x * gridOffsetX + _someGridVec1.getX() + gridOffsetX,
- pt._y * gridOffsetY + _someGridVec1.getY() + gridOffsetY);
+ pt._y * gridOffsetY + _someGridVec1.getY() + gridOffsetY);
- for (unsigned int i = 0; i < _blockers->size(); i++) {
+ for (uint i = 0; i < _blockers->size(); i++) {
const TeBlocker &blocker = (*_blockers)[i];
if (blocker._s != name())
continue;
- for (unsigned int b = 0; b < 4; b++) {
+ for (uint b = 0; b < 4; b++) {
int si = segmentIntersection(borders[b], borders[(b + 1) % 4], blocker._pts[0],
- blocker._pts[1], nullptr, nullptr, nullptr);
+ blocker._pts[1], nullptr, nullptr, nullptr);
if (si == 2)
return 2;
}
- TeVector2f32 borderVec = ((borders[0] + borders[3]) / 2.0) - blocker._pts[0];
- TeVector2f32 blockerVec = blocker._pts[1] - blocker._pts[0];
- float dotVal = borderVec.dotProduct(blockerVec.getNormalized());
- float crosVal = borderVec.crossProduct(blockerVec);
- if ((crosVal < 0.0) && (0.0 <= dotVal)) {
+ TeVector2f32 borderVec = ((borders[0] + borders[3]) / 2.0) - blocker._pts[0];
+ TeVector2f32 blockerVec = blocker._pts[1] - blocker._pts[0];
+ float dotVal = borderVec.dotProduct(blockerVec.getNormalized());
+ float crosVal = borderVec.crossProduct(blockerVec);
+ if ((crosVal < 0.0) && (0.0 <= dotVal)) {
if (dotVal < blockerVec.length())
return 1;
- }
+ }
}
return 0;
}
@@ -372,20 +372,20 @@ bool TeFreeMoveZone::hasCellBorderIntersection(const TeVector2s32 &pt) {
const float gridOffsetX = _gridOffsetSomething.getX();
const float gridOffsetY = _gridOffsetSomething.getX();
borders[0] = TeVector2f32(pt._x * gridOffsetX + _someGridVec1.getX(),
- pt._y * gridOffsetY + _someGridVec1.getY());
+ pt._y * gridOffsetY + _someGridVec1.getY());
borders[1] = TeVector2f32(pt._x * gridOffsetX + _someGridVec1.getX() + gridOffsetX,
- pt._y * gridOffsetY + _someGridVec1.getY());
+ pt._y * gridOffsetY + _someGridVec1.getY());
borders[2] = TeVector2f32(pt._x * gridOffsetX + _someGridVec1.getX(),
- pt._y * gridOffsetY + _someGridVec1.getY() + gridOffsetY);
+ pt._y * gridOffsetY + _someGridVec1.getY() + gridOffsetY);
borders[3] = TeVector2f32(pt._x * gridOffsetX + _someGridVec1.getX() + gridOffsetX,
- pt._y * gridOffsetY + _someGridVec1.getY() + gridOffsetY);
+ pt._y * gridOffsetY + _someGridVec1.getY() + gridOffsetY);
int iresult = 0;
- for (unsigned int border = 0; border < _borders.size() / 2; border++) {
+ for (uint border = 0; border < _borders.size() / 2; border++) {
TeVector2f32 v1;
TeVector2f32 v2;
- unsigned int off1 = _pickMesh[_borders[border * 2]];
- unsigned int off2 = _pickMesh[_borders[border * 2 + 1]];
+ uint off1 = _pickMesh[_borders[border * 2]];
+ uint off2 = _pickMesh[_borders[border * 2 + 1]];
if (!_loadedFromBin) {
v1 = TeVector2f32(_transformedVerticies[off1].x(), _transformedVerticies[off1].z());
v2 = TeVector2f32(_transformedVerticies[off2].x(), _transformedVerticies[off2].z());
@@ -443,47 +443,44 @@ void TeFreeMoveZone::preUpdateGrid() {
_gridWorldY = newVec.y();
}
- for (unsigned int i = 0; i < _pickMesh.size(); i++) {
- unsigned int vertNo = _pickMesh[_pickMesh[i]];
+ for (uint i = 0; i < _pickMesh.size(); i++) {
+ uint vertNo = _pickMesh[_pickMesh[i]];
- if (!_loadedFromBin)
+ if (!_loadedFromBin)
newVec = _transformedVerticies[vertNo];
- else
+ else
newVec = gridInverse * _freeMoveZoneVerticies[vertNo];
- if (_someGridVec1.getX() <= newVec.x()) {
- if (_someGridVec2.getX() < newVec.x()) {
- _someGridVec2.setX(newVec.x());
- }
- } else {
+ if (_someGridVec1.getX() <= newVec.x()) {
+ if (_someGridVec2.getX() < newVec.x())
+ _someGridVec2.setX(newVec.x());
+ } else {
_someGridVec1.setX(newVec.x());
- }
+ }
- if (_someGridVec1.getY() <= newVec.z()) {
- if (_someGridVec2.getY() < newVec.z()) {
- _someGridVec2.setY(newVec.z());
- }
- } else {
+ if (_someGridVec1.getY() <= newVec.z()) {
+ if (_someGridVec2.getY() < newVec.z())
+ _someGridVec2.setY(newVec.z());
+ } else {
_someGridVec1.setY(newVec.z());
- }
+ }
- if (newVec.y() < _gridWorldY) {
+ if (newVec.y() < _gridWorldY)
_gridWorldY = newVec.y();
- }
}
if (!_loadedFromBin) {
if (!name().contains("19000"))
- _gridOffsetSomething = TeVector2f32(5.0f, 5.0f);
+ _gridOffsetSomething = TeVector2f32(5.0f, 5.0f);
else
- _gridOffsetSomething = TeVector2f32(2.0f, 2.0f);
+ _gridOffsetSomething = TeVector2f32(2.0f, 2.0f);
} else {
const TeVector2f32 gridVecDiff = _someGridVec2 - _someGridVec1;
float minSide = MIN(gridVecDiff.getX(), gridVecDiff.getY()) / 20.0f;
_gridOffsetSomething.setX(minSide);
_gridOffsetSomething.setY(minSide);
- error("FIXME: Finish preUpdateGrid for non-loaded-from-bin case.");
+ error("FIXME: Finish preUpdateGrid for loaded-from-bin case.");
/*
// what's this field?
if (_field_0x414.x != 0.0)
@@ -517,10 +514,10 @@ Common::Array<TeVector3f32> TeFreeMoveZone::removeInsignificantPoints(const Comm
if (points.size() > 2) {
int point1 = 0;
int point2 = 2;
- do {
+ do {
const TeVector2f32 pt1(points[point1].x(), points[point1].z());
const TeVector2f32 pt2(points[point2].x(), points[point2].z());
- for (unsigned int i = 0; i * 2 < _borders.size() / 2; i++) {
+ for (uint i = 0; i * 2 < _borders.size() / 2; i++) {
const TeVector3f32 transpt3d1 = worldTransformationMatrix() * verticies()[_borders[i * 2]];
const TeVector2f32 transpt1(transpt3d1.x(), transpt3d1.z());
const TeVector3f32 transpt3d2 = worldTransformationMatrix() * verticies()[_borders[i * 2 + 1]];
@@ -531,13 +528,13 @@ Common::Array<TeVector3f32> TeFreeMoveZone::removeInsignificantPoints(const Comm
point1 = point2 - 1;
result.push_back(points[point1]);
point2++;
- } while (point2 < points.size());
+ } while (point2 < (int)points.size());
}
if (result.back() != points[points.size() - 2]) {
- result.push_back(points[points.size() - 1]);
+ result.push_back(points[points.size() - 1]);
} else {
- result.back() = points[points.size() - 1];
+ result.back() = points[points.size() - 1];
}
return result;
}
@@ -557,7 +554,7 @@ void TeFreeMoveZone::setCamera(TeIntrusivePtr<TeCamera> &cam, bool noRecalcProjP
_projectedPointsDirty = true;
}
-void TeFreeMoveZone::setNbTriangles(unsigned int len) {
+void TeFreeMoveZone::setNbTriangles(uint len) {
_freeMoveZoneVerticies.resize(len * 3);
_gridDirty = true;
@@ -574,7 +571,7 @@ void TeFreeMoveZone::setPathFindingOccluder(const TeOBP &occluder) {
_gridDirty = true;
}
-void TeFreeMoveZone::setVertex(unsigned int offset, const TeVector3f32 &vertex) {
+void TeFreeMoveZone::setVertex(uint offset, const TeVector3f32 &vertex) {
_freeMoveZoneVerticies[offset] = vertex;
_gridDirty = true;
@@ -614,23 +611,23 @@ void TeFreeMoveZone::updateBorders() {
updatePickMesh();
if (_verticies.size() > 2) {
- for (unsigned int triNo1 = 0; triNo1 < _verticies.size() / 3; triNo1++) {
- for (unsigned int vecNo1 = 0; vecNo1 < 3; vecNo1++) {
- unsigned int left1 = triNo1 * 3 + vecNo1;
- unsigned int left2 = triNo1 * 3 + (vecNo1 == 2 ? 0 : vecNo1 + 1);
+ for (uint triNo1 = 0; triNo1 < _verticies.size() / 3; triNo1++) {
+ for (uint vecNo1 = 0; vecNo1 < 3; vecNo1++) {
+ uint left1 = triNo1 * 3 + vecNo1;
+ uint left2 = triNo1 * 3 + (vecNo1 == 2 ? 0 : vecNo1 + 1);
const TeVector3f32 vleft1 = _verticies[left1];
const TeVector3f32 vleft2 = _verticies[left2];
bool skip = false;
- for (unsigned int triNo2 = 0; triNo2 < _verticies.size() / 3; triNo2++) {
+ for (uint triNo2 = 0; triNo2 < _verticies.size() / 3; triNo2++) {
if (skip)
break;
- for (unsigned int vecNo2 = 0; vecNo2 < 3; vecNo2++) {
+ for (uint vecNo2 = 0; vecNo2 < 3; vecNo2++) {
if (triNo2 == triNo1)
continue;
- unsigned int right1 = triNo2 * 3 + vecNo2;
- unsigned int right2 = triNo2 * 3 + (vecNo2 == 2 ? 0 : vecNo2 + 1);
+ uint right1 = triNo2 * 3 + vecNo2;
+ uint right2 = triNo2 * 3 + (vecNo2 == 2 ? 0 : vecNo2 + 1);
TeVector3f32 vright1 = _verticies[right1];
TeVector3f32 vright2 = _verticies[right2];
if (vright1 == vleft1 && vright2 == vleft2 && vright1 == vleft2 && vright2 == vleft1) {
@@ -645,7 +642,7 @@ void TeFreeMoveZone::updateBorders() {
}
}
}
- }
+ }
_bordersDirty = false;
}
@@ -669,25 +666,25 @@ void TeFreeMoveZone::updatePickMesh() {
_pickMesh.clear();
_pickMesh.reserve(_freeMoveZoneVerticies.size());
int vecNo = 0;
- for (unsigned int tri = 0; tri < _freeMoveZoneVerticies.size() / 3; tri++) {
- _pickMesh.push_back(vecNo);
- _pickMesh.push_back(vecNo + 1);
- _pickMesh.push_back(vecNo + 2);
- vecNo += 3;
- }
+ for (uint tri = 0; tri < _freeMoveZoneVerticies.size() / 3; tri++) {
+ _pickMesh.push_back(vecNo);
+ _pickMesh.push_back(vecNo + 1);
+ _pickMesh.push_back(vecNo + 2);
+ vecNo += 3;
+}
- debug("[TeFreeMoveZone::updatePickMesh] %s nb triangles reduced from : %d to : %d", name().c_str(),
- _freeMoveZoneVerticies.size() / 3, _pickMesh.size() / 3);
+ debug("[TeFreeMoveZone::updatePickMesh] %s nb triangles reduced from : %d to : %d", name().c_str(),
+ _freeMoveZoneVerticies.size() / 3, _pickMesh.size() / 3);
- TePickMesh2::setNbTriangles(_pickMesh.size() / 3);
+ TePickMesh2::setNbTriangles(_pickMesh.size() / 3);
- for (unsigned int i = 0; i < _pickMesh.size(); i++) {
- _verticies[i] = _freeMoveZoneVerticies[_pickMesh[i]];
- }
- _bordersDirty = true;
- _pickMeshDirty = false;
- _projectedPointsDirty = true;
- _gridDirty = true;
+ for (uint i = 0; i < _pickMesh.size(); i++) {
+ _verticies[i] = _freeMoveZoneVerticies[_pickMesh[i]];
+ }
+ _bordersDirty = true;
+ _pickMeshDirty = false;
+ _projectedPointsDirty = true;
+ _gridDirty = true;
}
void TeFreeMoveZone::updateProjectedPoints() {
@@ -703,10 +700,10 @@ void TeFreeMoveZone::updateTransformedVertices() {
const TeMatrix4x4 worldTransform = worldTransformationMatrix();
_transformedVerticies.resize(_freeMoveZoneVerticies.size());
- for (unsigned int i = 0; i < _transformedVerticies.size(); i++) {
- _transformedVerticies[i] = worldTransform * _freeMoveZoneVerticies[i];
- }
- _transformedVerticiesDirty = false;
+ for (uint i = 0; i < _transformedVerticies.size(); i++) {
+ _transformedVerticies[i] = worldTransform * _freeMoveZoneVerticies[i];
+ }
+ _transformedVerticiesDirty = false;
}
/*========*/
@@ -792,7 +789,7 @@ void TeFreeMoveZoneGraph::deserialize(Common::ReadStream &stream) {
if (flaglen > 1000000 || (int)flaglen != _size._x * _size._y)
error("TeFreeMoveZoneGraph: Flags unexpected size, expect %d got %d", _size._x * _size._y, flaglen);
_flags.resize(flaglen);
- for (unsigned int i = 0; i < flaglen; i++) {
+ for (uint i = 0; i < flaglen; i++) {
_flags[i] = stream.readByte();
}
_bordersDistance = stream.readFloatLE();
@@ -811,14 +808,14 @@ TePickMesh2 *TeFreeMoveZone::findNearestMesh(TeIntrusivePtr<TeCamera> &camera, c
return nullptr;
float closestDist = camera->orthoFarPlane();
Math::Ray camRay;
- for (unsigned int i = 0; i < pickMeshes.size(); i++) {
+ for (uint i = 0; i < pickMeshes.size(); i++) {
TePickMesh2 *mesh = pickMeshes[i];
const TeMatrix4x4 meshWorldTransform = mesh->worldTransformationMatrix();
if (lastHitFirst) {
// Note: it seems like a bug in the original.. this never sets
// the ray parameters?? It should still find the right triangle below.
- unsigned int tricount = mesh->verticies().size() / 3;
- unsigned int vert = mesh->lastTriangleHit() * 3;
+ uint tricount = mesh->verticies().size() / 3;
+ uint vert = mesh->lastTriangleHit() * 3;
if (mesh->lastTriangleHit() >= tricount)
vert = 0;
const TeVector3f32 v1 = meshWorldTransform * mesh->verticies()[vert + 0];
@@ -830,7 +827,7 @@ TePickMesh2 *TeFreeMoveZone::findNearestMesh(TeIntrusivePtr<TeCamera> &camera, c
if (intResult && intersectDist < closestDist && intersectDist >= camera->orthoNearPlane())
return mesh;
}
- for (unsigned int tri = 0; tri < mesh->verticies().size() / 3; tri++) {
+ for (uint tri = 0; tri < mesh->verticies().size() / 3; tri++) {
const TeVector3f32 v1 = meshWorldTransform * mesh->verticies()[tri * 3 + 0];
const TeVector3f32 v2 = meshWorldTransform * mesh->verticies()[tri * 3 + 1];
const TeVector3f32 v3 = meshWorldTransform * mesh->verticies()[tri * 3 + 2];
diff --git a/engines/tetraedge/te/te_free_move_zone.h b/engines/tetraedge/te/te_free_move_zone.h
index ec8cde052e4..45a96d1aeea 100644
--- a/engines/tetraedge/te/te_free_move_zone.h
+++ b/engines/tetraedge/te/te_free_move_zone.h
@@ -94,9 +94,9 @@ public:
Common::Array<TeVector3f32> removeInsignificantPoints(const Common::Array<TeVector3f32> &points);
void setBordersDistance(float dist);
void setCamera(TeIntrusivePtr<TeCamera> &cam, bool noRecalcProjPoints);
- void setNbTriangles(unsigned int len);
+ void setNbTriangles(uint len);
void setPathFindingOccluder(const TeOBP &occluder);
- void setVertex(unsigned int offset, const TeVector3f32 &vertex);
+ void setVertex(uint offset, const TeVector3f32 &vertex);
TeVector3f32 transformAStarGridInWorldSpace(const TeVector2s32 &gridpt);
float transformHeightMin(float minval);
TeVector3f32 transformVectorInWorldSpace(float param_3, float param_4);
@@ -122,9 +122,9 @@ private:
Common::Array<TeRectBlocker> *_rectBlockers;
Common::Array<TeVector3f32> _freeMoveZoneVerticies;
- Common::Array<unsigned int> _pickMesh;
+ Common::Array<uint> _pickMesh;
Common::Array<TeVector3f32> _transformedVerticies;
- Common::Array<unsigned int> _borders;
+ Common::Array<uint> _borders;
// TODO: Find better names..
TeVector2f32 _gridOffsetSomething;
diff --git a/engines/tetraedge/te/te_images_sequence.h b/engines/tetraedge/te/te_images_sequence.h
index fa0a5bdcb96..62ac59f00bc 100644
--- a/engines/tetraedge/te/te_images_sequence.h
+++ b/engines/tetraedge/te/te_images_sequence.h
@@ -61,11 +61,11 @@ public:
private:
float _frameRate;
- unsigned int _width;
- unsigned int _height;
+ uint _width;
+ uint _height;
Common::Array<Common::FSNode> _files;
Common::Array<Graphics::ManagedSurface *> _cachedSurfaces;
- unsigned int _curFrame;
+ uint _curFrame;
};
} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_layout.cpp b/engines/tetraedge/te/te_layout.cpp
index 3fde8410e1b..7578a111caf 100644
--- a/engines/tetraedge/te/te_layout.cpp
+++ b/engines/tetraedge/te/te_layout.cpp
@@ -244,9 +244,9 @@ void TeLayout::setPositionType(CoordinatesType newtype) {
void TeLayout::setRatio(float val) {
if (_ratio != val) {
- _ratio = val;
- _sizeChanged = true;
- _worldMatrixChanged = true;
+ _ratio = val;
+ _sizeChanged = true;
+ _worldMatrixChanged = true;
}
}
@@ -300,9 +300,9 @@ void TeLayout::setSizeType(CoordinatesType coordtype) {
void TeLayout::setZPosition(float zpos) {
if (_userPosition.z() != zpos) {
- _userPosition.z() = zpos;
- _positionChanged = true;
- _worldMatrixChanged = true;
+ _userPosition.z() = zpos;
+ _positionChanged = true;
+ _worldMatrixChanged = true;
}
}
diff --git a/engines/tetraedge/te/te_lua_context.cpp b/engines/tetraedge/te/te_lua_context.cpp
index c7a928cfe12..240a244bcc5 100644
--- a/engines/tetraedge/te/te_lua_context.cpp
+++ b/engines/tetraedge/te/te_lua_context.cpp
@@ -149,7 +149,7 @@ Common::Error TeLuaContext::syncState(Common::Serializer &s) {
lua_settop(_luaState, -2);
break;
}
- unsigned int vtype = lua_type(_luaState, -1);
+ uint vtype = lua_type(_luaState, -1);
Common::String name = lua_tolstring(_luaState, -2, nullptr);
if (vtype == LUA_TBOOLEAN) {
TeLuaSaveVarType stype = Boolean;
diff --git a/engines/tetraedge/te/te_lua_gui_lua_callbacks.cpp b/engines/tetraedge/te/te_lua_gui_lua_callbacks.cpp
index c76e1316041..f376da34ee0 100644
--- a/engines/tetraedge/te/te_lua_gui_lua_callbacks.cpp
+++ b/engines/tetraedge/te/te_lua_gui_lua_callbacks.cpp
@@ -132,21 +132,21 @@ static TeVector3f32 TeLuaToTeVector3f32(lua_State *L, int index, TeVector3f32 de
index--;
lua_gettable(L, index);
if (lua_isnumber(L, -1)) {
- retval.x() = TeLuaToF32(L, -1);
+ retval.x() = TeLuaToF32(L, -1);
}
lua_settop(L, -2);
lua_pushinteger(L, 2);
lua_gettable(L, index);
if (lua_isnumber(L, -1)) {
- retval.y() = TeLuaToF32(L, -1);
+ retval.y() = TeLuaToF32(L, -1);
}
lua_settop(L, -2);
lua_pushinteger(L, 3);
lua_gettable(L, index);
if (lua_isnumber(L, -1)) {
- retval.z() = TeLuaToF32(L, -1);
+ retval.z() = TeLuaToF32(L, -1);
}
lua_settop(L, -2);
}
@@ -166,7 +166,7 @@ static Common::Array<float> TeLuaToFloatArray(lua_State *L, int index) {
lua_settop(L, -2);
}
} else {
- warning("TeLuaToF32TeArray:: the lua value is not a table");
+ warning("TeLuaToF32TeArray:: the lua value is not a table");
}
return result;
}
diff --git a/engines/tetraedge/te/te_lua_thread.cpp b/engines/tetraedge/te/te_lua_thread.cpp
index 9b32db5908a..4c1a8368f88 100644
--- a/engines/tetraedge/te/te_lua_thread.cpp
+++ b/engines/tetraedge/te/te_lua_thread.cpp
@@ -42,7 +42,7 @@ TeLuaThread::TeLuaThread(TeLuaContext *context) : _resumeCount(0), _lastResumeRe
TeLuaThread::~TeLuaThread() {
luaL_unref(_luaThread, LUA_REGISTRYINDEX, _bottomRef);
- unsigned int i;
+ uint i;
for (i = 0; i < _threadList.size(); i++)
if (_threadList[i] == this)
break;
diff --git a/engines/tetraedge/te/te_matrix4x4.cpp b/engines/tetraedge/te/te_matrix4x4.cpp
index c9fe992bb65..afaadaa1324 100644
--- a/engines/tetraedge/te/te_matrix4x4.cpp
+++ b/engines/tetraedge/te/te_matrix4x4.cpp
@@ -151,12 +151,12 @@ TeVector3f32 TeMatrix4x4::operator*(const TeVector3f32 &mul) const {
const float *d = getData();
float w = d[3] * x + d[7] * y + d[11] * z + d[15];
if (w == 0.0)
- w = 1e-09f;
+ w = 1e-09f;
return TeVector3f32
- ((d[0] * x + d[4] * y + d[8] * z + d[12]) / w,
- (d[1] * x + d[5] * y + d[9] * z + d[13]) / w,
- (d[2] * x + d[6] * y + d[10] * z + d[14]) / w);
+ ((d[0] * x + d[4] * y + d[8] * z + d[12]) / w,
+ (d[1] * x + d[5] * y + d[9] * z + d[13]) / w,
+ (d[2] * x + d[6] * y + d[10] * z + d[14]) / w);
}
diff --git a/engines/tetraedge/te/te_mesh.cpp b/engines/tetraedge/te/te_mesh.cpp
index c368fc5501b..ccc439470a0 100644
--- a/engines/tetraedge/te/te_mesh.cpp
+++ b/engines/tetraedge/te/te_mesh.cpp
@@ -102,7 +102,7 @@ void TeMesh::draw() {
} else {
assert(_faceCounts.size() == _materials.size());
int totalFaceCount = 0;
- for (unsigned int i = 0; i < _faceCounts.size(); i++) {
+ for (uint i = 0; i < _faceCounts.size(); i++) {
if (!_faceCounts[i])
continue;
if (hasAlpha(i)) {
@@ -155,7 +155,7 @@ void TeMesh::draw() {
} else {
int totalFaceCount = 0;
assert(_faceCounts.size() == _materials.size());
- for (unsigned int i = 0; i < _materials.size(); i++) {
+ for (uint i = 0; i < _materials.size(); i++) {
if (!_faceCounts[i])
continue;
if (!hasAlpha(i) || renderer->shadowMode() == TeRenderer::ShadowMode1 || !_shouldDraw) {
@@ -182,7 +182,7 @@ void TeMesh::draw() {
TeLight::disableAll();
glBegin(GL_LINES);
renderer->setCurrentColor(TeColor(255, 255, 255, 255));
- for (unsigned int i = 0; i < verticies.size(); i++) {
+ for (uint i = 0; i < verticies.size(); i++) {
glVertex3f(verticies[i].x(), verticies[i].y(), verticies[i].z());
glVertex3f(verticies[i].x() + normals[i].x(),
verticies[i].y() + normals[i].y(),
@@ -261,7 +261,7 @@ void TeMesh::setColor(const TeColor &col) {
if (colnow.a() != 255)
_hasAlpha = true;
- for (unsigned int i = 0; i < _verticies.size(); i++) {
+ for (uint i = 0; i < _verticies.size(); i++) {
_colors[i] = colnow;
}
}
@@ -275,7 +275,7 @@ void TeMesh::setColor(uint idx, const TeColor &col) {
_colors[idx] = col;
}
-void TeMesh::setConf(unsigned long vertexCount, unsigned long indexCount, enum Mode mode, unsigned int materialCount, unsigned int materialIndexCount) {
+void TeMesh::setConf(unsigned long vertexCount, unsigned long indexCount, enum Mode mode, uint materialCount, uint materialIndexCount) {
destroy();
_initialMaterialIndexCount = materialIndexCount;
_verticies.resize(vertexCount);
@@ -309,21 +309,21 @@ void TeMesh::setConf(unsigned long vertexCount, unsigned long indexCount, enum M
}
}
-void TeMesh::setIndex(unsigned int idx, unsigned int val) {
+void TeMesh::setIndex(uint idx, uint val) {
_indexes[idx] = val;
}
-void TeMesh::setNormal(unsigned int idx, const TeVector3f32 &val) {
+void TeMesh::setNormal(uint idx, const TeVector3f32 &val) {
_normals.resize(_verticies.size());
_normals[idx] = val;
}
-void TeMesh::setTextureUV(unsigned int idx, const TeVector2f32 &val) {
+void TeMesh::setTextureUV(uint idx, const TeVector2f32 &val) {
_uvs.resize(_verticies.size());
_uvs[idx] = val;
}
-void TeMesh::setVertex(unsigned int idx, const TeVector3f32 &val) {
+void TeMesh::setVertex(uint idx, const TeVector3f32 &val) {
_verticies[idx] = val;
}
@@ -375,10 +375,10 @@ void TeMesh::update(TeIntrusivePtr<TeModelVertexAnimation> vertexanim) {
const Common::Array<TeVector3f32> &animverts = vertexanim->getVertices();
assert(animverts.size() >= _verticies.size());
- for (unsigned int i = 0; i < _verticies.size(); i++) {
+ for (uint i = 0; i < _verticies.size(); i++) {
_updatedVerticies[i] = animverts[i];
}
- for (unsigned int i = 0; i < _normals.size(); i++) {
+ for (uint i = 0; i < _normals.size(); i++) {
_updatedNormals[i] = _normals[i];
}
}
@@ -386,8 +386,8 @@ void TeMesh::update(TeIntrusivePtr<TeModelVertexAnimation> vertexanim) {
void TeMesh::updateTo(const Common::Array<TeMatrix4x4> *matricies1, const Common::Array<TeMatrix4x4> *matricies2,
Common::Array<TeVector3f32> &verts, Common::Array<TeVector3f32> &normals) {
static const TeMatrix4x4 emptyMatrix;
- for (unsigned int i = 0; i < _verticies.size(); i++) {
- unsigned int m = _matricies[i];
+ for (uint i = 0; i < _verticies.size(); i++) {
+ uint m = _matricies[i];
const TeMatrix4x4 *mat;
if (m < matricies1->size()) {
mat = &((*matricies1)[m]);
diff --git a/engines/tetraedge/te/te_mesh.h b/engines/tetraedge/te/te_mesh.h
index 1399d88f858..bc71f399d7a 100644
--- a/engines/tetraedge/te/te_mesh.h
+++ b/engines/tetraedge/te/te_mesh.h
@@ -90,11 +90,11 @@ public:
void setColor(const TeColor &col) override;
void setColor(uint idx, const TeColor &col);
- void setConf(unsigned long vertexCount, unsigned long indexCount, enum Mode mode, unsigned int materialCount, unsigned int materialIndexCount);
- void setIndex(unsigned int idx, unsigned int val);
- void setNormal(unsigned int idx, const TeVector3f32 &val);
- void setTextureUV(unsigned int idx, const TeVector2f32 &val);
- void setVertex(unsigned int idx, const TeVector3f32 &val);
+ void setConf(unsigned long vertexCount, unsigned long indexCount, enum Mode mode, uint materialCount, uint materialIndexCount);
+ void setIndex(uint idx, uint val);
+ void setNormal(uint idx, const TeVector3f32 &val);
+ void setTextureUV(uint idx, const TeVector2f32 &val);
+ void setVertex(uint idx, const TeVector3f32 &val);
void sortFaces();
void update(const Common::Array<TeMatrix4x4> *matricies1, const Common::Array<TeMatrix4x4> *matricies2);
@@ -115,11 +115,11 @@ public:
void setHasAlpha(bool val) { _hasAlpha = val; }
Common::Array<TeMaterial> &materials() { return _materials; }
- void setUpdatedVertex(unsigned int idx, const TeVector3f32 &val) { _updatedVerticies[idx] = val; }
- void setUpdatedNormal(unsigned int idx, const TeVector3f32 &val) { _updatedNormals[idx] = val; }
+ void setUpdatedVertex(uint idx, const TeVector3f32 &val) { _updatedVerticies[idx] = val; }
+ void setUpdatedNormal(uint idx, const TeVector3f32 &val) { _updatedNormals[idx] = val; }
- const TeVector3f32 &preUpdatedVertex(unsigned int idx) const { return _verticies[idx]; }
- const TeVector3f32 &preUpdatedNormal(unsigned int idx) const { return _normals[idx]; }
+ const TeVector3f32 &preUpdatedVertex(uint idx) const { return _verticies[idx]; }
+ const TeVector3f32 &preUpdatedNormal(uint idx) const { return _normals[idx]; }
private:
Common::Array<unsigned char> _materialIndexes;
@@ -134,7 +134,7 @@ private:
Common::Array<TeColor> _colors;
Common::Array<TeMaterial> _materials;
- unsigned int _glMeshMode;
+ uint _glMeshMode;
bool _matrixForced;
TeMatrix4x4 _forcedMatrix;
diff --git a/engines/tetraedge/te/te_model.cpp b/engines/tetraedge/te/te_model.cpp
index f2c1460302f..2ae90852127 100644
--- a/engines/tetraedge/te/te_model.cpp
+++ b/engines/tetraedge/te/te_model.cpp
@@ -128,7 +128,7 @@ void TeModel::forceMatrix(const TeMatrix4x4 &matrix) {
_forcedMatrix = matrix;
}
-TeTRS TeModel::getBone(TeIntrusivePtr<TeModelAnimation> anim, unsigned int num) {
+TeTRS TeModel::getBone(TeIntrusivePtr<TeModelAnimation> anim, uint num) {
if (anim) {
int bone = anim->findBone(_bones[num]._name);
if (bone != -1)
@@ -137,10 +137,10 @@ TeTRS TeModel::getBone(TeIntrusivePtr<TeModelAnimation> anim, unsigned int num)
return _bones[num]._trs;
}
-TeMatrix4x4 TeModel::lerpElementsMatrix(unsigned int weightsNum, const Common::Array<TeMatrix4x4> &matricies) {
+TeMatrix4x4 TeModel::lerpElementsMatrix(uint weightsNum, const Common::Array<TeMatrix4x4> &matricies) {
TeMatrix4x4 retval;
// Start with a 0 matrix.
- for (unsigned int i = 0; i < 4; i++)
+ for (uint i = 0; i < 4; i++)
retval.setValue(i, i, 0);
const Common::Array<weightElement> &weights = _weightElements[weightsNum];
@@ -173,7 +173,7 @@ void TeModel::update() {
if (_bones.size()) {
Common::Array<TeMatrix4x4> matricies;
matricies.resize(_bones.size());
- for (unsigned int i = 0; i < _bones.size(); i++) {
+ for (uint i = 0; i < _bones.size(); i++) {
const bone &b = _bones[i];
const TeMatrix4x4 matrix = TeMatrix4x4::fromTRS(b._trs);
if (b._parentBone == -1 || _bones.size() < 2) {
@@ -188,9 +188,9 @@ void TeModel::update() {
TeMatrix4x4 invertx;
invertx.scale(TeVector3f32(-1, 1, 1));
- for (unsigned int b = 0; b < _bones.size(); b++) {
+ for (uint b = 0; b < _bones.size(); b++) {
TeTRS trs = getBone(_modelAnim, b);
- for (unsigned int i = 0; i < _boneBlenders.size(); i++) {
+ for (uint i = 0; i < _boneBlenders.size(); i++) {
BonesBlender *blender = _boneBlenders[i];
float complete = blender->coef();
TeTRS endTRS = getBone(blender->_anim, b);
@@ -224,18 +224,18 @@ void TeModel::update() {
}
if (!_skinOffsets.empty() && !_bones.empty()) {
- for (unsigned int b = 0; b < _bones.size(); b++) {
+ for (uint b = 0; b < _bones.size(); b++) {
_boneMatricies[b] = _boneMatricies[b] * _skinOffsets[b];
}
}
if (!_skipSkinOffsets && !_weightElements.empty()) {
- for (unsigned int i = 0; i < _weightElements.size(); i++) {
+ for (uint i = 0; i < _weightElements.size(); i++) {
_lerpedElements[i] = lerpElementsMatrix(i, _boneMatricies);
}
}
- for (unsigned int m = 0; m < _meshes.size(); m++) {
+ for (uint m = 0; m < _meshes.size(); m++) {
TeMesh &mesh = _meshes[m];
if (!mesh.visible())
continue;
@@ -252,7 +252,7 @@ void TeModel::update() {
if (_modelVertexAnim && mesh.name() == _modelVertexAnim->head())
verticies = &_modelVertexAnim->getVertices();
- for (unsigned int i = 0; i < mesh.numVerticies(); i++) {
+ for (uint i = 0; i < mesh.numVerticies(); i++) {
TeVector3f32 vertex;
if (!verticies) {
vertex = mesh.preUpdatedVertex(i);
@@ -273,7 +273,7 @@ void TeModel::update() {
updatednormal = _boneMatricies[idx] * normal;
} else {
idx -= _bones.size();
- for (unsigned int w = 0; w < _weightElements[idx].size(); w++) {
+ for (uint w = 0; w < _weightElements[idx].size(); w++) {
const TeMatrix4x4 &wmatrix = _boneMatricies[_weightElements[idx][w]._x];
float weight = _weightElements[idx][w]._weight;
updatedvertex = updatedvertex + ((wmatrix * vertex) * weight);
@@ -374,7 +374,7 @@ bool TeModel::load(Common::SeekableReadStream &stream) {
error("[TeModel::load] Unable to find skeleton.");
}
- for (unsigned int i = 0; i < _bones.size(); i++) {
+ for (uint i = 0; i < _bones.size(); i++) {
_bones[i]._name = Te3DObject2::deserializeString(stream);
loadAlign(stream);
_bones[i]._parentBone = stream.readUint32LE();
@@ -384,7 +384,7 @@ bool TeModel::load(Common::SeekableReadStream &stream) {
}
}
- for (unsigned int m = 0; m < _meshes.size(); m++) {
+ for (uint m = 0; m < _meshes.size(); m++) {
if (!loadMesh(stream, _meshes[m])) {
error("[TeModel::load] Error on meshes loading.");
}
@@ -393,7 +393,7 @@ bool TeModel::load(Common::SeekableReadStream &stream) {
if (!loadAndCheckFourCC(stream, "WEIG")) {
error("[TeModel::load] Unable to load weight.");
}
- for (unsigned int i = 0; i < _weightElements.size(); i++) {
+ for (uint i = 0; i < _weightElements.size(); i++) {
loadWeights(stream, _weightElements[i]);
}
@@ -444,7 +444,7 @@ bool TeModel::loadWeights(Common::ReadStream &stream, Common::Array<weightElemen
if (nweights > 100000)
error("Improbable number of weights %d", (int)nweights);
weights.resize(nweights);
- for (unsigned int i = 0; i < nweights; i++) {
+ for (uint i = 0; i < nweights; i++) {
weights[i]._weight = stream.readFloatLE();
weights[i]._x = stream.readUint16LE();
stream.readUint16LE();
@@ -478,7 +478,7 @@ bool TeModel::loadMesh(Common::SeekableReadStream &stream, TeMesh &mesh) {
if (!loadAndCheckFourCC(stream, "MTRL"))
return false;
- for (unsigned int i = 0; i < mesh.materials().size(); i++) {
+ for (uint i = 0; i < mesh.materials().size(); i++) {
TeMaterial mat;
TeMaterial::deserialize(stream, mat, _texturePath);
if (_enableLights)
@@ -489,7 +489,7 @@ bool TeModel::loadMesh(Common::SeekableReadStream &stream, TeMesh &mesh) {
if (!loadAndCheckFourCC(stream, "VERT"))
return false;
- for (unsigned int i = 0; i < mesh.numVerticies(); i++) {
+ for (uint i = 0; i < mesh.numVerticies(); i++) {
TeVector3f32 v;
TeVector3f32::deserialize(stream, v);
mesh.setVertex(i, v);
@@ -497,7 +497,7 @@ bool TeModel::loadMesh(Common::SeekableReadStream &stream, TeMesh &mesh) {
if (mesh.hasUvs()) {
if (!loadAndCheckFourCC(stream, "TUVS"))
return false;
- for (unsigned int i = 0; i < mesh.numVerticies(); i++) {
+ for (uint i = 0; i < mesh.numVerticies(); i++) {
TeVector2f32 v;
TeVector2f32::deserialize(stream, v);
mesh.setTextureUV(i, v);
@@ -507,7 +507,7 @@ bool TeModel::loadMesh(Common::SeekableReadStream &stream, TeMesh &mesh) {
if (!loadAndCheckFourCC(stream, "NORM"))
return false;
- for (unsigned int i = 0; i < mesh.numVerticies(); i++) {
+ for (uint i = 0; i < mesh.numVerticies(); i++) {
TeVector3f32 v;
TeVector3f32::deserialize(stream, v);
mesh.setNormal(i, v);
@@ -517,7 +517,7 @@ bool TeModel::loadMesh(Common::SeekableReadStream &stream, TeMesh &mesh) {
if (!loadAndCheckFourCC(stream, "COLS"))
return false;
- for (unsigned int i = 0; i < mesh.numVerticies(); i++) {
+ for (uint i = 0; i < mesh.numVerticies(); i++) {
TeColor c;
c.deserialize(stream);
mesh.setColor(i, c);
@@ -527,7 +527,7 @@ bool TeModel::loadMesh(Common::SeekableReadStream &stream, TeMesh &mesh) {
if (!loadAndCheckFourCC(stream, "FCPM"))
return false;
- for (unsigned int i = 0; i < mesh.materials().size(); i++) {
+ for (uint i = 0; i < mesh.materials().size(); i++) {
mesh.facesPerMaterial(i, stream.readUint16LE());
}
@@ -535,7 +535,7 @@ bool TeModel::loadMesh(Common::SeekableReadStream &stream, TeMesh &mesh) {
if (!loadAndCheckFourCC(stream, "MTXI"))
return false;
- for (unsigned int i = 0; i < mesh.numVerticies(); i++) {
+ for (uint i = 0; i < mesh.numVerticies(); i++) {
mesh.matrixIndex(i, stream.readUint16LE());
}
@@ -543,7 +543,7 @@ bool TeModel::loadMesh(Common::SeekableReadStream &stream, TeMesh &mesh) {
if (!loadAndCheckFourCC(stream, "IDXS"))
return false;
- for (unsigned int i = 0; i < mesh.numIndexes(); i++) {
+ for (uint i = 0; i < mesh.numIndexes(); i++) {
mesh.setIndex(i, stream.readUint16LE());
}
diff --git a/engines/tetraedge/te/te_model.h b/engines/tetraedge/te/te_model.h
index ef9cf6da215..60862309f79 100644
--- a/engines/tetraedge/te/te_model.h
+++ b/engines/tetraedge/te/te_model.h
@@ -96,7 +96,7 @@ public:
int findModelBone(const Common::String &bname);
int findOrAddWeights(const Common::Array<weightElement> &weights);
void forceMatrix(const TeMatrix4x4 &matrix);
- TeTRS getBone(TeIntrusivePtr<TeModelAnimation> anim, unsigned int num);
+ TeTRS getBone(TeIntrusivePtr<TeModelAnimation> anim, uint num);
/* Align the stream to the nearest 4 byte boudary*/
static void loadAlign(Common::SeekableReadStream &stream);
@@ -113,7 +113,7 @@ public:
void saveBone(Common::SeekableWriteStream &stream, unsigned long boneno);
void saveMesh(Common::SeekableWriteStream &stream, const TeMesh &mesh);
- void saveModel(Common::SeekableWriteStream &stream, unsigned int num);
+ void saveModel(Common::SeekableWriteStream &stream, uint num);
void saveWeights(Common::SeekableWriteStream &stream, const Common::Array<weightElement> weights);
void setAnim(TeIntrusivePtr<TeModelAnimation> &anim, bool repeat);
@@ -135,7 +135,7 @@ public:
void setTexturePath(const Common::Path &path) { _texturePath = path; }
protected:
- TeMatrix4x4 lerpElementsMatrix(unsigned int weightNum, const Common::Array<TeMatrix4x4> &matricies);
+ TeMatrix4x4 lerpElementsMatrix(uint weightNum, const Common::Array<TeMatrix4x4> &matricies);
void optimize();
Common::Path _texturePath;
diff --git a/engines/tetraedge/te/te_model_animation.cpp b/engines/tetraedge/te/te_model_animation.cpp
index a5c28c8f329..7ab1f8bbc4a 100644
--- a/engines/tetraedge/te/te_model_animation.cpp
+++ b/engines/tetraedge/te/te_model_animation.cpp
@@ -80,7 +80,7 @@ void TeModelAnimation::destroy() {
}
int TeModelAnimation::findBone(const Common::String &bname) {
- for (unsigned int i = 0; i < _boneNames.size(); i++) {
+ for (uint i = 0; i < _boneNames.size(); i++) {
if (_boneNames[i] == bname)
return i;
}
@@ -99,7 +99,7 @@ TeQuaternion TeModelAnimation::getNMORotation(unsigned long boneNo, float amount
if (boneNo < _nmoRotArrays.size()) {
const Common::Array<NMORotation> &arr = _nmoRotArrays[boneNo];
if (arr.size()) {
- unsigned int i = 0;
+ uint i = 0;
while (i < arr.size() && arr[i]._f < amount)
i++;
@@ -123,7 +123,7 @@ TeVector3f32 TeModelAnimation::getNMOTranslation(unsigned long boneNo, float amo
if (boneNo < _nmoTransArrays.size()) {
const Common::Array<NMOTranslation> &arr = _nmoTransArrays[boneNo];
if (arr.size()) {
- unsigned int i = 0;
+ uint i = 0;
while (i < arr.size() && arr[i]._f < amount)
i++;
@@ -143,13 +143,13 @@ TeVector3f32 TeModelAnimation::getNMOTranslation(unsigned long boneNo, float amo
return TeVector3f32(0, 0, 0);
}
-//TeTRS TeModelAnimation::getTRS(const Common::String &boneName, unsigned long frame, bool param_5);
+//TeTRS TeModelAnimation::getTRS(const Common::String &boneName, unsigned long frame, bool forceUseFbx);
TeTRS TeModelAnimation::getTRS(unsigned long boneNo, unsigned long frame, bool forceUseFbx) const {
TeTRS retval;
if (!_useNMOArrays || forceUseFbx) {
- unsigned int nframes = 0;
+ uint nframes = 0;
if (!_useNMOArrays) {
nframes = _fbxArrays[0].size();
} else {
@@ -230,7 +230,7 @@ bool TeModelAnimation::load(Common::SeekableReadStream &stream) {
}
_speed = stream.readFloatLE();
- for (unsigned int i = 0; i < numBones; i++) {
+ for (uint i = 0; i < numBones; i++) {
if (!Te3DObject2::loadAndCheckFourCC(stream, "BONE"))
return false;
const Common::String boneName = Te3DObject2::deserializeString(stream);
@@ -241,7 +241,7 @@ bool TeModelAnimation::load(Common::SeekableReadStream &stream) {
uint32 numTrans = stream.readUint32LE();
if (numTrans > 100000)
error("TeModelAnimation::load: Improbable number of bone translations %d", numTrans);
- for (unsigned int j = 0; j < numTrans; j++) {
+ for (uint j = 0; j < numTrans; j++) {
float f = stream.readFloatLE();
TeVector3f32 trans;
TeVector3f32::deserialize(stream, trans);
@@ -252,7 +252,7 @@ bool TeModelAnimation::load(Common::SeekableReadStream &stream) {
uint32 numRots = stream.readUint32LE();
if (numRots > 100000)
error("TeModelAnimation::load: Improbable number of bone rotations %d", numRots);
- for (unsigned int j = 0; j < numRots; j++) {
+ for (uint j = 0; j < numRots; j++) {
float f = stream.readFloatLE();
TeQuaternion rot;
TeQuaternion::deserialize(stream, rot);
diff --git a/engines/tetraedge/te/te_model_animation.h b/engines/tetraedge/te/te_model_animation.h
index 4604c818c76..5eb540f4362 100644
--- a/engines/tetraedge/te/te_model_animation.h
+++ b/engines/tetraedge/te/te_model_animation.h
@@ -67,10 +67,10 @@ public:
int findBone(const Common::String &bname);
int firstFrame() const;
TeMatrix4x4 getMatrix(const Common::String &name, unsigned long frame, bool param_5);
- TeQuaternion getNMORotation(unsigned long param_3, float param_4) const;
- TeVector3f32 getNMOTranslation(unsigned long param_3, float param_4) const;
- TeTRS getTRS(const Common::String &boneName, unsigned long frame, bool param_5);
- TeTRS getTRS(unsigned long boneNo, unsigned long frame, bool param_5) const;
+ TeQuaternion getNMORotation(unsigned long boneNo, float amount) const;
+ TeVector3f32 getNMOTranslation(unsigned long boneNo, float amount) const;
+ TeTRS getTRS(const Common::String &boneName, unsigned long frame, bool forceUseFbx);
+ TeTRS getTRS(unsigned long boneNo, unsigned long frame, bool forceUseFbx) const;
int lastFrame() const;
bool load(const Common::Path &path);
bool load(Common::SeekableReadStream &stream);
@@ -79,7 +79,7 @@ public:
void resizeFBXArrays(unsigned long len);
void resizeNMOArrays(unsigned long len);
void save(Common::SeekableWriteStream &stream);
- void saveBone(Common::SeekableWriteStream &stream, uint param_2);
+ void saveBone(Common::SeekableWriteStream &stream, uint boneNo);
void setBoneName(uint boneNo, const Common::String &bname);
void setFrameLimits(int framemin, int framemax) {
_firstFrame = framemin;
@@ -93,13 +93,12 @@ public:
int curFrame2() const { return _curFrame2; }
float speed() const { return _speed; }
+ const Common::Path &loadedPath() const { return _loadedPath; }
+private:
TeIntrusivePtr<TeModel> _model;
- int _firstFrame;
- int _lastFrame;
Common::Path _loadedPath;
-private:
Common::Array<Common::Array<TeTRS>> _fbxArrays;
Common::Array<Common::Array<NMOTranslation>> _nmoTransArrays;
Common::Array<Common::Array<NMORotation>> _nmoRotArrays;
@@ -107,11 +106,16 @@ private:
Common::Array<Common::String> _boneNames;
int _curFrame;
int _curFrame2;
- bool _curFrameValFresh;
+ int _firstFrame;
+ int _lastFrame;
int _repeatNum;
+
+ bool _curFrameValFresh;
bool _finishedSignalPending;
+
int _useNMOArrays;
int _numNMOFrames;
+
float _speed;
};
diff --git a/engines/tetraedge/te/te_model_vertex_animation.cpp b/engines/tetraedge/te/te_model_vertex_animation.cpp
index 17479130bdc..cd71198e331 100644
--- a/engines/tetraedge/te/te_model_vertex_animation.cpp
+++ b/engines/tetraedge/te/te_model_vertex_animation.cpp
@@ -37,7 +37,7 @@ void TeModelVertexAnimation::destroy() {
_keydata.clear();
}
-TeVector3f32 TeModelVertexAnimation::getKeyVertex(unsigned long keyno, unsigned int vertexno) {
+TeVector3f32 TeModelVertexAnimation::getKeyVertex(unsigned long keyno, uint vertexno) {
assert(keyno < _keydata.size());
const KeyData &data = _keydata[keyno];
assert(vertexno < data._vectors.size());
@@ -57,7 +57,7 @@ const Common::Array<TeVector3f32> &TeModelVertexAnimation::getVertices() {
return lerpVtx;
float frame = fmod((_lastMillis / 1000.0) * 30, _keydata[_keydata.size() - 1]._frame);
- unsigned int keyno = 0;
+ uint keyno = 0;
while (keyno < _keydata.size() - 1 && _keydata[keyno]._frame < frame)
keyno++;
@@ -66,7 +66,7 @@ const Common::Array<TeVector3f32> &TeModelVertexAnimation::getVertices() {
float nextFrame = _keydata[keyno + 1]._frame;
float interp = (frame - nextFrame) / (nextFrame - prevFrame);
- for (unsigned int i = 0; i < _keydata[0]._vectors.size(); i++) {
+ for (uint i = 0; i < _keydata[0]._vectors.size(); i++) {
const TeVector3f32 prevVector = getKeyVertex(keyno, i);
const TeVector3f32 nextVector = getKeyVertex(keyno + 1, i);
lerpVtx[i] = prevVector * (1.0 - interp) + nextVector * interp;
diff --git a/engines/tetraedge/te/te_model_vertex_animation.h b/engines/tetraedge/te/te_model_vertex_animation.h
index 71e29eaccdd..87b30a1e38d 100644
--- a/engines/tetraedge/te/te_model_vertex_animation.h
+++ b/engines/tetraedge/te/te_model_vertex_animation.h
@@ -56,7 +56,7 @@ public:
void destroy();
const Common::String &head() const { return _head; }
- TeVector3f32 getKeyVertex(unsigned long keyno, unsigned int vertexno);
+ TeVector3f32 getKeyVertex(unsigned long keyno, uint vertexno);
const Common::Array<TeVector3f32> &getVertices();
bool load(Common::ReadStream &stream);
diff --git a/engines/tetraedge/te/te_music.cpp b/engines/tetraedge/te/te_music.cpp
index b3fbd96f681..59d93cce780 100644
--- a/engines/tetraedge/te/te_music.cpp
+++ b/engines/tetraedge/te/te_music.cpp
@@ -39,7 +39,7 @@ _retain(false) {
TeMusic::~TeMusic() {
close();
Common::Array<TeMusic *> &m = g_engine->getSoundManager()->musics();
- for (unsigned int i = 0; i < m.size(); i++) {
+ for (uint i = 0; i < m.size(); i++) {
if (m[i] == this) {
m.remove_at(i);
break;
diff --git a/engines/tetraedge/te/te_name_val_xml_parser.cpp b/engines/tetraedge/te/te_name_val_xml_parser.cpp
index c5a4d96f0be..748dec4548b 100644
--- a/engines/tetraedge/te/te_name_val_xml_parser.cpp
+++ b/engines/tetraedge/te/te_name_val_xml_parser.cpp
@@ -29,7 +29,7 @@ bool TeNameValXmlParser::parserCallback_value(ParserNode *node) {
// Replace """ with " character. This is the only character
// entity used in the game files.
- unsigned int qpos = valStr.find(""");
+ uint qpos = valStr.find(""");
while (qpos != Common::String::npos) {
valStr.replace(qpos, 6, "\"");
qpos = valStr.find(""");
diff --git a/engines/tetraedge/te/te_pick_mesh2.cpp b/engines/tetraedge/te/te_pick_mesh2.cpp
index 7e4f160e4b3..4e027aa4408 100644
--- a/engines/tetraedge/te/te_pick_mesh2.cpp
+++ b/engines/tetraedge/te/te_pick_mesh2.cpp
@@ -38,10 +38,10 @@ void TePickMesh2::draw() {
if (!worldVisible())
return;
- const unsigned int nverticies = _verticies.size();
+ const uint nverticies = _verticies.size();
TeMesh mesh;
mesh.setConf(nverticies, nverticies, TeMesh::MeshMode_Triangles, 0, 0);
- for (unsigned int i = 0; i < nverticies; i++) {
+ for (uint i = 0; i < nverticies; i++) {
mesh.setIndex(i, i);
mesh.setVertex(i, _verticies[i]);
}
@@ -84,7 +84,7 @@ bool TePickMesh2::intersect(const TeVector3f32 &origin, const TeVector3f32 &dir,
}
float lastHitDist = FLT_MAX;
- for (unsigned int i = 0; i < _verticies.size() / 3; i++) {
+ for (uint i = 0; i < _verticies.size() / 3; i++) {
const TeVector3f32 triv1 = worldTrans * _verticies[i * 3 + 0];
const TeVector3f32 triv2 = worldTrans * _verticies[i * 3 + 1];
const TeVector3f32 triv3 = worldTrans * _verticies[i * 3 + 2];
@@ -140,12 +140,12 @@ bool TePickMesh2::pointInTriangle(const TeVector2f32 &p1, const TeVector2f32 &p2
return f1 != f2;
}
-void TePickMesh2::setNbTriangles(unsigned int num) {
+void TePickMesh2::setNbTriangles(uint num) {
_verticies.resize(num * 3);
_lastTriangleHit = 0;
}
-void TePickMesh2::setTriangle(unsigned int num, const TeVector3f32 &v1, const TeVector3f32 &v2, const TeVector3f32 &v3) {
+void TePickMesh2::setTriangle(uint num, const TeVector3f32 &v1, const TeVector3f32 &v2, const TeVector3f32 &v3) {
assert(num <= _verticies.size() / 3);
_verticies[num * 3 + 0] = v1;
_verticies[num * 3 + 1] = v2;
@@ -167,7 +167,7 @@ void TePickMesh2::deserialize(Common::ReadStream &stream, TePickMesh2 &mesh) {
mesh._verticies.resize(ntriangles * 3);
mesh._lastTriangleHit = 0;
- for (unsigned int i = 0; i < ntriangles * 3; i++) {
+ for (uint i = 0; i < ntriangles * 3; i++) {
TeVector3f32 vec;
TeVector3f32::deserialize(stream, vec);
mesh._verticies[i] = vec;
diff --git a/engines/tetraedge/te/te_pick_mesh2.h b/engines/tetraedge/te/te_pick_mesh2.h
index 42c1a4235aa..bdda1bab0b6 100644
--- a/engines/tetraedge/te/te_pick_mesh2.h
+++ b/engines/tetraedge/te/te_pick_mesh2.h
@@ -41,11 +41,11 @@ public:
bool pointInTriangle(const TeVector2f32 &p1, const TeVector2f32 &p2, const TeVector2f32 &p3, const TeVector2f32 &p4) const;
- void setLastTriangleHit(unsigned int lastHit) { _lastTriangleHit = lastHit; }
- void setNbTriangles(unsigned int num);
+ void setLastTriangleHit(uint lastHit) { _lastTriangleHit = lastHit; }
+ void setNbTriangles(uint num);
- void setTriangle(unsigned int num, const TeVector3f32 &v1, const TeVector3f32 &v2, const TeVector3f32 &v3);
- void triangle(unsigned int num, TeVector3f32 &v1out, TeVector3f32 &v2out, TeVector3f32 &v3out) const;
+ void setTriangle(uint num, const TeVector3f32 &v1, const TeVector3f32 &v2, const TeVector3f32 &v3);
+ void triangle(uint num, TeVector3f32 &v1out, TeVector3f32 &v2out, TeVector3f32 &v3out) const;
static void serialize(Common::WriteStream &stream, const TePickMesh2 &mesh);
static void deserialize(Common::ReadStream &stream, TePickMesh2 &mesh);
@@ -55,7 +55,7 @@ public:
protected:
Common::Array<TeVector3f32> _verticies;
- unsigned int _lastTriangleHit;
+ uint _lastTriangleHit;
};
diff --git a/engines/tetraedge/te/te_ray_intersection.h b/engines/tetraedge/te/te_ray_intersection.h
index 5b9a65f13e4..fccb6f79a58 100644
--- a/engines/tetraedge/te/te_ray_intersection.h
+++ b/engines/tetraedge/te/te_ray_intersection.h
@@ -36,7 +36,7 @@ TePickMesh *getMesh(const TeVector3f32 ¶m_1, const TeVector3f32 ¶m_2, co
// Replaced with Math::Ray::intersectTriangle
//int intersect(const TeVector3f32 &rayPos, const TeVector3f32 &rayDir, const TeVector3f32 &v1,
-// const TeVector3f32 &v2, const TeVector3f32 &v3, TeVector3f32 &vout, float &fout);
+// const TeVector3f32 &v2, const TeVector3f32 &v3, TeVector3f32 &vout, float &fout);
} // end namespace TeRayIntersection
diff --git a/engines/tetraedge/te/te_renderer.cpp b/engines/tetraedge/te/te_renderer.cpp
index 3da806d02d5..bf97c200eba 100644
--- a/engines/tetraedge/te/te_renderer.cpp
+++ b/engines/tetraedge/te/te_renderer.cpp
@@ -54,7 +54,7 @@ void TeRenderer::addTransparentMesh(const TeMesh &mesh, unsigned long i1, unsign
int newPropsSize = _pendingTransparentMeshProperties + (mesh.shouldDrawMaybe() ? tricount : 1);
_transparentMeshProps.resize(newPropsSize);
if (meshMode == TeMesh::MeshMode_Triangles) {
- for (unsigned int i = 0; i < tricount; i++) {
+ for (uint i = 0; i < tricount; i++) {
const uint meshNo0 = (i1 + i) * 3;
const uint propNo = (_numTransparentMeshes + i) * 3;
@@ -83,7 +83,7 @@ void TeRenderer::addTransparentMesh(const TeMesh &mesh, unsigned long i1, unsign
}
}
} else if (meshMode == TeMesh::MeshMode_TriangleStrip && tricount > 0) {
- for (unsigned int i = 0; i < tricount; i++) {
+ for (uint i = 0; i < tricount; i++) {
const uint meshNo0 = (i1 + i); // TODO: This appears to be the only difference between this and the above?
const uint propNo = (_numTransparentMeshes + i) * 3;
@@ -317,9 +317,9 @@ void TeRenderer::optimiseTransparentMeshProperties() {
if (_transparentMeshProps.size() <= 1)
return;
- unsigned int i = 0;
- for (unsigned int other = 1; other < _transparentMeshProps.size(); other++) {
- unsigned int nextI = other;
+ uint i = 0;
+ for (uint other = 1; other < _transparentMeshProps.size(); other++) {
+ uint nextI = other;
if (_transparentMeshProps[i]._camera == _transparentMeshProps[other]._camera
&& _transparentMeshProps[i]._material == _transparentMeshProps[other]._material
&& _transparentMeshProps[i]._glTexEnvMode == _transparentMeshProps[other]._glTexEnvMode
@@ -359,7 +359,7 @@ static bool compareTransparentMeshProperties(const TeRenderer::TransparentMeshPr
void TeRenderer::dumpTransparentMeshProps() const {
debug("** Transparent MeshProps: num:%ld pending:%d **", _numTransparentMeshes, _pendingTransparentMeshProperties);
debug("draw? / nverts / source / transl / zorder");
- for (unsigned int i = 0; i < _transparentMeshProps.size(); i++) {
+ for (uint i = 0; i < _transparentMeshProps.size(); i++) {
debug("%s %d %d %s %f",
_transparentMeshProps[i]._shouldDraw ? "draw" : "nodr",
_transparentMeshProps[i]._vertexCount,
@@ -373,7 +373,7 @@ void TeRenderer::dumpTransparentMeshProps() const {
void TeRenderer::dumpTransparentMeshData() const {
debug("** Transparent Meshes: num:%ld pending:%d **", _numTransparentMeshes, _pendingTransparentMeshProperties);
debug("vert / normal / coord / color / vertNo");
- for (unsigned int i = 0; i < _transparentMeshVertexes.size(); i++) {
+ for (uint i = 0; i < _transparentMeshVertexes.size(); i++) {
debug("%s %s %s %s %d",
_transparentMeshVertexes[i].dump().c_str(),
_transparentMeshNormals[i].dump().c_str(),
@@ -395,9 +395,9 @@ void TeRenderer::renderTransparentMeshes() {
compareTransparentMeshProperties);
int vertsDrawn = 0;
- for (unsigned int i = 0; i < _transparentMeshProps.size(); i++) {
+ for (uint i = 0; i < _transparentMeshProps.size(); i++) {
const uint vcount = _transparentMeshProps[i]._vertexCount;
- for (unsigned int j = 0; j < vcount; j++)
+ for (uint j = 0; j < vcount; j++)
_transparentMeshVertexNums[vertsDrawn + j] = (short)(_transparentMeshProps[i]._sourceTransparentMesh + j);
vertsDrawn += vcount;
}
@@ -421,7 +421,7 @@ void TeRenderer::renderTransparentMeshes() {
TeMatrix4x4 lastMatrix;
vertsDrawn = 0;
- for (unsigned int i = 0; i < _transparentMeshProps.size(); i++) {
+ for (uint i = 0; i < _transparentMeshProps.size(); i++) {
const TransparentMeshProperties &meshProperties = _transparentMeshProps[i];
if (!meshProperties._shouldDraw)
continue;
@@ -491,7 +491,7 @@ void TeRenderer::renderTransparentMeshes() {
}
void TeRenderer::reset() {
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+ clearBuffer(AllBuffers);
glMatrixMode(GL_PROJECTION);
_matrixMode = MM_GL_PROJECTION;
_matriciesStacks[MM_GL_PROJECTION].loadIdentity();
diff --git a/engines/tetraedge/te/te_renderer.h b/engines/tetraedge/te/te_renderer.h
index 752e29b8f55..a481d2f2936 100644
--- a/engines/tetraedge/te/te_renderer.h
+++ b/engines/tetraedge/te/te_renderer.h
@@ -70,7 +70,9 @@ public:
enum Buffer {
DepthBuffer = 1,
ColorBuffer = 2,
- StencilBuffer = 4
+ StencilBuffer = 4,
+ ColorAndDepth = DepthBuffer | ColorBuffer,
+ AllBuffers = DepthBuffer | ColorBuffer | StencilBuffer
};
void addTransparentMesh(const TeMesh &mesh, unsigned long i1, unsigned long i2, unsigned long i3);
diff --git a/engines/tetraedge/te/te_scrolling_layout.cpp b/engines/tetraedge/te/te_scrolling_layout.cpp
index bd15fffc8a8..5a0b931f682 100644
--- a/engines/tetraedge/te/te_scrolling_layout.cpp
+++ b/engines/tetraedge/te/te_scrolling_layout.cpp
@@ -97,19 +97,19 @@ void TeScrollingLayout::setScrollPosition(const TeVector3f32 &scrPos) {
pos.x() = CLIP(pos.x(), 0.0f, 1.0f);
pos.y() = CLIP(pos.y(), 0.0f, 1.0f);
- const TeVector3f32 thisSize(xSize(), ySize(), 1.0);
- const TeVector3f32 contentSize(_contentLayout->xSize(), _contentLayout->ySize(), 1.0);
- TeVector3f32 sizeRatio;
+ const TeVector3f32 thisSize(xSize(), ySize(), 1.0);
+ const TeVector3f32 contentSize(_contentLayout->xSize(), _contentLayout->ySize(), 1.0);
+ TeVector3f32 sizeRatio;
- if (thisSize.x() == 0.0 || thisSize.y() == 0.0) {
+ if (thisSize.x() == 0.0 || thisSize.y() == 0.0) {
sizeRatio = TeVector3f32(1.0, 1.0, 1.0);
- } else {
+ } else {
sizeRatio = contentSize / thisSize;
- }
+ }
- TeVector3f32 posToSet = _contentLayout->userPosition();
- const TeVector3f32 contentAnchor = _contentLayout->anchor();
- if (!_enclose) {
+ TeVector3f32 posToSet = _contentLayout->userPosition();
+ const TeVector3f32 contentAnchor = _contentLayout->anchor();
+ if (!_enclose) {
if (thisSize.x() < contentSize.x()) {
float offset = (sizeRatio.x() + 1.0) * pos.x();
posToSet.x() = contentAnchor.x() * sizeRatio.x() + (1.0 - offset);
@@ -118,7 +118,7 @@ void TeScrollingLayout::setScrollPosition(const TeVector3f32 &scrPos) {
float offset = (sizeRatio.y() + 1.0) * pos.y();
posToSet.y() = contentAnchor.y() * sizeRatio.y() + (1.0 - offset);
}
- } else {
+ } else {
if (thisSize.x() < contentSize.x()) {
float offset = (sizeRatio.x() - 1.0) * pos.x();
posToSet.x() = contentAnchor.x() * sizeRatio.x() - offset;
@@ -127,25 +127,25 @@ void TeScrollingLayout::setScrollPosition(const TeVector3f32 &scrPos) {
float offset = (sizeRatio.y() - 1.0) * pos.y();
posToSet.y() = contentAnchor.y() * sizeRatio.y() - offset;
}
- }
+ }
- _contentLayout->setPosition(posToSet);
- _posUpdatedSignal.call();
+ _contentLayout->setPosition(posToSet);
+ _posUpdatedSignal.call();
}
TeVector3f32 TeScrollingLayout::scrollPosition() {
if (!_contentLayout)
return TeVector3f32();
- const TeVector3f32 thisSize(xSize(), ySize(), 1.0);
- const TeVector3f32 contentSize(_contentLayout->xSize(), _contentLayout->ySize(), 1.0);
+ const TeVector3f32 thisSize(xSize(), ySize(), 1.0);
+ const TeVector3f32 contentSize(_contentLayout->xSize(), _contentLayout->ySize(), 1.0);
TeVector3f32 sizeRatio;
- if (thisSize.x() == 0.0 || thisSize.y() == 0.0) {
+ if (thisSize.x() == 0.0 || thisSize.y() == 0.0) {
sizeRatio = TeVector3f32(1.0, 1.0, 1.0);
- } else {
+ } else {
sizeRatio = contentSize / thisSize;
- }
+ }
TeVector3f32 result(0.0, 0.0, 0.0);
if (_enclose) {
@@ -165,7 +165,7 @@ TeVector3f32 TeScrollingLayout::scrollPosition() {
}
bool TeScrollingLayout::onAutoScrollDelayTimer() {
- _autoScrollDelayTimer.stop();
+ _autoScrollDelayTimer.stop();
playAutoScrollAnimation1();
return false;
}
@@ -275,15 +275,15 @@ bool TeScrollingLayout::onMouseMove(const Common::Point &pt) {
}
}
- setScrollPosition(scrollPos + offset);
- _slideDownMousePos = inputmgr->lastMousePos();
- TeVector3f32 nowMousePos(inputmgr->lastMousePos());
- _insideMouseThreshold = (_lastMouseDownPos - nowMousePos).length() <= _mouseMoveThreshold;
- long elapsed = _scrollTimer.timeElapsed();
- if (elapsed > 0) {
+ setScrollPosition(scrollPos + offset);
+ _slideDownMousePos = inputmgr->lastMousePos();
+ TeVector3f32 nowMousePos(inputmgr->lastMousePos());
+ _insideMouseThreshold = (_lastMouseDownPos - nowMousePos).length() <= _mouseMoveThreshold;
+ long elapsed = _scrollTimer.timeElapsed();
+ if (elapsed > 0) {
_speed = offset / (float)(elapsed / 1000000.0);
- }
- return false;
+ }
+ return false;
}
bool TeScrollingLayout::onMouseLeftUp(const Common::Point &pt) {
@@ -292,7 +292,7 @@ bool TeScrollingLayout::onMouseLeftUp(const Common::Point &pt) {
_inertiaAnimation.setCurve(_inertiaAnimationCurve);
_inertiaAnimation._duration = _inertiaAnimationDuration;
_inertiaAnimation._startVal = _speed;
- _inertiaAnimation._endVal = TeVector3f32(0.0, 0.0, 0.0);
+ _inertiaAnimation._endVal = TeVector3f32(0, 0, 0);
_inertiaAnimation._callbackObj = this;
_inertiaAnimation._callbackMethod = &TeScrollingLayout::setSpeed;
_inertiaAnimation.play();
diff --git a/engines/tetraedge/te/te_scrolling_layout.h b/engines/tetraedge/te/te_scrolling_layout.h
index 528019bf8c4..ea38d322451 100644
--- a/engines/tetraedge/te/te_scrolling_layout.h
+++ b/engines/tetraedge/te/te_scrolling_layout.h
@@ -41,7 +41,7 @@ public:
void setInertiaAnimationCurve(const Common::Array<float> &curve) {
_inertiaAnimationCurve = curve;
}
- void setAutoScrollDelay(unsigned int val) {
+ void setAutoScrollDelay(uint val) {
_autoScrollDelay = val;
}
void setAutoScrollLoop(int loop) {
diff --git a/engines/tetraedge/te/te_text_base2.cpp b/engines/tetraedge/te/te_text_base2.cpp
index ed5015a16c7..2f5f39e131a 100644
--- a/engines/tetraedge/te/te_text_base2.cpp
+++ b/engines/tetraedge/te/te_text_base2.cpp
@@ -95,7 +95,7 @@ void TeTextBase2::build() {
img.create(_size._x, _size._y, nullpal, TeImage::RGBA8);
img.fill(_globalColor.r(), _globalColor.g(), _globalColor.b(), 0);
- for (unsigned int i = 0; i < _wrappedLines.size(); i++) {
+ for (uint i = 0; i < _wrappedLines.size(); i++) {
drawLine(img, _wrappedLines[i], lineoffsets[i]);
}
@@ -155,12 +155,12 @@ void TeTextBase2::clearText() {
_valueWasSet = true;
}
-void TeTextBase2::computeNbSpaces(Line &line, unsigned int startOffset, unsigned int endOffset) {
+void TeTextBase2::computeNbSpaces(Line &line, uint startOffset, uint endOffset) {
// only needed if we implement Justify
error("TODO: Implement TeTextBase2::computeNbSpaces");
}
-TeColor TeTextBase2::currentColor(unsigned int offset) const {
+TeColor TeTextBase2::currentColor(uint offset) const {
if (_colors.size() == 0)
return _globalColor;
int closest_off = -1;
@@ -177,7 +177,7 @@ TeColor TeTextBase2::currentColor(unsigned int offset) const {
return result;
}
-TeIntrusivePtr<TeFont3> TeTextBase2::currentFont(unsigned int offset) {
+TeIntrusivePtr<TeFont3> TeTextBase2::currentFont(uint offset) {
if (_fonts.size() == 0)
return TeIntrusivePtr<TeFont3>();
int closest_off = -1;
@@ -207,7 +207,7 @@ void TeTextBase2::draw() {
// warning("TODO: Implement TeTextBase2::draw strikethrough support");
}
-void TeTextBase2::drawEmptyChar(unsigned int offset) {
+void TeTextBase2::drawEmptyChar(uint offset) {
error("TODO: Implement TeTextBase2::drawEmptychar");
}
@@ -219,31 +219,31 @@ void TeTextBase2::drawLine(TeImage &img, const Common::String &str, int yoffset)
font->draw(img, str, _fontSize, yoffset, TeColor(0, 0, 0, 255), _alignStyle);
}
-unsigned int TeTextBase2::endOfWord(unsigned int offset) const {
+uint TeTextBase2::endOfWord(uint offset) const {
while (offset < _text.size() && !newLines(offset) && !isASpace(offset))
offset++;
return offset;
}
-void TeTextBase2::insertNewLine(unsigned int offset) {
+void TeTextBase2::insertNewLine(uint offset) {
_lineBreaks.push_back(offset);
}
-bool TeTextBase2::isASpace(unsigned int offset) const {
+bool TeTextBase2::isASpace(uint offset) const {
char c = _text[offset];
return (c == ' ' || c == '\t' || c == '\n' || c == '\r');
}
-int TeTextBase2::newLines(unsigned int offset) const {
+int TeTextBase2::newLines(uint offset) const {
int result = 0;
- for (unsigned int off : _lineBreaks) {
+ for (uint off : _lineBreaks) {
if (off == offset)
result++;
}
return result;
}
-int TeTextBase2::nextNonSpaceChar(unsigned int offset) {
+int TeTextBase2::nextNonSpaceChar(uint offset) {
while (isASpace(offset))
offset++;
return offset; // TODO: or offset - 1?
@@ -254,12 +254,12 @@ void TeTextBase2::setAlignStyle(TeFont3::AlignStyle style) {
_valueWasSet = true;
}
-void TeTextBase2::setColor(unsigned int offset, const TeColor &color) {
+void TeTextBase2::setColor(uint offset, const TeColor &color) {
_colors.setVal(offset, color);
_valueWasSet = true;
}
-void TeTextBase2::setFont(unsigned int offset, const TeIntrusivePtr<TeFont3> &newfont) {
+void TeTextBase2::setFont(uint offset, const TeIntrusivePtr<TeFont3> &newfont) {
_fonts.setVal(offset, newfont);
_valueWasSet = true;
}
diff --git a/engines/tetraedge/te/te_text_base2.h b/engines/tetraedge/te/te_text_base2.h
index 3033669b7ff..b64f2fc757f 100644
--- a/engines/tetraedge/te/te_text_base2.h
+++ b/engines/tetraedge/te/te_text_base2.h
@@ -38,8 +38,8 @@ public:
TeTextBase2();
struct Line {
- unsigned int _startOffset;
- unsigned int _endOffset;
+ uint _startOffset;
+ uint _endOffset;
float _height;
float _width;
};
@@ -54,17 +54,17 @@ public:
void clearStyles();
void clearText();
- TeColor currentColor(unsigned int offset) const;
- TeIntrusivePtr<TeFont3> currentFont(unsigned int offset);
+ TeColor currentColor(uint offset) const;
+ TeIntrusivePtr<TeFont3> currentFont(uint offset);
void draw();
- unsigned int endOfWord(unsigned int i) const;
- void insertNewLine(unsigned int offset);
- bool isASpace(unsigned int offset) const;
- int newLines(unsigned int offset) const;
- int nextNonSpaceChar(unsigned int start);
+ uint endOfWord(uint i) const;
+ void insertNewLine(uint offset);
+ bool isASpace(uint offset) const;
+ int newLines(uint offset) const;
+ int nextNonSpaceChar(uint start);
void setAlignStyle(TeFont3::AlignStyle style);
- void setColor(unsigned int offset, const TeColor &color);
- void setFont(unsigned int offset, const TeIntrusivePtr<TeFont3> &newfont);
+ void setColor(uint offset, const TeColor &color);
+ void setFont(uint offset, const TeIntrusivePtr<TeFont3> &newfont);
void setFontSize(unsigned long fontSz);
void setGlobalColor(const TeColor &color);
void setInterLine(float val);
@@ -79,8 +79,8 @@ public:
const TeVector2s32 &size() const { return _size; }
private:
- void computeNbSpaces(Line &line, unsigned int startOffset, unsigned int endOffset);
- void drawEmptyChar(unsigned int offset);
+ void computeNbSpaces(Line &line, uint startOffset, uint endOffset);
+ void drawEmptyChar(uint offset);
void drawLine(TeImage &img, const Common::String &str, int yoffset);
TeFont3::AlignStyle _alignStyle;
@@ -99,8 +99,8 @@ private:
Common::Array<Common::String> _wrappedLines;
Common::Array<uint32> _lineBreaks;
- Common::HashMap<unsigned int, TeColor> _colors;
- Common::HashMap<unsigned int, TeIntrusivePtr<TeFont3>> _fonts;
+ Common::HashMap<uint, TeColor> _colors;
+ Common::HashMap<uint, TeIntrusivePtr<TeFont3>> _fonts;
};
} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_text_layout.cpp b/engines/tetraedge/te/te_text_layout.cpp
index b448b96144f..2b55b0e4b8b 100644
--- a/engines/tetraedge/te/te_text_layout.cpp
+++ b/engines/tetraedge/te/te_text_layout.cpp
@@ -125,7 +125,7 @@ void TeTextLayout::setText(const Common::String &val) {
}
if (parser.style().size())
_base.setAlignStyle(_alignNameToEnum(parser.style()));
- for (unsigned int offset : parser.lineBreaks())
+ for (uint offset : parser.lineBreaks())
_base.insertNewLine(offset);
_sizeChanged = true;
}
diff --git a/engines/tetraedge/te/te_text_layout_xml_parser.h b/engines/tetraedge/te/te_text_layout_xml_parser.h
index c913b0c92cd..627f3a3cc6d 100644
--- a/engines/tetraedge/te/te_text_layout_xml_parser.h
+++ b/engines/tetraedge/te/te_text_layout_xml_parser.h
@@ -71,7 +71,7 @@ public:
int fontSize() const { return _fontSize; }
const Common::String &style() const { return _style; }
const Common::String &textContent() const { return _textContent; }
- const Common::Array<unsigned int> &lineBreaks() const { return _lineBreaks; }
+ const Common::Array<uint> &lineBreaks() const { return _lineBreaks; }
private:
TeColor _color;
@@ -79,7 +79,7 @@ private:
int _fontSize;
Common::String _style;
Common::String _textContent;
- Common::Array<unsigned int> _lineBreaks;
+ Common::Array<uint> _lineBreaks;
};
} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_tiled_surface.cpp b/engines/tetraedge/te/te_tiled_surface.cpp
index 5f60feec8b3..9c9d19eb939 100644
--- a/engines/tetraedge/te/te_tiled_surface.cpp
+++ b/engines/tetraedge/te/te_tiled_surface.cpp
@@ -256,9 +256,9 @@ void TeTiledSurface::updateSurface() {
getRangeIntersection(_leftCrop, 1.0 - _rightCrop, tile->_vec1.x(), tile->_vec2.x() + tile->_vec1.x(), &left, &right);
getRangeIntersection(_bottomCrop, 1.0 - _topCrop, tile->_vec1.y(), tile->_vec2.y() + tile->_vec1.y(), &top, &bottom);
if (right < left)
- right = left;
+ right = left;
if (bottom < top)
- bottom = top;
+ bottom = top;
const float scaled_l = (left - tile->_vec1.x()) / tile->_vec2.x();
const float scaled_r = (right - tile->_vec1.x()) / tile->_vec2.x();
diff --git a/engines/tetraedge/te/te_tiled_texture.cpp b/engines/tetraedge/te/te_tiled_texture.cpp
index b6438ea57b1..654225092e4 100644
--- a/engines/tetraedge/te/te_tiled_texture.cpp
+++ b/engines/tetraedge/te/te_tiled_texture.cpp
@@ -103,12 +103,11 @@ bool TeTiledTexture::load(const TeImage &img) {
_somethingSize += TeVector2s32(tiledata->_texture->width(), tiledata->_texture->height());
} else {
tiledata->_texture.release();
- tiledata->_vec2 = TeVector3f32(0.0, 0.0, 0.0);
+ tiledata->_vec2 = TeVector3f32(0, 0, 0);
_somethingSize = Te3DTexture::optimisedSize(TeVector2s32(tileimage->w, tileimage->h));
}
- tiledata->_vec1 = TeVector3f32
- (row * ((float)_tileSize._x / _totalSize._x),
- col * ((float)_tileSize._y / _totalSize._y), 0.0);
+ tiledata->_vec1 = TeVector3f32(row * ((float)_tileSize._x / _totalSize._x),
+ col * ((float)_tileSize._y / _totalSize._y), 0.0);
}
}
@@ -128,8 +127,8 @@ bool TeTiledTexture::load(const TeIntrusivePtr<Te3DTexture> &texture) {
_tileArray.resize(1);
Tile *tileData = tile(TeVector2s32(0, 0));
tileData->_texture = texture;
- tileData->_vec2 = TeVector3f32(1.0, 1.0, 0.0);
- tileData->_vec1 = TeVector3f32(0.0, 0.0, 0.0);
+ tileData->_vec2 = TeVector3f32(1, 1, 0);
+ tileData->_vec1 = TeVector3f32(0, 0, 0);
setAccessName(texture->getAccessName().append(".tt"));
return true;
}
@@ -144,7 +143,7 @@ long TeTiledTexture::numberOfRow() const {
/*static*/
TeImage *TeTiledTexture::optimisedTileImage(Common::Array<TeImage> &images, const TeVector2s32 &size,
- const Common::SharedPtr<TePalette> &pal, enum TeImage::Format format) {
+ const Common::SharedPtr<TePalette> &pal, enum TeImage::Format format) {
for (TeImage &image : images) {
if (image.w == size._x && image.h == size._y && image.teFormat() == format) {
return ℑ
diff --git a/engines/tetraedge/te/te_tiled_texture.h b/engines/tetraedge/te/te_tiled_texture.h
index 402a6d1aa21..a49ac9b2457 100644
--- a/engines/tetraedge/te/te_tiled_texture.h
+++ b/engines/tetraedge/te/te_tiled_texture.h
@@ -53,7 +53,7 @@ public:
long numberOfRow() const;
TeImage *optimisedTileImage(Common::Array<TeImage> &images, const TeVector2s32 &size,
- const Common::SharedPtr<TePalette> &pal, enum TeImage::Format format);
+ const Common::SharedPtr<TePalette> &pal, enum TeImage::Format format);
void release();
void save() {};
diff --git a/engines/tetraedge/tetraedge.h b/engines/tetraedge/tetraedge.h
index 290638adbc5..0ee0510fcac 100644
--- a/engines/tetraedge/tetraedge.h
+++ b/engines/tetraedge/tetraedge.h
@@ -85,9 +85,9 @@ public:
bool hasFeature(EngineFeature f) const override {
return
- (f == kSupportsLoadingDuringRuntime) ||
- (f == kSupportsSavingDuringRuntime) ||
- (f == kSupportsReturnToLauncher);
+ (f == kSupportsLoadingDuringRuntime) ||
+ (f == kSupportsSavingDuringRuntime) ||
+ (f == kSupportsReturnToLauncher);
};
bool canLoadGameStateCurrently() override {
Commit: b75e9faae392daa232ea4f3f01e24be97d1f0416
https://github.com/scummvm/scummvm/commit/b75e9faae392daa232ea4f3f01e24be97d1f0416
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2023-01-16T17:36:43+01:00
Commit Message:
TETRAEDGE: Remove unused Console class
Changed paths:
R engines/tetraedge/console.cpp
R engines/tetraedge/console.h
engines/tetraedge/module.mk
engines/tetraedge/tetraedge.cpp
diff --git a/engines/tetraedge/console.cpp b/engines/tetraedge/console.cpp
deleted file mode 100644
index c455866a69a..00000000000
--- a/engines/tetraedge/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 "tetraedge/console.h"
-
-namespace Tetraedge {
-
-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;
-}
-
-} // namespace Tetraedge
diff --git a/engines/tetraedge/console.h b/engines/tetraedge/console.h
deleted file mode 100644
index 210f467ab37..00000000000
--- a/engines/tetraedge/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 TETRAEDGE_CONSOLE_H
-#define TETRAEDGE_CONSOLE_H
-
-#include "gui/debugger.h"
-
-namespace Tetraedge {
-
-class Console : public GUI::Debugger {
-private:
- bool Cmd_test(int argc, const char **argv);
-public:
- Console();
- ~Console() override;
-};
-
-} // End of namespace Tetraedge
-
-#endif
diff --git a/engines/tetraedge/module.mk b/engines/tetraedge/module.mk
index 01df59acb24..7f55a5eb390 100644
--- a/engines/tetraedge/module.mk
+++ b/engines/tetraedge/module.mk
@@ -112,7 +112,6 @@ MODULE_OBJS := \
te/te_vector3f32.o \
te/te_visual_fade.o \
te/te_xml_gui.o \
- console.o \
metaengine.o
# This module can be built as a plugin
diff --git a/engines/tetraedge/tetraedge.cpp b/engines/tetraedge/tetraedge.cpp
index 05bf6b71680..b7fa2f60aba 100644
--- a/engines/tetraedge/tetraedge.cpp
+++ b/engines/tetraedge/tetraedge.cpp
@@ -21,7 +21,6 @@
#include "tetraedge/tetraedge.h"
#include "tetraedge/detection.h"
-#include "tetraedge/console.h"
#include "common/scummsys.h"
#include "common/config-manager.h"
#include "common/debug-channels.h"
@@ -194,9 +193,6 @@ Common::Error TetraedgeEngine::run() {
_renderer->init();
_renderer->reset();
- // Set the engine's debugger console
- setDebugger(new Console());
-
getInputMgr()->_keyUpSignal.add(this, &TetraedgeEngine::onKeyUp);
// If a savegame was selected from the launcher, load it.
Commit: 68790973baafd419705a5ffca7ddb4cf4a20b186
https://github.com/scummvm/scummvm/commit/68790973baafd419705a5ffca7ddb4cf4a20b186
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2023-01-16T17:36:43+01:00
Commit Message:
TETRAEDGE: Comment for detection entry
Changed paths:
engines/tetraedge/detection_tables.h
diff --git a/engines/tetraedge/detection_tables.h b/engines/tetraedge/detection_tables.h
index a6db2b5a904..f141b5c3510 100644
--- a/engines/tetraedge/detection_tables.h
+++ b/engines/tetraedge/detection_tables.h
@@ -29,6 +29,9 @@ const PlainGameDescriptor GAME_NAMES[] = {
};
const ADGameDescription GAME_DESCRIPTIONS[] = {
+ // GOG and Steam releases
+ // Note: Full sum of GOG and Steam are different,
+ // but size and first 5000 bytes are the same.
{
"syberia",
nullptr,
Commit: 1a793bae5bdcde396bda2b7b2893a7f67f6a6be0
https://github.com/scummvm/scummvm/commit/1a793bae5bdcde396bda2b7b2893a7f67f6a6be0
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2023-01-16T17:36:43+01:00
Commit Message:
TETRAEDGE: Remove static objects and improve cleanup
Changed paths:
engines/tetraedge/game/application.cpp
engines/tetraedge/game/character.cpp
engines/tetraedge/game/character.h
engines/tetraedge/game/game.cpp
engines/tetraedge/game/objectif.cpp
engines/tetraedge/te/te_3d_object2.cpp
engines/tetraedge/te/te_animation.cpp
engines/tetraedge/te/te_animation.h
engines/tetraedge/te/te_core.cpp
engines/tetraedge/te/te_layout.cpp
engines/tetraedge/te/te_lua_thread.cpp
engines/tetraedge/te/te_lua_thread.h
engines/tetraedge/te/te_mesh.cpp
engines/tetraedge/te/te_model.cpp
engines/tetraedge/te/te_model_vertex_animation.cpp
engines/tetraedge/te/te_model_vertex_animation.h
engines/tetraedge/te/te_object.cpp
engines/tetraedge/te/te_object.h
engines/tetraedge/te/te_timer.cpp
engines/tetraedge/te/te_timer.h
engines/tetraedge/tetraedge.cpp
diff --git a/engines/tetraedge/game/application.cpp b/engines/tetraedge/game/application.cpp
index bd0b9e3e526..f89442e05eb 100644
--- a/engines/tetraedge/game/application.cpp
+++ b/engines/tetraedge/game/application.cpp
@@ -291,6 +291,13 @@ void Application::create() {
void Application::destroy() {
Character::animCacheFreeAll();
+
+ _globalBonusMenu.unload();
+ _bonusMenu.unload();
+ _mainMenu.unload();
+ _credits.leave();
+ _ownerErrorMenu.unload();
+ _splashScreens.unload();
}
void Application::startGame(bool newGame, int difficulty) {
diff --git a/engines/tetraedge/game/character.cpp b/engines/tetraedge/game/character.cpp
index ae9600d3edc..0790f25d382 100644
--- a/engines/tetraedge/game/character.cpp
+++ b/engines/tetraedge/game/character.cpp
@@ -36,10 +36,10 @@
namespace Tetraedge {
/*static*/ Common::HashMap<Common::String, Character::CharacterSettings> *Character::_globalCharacterSettings = nullptr;
+/*static*/ Common::HashMap<Common::String, TeIntrusivePtr<TeModelAnimation>> *Character::_animCacheMap = nullptr;
-/*static*/ Common::Array<Character::AnimCacheElement> Character::_animCache;
-/*static*/ Common::HashMap<Common::String, TeIntrusivePtr<TeModelAnimation>> Character::_animCacheMap;
-uint Character::_animCacheSize = 0;
+// /*static*/ Common::Array<Character::AnimCacheElement> *Character::_animCache = nullptr;
+// /*static*/ uint Character::_animCacheSize = 0;
void Character::CharacterSettings::clear() {
_name.clear();
@@ -139,14 +139,24 @@ void Character::addCallback(const Common::String &animKey, const Common::String
}
}
-/*static*/ void Character::animCacheFreeAll() {
- for (const auto &entry : _animCache)
- _animCacheSize -= entry._size;
- _animCache.clear();
- _animCacheMap.clear();
+/*static*/
+void Character::animCacheFreeAll() {
+ /*
+ if (_animCache) {
+ for (const auto &entry : (*_animCache))
+ _animCacheSize -= entry._size;
+ delete _animCache;
+ _animCache = nullptr;
+ } */
+ if (_animCacheMap) {
+ delete _animCacheMap;
+ _animCacheMap = nullptr;
+ }
}
-/*static*/ void Character::animCacheFreeOldest() {
+/*static*/
+void Character::animCacheFreeOldest() {
+ // Unused?
//_animCacheSize -= _animCache[_animCache.size() - 1]._size;
//_animCache.pop_back();
}
@@ -154,9 +164,12 @@ void Character::addCallback(const Common::String &animKey, const Common::String
/*static*/
TeIntrusivePtr<TeModelAnimation> Character::animCacheLoad(const Common::Path &path) {
const Common::String pathStr = path.toString();
- if (_animCacheMap.contains(pathStr)) {
+ if (!_animCacheMap) {
+ _animCacheMap = new Common::HashMap<Common::String, TeIntrusivePtr<TeModelAnimation>>();
+ }
+ if (_animCacheMap->contains(pathStr)) {
// Copy from the cache (keep the cached instance clean)
- return new TeModelAnimation(*_animCacheMap.getVal(pathStr));
+ return new TeModelAnimation(*_animCacheMap->getVal(pathStr));
}
TeIntrusivePtr<TeModelAnimation> modelAnim = new TeModelAnimation();
@@ -164,7 +177,7 @@ TeIntrusivePtr<TeModelAnimation> Character::animCacheLoad(const Common::Path &pa
warning("Failed to load anim %s", path.toString().c_str());
}
- _animCacheMap.setVal(pathStr, modelAnim);
+ _animCacheMap->setVal(pathStr, modelAnim);
return modelAnim;
}
diff --git a/engines/tetraedge/game/character.h b/engines/tetraedge/game/character.h
index 8eb0b41e9da..a9bbe6df77c 100644
--- a/engines/tetraedge/game/character.h
+++ b/engines/tetraedge/game/character.h
@@ -238,9 +238,9 @@ private:
Common::HashMap<Common::String, Common::Array<Callback *>> _callbacks;
- static Common::Array<AnimCacheElement> _animCache;
- static Common::HashMap<Common::String, TeIntrusivePtr<TeModelAnimation>> _animCacheMap;
- static uint _animCacheSize;
+ // static Common::Array<AnimCacheElement> *_animCache; // Never used?
+ // static uint _animCacheSize; // Never used?
+ static Common::HashMap<Common::String, TeIntrusivePtr<TeModelAnimation>> *_animCacheMap;
static Common::HashMap<Common::String, CharacterSettings> *_globalCharacterSettings;
};
diff --git a/engines/tetraedge/game/game.cpp b/engines/tetraedge/game/game.cpp
index ec45dbf41e4..ae01a2294ef 100644
--- a/engines/tetraedge/game/game.cpp
+++ b/engines/tetraedge/game/game.cpp
@@ -736,18 +736,24 @@ void Game::leave(bool flag) {
if (!_enteredFlag2)
return;
+ Application *app = g_engine->getApplication();
+
deleteNoScale();
_entered = false;
_running = false;
_notifier.unload();
g_engine->getInputMgr()->_mouseLUpSignal.remove(this, &Game::onMouseClick);
_question2.unload();
+ TeLayout *cellbg = _inventory.cellphone()->gui().buttonLayout("background");
+ if (cellbg)
+ app->frontLayout().removeChild(cellbg);
_inventory.cellphone()->leave();
_dialog2.unload();
_inventory.unload();
_documentsBrowser.unload();
_inventoryMenu.unload();
_gui1.unload();
+ _objectif.unload(); // not done in original, but should be.
_scene.close();
_forGui.unload();
if (_scene._character) {
@@ -786,7 +792,6 @@ void Game::leave(bool flag) {
_playedTimer.stop();
_enteredFlag2 = false;
- Application *app = g_engine->getApplication();
app->lockCursor(false);
app->lockCursorFromAction(false);
// TODO: Set some inputmgr flag here?
diff --git a/engines/tetraedge/game/objectif.cpp b/engines/tetraedge/game/objectif.cpp
index 42a93841cb7..adf0bfb668c 100644
--- a/engines/tetraedge/game/objectif.cpp
+++ b/engines/tetraedge/game/objectif.cpp
@@ -80,6 +80,7 @@ void Objectif::load() {
}
void Objectif::leave() {
+ Application *app = g_engine->getApplication();
TeLayout *layout;
layout = _gui1.layout("background");
if (layout)
@@ -228,6 +229,13 @@ void Objectif::createChildLayout(TeLayout *layout, Common::String const &taskId,
void Objectif::unload() {
removeChildren();
leave();
+
+ Application *app = g_engine->getApplication();
+ TeButtonLayout *btn = _gui2.buttonLayoutChecked("helpButton");
+ app->frontLayout().removeChild(btn);
+ btn = _gui1.buttonLayoutChecked("background");
+ app->frontLayout().removeChild(btn);
+
_gui1.unload();
_gui2.unload();
_tasks.clear();
diff --git a/engines/tetraedge/te/te_3d_object2.cpp b/engines/tetraedge/te/te_3d_object2.cpp
index 5f96a047c37..069d1bb04ef 100644
--- a/engines/tetraedge/te/te_3d_object2.cpp
+++ b/engines/tetraedge/te/te_3d_object2.cpp
@@ -36,6 +36,8 @@ Te3DObject2::~Te3DObject2() {
for (auto *child : _children) {
child->setParent(nullptr);
}
+ // clear list in case parent->removeChild triggers a signal which ends up referencing it.
+ _children.clear();
if (parent()) {
parent()->removeChild(this);
}
diff --git a/engines/tetraedge/te/te_animation.cpp b/engines/tetraedge/te/te_animation.cpp
index 7048112b137..2b56fb20740 100644
--- a/engines/tetraedge/te/te_animation.cpp
+++ b/engines/tetraedge/te/te_animation.cpp
@@ -23,12 +23,13 @@
namespace Tetraedge {
+/*static*/
Common::Array<TeAnimation *> *TeAnimation::_animations = nullptr;
-/*static*/ Common::Array<TeAnimation *> *TeAnimation::animations() {
+/*static*/
+Common::Array<TeAnimation *> *TeAnimation::animations() {
if (!_animations)
_animations = new Common::Array<TeAnimation *>();
-
return _animations;
}
@@ -108,6 +109,12 @@ void TeAnimation::resumeAll() {
}
}
+/*static*/
+void TeAnimation::cleanup() {
+ delete _animations;
+ _animations = nullptr;
+}
+
/*static*/
void TeAnimation::updateAll() {
Common::Array<TeAnimation *> &anims = *animations();
diff --git a/engines/tetraedge/te/te_animation.h b/engines/tetraedge/te/te_animation.h
index 576b0688776..f5e3d5766ad 100644
--- a/engines/tetraedge/te/te_animation.h
+++ b/engines/tetraedge/te/te_animation.h
@@ -49,6 +49,7 @@ public:
static void resumeAll();
static void updateAll();
+ static void cleanup();
TeSignal0Param &onStop() { return _onStopSignal; }
TeSignal0Param &onFinished() { return _onFinishedSignal; }
diff --git a/engines/tetraedge/te/te_core.cpp b/engines/tetraedge/te/te_core.cpp
index bb6b76e292d..73960d82ca2 100644
--- a/engines/tetraedge/te/te_core.cpp
+++ b/engines/tetraedge/te/te_core.cpp
@@ -125,8 +125,8 @@ Common::Path TeCore::findFile(const Common::Path &path) {
const Common::Path fname = path.getLastComponent();
const Common::Path dir = path.getParent();
- static const Common::Path pathSuffixes[] = {
- "",
+ static const char *pathSuffixes[] = {
+ nullptr, // no suffix
"PC-MacOSX",
"PC-PS3-Android-MacOSX",
"PC-MacOSX-Xbox360-PS3",
@@ -156,10 +156,10 @@ Common::Path TeCore::findFile(const Common::Path &path) {
for (int langtype = 0; langtype < ARRAYSIZE(langs); langtype++) {
const Common::Path &lang = langs[langtype];
for (int i = 0; i < ARRAYSIZE(pathSuffixes); i++) {
- const Common::Path &suffix = pathSuffixes[i];
+ const char *suffix = pathSuffixes[i];
Common::Path testPath = dir;
- if (!suffix.empty())
+ if (suffix)
testPath.joinInPlace(suffix);
if (!lang.empty())
testPath.joinInPlace(lang);
@@ -168,7 +168,7 @@ Common::Path TeCore::findFile(const Common::Path &path) {
return testPath;
// also try the other way around
- if (!lang.empty() && !suffix.empty()) {
+ if (!lang.empty() && suffix) {
testPath = dir.join(lang).joinInPlace(suffix).join(fname);
if (Common::File::exists(testPath) || Common::FSNode(testPath).exists())
return testPath;
diff --git a/engines/tetraedge/te/te_layout.cpp b/engines/tetraedge/te/te_layout.cpp
index 7578a111caf..3f0660cf2e2 100644
--- a/engines/tetraedge/te/te_layout.cpp
+++ b/engines/tetraedge/te/te_layout.cpp
@@ -51,7 +51,9 @@ TeLayout::TeLayout() : Te3DObject2(), _autoz(true), _needZUpdate(true), _updatin
TeLayout::~TeLayout() {
if (parent() && _onParentSizeChangedCallback) {
parent()->onSizeChanged().remove(_onParentSizeChangedCallback);
+ _onParentSizeChangedCallback.reset();
parent()->onWorldTransformationMatrixChanged().remove(_onParentWorldTransformationMatrixChangedCallback);
+ _onParentWorldTransformationMatrixChangedCallback.reset();
}
if (_onChildSizeChangedCallback) {
diff --git a/engines/tetraedge/te/te_lua_thread.cpp b/engines/tetraedge/te/te_lua_thread.cpp
index 4c1a8368f88..5800e6d0e01 100644
--- a/engines/tetraedge/te/te_lua_thread.cpp
+++ b/engines/tetraedge/te/te_lua_thread.cpp
@@ -32,22 +32,24 @@
namespace Tetraedge {
-/*static*/ Common::Array<TeLuaThread *> TeLuaThread::_threadList;
+/*static*/
+Common::Array<TeLuaThread *> *TeLuaThread::_threadList = nullptr;
TeLuaThread::TeLuaThread(TeLuaContext *context) : _resumeCount(0), _lastResumeResult(0), _released(false) {
_luaThread = lua_newthread(context->luaState());
_bottomRef = luaL_ref(context->luaState(), LUA_REGISTRYINDEX);
- _threadList.push_back(this);
+ threadList()->push_back(this);
}
TeLuaThread::~TeLuaThread() {
luaL_unref(_luaThread, LUA_REGISTRYINDEX, _bottomRef);
uint i;
- for (i = 0; i < _threadList.size(); i++)
- if (_threadList[i] == this)
+ Common::Array<TeLuaThread *> *threads = threadList();
+ for (i = 0; i < threads->size(); i++)
+ if ((*threads)[i] == this)
break;
- if (i < _threadList.size())
- _threadList.remove_at(i);
+ if (i < threads->size())
+ threads->remove_at(i);
}
/*static*/ TeLuaThread *TeLuaThread::create(TeLuaContext *context) {
@@ -226,14 +228,29 @@ void TeLuaThread::resume(const TeVariant &p1, const TeVariant &p2, const TeVaria
}
}
-/*static*/ TeLuaThread *TeLuaThread::threadFromState(lua_State *state) {
- for (auto &thread : _threadList) {
+/*static*/
+TeLuaThread *TeLuaThread::threadFromState(lua_State *state) {
+ Common::Array<TeLuaThread *> *threads = threadList();
+ for (auto &thread : *threads) {
if (thread->_luaThread == state)
return thread;
}
return nullptr;
}
+/*static*/
+Common::Array<TeLuaThread *> *TeLuaThread::threadList() {
+ if (!_threadList)
+ _threadList = new Common::Array<TeLuaThread *>();
+ return _threadList;
+}
+
+/*static*/
+void TeLuaThread::cleanup() {
+ delete _threadList;
+ _threadList = nullptr;
+}
+
int TeLuaThread::yield() {
return lua_yield(_luaThread, 0);
}
diff --git a/engines/tetraedge/te/te_lua_thread.h b/engines/tetraedge/te/te_lua_thread.h
index a7c96efffea..86e554d613f 100644
--- a/engines/tetraedge/te/te_lua_thread.h
+++ b/engines/tetraedge/te/te_lua_thread.h
@@ -59,6 +59,8 @@ public:
static TeLuaThread *threadFromState(lua_State *state);
int yield();
+ static void cleanup();
+
private:
void _resume(int nargs);
@@ -68,7 +70,8 @@ private:
int _lastResumeResult;
bool _released;
- static Common::Array<TeLuaThread *> _threadList;
+ static Common::Array<TeLuaThread *> *threadList();
+ static Common::Array<TeLuaThread *> *_threadList;
};
diff --git a/engines/tetraedge/te/te_mesh.cpp b/engines/tetraedge/te/te_mesh.cpp
index ccc439470a0..77cc00b0b04 100644
--- a/engines/tetraedge/te/te_mesh.cpp
+++ b/engines/tetraedge/te/te_mesh.cpp
@@ -373,7 +373,7 @@ void TeMesh::update(TeIntrusivePtr<TeModelVertexAnimation> vertexanim) {
_updatedVerticies.resize(_verticies.size());
_updatedNormals.resize(_normals.size());
- const Common::Array<TeVector3f32> &animverts = vertexanim->getVertices();
+ const Common::Array<TeVector3f32> animverts = vertexanim->getVertices();
assert(animverts.size() >= _verticies.size());
for (uint i = 0; i < _verticies.size(); i++) {
_updatedVerticies[i] = animverts[i];
diff --git a/engines/tetraedge/te/te_model.cpp b/engines/tetraedge/te/te_model.cpp
index 2ae90852127..919a12253ac 100644
--- a/engines/tetraedge/te/te_model.cpp
+++ b/engines/tetraedge/te/te_model.cpp
@@ -248,17 +248,17 @@ void TeModel::update() {
mesh.update(&_boneMatricies, &_lerpedElements);
} else {
mesh.resizeUpdatedTables(mesh.numVerticies());
- const Common::Array<TeVector3f32> *verticies = nullptr;
+ Common::Array<TeVector3f32> verticies;
if (_modelVertexAnim && mesh.name() == _modelVertexAnim->head())
- verticies = &_modelVertexAnim->getVertices();
+ verticies = _modelVertexAnim->getVertices();
for (uint i = 0; i < mesh.numVerticies(); i++) {
TeVector3f32 vertex;
- if (!verticies) {
+ if (verticies.empty()) {
vertex = mesh.preUpdatedVertex(i);
} else {
- if (i < verticies->size())
- vertex = (*verticies)[i];
+ if (i < verticies.size())
+ vertex = verticies[i];
}
TeVector3f32 normal = mesh.preUpdatedNormal(i);
int idx = (int)mesh.matrixIndex(i);
@@ -268,7 +268,7 @@ void TeModel::update() {
if (idx < (int)_bones.size()) {
updatedvertex = vertex;
- if (!verticies)
+ if (verticies.empty())
updatedvertex = _boneMatricies[idx] * updatedvertex;
updatednormal = _boneMatricies[idx] * normal;
} else {
diff --git a/engines/tetraedge/te/te_model_vertex_animation.cpp b/engines/tetraedge/te/te_model_vertex_animation.cpp
index cd71198e331..83073e17cc5 100644
--- a/engines/tetraedge/te/te_model_vertex_animation.cpp
+++ b/engines/tetraedge/te/te_model_vertex_animation.cpp
@@ -49,10 +49,9 @@ TeVector3f32 TeModelVertexAnimation::getKeyVertex(unsigned long keyno, uint vert
return retval;
}
-const Common::Array<TeVector3f32> &TeModelVertexAnimation::getVertices() {
- static Common::Array<TeVector3f32> lerpVtx;
+Common::Array<TeVector3f32> TeModelVertexAnimation::getVertices() {
+ Common::Array<TeVector3f32> lerpVtx;
- lerpVtx.clear();
if (_keydata.size() < 2)
return lerpVtx;
diff --git a/engines/tetraedge/te/te_model_vertex_animation.h b/engines/tetraedge/te/te_model_vertex_animation.h
index 87b30a1e38d..27ed4fffe91 100644
--- a/engines/tetraedge/te/te_model_vertex_animation.h
+++ b/engines/tetraedge/te/te_model_vertex_animation.h
@@ -57,7 +57,7 @@ public:
const Common::String &head() const { return _head; }
TeVector3f32 getKeyVertex(unsigned long keyno, uint vertexno);
- const Common::Array<TeVector3f32> &getVertices();
+ Common::Array<TeVector3f32> getVertices();
bool load(Common::ReadStream &stream);
void save(Common::WriteStream &stream) const;
diff --git a/engines/tetraedge/te/te_object.cpp b/engines/tetraedge/te/te_object.cpp
index ea856557979..ac63db8e899 100644
--- a/engines/tetraedge/te/te_object.cpp
+++ b/engines/tetraedge/te/te_object.cpp
@@ -20,6 +20,7 @@
*/
#include "tetraedge/te/te_object.h"
+#include "common/debug.h"
namespace Tetraedge {
@@ -27,17 +28,40 @@ TeObject::TeObject() {
}
void TeObject::deleteLater() {
- _pendingDeleteList.push_back(this);
+ pendingDeleteList()->push_back(this);
}
-/*static*/ void TeObject::deleteNow() {
- uint len = _pendingDeleteList.size();
- for (uint i = 0; i < len; i++) {
- delete _pendingDeleteList[i];
+/*static*/
+void TeObject::deleteNow() {
+ Common::Array<TeObject *> *pending = pendingDeleteList();
+ for (auto *obj : (*pending)) {
+ delete obj;
}
- _pendingDeleteList.clear();
+ pending->clear();
+}
+
+/*static*/
+Common::Array<TeObject *> *TeObject::_pendingDeleteList = nullptr;
+
+/*static*/
+Common::Array<TeObject *> *TeObject::pendingDeleteList() {
+ if (!_pendingDeleteList)
+ _pendingDeleteList = new Common::Array<TeObject *>();
+ return _pendingDeleteList;
+}
+
+/*static*/
+void TeObject::cleanup() {
+ // Should be deleted already, but if not..
+ if (_pendingDeleteList && _pendingDeleteList->size()) {
+ warning("Leaking %d objects on shutdown.", _pendingDeleteList->size());
+ for (auto *obj : (*_pendingDeleteList)) {
+ debug("Leaked %p", obj);
+ }
+ }
+ delete _pendingDeleteList;
+ _pendingDeleteList = nullptr;
}
-Common::Array<TeObject *> TeObject::_pendingDeleteList;
} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_object.h b/engines/tetraedge/te/te_object.h
index cb4b4a35188..6725d41a8ac 100644
--- a/engines/tetraedge/te/te_object.h
+++ b/engines/tetraedge/te/te_object.h
@@ -38,8 +38,11 @@ public:
/** Delete all pending objects now */
static void deleteNow();
+ static void cleanup();
+
private:
- static Common::Array<TeObject *> _pendingDeleteList;
+ static Common::Array<TeObject *> *_pendingDeleteList;
+ static Common::Array<TeObject *> *pendingDeleteList();
};
diff --git a/engines/tetraedge/te/te_timer.cpp b/engines/tetraedge/te/te_timer.cpp
index 97e62ec6a21..ea02846a2a8 100644
--- a/engines/tetraedge/te/te_timer.cpp
+++ b/engines/tetraedge/te/te_timer.cpp
@@ -24,11 +24,11 @@
namespace Tetraedge {
-/*static*/ bool TeTimer::_pausedAll;
-/*static*/ unsigned long TeTimer::_realTime;
-/*static*/ Common::Array<TeTimer *> TeTimer::_timers;
-/*static*/ Common::Array<TeTimer *> TeTimer::_pausedTimers;
-/*static*/ TeRealTimer *TeTimer::_realTimer;
+/*static*/ bool TeTimer::_pausedAll = false;
+/*static*/ unsigned long TeTimer::_realTime = 0;
+/*static*/ Common::Array<TeTimer *> *TeTimer::_timers = nullptr;
+/*static*/ Common::Array<TeTimer *> *TeTimer::_pausedTimers = nullptr;
+/*static*/ TeRealTimer *TeTimer::_realTimer = nullptr;
TeTimer::TeTimer() : _stopped(true), _pausable(true), _alarmTime(0),
@@ -40,16 +40,19 @@ _startTime(0), _lastTimeElapsed(0), _startTimeOffset(0), _updated(false) {
}
TeTimer::~TeTimer() {
- for (uint i = 0; i < _timers.size(); i++) {
- if (_timers[i] == this) {
- _timers.remove_at(i);
+ Common::Array<TeTimer *> *ts = timers();
+ for (uint i = 0; i < ts->size(); i++) {
+ if ((*ts)[i] == this) {
+ ts->remove_at(i);
break;
}
}
+
// Not done in original, but probably should be?
- for (uint i = 0; i < _pausedTimers.size(); i++) {
- if (_pausedTimers[i] == this) {
- _pausedTimers.remove_at(i);
+ Common::Array<TeTimer *> *pts = pausedTimers();
+ for (uint i = 0; i < pts->size(); i++) {
+ if ((*pts)[i] == this) {
+ pts->remove_at(i);
break;
}
}
@@ -72,9 +75,9 @@ void TeTimer::start() {
_lastTimeElapsed = timeOffset;
_stopped = false;
_updated = false;
- _timers.push_back(this);
+ timers()->push_back(this);
if (_pausedAll && _pausable) {
- _pausedTimers.push_back(this);
+ pausedTimers()->push_back(this);
pause();
}
}
@@ -83,9 +86,10 @@ void TeTimer::pause() {
if (!_stopped) {
_startTime = _realTime;
_stopped = true;
- for (uint i = 0; i < _timers.size(); i++) {
- if (_timers[i] == this) {
- _timers.remove_at(i);
+ Common::Array<TeTimer *> *ts = timers();
+ for (uint i = 0; i < ts->size(); i++) {
+ if ((*ts)[i] == this) {
+ ts->remove_at(i);
break;
}
}
@@ -138,24 +142,25 @@ unsigned long TeTimer::time_() {
void TeTimer::pausable(bool ispausable) {
_pausable = ispausable;
+ Common::Array<TeTimer *> *paused = pausedTimers();
if (!_pausable) {
- for (uint i = 0; i < _pausedTimers.size(); i++) {
- if (_pausedTimers[i] == this) {
- _pausedTimers.remove_at(i);
+ for (uint i = 0; i < paused->size(); i++) {
+ if ((*paused)[i] == this) {
+ paused->remove_at(i);
break;
}
}
} else if (_pausedAll) {
// ensure this is paused now
bool add = true;
- for (TeTimer *pausedTimer : _pausedTimers) {
+ for (TeTimer *pausedTimer : *paused) {
if (pausedTimer == this) {
add = false;
break;
}
}
if (add)
- _pausedTimers.push_back(this);
+ paused->push_back(this);
pause();
}
}
@@ -169,43 +174,72 @@ void TeTimer::setAlarmIn(unsigned long offset) {
_alarmSet = true;
}
-/*static*/ TeRealTimer *TeTimer::realTimer() {
+/*static*/
+TeRealTimer *TeTimer::realTimer() {
if (!_realTimer)
_realTimer = new TeRealTimer();
return _realTimer;
}
-/*static*/ void TeTimer::pauseAll() {
+/*static*/
+Common::Array<TeTimer *> *TeTimer::timers() {
+ if (!_timers)
+ _timers = new Common::Array<TeTimer *>();
+ return _timers;
+}
+
+/*static*/
+Common::Array<TeTimer *> *TeTimer::pausedTimers() {
+ if (!_pausedTimers)
+ _pausedTimers = new Common::Array<TeTimer *>();
+ return _pausedTimers;
+}
+
+/*static*/
+void TeTimer::pauseAll() {
if (_pausedAll)
return;
_pausedAll = true;
_realTime = realTimer()->getTimeFromStart();
- for (TeTimer *timer : _timers) {
+ for (TeTimer *timer : (*timers())) {
if (timer->_stopped || !timer->_pausable)
continue;
- _pausedTimers.push_back(timer);
+ pausedTimers()->push_back(timer);
timer->pause();
}
}
-/*static*/ void TeTimer::resumeAll() {
+/*static*/
+void TeTimer::resumeAll() {
if (!_pausedAll)
return;
_pausedAll = false;
_realTime = realTimer()->getTimeFromStart();
- for (TeTimer *timer : _pausedTimers) {
+ for (TeTimer *timer : (*pausedTimers())) {
timer->start();
}
- _pausedTimers.clear();
+ pausedTimers()->clear();
}
-/*static*/ void TeTimer::updateAll() {
+/*static*/
+void TeTimer::updateAll() {
_realTime = realTimer()->getTimeFromStart();
- for (auto *timer : _timers)
+ for (auto *timer : (*timers()))
timer->update();
}
+/*static*/
+void TeTimer::cleanup() {
+ delete _timers;
+ _timers = nullptr;
+ delete _pausedTimers;
+ _pausedTimers = nullptr;
+ delete _realTimer;
+ _realTimer = nullptr;
+}
+
+
} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_timer.h b/engines/tetraedge/te/te_timer.h
index 824dfd70539..93d5d6d348d 100644
--- a/engines/tetraedge/te/te_timer.h
+++ b/engines/tetraedge/te/te_timer.h
@@ -53,10 +53,14 @@ public:
static void resumeAll();
static void updateAll();
+ static void cleanup();
+
bool running() const { return !_stopped; }
private:
static TeRealTimer *realTimer();
+ static Common::Array<TeTimer *> *timers();
+ static Common::Array<TeTimer *> *pausedTimers();
unsigned long _startTime;
unsigned long _startTimeOffset;
@@ -71,8 +75,8 @@ private:
static bool _pausedAll;
static unsigned long _realTime;
- static Common::Array<TeTimer *> _timers;
- static Common::Array<TeTimer *> _pausedTimers;
+ static Common::Array<TeTimer *> *_timers;
+ static Common::Array<TeTimer *> *_pausedTimers;
static TeRealTimer *_realTimer;
};
diff --git a/engines/tetraedge/tetraedge.cpp b/engines/tetraedge/tetraedge.cpp
index b7fa2f60aba..2c9c0302d99 100644
--- a/engines/tetraedge/tetraedge.cpp
+++ b/engines/tetraedge/tetraedge.cpp
@@ -37,6 +37,7 @@
#include "tetraedge/te/te_core.h"
#include "tetraedge/te/te_renderer.h"
#include "tetraedge/te/te_resource_manager.h"
+#include "tetraedge/te/te_lua_thread.h"
#include "tetraedge/te/te_sound_manager.h"
#include "tetraedge/te/te_input_mgr.h"
@@ -52,6 +53,7 @@ TetraedgeEngine::TetraedgeEngine(OSystem *syst, const ADGameDescription *gameDes
}
TetraedgeEngine::~TetraedgeEngine() {
+ //TeObject::deleteNow();
delete _core;
delete _game;
delete _application;
@@ -61,6 +63,10 @@ TetraedgeEngine::~TetraedgeEngine() {
delete _inputMgr;
Object3D::cleanup();
Character::cleanup();
+ TeAnimation::cleanup();
+ TeLuaThread::cleanup();
+ TeTimer::cleanup();
+ TeObject::cleanup();
}
/*static*/
@@ -217,6 +223,11 @@ Common::Error TetraedgeEngine::run() {
g_system->delayMillis(10);
}
+ // Ensure game has stopped.
+ _game->leave(true);
+ TeObject::deleteNow();
+ _application->destroy();
+
return Common::kNoError;
}
Commit: 16c607cd94b97a6b4ca6a2c1725adb9c9b8ffb98
https://github.com/scummvm/scummvm/commit/16c607cd94b97a6b4ca6a2c1725adb9c9b8ffb98
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2023-01-16T17:36:43+01:00
Commit Message:
TETRAEDGE: Split OpenGL-specific code out to allow TinyGL support
Changed paths:
A engines/tetraedge/game/characters_shadow_opengl.cpp
A engines/tetraedge/game/characters_shadow_opengl.h
A engines/tetraedge/game/characters_shadow_tinygl.cpp
A engines/tetraedge/game/characters_shadow_tinygl.h
A engines/tetraedge/te/te_3d_texture_opengl.cpp
A engines/tetraedge/te/te_3d_texture_opengl.h
A engines/tetraedge/te/te_3d_texture_tinygl.cpp
A engines/tetraedge/te/te_3d_texture_tinygl.h
A engines/tetraedge/te/te_light_opengl.cpp
A engines/tetraedge/te/te_light_opengl.h
A engines/tetraedge/te/te_light_tinygl.cpp
A engines/tetraedge/te/te_light_tinygl.h
A engines/tetraedge/te/te_mesh_opengl.cpp
A engines/tetraedge/te/te_mesh_opengl.h
A engines/tetraedge/te/te_mesh_tinygl.cpp
A engines/tetraedge/te/te_mesh_tinygl.h
A engines/tetraedge/te/te_renderer_opengl.cpp
A engines/tetraedge/te/te_renderer_opengl.h
A engines/tetraedge/te/te_renderer_tinygl.cpp
A engines/tetraedge/te/te_renderer_tinygl.h
engines/tetraedge/game/billboard.cpp
engines/tetraedge/game/character.cpp
engines/tetraedge/game/characters_shadow.cpp
engines/tetraedge/game/characters_shadow.h
engines/tetraedge/game/in_game_scene.cpp
engines/tetraedge/game/in_game_scene.h
engines/tetraedge/game/lua_binds.cpp
engines/tetraedge/game/scene_lights_xml_parser.cpp
engines/tetraedge/game/scene_lights_xml_parser.h
engines/tetraedge/module.mk
engines/tetraedge/te/te_3d_texture.cpp
engines/tetraedge/te/te_3d_texture.h
engines/tetraedge/te/te_bezier_curve.cpp
engines/tetraedge/te/te_free_move_zone.cpp
engines/tetraedge/te/te_light.cpp
engines/tetraedge/te/te_light.h
engines/tetraedge/te/te_material.cpp
engines/tetraedge/te/te_material.h
engines/tetraedge/te/te_mesh.cpp
engines/tetraedge/te/te_mesh.h
engines/tetraedge/te/te_model.cpp
engines/tetraedge/te/te_model.h
engines/tetraedge/te/te_pick_mesh2.cpp
engines/tetraedge/te/te_renderer.cpp
engines/tetraedge/te/te_renderer.h
engines/tetraedge/te/te_resource_manager.h
engines/tetraedge/te/te_text_base2.cpp
engines/tetraedge/te/te_text_base2.h
engines/tetraedge/te/te_tiled_surface.cpp
engines/tetraedge/te/te_tiled_texture.cpp
engines/tetraedge/te/te_visual_fade.cpp
engines/tetraedge/tetraedge.cpp
engines/tetraedge/tetraedge.h
diff --git a/engines/tetraedge/game/billboard.cpp b/engines/tetraedge/game/billboard.cpp
index d3c8f002568..466fc059650 100644
--- a/engines/tetraedge/game/billboard.cpp
+++ b/engines/tetraedge/game/billboard.cpp
@@ -32,7 +32,7 @@ Billboard::Billboard() : _hasPos2(false) {
bool Billboard::load(const Common::String &path) {
_model = new TeModel();
- TeIntrusivePtr<Te3DTexture> texture = new Te3DTexture();
+ TeIntrusivePtr<Te3DTexture> texture = Te3DTexture::makeInstance();
Game *game = g_engine->getGame();
Common::Path texpath = game->sceneZonePath().join(path);
texture->load(texpath);
@@ -70,22 +70,22 @@ void Billboard::calcVertex() {
fx = _pos.x();
fy = _pos.y();
meshVertex = camTotalInverse * TeVector3f32(fx + fx - 1.0f, fy + fy - 1.0f, posvec.z());
- _model->meshes()[0].setVertex(0, meshVertex);
+ _model->meshes()[0]->setVertex(0, meshVertex);
fx = _pos.x();
fy = _pos.y() + _size.getY();
meshVertex = camTotalInverse * TeVector3f32(fx + fx - 1.0f, fy + fy - 1.0f, posvec.z());
- _model->meshes()[0].setVertex(1, meshVertex);
+ _model->meshes()[0]->setVertex(1, meshVertex);
fx = _pos.x() + _size.getX();
fy = _pos.y();
meshVertex = camTotalInverse * TeVector3f32(fx + fx - 1.0f, fy + fy - 1.0f, posvec.z());
- _model->meshes()[0].setVertex(2, meshVertex);
+ _model->meshes()[0]->setVertex(2, meshVertex);
fx = _pos.x() + _size.getX();
fy = _pos.y() + _size.getY();
meshVertex = camTotalInverse * TeVector3f32(fx + fx - 1.0f, fy + fy - 1.0f, posvec.z());
- _model->meshes()[0].setVertex(3, meshVertex);
+ _model->meshes()[0]->setVertex(3, meshVertex);
}
void Billboard::position(const TeVector3f32 &pos) {
diff --git a/engines/tetraedge/game/character.cpp b/engines/tetraedge/game/character.cpp
index 0790f25d382..f57b8a3a1a2 100644
--- a/engines/tetraedge/game/character.cpp
+++ b/engines/tetraedge/game/character.cpp
@@ -370,7 +370,7 @@ bool Character::loadModel(const Common::String &mname, bool unused) {
_model->setScale(_characterSettings._defaultScale);
for (auto &mesh : _model->meshes())
- mesh.setVisible(true);
+ mesh->setVisible(true);
// Set all mouthes not visible by default
_model->setVisibleByName("_B_", false);
@@ -388,7 +388,7 @@ bool Character::loadModel(const Common::String &mname, bool unused) {
_walkEndGAnimLen = animLengthFromFile(walkAnim(WalkPart_EndG), &_walkEndGAnimFrameCount);
_walkLoopAnimLen = animLengthFromFile(walkAnim(WalkPart_Loop), &_walkLoopAnimFrameCount);
- TeIntrusivePtr<Te3DTexture> shadow = new Te3DTexture();
+ TeIntrusivePtr<Te3DTexture> shadow = Te3DTexture::makeInstance();
shadow->load("models/Textures/simple_shadow_alpha.tga");
for (int i = 0; i < 2; i++) {
diff --git a/engines/tetraedge/game/characters_shadow.cpp b/engines/tetraedge/game/characters_shadow.cpp
index 3593488eedb..09fc4c55537 100644
--- a/engines/tetraedge/game/characters_shadow.cpp
+++ b/engines/tetraedge/game/characters_shadow.cpp
@@ -19,21 +19,22 @@
*
*/
-#include "graphics/opengl/system_headers.h"
-
#include "tetraedge/tetraedge.h"
#include "tetraedge/game/character.h"
#include "tetraedge/game/characters_shadow.h"
+#include "tetraedge/game/characters_shadow_opengl.h"
+#include "tetraedge/game/characters_shadow_tinygl.h"
#include "tetraedge/te/te_light.h"
#include "tetraedge/te/te_renderer.h"
#include "tetraedge/te/te_3d_texture.h"
+
namespace Tetraedge {
/*static*/
Te3DObject2 *CharactersShadow::_camTarget = nullptr;
-CharactersShadow::CharactersShadow() {
+CharactersShadow::CharactersShadow() : _glTex(0), _texSize(0) {
}
void CharactersShadow::create(InGameScene *scene) {
@@ -46,14 +47,9 @@ void CharactersShadow::create(InGameScene *scene) {
_camera->setPerspectiveVal(1.0);
_camera->setName("_shadowCam");
_camera->viewport(0, 0, _texSize, _texSize);
- Te3DTexture::unbind();
- glGenTextures(1, &_glTex);
- glBindTexture(GL_TEXTURE_2D, _glTex);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, _texSize, _texSize, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, nullptr);
+
+ createInternal();
+
renderer->disableTexture();
}
@@ -70,28 +66,15 @@ void CharactersShadow::createTexture(InGameScene *scene) {
_camera->setFov((float)(scene->shadowFov() * M_PI / 180.0));
_camera->setOrthoPlanes(scene->shadowNearPlane(), scene->shadowFarPlane());
_camera->apply();
-
- glClearColor(0.0, 0.0, 0.0, 0.0);
- renderer->clearBuffer(TeRenderer::ColorAndDepth);
-
- for (Character *character : scene->_characters) {
- character->_model->draw();
- }
- scene->_character->_model->draw();
- Te3DTexture::unbind();
- glBindTexture(GL_TEXTURE_2D, _glTex);
- glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, _texSize, _texSize);
- renderer->clearBuffer(TeRenderer::ColorAndDepth);
+
+ createTextureInternal(scene);
TeCamera::restore();
TeCamera::restore();
}
void CharactersShadow::destroy() {
- TeRenderer *renderer = g_engine->getRenderer();
- renderer->disableTexture();
- glBindTexture(GL_TEXTURE_2D, 0);
- glDeleteTextures(1, &_glTex);
+ deleteTexture();
if (_camera)
_camera = nullptr;
if (_camTarget) {
@@ -100,70 +83,20 @@ void CharactersShadow::destroy() {
}
}
-void CharactersShadow::draw(InGameScene *scene) {
- TeRenderer *renderer = g_engine->getRenderer();
- glDepthMask(false);
- renderer->disableZBuffer();
- renderer->enableTexture();
- glBindTexture(GL_TEXTURE_2D, _glTex);
- Te3DTexture::unbind();
- glBindTexture(GL_TEXTURE_2D, _glTex);
- glEnable(GL_BLEND);
- renderer->setCurrentColor(scene->shadowColor());
-
- TeMatrix4x4 matrix;
- matrix.translate(TeVector3f32(0.5f, 0.5f, 0.5f));
- matrix.scale(TeVector3f32(0.5f, 0.5f, 0.5f));
- matrix = matrix * _camera->projectionMatrix();
-
- TeMatrix4x4 cammatrix = _camera->worldTransformationMatrix();
- cammatrix.inverse();
-
- matrix = matrix * cammatrix;
-
- glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
-
- float f[4];
- for (uint i = 0; i < 4; i++)
- f[i] = matrix(i, 0);
-
- glTexGenfv(GL_S, GL_EYE_PLANE, f);
- glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
-
- for (uint i = 0; i < 4; i++)
- f[i] = matrix(i, 1);
-
- glTexGenfv(GL_T, GL_EYE_PLANE, f);
- glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
-
- for (uint i = 0; i < 4; i++)
- f[i] = matrix(i, 2);
-
- glTexGenfv(GL_R, GL_EYE_PLANE, f);
- glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
-
- for (uint i = 0; i < 4; i++)
- f[i] = matrix(i, 3);
-
- glTexGenfv(GL_Q, GL_EYE_PLANE, f);
-
- Te3DTexture::unbind();
- glBindTexture(GL_TEXTURE_2D, _glTex);
- glEnable(GL_BLEND);
- renderer->setCurrentColor(scene->shadowColor());
-
- for (TeIntrusivePtr<TeModel> model : scene->zoneModels()) {
- if (model->meshes().size() > 0 && model->meshes()[0].materials().empty()) {
- model->meshes()[0].defaultMaterial(TeIntrusivePtr<Te3DTexture>());
- model->meshes()[0].materials()[0]._enableSomethingDefault0 = true;
- model->meshes()[0].materials()[0]._diffuseColor = scene->shadowColor();
- }
- model->draw();
- }
-
- renderer->disableTexture();
- glDepthMask(true);
- renderer->enableZBuffer();
+/*static*/
+CharactersShadow *CharactersShadow::makeInstance() {
+ Graphics::RendererType r = g_engine->preferredRendererType();
+
+#if defined(USE_OPENGL_GAME) || defined(USE_OPENGL_SHADERS)
+ if (r == Graphics::kRendererTypeOpenGL)
+ return new CharactersShadowOpenGL();
+#endif
+
+#if defined(USE_TINYGL)
+ if (r == Graphics::kRendererTypeTinyGL)
+ return new CharactersShadowTinyGL();
+#endif
+ error("Couldn't create CharactersShadow for selected renderer");
}
} // end namespace Tetraedge
diff --git a/engines/tetraedge/game/characters_shadow.h b/engines/tetraedge/game/characters_shadow.h
index e0b8c51efe7..46ac1f1cc68 100644
--- a/engines/tetraedge/game/characters_shadow.h
+++ b/engines/tetraedge/game/characters_shadow.h
@@ -31,14 +31,22 @@ class InGameScene;
class CharactersShadow {
public:
CharactersShadow();
+ virtual ~CharactersShadow() {};
void create(InGameScene *scene);
void createTexture(InGameScene *scene);
void destroy();
- void draw(InGameScene *scene);
+ virtual void draw(InGameScene *scene) = 0;
//void drawTexture(); // empty?
-private:
+ // Make an instance which is correct for the preferred renderer
+ static CharactersShadow *makeInstance();
+
+protected:
+ virtual void createInternal() = 0;
+ virtual void createTextureInternal(InGameScene *scene) = 0;
+ virtual void deleteTexture() = 0;
+
uint _glTex;
int _texSize;
TeIntrusivePtr<TeCamera> _camera;
diff --git a/engines/tetraedge/game/characters_shadow_opengl.cpp b/engines/tetraedge/game/characters_shadow_opengl.cpp
new file mode 100644
index 00000000000..ccba697b9fe
--- /dev/null
+++ b/engines/tetraedge/game/characters_shadow_opengl.cpp
@@ -0,0 +1,132 @@
+/* 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 "graphics/opengl/system_headers.h"
+
+#include "tetraedge/tetraedge.h"
+#include "tetraedge/game/character.h"
+#include "tetraedge/game/characters_shadow_opengl.h"
+#include "tetraedge/te/te_light.h"
+#include "tetraedge/te/te_renderer.h"
+#include "tetraedge/te/te_3d_texture_opengl.h"
+
+namespace Tetraedge {
+
+void CharactersShadowOpenGL::createInternal() {
+ Te3DTextureOpenGL::unbind();
+ glGenTextures(1, &_glTex);
+ glBindTexture(GL_TEXTURE_2D, _glTex);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, _texSize, _texSize, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, nullptr);
+}
+
+void CharactersShadowOpenGL::createTextureInternal(InGameScene *scene) {
+ TeRenderer *renderer = g_engine->getRenderer();
+ glClearColor(0.0, 0.0, 0.0, 0.0);
+ renderer->clearBuffer(TeRenderer::ColorAndDepth);
+
+ for (Character *character : scene->_characters) {
+ character->_model->draw();
+ }
+ scene->_character->_model->draw();
+ Te3DTextureOpenGL::unbind();
+ glBindTexture(GL_TEXTURE_2D, _glTex);
+ glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, _texSize, _texSize);
+ renderer->clearBuffer(TeRenderer::ColorAndDepth);
+}
+
+void CharactersShadowOpenGL::deleteTexture() {
+ TeRenderer *renderer = g_engine->getRenderer();
+ renderer->disableTexture();
+ glBindTexture(GL_TEXTURE_2D, 0);
+ glDeleteTextures(1, &_glTex);
+}
+
+void CharactersShadowOpenGL::draw(InGameScene *scene) {
+ TeRenderer *renderer = g_engine->getRenderer();
+ glDepthMask(false);
+ renderer->disableZBuffer();
+ renderer->enableTexture();
+ glBindTexture(GL_TEXTURE_2D, _glTex);
+ Te3DTextureOpenGL::unbind();
+ glBindTexture(GL_TEXTURE_2D, _glTex);
+ glEnable(GL_BLEND);
+ renderer->setCurrentColor(scene->shadowColor());
+
+ TeMatrix4x4 matrix;
+ matrix.translate(TeVector3f32(0.5f, 0.5f, 0.5f));
+ matrix.scale(TeVector3f32(0.5f, 0.5f, 0.5f));
+ matrix = matrix * _camera->projectionMatrix();
+
+ TeMatrix4x4 cammatrix = _camera->worldTransformationMatrix();
+ cammatrix.inverse();
+
+ matrix = matrix * cammatrix;
+
+ glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
+
+ float f[4];
+ for (uint i = 0; i < 4; i++)
+ f[i] = matrix(i, 0);
+
+ glTexGenfv(GL_S, GL_EYE_PLANE, f);
+ glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
+
+ for (uint i = 0; i < 4; i++)
+ f[i] = matrix(i, 1);
+
+ glTexGenfv(GL_T, GL_EYE_PLANE, f);
+ glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
+
+ for (uint i = 0; i < 4; i++)
+ f[i] = matrix(i, 2);
+
+ glTexGenfv(GL_R, GL_EYE_PLANE, f);
+ glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
+
+ for (uint i = 0; i < 4; i++)
+ f[i] = matrix(i, 3);
+
+ glTexGenfv(GL_Q, GL_EYE_PLANE, f);
+
+ Te3DTextureOpenGL::unbind();
+ glBindTexture(GL_TEXTURE_2D, _glTex);
+ glEnable(GL_BLEND);
+ renderer->setCurrentColor(scene->shadowColor());
+
+ for (TeIntrusivePtr<TeModel> model : scene->zoneModels()) {
+ if (model->meshes().size() > 0 && model->meshes()[0]->materials().empty()) {
+ model->meshes()[0]->defaultMaterial(TeIntrusivePtr<Te3DTexture>());
+ model->meshes()[0]->materials()[0]._enableSomethingDefault0 = true;
+ model->meshes()[0]->materials()[0]._diffuseColor = scene->shadowColor();
+ }
+ model->draw();
+ }
+
+ renderer->disableTexture();
+ glDepthMask(true);
+ renderer->enableZBuffer();
+}
+
+} // end namespace Tetraedge
diff --git a/engines/tetraedge/game/characters_shadow_opengl.h b/engines/tetraedge/game/characters_shadow_opengl.h
new file mode 100644
index 00000000000..84d7178c0f5
--- /dev/null
+++ b/engines/tetraedge/game/characters_shadow_opengl.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 TETRAEDGE_GAME_CHARACTERS_SHADOW_OPENGL_H
+#define TETRAEDGE_GAME_CHARACTERS_SHADOW_OPENGL_H
+
+#if defined(USE_OPENGL_GAME) || defined(USE_OPENGL_SHADERS)
+
+#include "tetraedge/game/characters_shadow.h"
+
+namespace Tetraedge {
+
+class InGameScene;
+
+class CharactersShadowOpenGL : public CharactersShadow {
+public:
+ CharactersShadowOpenGL() {};
+
+ void draw(InGameScene *scene) override;
+
+protected:
+ virtual void createInternal() override;
+ virtual void createTextureInternal(InGameScene *scene) override;
+ virtual void deleteTexture() override;
+
+};
+
+} // end namespace Tetraedge
+
+#endif // USE_OPENGL
+
+#endif // TETRAEDGE_GAME_CHARACTERS_SHADOW_OPENGL_H
diff --git a/engines/tetraedge/game/characters_shadow_tinygl.cpp b/engines/tetraedge/game/characters_shadow_tinygl.cpp
new file mode 100644
index 00000000000..278a205c8a4
--- /dev/null
+++ b/engines/tetraedge/game/characters_shadow_tinygl.cpp
@@ -0,0 +1,137 @@
+/* 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 "graphics/tinygl/tinygl.h"
+
+#include "tetraedge/tetraedge.h"
+#include "tetraedge/game/character.h"
+#include "tetraedge/game/characters_shadow_tinygl.h"
+#include "tetraedge/te/te_light.h"
+#include "tetraedge/te/te_renderer.h"
+#include "tetraedge/te/te_3d_texture_tinygl.h"
+
+namespace Tetraedge {
+
+void CharactersShadowTinyGL::createInternal() {
+ Te3DTextureTinyGL::unbind();
+ tglGenTextures(1, &_glTex);
+ tglBindTexture(TGL_TEXTURE_2D, _glTex);
+ tglTexParameteri(TGL_TEXTURE_2D, TGL_TEXTURE_MIN_FILTER, TGL_LINEAR);
+ tglTexParameteri(TGL_TEXTURE_2D, TGL_TEXTURE_MAG_FILTER, TGL_LINEAR);
+ tglTexParameteri(TGL_TEXTURE_2D, TGL_TEXTURE_WRAP_S, TGL_CLAMP);
+ tglTexParameteri(TGL_TEXTURE_2D, TGL_TEXTURE_WRAP_T, TGL_CLAMP);
+ // TODO: not supported in TGL
+ //tglTexImage2D(TGL_TEXTURE_2D, 0, TGL_LUMINANCE_ALPHA, _texSize, _texSize, 0, TGL_LUMINANCE_ALPHA, TGL_UNSIGNED_BYTE, nullptr);
+}
+
+void CharactersShadowTinyGL::createTextureInternal(InGameScene *scene) {
+ TeRenderer *renderer = g_engine->getRenderer();
+ tglClearColor(0.0, 0.0, 0.0, 0.0);
+ renderer->clearBuffer(TeRenderer::ColorAndDepth);
+
+ for (Character *character : scene->_characters) {
+ character->_model->draw();
+ }
+ scene->_character->_model->draw();
+ Te3DTextureTinyGL::unbind();
+ tglBindTexture(TGL_TEXTURE_2D, _glTex);
+ // TODO: Find TGL equivalent for this..
+ // tglCopyTexSubImage2D(TGL_TEXTURE_2D, 0, 0, 0, 0, 0, _texSize, _texSize);
+ renderer->clearBuffer(TeRenderer::ColorAndDepth);
+}
+
+void CharactersShadowTinyGL::deleteTexture() {
+ TeRenderer *renderer = g_engine->getRenderer();
+ renderer->disableTexture();
+ tglBindTexture(TGL_TEXTURE_2D, 0);
+ tglDeleteTextures(1, &_glTex);
+}
+
+void CharactersShadowTinyGL::draw(InGameScene *scene) {
+ TeRenderer *renderer = g_engine->getRenderer();
+ tglDepthMask(false);
+ renderer->disableZBuffer();
+ renderer->enableTexture();
+ tglBindTexture(TGL_TEXTURE_2D, _glTex);
+ Te3DTextureTinyGL::unbind();
+ tglBindTexture(TGL_TEXTURE_2D, _glTex);
+ tglEnable(TGL_BLEND);
+ renderer->setCurrentColor(scene->shadowColor());
+
+ TeMatrix4x4 matrix;
+ matrix.translate(TeVector3f32(0.5f, 0.5f, 0.5f));
+ matrix.scale(TeVector3f32(0.5f, 0.5f, 0.5f));
+ matrix = matrix * _camera->projectionMatrix();
+
+ TeMatrix4x4 cammatrix = _camera->worldTransformationMatrix();
+ cammatrix.inverse();
+
+ matrix = matrix * cammatrix;
+
+ /* TODO: Find TGL equivalents for the following block. */
+ /*
+ tglTexGeni(TGL_S, TGL_TEXTURE_GEN_MODE, TGL_EYE_LINEAR);
+
+ float f[4];
+ for (uint i = 0; i < 4; i++)
+ f[i] = matrix(i, 0);
+
+ tglTexGenfv(TGL_S, TGL_EYE_PLANE, f);
+ tglTexGeni(TGL_T, TGL_TEXTURE_GEN_MODE, TGL_EYE_LINEAR);
+
+ for (uint i = 0; i < 4; i++)
+ f[i] = matrix(i, 1);
+
+ tglTexGenfv(TGL_T, TGL_EYE_PLANE, f);
+ tglTexGeni(TGL_R, TGL_TEXTURE_GEN_MODE, TGL_EYE_LINEAR);
+
+ for (uint i = 0; i < 4; i++)
+ f[i] = matrix(i, 2);
+
+ tglTexGenfv(TGL_R, TGL_EYE_PLANE, f);
+ tglTexGeni(TGL_Q, TGL_TEXTURE_GEN_MODE, TGL_EYE_LINEAR);
+
+ for (uint i = 0; i < 4; i++)
+ f[i] = matrix(i, 3);
+
+ tglTexGenfv(TGL_Q, TGL_EYE_PLANE, f);
+ */
+
+ Te3DTextureTinyGL::unbind();
+ tglBindTexture(TGL_TEXTURE_2D, _glTex);
+ tglEnable(TGL_BLEND);
+ renderer->setCurrentColor(scene->shadowColor());
+
+ for (TeIntrusivePtr<TeModel> model : scene->zoneModels()) {
+ if (model->meshes().size() > 0 && model->meshes()[0]->materials().empty()) {
+ model->meshes()[0]->defaultMaterial(TeIntrusivePtr<Te3DTexture>());
+ model->meshes()[0]->materials()[0]._enableSomethingDefault0 = true;
+ model->meshes()[0]->materials()[0]._diffuseColor = scene->shadowColor();
+ }
+ model->draw();
+ }
+
+ renderer->disableTexture();
+ tglDepthMask(true);
+ renderer->enableZBuffer();
+}
+
+} // end namespace Tetraedge
diff --git a/engines/tetraedge/game/characters_shadow_tinygl.h b/engines/tetraedge/game/characters_shadow_tinygl.h
new file mode 100644
index 00000000000..165ccdaa0cc
--- /dev/null
+++ b/engines/tetraedge/game/characters_shadow_tinygl.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 TETRAEDGE_GAME_CHARACTERS_SHADOW_TINYGL_H
+#define TETRAEDGE_GAME_CHARACTERS_SHADOW_TINYGL_H
+
+#if defined(USE_TINYGL)
+
+#include "tetraedge/game/characters_shadow.h"
+
+namespace Tetraedge {
+
+class InGameScene;
+
+class CharactersShadowTinyGL : public CharactersShadow {
+public:
+ CharactersShadowTinyGL() {};
+
+ void draw(InGameScene *scene) override;
+
+protected:
+ virtual void createInternal() override;
+ virtual void createTextureInternal(InGameScene *scene) override;
+ virtual void deleteTexture() override;
+
+};
+
+} // end namespace Tetraedge
+
+#endif // USE_TINYGL
+
+#endif // TETRAEDGE_GAME_CHARACTERS_SHADOW_TINYGL_H
diff --git a/engines/tetraedge/game/in_game_scene.cpp b/engines/tetraedge/game/in_game_scene.cpp
index 4270975a61e..0e1416d0f44 100644
--- a/engines/tetraedge/game/in_game_scene.cpp
+++ b/engines/tetraedge/game/in_game_scene.cpp
@@ -220,17 +220,18 @@ void InGameScene::close() {
void InGameScene::convertPathToMesh(TeFreeMoveZone *zone) {
TeIntrusivePtr<TeModel> model = new TeModel();
- model->meshes().resize(1);
+ model->meshes().clear();
+ model->meshes().push_back(Common::SharedPtr<TeMesh>(TeMesh::makeInstance()));
model->setName("shadowReceiving");
model->setPosition(zone->position());
model->setRotation(zone->rotation());
model->setScale(zone->scale());
unsigned long nverticies = zone->verticies().size();
- model->meshes()[0].setConf(nverticies, nverticies, TeMesh::MeshMode_Triangles, 0, 0);
+ model->meshes()[0]->setConf(nverticies, nverticies, TeMesh::MeshMode_Triangles, 0, 0);
for (uint i = 0; i < nverticies; i++) {
- model->meshes()[0].setIndex(i, i);
- model->meshes()[0].setVertex(i, zone->verticies()[i]);
- model->meshes()[0].setNormal(i, TeVector3f32(0, 0, 1));
+ model->meshes()[0]->setIndex(i, i);
+ model->meshes()[0]->setVertex(i, zone->verticies()[i]);
+ model->meshes()[0]->setNormal(i, TeVector3f32(0, 0, 1));
}
_zoneModels.push_back(model);
}
@@ -293,7 +294,7 @@ void InGameScene::deserializeModel(Common::ReadStream &stream, TeIntrusivePtr<Te
TeVector2f32 vec2;
TeQuaternion rot;
TeColor col;
- TeMesh mesh;
+ Common::SharedPtr<TeMesh> mesh(TeMesh::makeInstance());
assert(pickmesh);
@@ -312,30 +313,30 @@ void InGameScene::deserializeModel(Common::ReadStream &stream, TeIntrusivePtr<Te
if (indexcount > 100000 || vertexcount > 100000)
error("InGameScene::deserializeModel: Unxpected counts %d %d", indexcount, vertexcount);
- mesh.setConf(vertexcount, indexcount, TeMesh::MeshMode_Triangles, 0, 0);
+ mesh->setConf(vertexcount, indexcount, TeMesh::MeshMode_Triangles, 0, 0);
for (uint i = 0; i < indexcount; i++)
- mesh.setIndex(i, stream.readUint32LE());
+ mesh->setIndex(i, stream.readUint32LE());
for (uint i = 0; i < vertexcount; i++) {
TeVector3f32::deserialize(stream, vec);
- mesh.setVertex(i, vec);
+ mesh->setVertex(i, vec);
}
for (uint i = 0; i < vertexcount; i++) {
TeVector3f32::deserialize(stream, vec);
- mesh.setNormal(i, vec);
+ mesh->setNormal(i, vec);
}
for (uint i = 0; i < vertexcount; i++) {
TeVector2f32::deserialize(stream, vec2);
- mesh.setTextureUV(i, vec2);
+ mesh->setTextureUV(i, vec2);
}
for (uint i = 0; i < vertexcount; i++) {
col.deserialize(stream);
- mesh.setColor(i, col);
+ mesh->setColor(i, col);
}
pickmesh->setNbTriangles(indexcount / 3);
for (uint i = 0; i < indexcount; i++) {
- vec = mesh.vertex(mesh.index(i));
+ vec = mesh->vertex(mesh->index(i));
pickmesh->verticies()[i] = vec;
}
model->addMesh(mesh);
@@ -368,7 +369,7 @@ void InGameScene::draw() {
TeLight::updateGlobal();
for (uint i = 0; i < _lights.size(); i++)
- _lights[i].update(i);
+ _lights[i]->update(i);
TeCamera::restore();
}
@@ -556,9 +557,9 @@ bool InGameScene::load(const Common::Path &path) {
}
}
if (!_lights.empty()) {
- TeLight::disableAll();
+ g_engine->getRenderer()->disableAllLights();
for (uint i = 0; i < _lights.size(); i++) {
- _lights[i].disable(i);
+ _lights[i]->disable(i);
}
_lights.clear();
}
@@ -661,7 +662,7 @@ bool InGameScene::load(const Common::Path &path) {
for (TeFreeMoveZone *zone : _freeMoveZones) {
convertPathToMesh(zone);
}
- _charactersShadow = new CharactersShadow();
+ _charactersShadow = CharactersShadow::makeInstance();
_charactersShadow->create(this);
onMainWindowSizeChanged();
@@ -701,9 +702,9 @@ bool InGameScene::loadLights(const Common::Path &path) {
_shadowNearPlane = parser.getShadowNearPlane();
_shadowFov = parser.getShadowFov();
- TeLight::enableAll();
+ g_engine->getRenderer()->enableAllLights();
for (uint i = 0; i < _lights.size(); i++) {
- _lights[i].enable(i);
+ _lights[i]->enable(i);
}
#if DEBUG_LIGHTS
@@ -752,9 +753,9 @@ bool InGameScene::loadObjectMaterials(const Common::String &name) {
Common::Path mpath = _loadedPath.getParent().join(name).join(obj._name + ".png");
if (img.load(mpath)) {
- Te3DTexture *tex = new Te3DTexture();
+ Te3DTexture *tex = Te3DTexture::makeInstance();
tex->load(img);
- obj._model->meshes()[0].defaultMaterial(tex);
+ obj._model->meshes()[0]->defaultMaterial(tex);
retval = true;
}
}
@@ -960,7 +961,7 @@ TeLight *InGameScene::shadowLight() {
if (_shadowLightNo == -1) {
return nullptr;
}
- return &_lights[_shadowLightNo];
+ return _lights[_shadowLightNo].get();
}
void InGameScene::setImagePathMarker(const Common::String &markerName, const Common::String &path) {
diff --git a/engines/tetraedge/game/in_game_scene.h b/engines/tetraedge/game/in_game_scene.h
index 2d6fdc46eb0..7f799b6059c 100644
--- a/engines/tetraedge/game/in_game_scene.h
+++ b/engines/tetraedge/game/in_game_scene.h
@@ -197,7 +197,7 @@ public:
Common::Array<Object3D *> object3Ds() { return _object3Ds; }
void setWaitTime(float usecs) { _waitTime = usecs; }
TeTimer &waitTimeTimer() { return _waitTimeTimer; }
- Common::Array<TeLight> &lights() { return _lights; }
+ Common::Array<Common::SharedPtr<TeLight>> &lights() { return _lights; }
private:
@@ -239,7 +239,7 @@ private:
TeLuaGUI _markerGui;
TeLuaGUI _hitObjectGui;
- Common::Array<TeLight> _lights;
+ Common::Array<Common::SharedPtr<TeLight>> _lights;
TeVector2f32 _someScrollVector;
TeVector2f32 _viewportSize;
diff --git a/engines/tetraedge/game/lua_binds.cpp b/engines/tetraedge/game/lua_binds.cpp
index 01a57c56126..4b37235aa2d 100644
--- a/engines/tetraedge/game/lua_binds.cpp
+++ b/engines/tetraedge/game/lua_binds.cpp
@@ -993,11 +993,11 @@ static void EnableLight(uint lightno, bool enable) {
if (lightno > game->scene().lights().size()) {
error("[EnableLight] Light not found %d", lightno);
}
- TeLight &light = game->scene().lights()[lightno];
+ Common::SharedPtr<TeLight> light = game->scene().lights()[lightno];
if (enable)
- light.enable(lightno);
+ light->enable(lightno);
else
- light.disable(lightno);
+ light->disable(lightno);
}
static int tolua_ExportedFunctions_EnableLight00(lua_State *L) {
diff --git a/engines/tetraedge/game/scene_lights_xml_parser.cpp b/engines/tetraedge/game/scene_lights_xml_parser.cpp
index 81043ac87a7..c5fb3727518 100644
--- a/engines/tetraedge/game/scene_lights_xml_parser.cpp
+++ b/engines/tetraedge/game/scene_lights_xml_parser.cpp
@@ -56,7 +56,7 @@ bool SceneLightsXmlParser::parserCallback_Ambient(ParserNode *node) {
if (_parent == Parent_Global) {
TeLight::setGlobalAmbient(col);
} else {
- _lights->back().setAmbient(col);
+ _lights->back()->setAmbient(col);
}
return true;
}
@@ -68,13 +68,13 @@ bool SceneLightsXmlParser::parserCallback_Lights(ParserNode *node) {
bool SceneLightsXmlParser::parserCallback_Light(ParserNode *node) {
_parent = Parent_Light;
- _lights->push_back(TeLight());
+ _lights->push_back(Common::SharedPtr<TeLight>(TeLight::makeInstance()));
TeLightType ltype = TeLightType::LightTypeDirectional;
if (node->values["Type"] == "Spot")
ltype = TeLightType::LightTypeSpot;
else if (node->values["Type"] == "Point")
ltype = TeLightType::LightTypePoint;
- _lights->back().setType(ltype);
+ _lights->back()->setType(ltype);
return true;
}
@@ -82,14 +82,14 @@ bool SceneLightsXmlParser::parserCallback_Position(ParserNode *node) {
float x = atof(node->values["x"].c_str());
float y = atof(node->values["y"].c_str());
float z = atof(node->values["z"].c_str());
- _lights->back().setPosition3d(TeVector3f32(x, y, z));
+ _lights->back()->setPosition3d(TeVector3f32(x, y, z));
return true;
}
bool SceneLightsXmlParser::parserCallback_Direction(ParserNode *node) {
float h = (atof(node->values["h"].c_str()) * M_PI) / 180.0;
float v = (atof(node->values["v"].c_str()) * M_PI) / 180.0;
- _lights->back().setPositionRadial(TeVector2f32(h, v));
+ _lights->back()->setPositionRadial(TeVector2f32(h, v));
return true;
}
@@ -98,7 +98,7 @@ bool SceneLightsXmlParser::parserCallback_Diffuse(ParserNode *node) {
if (!parseCol(node, col))
return false;
- _lights->back().setDiffuse(col);
+ _lights->back()->setDiffuse(col);
return true;
}
@@ -107,7 +107,7 @@ bool SceneLightsXmlParser::parserCallback_Specular(ParserNode *node) {
if (!parseCol(node, col))
return false;
- _lights->back().setSpecular(col);
+ _lights->back()->setSpecular(col);
return true;
}
@@ -117,9 +117,9 @@ bool SceneLightsXmlParser::parserCallback_Attenuation(ParserNode *node) {
float q = atof(node->values["quadratic"].c_str());
if (c < 0 || l < 0 || q < 0)
warning("Loaded invalid lighting attenuation vals %f %f %f", c, l, q);
- _lights->back().setConstAtten(c);
- _lights->back().setLinearAtten(l);
- _lights->back().setQuadraticAtten(q);
+ _lights->back()->setConstAtten(c);
+ _lights->back()->setLinearAtten(l);
+ _lights->back()->setQuadraticAtten(q);
return true;
}
@@ -127,7 +127,7 @@ bool SceneLightsXmlParser::parserCallback_Cutoff(ParserNode *node) {
float cutoff = atof(node->values["value"].c_str());
if (cutoff < 0.0f || (cutoff > 90.0f && cutoff != 180.0f))
warning("Loaded invalid lighting cutoff value %f", cutoff);
- _lights->back().setCutoff((cutoff * M_PI) / 180.0);
+ _lights->back()->setCutoff((cutoff * M_PI) / 180.0);
return true;
}
@@ -135,12 +135,12 @@ bool SceneLightsXmlParser::parserCallback_Exponent(ParserNode *node) {
float expon = atof(node->values["value"].c_str());
if (expon < 0.0f || expon > 128.0f)
warning("Loaded invalid lighting exponent value %f", expon);
- _lights->back().setExponent(expon);
+ _lights->back()->setExponent(expon);
return true;
}
bool SceneLightsXmlParser::parserCallback_DisplaySize(ParserNode *node) {
- _lights->back().setDisplaySize(atof(node->values["value"].c_str()));
+ _lights->back()->setDisplaySize(atof(node->values["value"].c_str()));
return true;
}
diff --git a/engines/tetraedge/game/scene_lights_xml_parser.h b/engines/tetraedge/game/scene_lights_xml_parser.h
index a6159b0b099..ef701e3c8f7 100644
--- a/engines/tetraedge/game/scene_lights_xml_parser.h
+++ b/engines/tetraedge/game/scene_lights_xml_parser.h
@@ -31,7 +31,7 @@ namespace Tetraedge {
class SceneLightsXmlParser : public Common::XMLParser {
public:
- void setLightArray(Common::Array<TeLight> *lights) {
+ void setLightArray(Common::Array<Common::SharedPtr<TeLight>> *lights) {
_lights = lights;
}
TeColor getShadowColor() { return _shadowColor; }
@@ -115,7 +115,7 @@ public:
} PARSER_END()
private:
- Common::Array<TeLight> *_lights;
+ Common::Array<Common::SharedPtr<TeLight>> *_lights;
enum ParentNodeType {
Parent_Global,
diff --git a/engines/tetraedge/module.mk b/engines/tetraedge/module.mk
index 7f55a5eb390..635dd0450d6 100644
--- a/engines/tetraedge/module.mk
+++ b/engines/tetraedge/module.mk
@@ -10,6 +10,7 @@ MODULE_OBJS := \
game/character.o \
game/character_settings_xml_parser.o \
game/characters_shadow.o \
+ game/characters_shadow_opengl.o \
game/confirm.o \
game/credits.o \
game/dialog2.o \
@@ -42,6 +43,7 @@ MODULE_OBJS := \
te/micropather.o \
te/te_3d_object2.o \
te/te_3d_texture.o \
+ te/te_3d_texture_opengl.o \
te/te_act_zone.o \
te/te_animation.o \
te/te_bezier_curve.o \
@@ -66,6 +68,7 @@ MODULE_OBJS := \
te/te_jpeg.o \
te/te_layout.o \
te/te_light.o \
+ te/te_light_opengl.o \
te/te_list_layout.o \
te/te_lua_context.o \
te/te_lua_gui.o \
@@ -76,6 +79,7 @@ MODULE_OBJS := \
te/te_matricies_stack.o \
te/te_matrix4x4.o \
te/te_mesh.o \
+ te/te_mesh_opengl.o \
te/te_model.o \
te/te_model_animation.o \
te/te_model_vertex_animation.o \
@@ -90,6 +94,7 @@ MODULE_OBJS := \
te/te_ray_intersection.o \
te/te_real_timer.o \
te/te_renderer.o \
+ te/te_renderer_opengl.o \
te/te_resource.o \
te/te_resource_manager.o \
te/te_scene.o \
@@ -114,6 +119,16 @@ MODULE_OBJS := \
te/te_xml_gui.o \
metaengine.o
+ifdef USE_TINYGL
+MODULE_OBJS += \
+ game/characters_shadow_tinygl.o \
+ te/te_3d_texture_tinygl.o \
+ te/te_light_tinygl.o \
+ te/te_mesh_tinygl.o \
+ te/te_renderer_tinygl.o
+endif
+
+
# This module can be built as a plugin
ifeq ($(ENABLE_TETRAEDGE), DYNAMIC_PLUGIN)
PLUGIN := 1
diff --git a/engines/tetraedge/te/te_3d_texture.cpp b/engines/tetraedge/te/te_3d_texture.cpp
index 8d4e7a9a00d..c3d25bcfb71 100644
--- a/engines/tetraedge/te/te_3d_texture.cpp
+++ b/engines/tetraedge/te/te_3d_texture.cpp
@@ -23,96 +23,18 @@
#include "tetraedge/tetraedge.h"
#include "tetraedge/te/te_3d_texture.h"
+#include "tetraedge/te/te_3d_texture_opengl.h"
+#include "tetraedge/te/te_3d_texture_tinygl.h"
#include "tetraedge/te/te_resource_manager.h"
#include "tetraedge/te/te_renderer.h"
namespace Tetraedge {
-static const uint NO_TEXTURE = 0xffffffff;
-
-Te3DTexture::Te3DTexture() : _glTexture(NO_TEXTURE), _createdTexture(false),
-_numFrames(1), _frameRate(0), _format(TeImage::INVALID)/*, _glPixelFormat(GL_INVALID_ENUM)*/ {
- create();
+Te3DTexture::Te3DTexture() : _createdTexture(false),
+_numFrames(1), _frameRate(0), _format(TeImage::INVALID) {
}
Te3DTexture::~Te3DTexture() {
- destroy();
-}
-
-void Te3DTexture::bind() const {
- TeRenderer *renderer = g_engine->getRenderer();
- glBindTexture(GL_TEXTURE_2D, _glTexture);
- renderer->setMatrixMode(TeRenderer::MM_GL_TEXTURE);
- renderer->loadMatrix(_matrix);
- renderer->loadCurrentMatrixToGL();
- renderer->setMatrixMode(TeRenderer::MM_GL_MODELVIEW);
-}
-
-void Te3DTexture::copyCurrentRender(uint xoffset, uint yoffset, uint x, uint y) {
- _matrix.setToIdentity();
- const TeVector3f32 texScale((float)_width / _texWidth, (float)_height / _texHeight, 1.0);
- _matrix.scale(texScale);
- const TeVector3f32 offset((float)_leftBorder / _width, (float)_btmBorder / _height, 0.0);
- _matrix.translate(offset);
- const TeVector3f32 borderScale(
- 1.0 - (float)(_rightBorder + _leftBorder) / (float)_width,
- 1.0 - (float)(_topBorder + _btmBorder) / (float)_height, 1.0);
- _matrix.scale(borderScale);
- bind();
- glCopyTexSubImage2D(GL_TEXTURE_2D, 0, xoffset, yoffset, x, y, _texWidth, _texHeight);
-}
-
-void Te3DTexture::writeTo(Graphics::Surface &surf) {
- Graphics::Surface fullTex;
- fullTex.create(_texWidth, _texHeight, Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24));
- glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, fullTex.getPixels());
- surf.create(_width, _height, Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24));
- surf.copyRectToSurface(fullTex, 0, 0, Common::Rect(_width, _height));
- fullTex.free();
-}
-
-void Te3DTexture::create() {
- _flipY = false;
- _leftBorder = _btmBorder = _texWidth = _texHeight = 0;
- _rightBorder = _topBorder = _width = _height = 0;
- _format = TeImage::INVALID;
- _loaded = false;
- if (!_createdTexture)
- glGenTextures(1, &_glTexture);
- if (_glTexture == NO_TEXTURE) {
- _createdTexture = false;
- return;
- }
-
- _createdTexture = true;
- glBindTexture(GL_TEXTURE_2D, _glTexture);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-}
-
-void Te3DTexture::destroy() {
- if (_createdTexture) {
- glDeleteTextures(1, &_glTexture);
- }
- _createdTexture = false;
- _loaded = false;
- _glTexture = NO_TEXTURE;
-}
-
-void Te3DTexture::forceTexData(uint gltexture, uint xsize, uint ysize) {
- if (_glTexture != 0xffffffff) {
- if (_createdTexture)
- glDeleteTextures(1, &_glTexture);
- _createdTexture = false;
- _loaded = false;
- }
- _glTexture = gltexture;
- _width = xsize;
- _height = ysize;
- _texWidth = xsize;
- _texHeight = ysize;
}
bool Te3DTexture::hasAlpha() const {
@@ -127,13 +49,13 @@ TeIntrusivePtr<Te3DTexture> Te3DTexture::load2(const Common::Path &path, uint si
TeResourceManager *resMgr = g_engine->getResourceManager();
if (!resMgr->exists(fullPath)) {
- TeIntrusivePtr<Te3DTexture> retval(new Te3DTexture());
+ TeIntrusivePtr<Te3DTexture> retval(makeInstance());
retval->load(path);
retval->setAccessName(fullPath);
resMgr->addResource(retval.get());
return retval;
} else {
- return resMgr->getResource<Te3DTexture>(fullPath);
+ return resMgr->getResourceOrMakeInstance<Te3DTexture>(fullPath);
}
}
@@ -146,67 +68,6 @@ bool Te3DTexture::load(const Common::Path &path) {
return true;
}
-bool Te3DTexture::load(const TeImage &img) {
- Common::Path accessName = img.getAccessName();
- setAccessName(accessName.append(".3dtex"));
-
- _width = img.w;
- _height = img.h;
- _format = img.teFormat();
-
- // TODO? set some other fields from the image here.
- // for now just set some good defaults.
- _flipY = true; //img._flipY;
- _leftBorder = 0; //img._leftBorder;
- _btmBorder = 0; //img._btmBorder;
- _rightBorder = 0; //img._rightBorder;
- _topBorder = 0; //img._topBorder;
-
- const TeVector2s32 optimizedSz = optimisedSize(img.bufSize());
- _texWidth = optimizedSz._x;
- _texHeight = optimizedSz._y;
-
- glBindTexture(GL_TEXTURE_2D, _glTexture);
- glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
- glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE);
- glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
- glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
- glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
- glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
-
- const void *imgdata = img.getPixels();
- if (_format == TeImage::RGB8) {
- /*GLenum glpxformat = GL_RGB;
- if (_glPixelFormat != GL_INVALID_ENUM) {
- glpxformat = _glPixelFormat;
- }*/
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, _texWidth, _texHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
- glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, img.pitch / 3, img.h, GL_RGB, GL_UNSIGNED_BYTE, imgdata);
- } else if (_format == TeImage::RGBA8) {
- /*GLenum glpxformat = GL_RGBA8;
- if (_glPixelFormat != GL_INVALID_ENUM) {
- glpxformat = _glPixelFormat;
- }*/
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, _texWidth, _texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
- glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, img.w, img.h, GL_RGBA, GL_UNSIGNED_BYTE, imgdata);
- } else {
- warning("Te3DTexture::load can't send image format %d to GL.", _format);
- }
-
- _matrix.setToIdentity();
-
- _matrix.scale(TeVector3f32((float)_width / _texWidth, (float)_height / _texHeight, 1.0f));
- _matrix.translate(TeVector3f32((float)_leftBorder / _width, (float)_btmBorder / _height, 0.0f));
- _matrix.scale(TeVector3f32(1.0 - (float)(_rightBorder + _leftBorder) / _width,
- 1.0 - (float)(_topBorder + _btmBorder) / _height, 1.0f));
- if (_flipY) {
- _matrix.translate(TeVector3f32(0.0f, 1.0f, 0.0f));
- _matrix.scale(TeVector3f32(1.0f, -1.0f, 1.0f));
- }
- _loaded = true;
- return true;
-}
-
/*static*/
TeVector2s32 Te3DTexture::optimisedSize(const TeVector2s32 &size) {
//
@@ -244,44 +105,19 @@ TeVector2s32 Te3DTexture::optimisedSize(const TeVector2s32 &size) {
}
/*static*/
-void Te3DTexture::unbind() {
- TeRenderer *renderer = g_engine->getRenderer();
- renderer->setMatrixMode(TeRenderer::MM_GL_TEXTURE);
- renderer->loadIdentityMatrix();
- renderer->loadCurrentMatrixToGL();
- glBindTexture(GL_TEXTURE_2D, 0);
- renderer->setMatrixMode(TeRenderer::MM_GL_MODELVIEW);
-}
-
-bool Te3DTexture::unload() {
- glBindTexture(GL_TEXTURE_2D, _glTexture);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
- _loaded = false;
- return true;
-}
-
-void Te3DTexture::update(const TeImage &img, uint xoff, uint yoff) {
- if (!img.w || !img.h)
- return;
-
- setAccessName(img.getAccessName().append(".3dtex"));
- glBindTexture(GL_TEXTURE_2D, _glTexture);
- glPixelStorei(GL_UNPACK_SWAP_BYTES, 0);
- glPixelStorei(GL_UNPACK_LSB_FIRST, 0);
- glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
- glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
- glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
- glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
-
- const void *imgdata = img.getPixels();
- if (_format == TeImage::RGB8) {
- glTexSubImage2D(GL_TEXTURE_2D, 0, xoff, yoff, img.w, img.h, GL_RGB, GL_UNSIGNED_BYTE, imgdata);
- } else if (_format == TeImage::RGBA8) {
- glTexSubImage2D(GL_TEXTURE_2D, 0, xoff, yoff, img.w, img.h, GL_RGBA, GL_UNSIGNED_BYTE, imgdata);
- } else {
- warning("Te3DTexture::update can't send image format %d to GL.", _format);
- }
- return;
+Te3DTexture *Te3DTexture::makeInstance() {
+ Graphics::RendererType r = g_engine->preferredRendererType();
+
+#if defined(USE_OPENGL_GAME) || defined(USE_OPENGL_SHADERS)
+ if (r == Graphics::kRendererTypeOpenGL)
+ return new Te3DTextureOpenGL();
+#endif
+
+#if defined(USE_TINYGL)
+ if (r == Graphics::kRendererTypeTinyGL)
+ return new Te3DTextureTinyGL();
+#endif
+ error("Couldn't create Te3DTexture for selected renderer");
}
} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_3d_texture.h b/engines/tetraedge/te/te_3d_texture.h
index b217d8cf6b8..3182853e967 100644
--- a/engines/tetraedge/te/te_3d_texture.h
+++ b/engines/tetraedge/te/te_3d_texture.h
@@ -39,32 +39,32 @@ public:
Te3DTexture();
virtual ~Te3DTexture();
- void bind() const;
- void copyCurrentRender(uint xoffset, uint yoffset, uint x, uint y);
- void create();
- void destroy();
-
- void forceTexData(uint gltexture, uint xsize, uint ysize);
+ virtual void bind() const = 0;
+ virtual void copyCurrentRender(uint xoffset, uint yoffset, uint x, uint y) = 0;
+ virtual void create() = 0;
+ virtual void destroy() = 0;
+ virtual void forceTexData(uint gltexture, uint xsize, uint ysize) = 0;
TeImage::Format getFormat() const { return _format; }
bool hasAlpha() const;
bool load(const Common::Path &path);
- bool load(const TeImage &img);
+ virtual bool load(const TeImage &img) = 0;
static TeIntrusivePtr<Te3DTexture> load2(const Common::Path &path, uint size);
static TeVector2s32 optimisedSize(const TeVector2s32 &size);
- static void unbind();
- bool unload();
- void update(const TeImage &img, uint xoff, uint yoff);
+ virtual bool unload() = 0;
+ virtual void update(const TeImage &img, uint xoff, uint yoff) = 0;
- void writeTo(Graphics::Surface &surf);
+ virtual void writeTo(Graphics::Surface &surf) = 0;
uint width() const { return _width; }
uint height() const { return _height; }
-private:
+ static Te3DTexture *makeInstance();
+
+protected:
uint _width;
uint _height;
int _numFrames;
@@ -72,8 +72,6 @@ private:
TeImage::Format _format;
bool _createdTexture;
bool _loaded;
- uint _glTexture;
- //uint _glPixelFormat;
TeMatrix4x4 _matrix;
uint _texWidth;
diff --git a/engines/tetraedge/te/te_3d_texture_opengl.cpp b/engines/tetraedge/te/te_3d_texture_opengl.cpp
new file mode 100644
index 00000000000..492c16320a0
--- /dev/null
+++ b/engines/tetraedge/te/te_3d_texture_opengl.cpp
@@ -0,0 +1,219 @@
+/* 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 "graphics/opengl/system_headers.h"
+
+#include "tetraedge/tetraedge.h"
+#include "tetraedge/te/te_3d_texture_opengl.h"
+#include "tetraedge/te/te_resource_manager.h"
+#include "tetraedge/te/te_renderer.h"
+
+namespace Tetraedge {
+
+static const uint NO_TEXTURE = 0xffffffff;
+
+Te3DTextureOpenGL::Te3DTextureOpenGL() : _glTexture(NO_TEXTURE)/*, _glPixelFormat(GL_INVALID_ENUM)*/ {
+ create();
+}
+
+Te3DTextureOpenGL::~Te3DTextureOpenGL() {
+ destroy();
+}
+
+void Te3DTextureOpenGL::bind() const {
+ TeRenderer *renderer = g_engine->getRenderer();
+ glBindTexture(GL_TEXTURE_2D, _glTexture);
+ renderer->setMatrixMode(TeRenderer::MM_GL_TEXTURE);
+ renderer->loadMatrix(_matrix);
+ renderer->loadCurrentMatrixToGL();
+ renderer->setMatrixMode(TeRenderer::MM_GL_MODELVIEW);
+}
+
+void Te3DTextureOpenGL::copyCurrentRender(uint xoffset, uint yoffset, uint x, uint y) {
+ _matrix.setToIdentity();
+ const TeVector3f32 texScale((float)_width / _texWidth, (float)_height / _texHeight, 1.0);
+ _matrix.scale(texScale);
+ const TeVector3f32 offset((float)_leftBorder / _width, (float)_btmBorder / _height, 0.0);
+ _matrix.translate(offset);
+ const TeVector3f32 borderScale(
+ 1.0 - (float)(_rightBorder + _leftBorder) / (float)_width,
+ 1.0 - (float)(_topBorder + _btmBorder) / (float)_height, 1.0);
+ _matrix.scale(borderScale);
+ bind();
+ glCopyTexSubImage2D(GL_TEXTURE_2D, 0, xoffset, yoffset, x, y, _texWidth, _texHeight);
+}
+
+void Te3DTextureOpenGL::writeTo(Graphics::Surface &surf) {
+ Graphics::Surface fullTex;
+ fullTex.create(_texWidth, _texHeight, Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24));
+ glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, fullTex.getPixels());
+ surf.create(_width, _height, Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24));
+ surf.copyRectToSurface(fullTex, 0, 0, Common::Rect(_width, _height));
+ fullTex.free();
+}
+
+void Te3DTextureOpenGL::create() {
+ _flipY = false;
+ _leftBorder = _btmBorder = _texWidth = _texHeight = 0;
+ _rightBorder = _topBorder = _width = _height = 0;
+ _format = TeImage::INVALID;
+ _loaded = false;
+ if (!_createdTexture)
+ glGenTextures(1, &_glTexture);
+ if (_glTexture == NO_TEXTURE) {
+ _createdTexture = false;
+ return;
+ }
+
+ _createdTexture = true;
+ glBindTexture(GL_TEXTURE_2D, _glTexture);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+}
+
+void Te3DTextureOpenGL::destroy() {
+ if (_createdTexture) {
+ glDeleteTextures(1, &_glTexture);
+ }
+ _createdTexture = false;
+ _loaded = false;
+ _glTexture = NO_TEXTURE;
+}
+
+void Te3DTextureOpenGL::forceTexData(uint gltexture, uint xsize, uint ysize) {
+ if (_glTexture != 0xffffffff) {
+ if (_createdTexture)
+ glDeleteTextures(1, &_glTexture);
+ _createdTexture = false;
+ _loaded = false;
+ }
+ _glTexture = gltexture;
+ _width = xsize;
+ _height = ysize;
+ _texWidth = xsize;
+ _texHeight = ysize;
+}
+
+bool Te3DTextureOpenGL::load(const TeImage &img) {
+ Common::Path accessName = img.getAccessName();
+ setAccessName(accessName.append(".3dtex"));
+
+ _width = img.w;
+ _height = img.h;
+ _format = img.teFormat();
+
+ // TODO? set some other fields from the image here.
+ // for now just set some good defaults.
+ _flipY = true; //img._flipY;
+ _leftBorder = 0; //img._leftBorder;
+ _btmBorder = 0; //img._btmBorder;
+ _rightBorder = 0; //img._rightBorder;
+ _topBorder = 0; //img._topBorder;
+
+ const TeVector2s32 optimizedSz = optimisedSize(img.bufSize());
+ _texWidth = optimizedSz._x;
+ _texHeight = optimizedSz._y;
+
+ glBindTexture(GL_TEXTURE_2D, _glTexture);
+ glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
+ glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+
+ const void *imgdata = img.getPixels();
+ if (_format == TeImage::RGB8) {
+ /*GLenum glpxformat = GL_RGB;
+ if (_glPixelFormat != GL_INVALID_ENUM) {
+ glpxformat = _glPixelFormat;
+ }*/
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, _texWidth, _texHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, img.pitch / 3, img.h, GL_RGB, GL_UNSIGNED_BYTE, imgdata);
+ } else if (_format == TeImage::RGBA8) {
+ /*GLenum glpxformat = GL_RGBA8;
+ if (_glPixelFormat != GL_INVALID_ENUM) {
+ glpxformat = _glPixelFormat;
+ }*/
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, _texWidth, _texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, img.w, img.h, GL_RGBA, GL_UNSIGNED_BYTE, imgdata);
+ } else {
+ warning("Te3DTexture::load can't send image format %d to GL.", _format);
+ }
+
+ _matrix.setToIdentity();
+
+ _matrix.scale(TeVector3f32((float)_width / _texWidth, (float)_height / _texHeight, 1.0f));
+ _matrix.translate(TeVector3f32((float)_leftBorder / _width, (float)_btmBorder / _height, 0.0f));
+ _matrix.scale(TeVector3f32(1.0 - (float)(_rightBorder + _leftBorder) / _width,
+ 1.0 - (float)(_topBorder + _btmBorder) / _height, 1.0f));
+ if (_flipY) {
+ _matrix.translate(TeVector3f32(0.0f, 1.0f, 0.0f));
+ _matrix.scale(TeVector3f32(1.0f, -1.0f, 1.0f));
+ }
+ _loaded = true;
+ return true;
+}
+
+/*static*/
+void Te3DTextureOpenGL::unbind() {
+ TeRenderer *renderer = g_engine->getRenderer();
+ renderer->setMatrixMode(TeRenderer::MM_GL_TEXTURE);
+ renderer->loadIdentityMatrix();
+ renderer->loadCurrentMatrixToGL();
+ glBindTexture(GL_TEXTURE_2D, 0);
+ renderer->setMatrixMode(TeRenderer::MM_GL_MODELVIEW);
+}
+
+bool Te3DTextureOpenGL::unload() {
+ glBindTexture(GL_TEXTURE_2D, _glTexture);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
+ _loaded = false;
+ return true;
+}
+
+void Te3DTextureOpenGL::update(const TeImage &img, uint xoff, uint yoff) {
+ if (!img.w || !img.h)
+ return;
+
+ setAccessName(img.getAccessName().append(".3dtex"));
+ glBindTexture(GL_TEXTURE_2D, _glTexture);
+ glPixelStorei(GL_UNPACK_SWAP_BYTES, 0);
+ glPixelStorei(GL_UNPACK_LSB_FIRST, 0);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+
+ const void *imgdata = img.getPixels();
+ if (_format == TeImage::RGB8) {
+ glTexSubImage2D(GL_TEXTURE_2D, 0, xoff, yoff, img.w, img.h, GL_RGB, GL_UNSIGNED_BYTE, imgdata);
+ } else if (_format == TeImage::RGBA8) {
+ glTexSubImage2D(GL_TEXTURE_2D, 0, xoff, yoff, img.w, img.h, GL_RGBA, GL_UNSIGNED_BYTE, imgdata);
+ } else {
+ warning("Te3DTexture::update can't send image format %d to GL.", _format);
+ }
+ return;
+}
+
+} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_3d_texture_opengl.h b/engines/tetraedge/te/te_3d_texture_opengl.h
new file mode 100644
index 00000000000..ad2a0801f75
--- /dev/null
+++ b/engines/tetraedge/te/te_3d_texture_opengl.h
@@ -0,0 +1,60 @@
+/* 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 TETRAEDGE_TE_TE_3D_TEXTURE_OPENGL_H
+#define TETRAEDGE_TE_TE_3D_TEXTURE_OPENGL_H
+
+#if defined(USE_OPENGL_GAME) || defined(USE_OPENGL_SHADERS)
+
+#include "tetraedge/te/te_3d_texture.h"
+
+namespace Tetraedge {
+
+class Te3DTextureOpenGL : public Te3DTexture {
+public:
+ Te3DTextureOpenGL();
+ virtual ~Te3DTextureOpenGL();
+
+ void bind() const override;
+ void copyCurrentRender(uint xoffset, uint yoffset, uint x, uint y) override;
+ void create() override;
+ void destroy() override;
+ void forceTexData(uint gltexture, uint xsize, uint ysize) override;
+
+ bool load(const TeImage &img) override;
+
+ static void unbind();
+ bool unload() override;
+ void update(const TeImage &img, uint xoff, uint yoff) override;
+
+ void writeTo(Graphics::Surface &surf) override;
+
+private:
+ uint _glTexture;
+ //uint _glPixelFormat;
+
+};
+
+} // end namespace Tetraedge
+
+#endif // USE_OPENGL
+
+#endif // TETRAEDGE_TE_TE_3D_TEXTURE_OPENGL_H
diff --git a/engines/tetraedge/te/te_3d_texture_tinygl.cpp b/engines/tetraedge/te/te_3d_texture_tinygl.cpp
new file mode 100644
index 00000000000..ab7292c46a5
--- /dev/null
+++ b/engines/tetraedge/te/te_3d_texture_tinygl.cpp
@@ -0,0 +1,220 @@
+/* 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 "graphics/tinygl/tinygl.h"
+
+#include "tetraedge/tetraedge.h"
+#include "tetraedge/te/te_3d_texture_tinygl.h"
+#include "tetraedge/te/te_resource_manager.h"
+#include "tetraedge/te/te_renderer.h"
+
+namespace Tetraedge {
+
+static const uint NO_TEXTURE = 0xffffffff;
+
+Te3DTextureTinyGL::Te3DTextureTinyGL() : _glTexture(NO_TEXTURE)/*, _glPixelFormat(TGL_INVALID_ENUM)*/ {
+ create();
+}
+
+Te3DTextureTinyGL::~Te3DTextureTinyGL() {
+ destroy();
+}
+
+void Te3DTextureTinyGL::bind() const {
+ TeRenderer *renderer = g_engine->getRenderer();
+ tglBindTexture(TGL_TEXTURE_2D, _glTexture);
+ renderer->setMatrixMode(TeRenderer::MM_GL_TEXTURE);
+ renderer->loadMatrix(_matrix);
+ renderer->loadCurrentMatrixToGL();
+ renderer->setMatrixMode(TeRenderer::MM_GL_MODELVIEW);
+}
+
+void Te3DTextureTinyGL::copyCurrentRender(uint xoffset, uint yoffset, uint x, uint y) {
+ _matrix.setToIdentity();
+ const TeVector3f32 texScale((float)_width / _texWidth, (float)_height / _texHeight, 1.0);
+ _matrix.scale(texScale);
+ const TeVector3f32 offset((float)_leftBorder / _width, (float)_btmBorder / _height, 0.0);
+ _matrix.translate(offset);
+ const TeVector3f32 borderScale(
+ 1.0 - (float)(_rightBorder + _leftBorder) / (float)_width,
+ 1.0 - (float)(_topBorder + _btmBorder) / (float)_height, 1.0);
+ _matrix.scale(borderScale);
+ bind();
+ //TODO: Come up with equivalent for TGL.
+ //tglCopyTexSubImage2D(TGL_TEXTURE_2D, 0, xoffset, yoffset, x, y, _texWidth, _texHeight);
+}
+
+void Te3DTextureTinyGL::writeTo(Graphics::Surface &surf) {
+ Graphics::Surface fullTex;
+ fullTex.create(_texWidth, _texHeight, Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24));
+ //TODO: Come up with equivalent for TGL.
+ //tglGetTexImage(TGL_TEXTURE_2D, 0, TGL_RGBA, TGL_UNSIGNED_BYTE, fullTex.getPixels());
+ surf.create(_width, _height, Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24));
+ surf.copyRectToSurface(fullTex, 0, 0, Common::Rect(_width, _height));
+ fullTex.free();
+}
+
+void Te3DTextureTinyGL::create() {
+ _flipY = false;
+ _leftBorder = _btmBorder = _texWidth = _texHeight = 0;
+ _rightBorder = _topBorder = _width = _height = 0;
+ _format = TeImage::INVALID;
+ _loaded = false;
+ if (!_createdTexture)
+ tglGenTextures(1, &_glTexture);
+ if (_glTexture == NO_TEXTURE) {
+ _createdTexture = false;
+ return;
+ }
+
+ _createdTexture = true;
+ tglBindTexture(TGL_TEXTURE_2D, _glTexture);
+ tglTexParameteri(TGL_TEXTURE_2D, TGL_TEXTURE_MAG_FILTER, TGL_LINEAR);
+ tglTexParameteri(TGL_TEXTURE_2D, TGL_TEXTURE_MIN_FILTER, TGL_LINEAR);
+ tglTexParameteri(TGL_TEXTURE_2D, TGL_TEXTURE_WRAP_S, TGL_CLAMP_TO_EDGE);
+ tglTexParameteri(TGL_TEXTURE_2D, TGL_TEXTURE_WRAP_T, TGL_CLAMP_TO_EDGE);
+}
+
+void Te3DTextureTinyGL::destroy() {
+ if (_createdTexture) {
+ tglDeleteTextures(1, &_glTexture);
+ }
+ _createdTexture = false;
+ _loaded = false;
+ _glTexture = NO_TEXTURE;
+}
+
+void Te3DTextureTinyGL::forceTexData(uint gltexture, uint xsize, uint ysize) {
+ if (_glTexture != 0xffffffff) {
+ if (_createdTexture)
+ tglDeleteTextures(1, &_glTexture);
+ _createdTexture = false;
+ _loaded = false;
+ }
+ _glTexture = gltexture;
+ _width = xsize;
+ _height = ysize;
+ _texWidth = xsize;
+ _texHeight = ysize;
+}
+
+bool Te3DTextureTinyGL::load(const TeImage &img) {
+ Common::Path accessName = img.getAccessName();
+ setAccessName(accessName.append(".3dtex"));
+
+ _width = img.w;
+ _height = img.h;
+ _format = img.teFormat();
+
+ // TODO? set some other fields from the image here.
+ // for now just set some good defaults.
+ _flipY = true; //img._flipY;
+ _leftBorder = 0; //img._leftBorder;
+ _btmBorder = 0; //img._btmBorder;
+ _rightBorder = 0; //img._rightBorder;
+ _topBorder = 0; //img._topBorder;
+
+ _texWidth = _width;
+ _texHeight = _height;
+
+ tglBindTexture(TGL_TEXTURE_2D, _glTexture);
+ //tglPixelStorei(TGL_UNPACK_SWAP_BYTES, TGL_FALSE);
+ //tglPixelStorei(TGL_UNPACK_LSB_FIRST, TGL_FALSE);
+ //tglPixelStorei(TGL_UNPACK_ROW_LENGTH, 0);
+ //tglPixelStorei(TGL_UNPACK_SKIP_ROWS, 0);
+ //tglPixelStorei(TGL_UNPACK_SKIP_PIXELS, 0);
+ //tglPixelStorei(TGL_UNPACK_ALIGNMENT, 1);
+
+ const void *imgdata = img.getPixels();
+ if (_format == TeImage::RGB8) {
+ /*GLenum glpxformat = GL_RGB;
+ if (_glPixelFormat != GL_INVALID_ENUM) {
+ glpxformat = _glPixelFormat;
+ }*/
+ tglTexImage2D(TGL_TEXTURE_2D, 0, TGL_RGBA, img.pitch / 3, img.h, 0, TGL_RGB, TGL_UNSIGNED_BYTE, imgdata);
+ } else if (_format == TeImage::RGBA8) {
+ /*GLenum glpxformat = GL_RGBA8;
+ if (_glPixelFormat != GL_INVALID_ENUM) {
+ glpxformat = _glPixelFormat;
+ }*/
+ tglTexImage2D(TGL_TEXTURE_2D, 0, TGL_RGBA, img.w, img.h, 0, TGL_RGBA, TGL_UNSIGNED_BYTE, imgdata);
+ } else {
+ warning("Te3DTexture::load can't send image format %d to GL.", _format);
+ }
+
+ _matrix.setToIdentity();
+
+ _matrix.scale(TeVector3f32((float)_width / _texWidth, (float)_height / _texHeight, 1.0f));
+ _matrix.translate(TeVector3f32((float)_leftBorder / _width, (float)_btmBorder / _height, 0.0f));
+ _matrix.scale(TeVector3f32(1.0 - (float)(_rightBorder + _leftBorder) / _width,
+ 1.0 - (float)(_topBorder + _btmBorder) / _height, 1.0f));
+ if (_flipY) {
+ _matrix.translate(TeVector3f32(0.0f, 1.0f, 0.0f));
+ _matrix.scale(TeVector3f32(1.0f, -1.0f, 1.0f));
+ }
+ _loaded = true;
+ return true;
+}
+
+/*static*/
+void Te3DTextureTinyGL::unbind() {
+ TeRenderer *renderer = g_engine->getRenderer();
+ renderer->setMatrixMode(TeRenderer::MM_GL_TEXTURE);
+ renderer->loadIdentityMatrix();
+ renderer->loadCurrentMatrixToGL();
+ tglBindTexture(TGL_TEXTURE_2D, 0);
+ renderer->setMatrixMode(TeRenderer::MM_GL_MODELVIEW);
+}
+
+bool Te3DTextureTinyGL::unload() {
+ tglBindTexture(TGL_TEXTURE_2D, _glTexture);
+ tglTexImage2D(TGL_TEXTURE_2D, 0, TGL_RGB, 0, 0, 0, TGL_RGB, TGL_UNSIGNED_BYTE, NULL);
+ _loaded = false;
+ return true;
+}
+
+void Te3DTextureTinyGL::update(const TeImage &img, uint xoff, uint yoff) {
+ if (!img.w || !img.h)
+ return;
+
+ setAccessName(img.getAccessName().append(".3dtex"));
+ tglBindTexture(TGL_TEXTURE_2D, _glTexture);
+ tglPixelStorei(TGL_UNPACK_SWAP_BYTES, 0);
+ tglPixelStorei(TGL_UNPACK_LSB_FIRST, 0);
+ tglPixelStorei(TGL_UNPACK_ROW_LENGTH, 0);
+ tglPixelStorei(TGL_UNPACK_SKIP_ROWS, 0);
+ tglPixelStorei(TGL_UNPACK_SKIP_PIXELS, 0);
+ tglPixelStorei(TGL_UNPACK_ALIGNMENT, 1);
+
+ const void *imgdata = img.getPixels();
+ if (_format == TeImage::RGB8) {
+ //TODO: Come up with equivalent for TGL.
+ //tglTexSubImage2D(TGL_TEXTURE_2D, 0, xoff, yoff, img.w, img.h, TGL_RGB, TGL_UNSIGNED_BYTE, imgdata);
+ } else if (_format == TeImage::RGBA8) {
+ //TODO: Come up with equivalent for TGL.
+ //tglTexSubImage2D(TGL_TEXTURE_2D, 0, xoff, yoff, img.w, img.h, TGL_RGBA, TGL_UNSIGNED_BYTE, imgdata);
+ } else {
+ warning("Te3DTexture::update can't send image format %d to GL.", _format);
+ }
+ return;
+}
+
+} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_3d_texture_tinygl.h b/engines/tetraedge/te/te_3d_texture_tinygl.h
new file mode 100644
index 00000000000..fa190631e07
--- /dev/null
+++ b/engines/tetraedge/te/te_3d_texture_tinygl.h
@@ -0,0 +1,60 @@
+/* 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 TETRAEDGE_TE_TE_3D_TEXTURE_TINYGL_H
+#define TETRAEDGE_TE_TE_3D_TEXTURE_TINYGL_H
+
+#if defined(USE_TINYGL)
+
+#include "tetraedge/te/te_3d_texture.h"
+
+namespace Tetraedge {
+
+class Te3DTextureTinyGL : public Te3DTexture {
+public:
+ Te3DTextureTinyGL();
+ virtual ~Te3DTextureTinyGL();
+
+ void bind() const override;
+ void copyCurrentRender(uint xoffset, uint yoffset, uint x, uint y) override;
+ void create() override;
+ void destroy() override;
+ void forceTexData(uint gltexture, uint xsize, uint ysize) override;
+
+ bool load(const TeImage &img) override;
+
+ static void unbind();
+ bool unload() override;
+ void update(const TeImage &img, uint xoff, uint yoff) override;
+
+ void writeTo(Graphics::Surface &surf) override;
+
+private:
+ uint _glTexture;
+ //uint _glPixelFormat;
+
+};
+
+} // end namespace Tetraedge
+
+#endif // USE_TINYGL
+
+#endif // TETRAEDGE_TE_TE_3D_TEXTURE_TINYGL_H
diff --git a/engines/tetraedge/te/te_bezier_curve.cpp b/engines/tetraedge/te/te_bezier_curve.cpp
index b92a6f9df98..a7d9407352a 100644
--- a/engines/tetraedge/te/te_bezier_curve.cpp
+++ b/engines/tetraedge/te/te_bezier_curve.cpp
@@ -44,21 +44,21 @@ void TeBezierCurve::draw() {
if (!worldVisible() || _controlPoints.empty())
return;
- TeMesh mesh1;
- TeMesh mesh2;
+ Common::SharedPtr<TeMesh> mesh1(TeMesh::makeInstance());
+ Common::SharedPtr<TeMesh> mesh2(TeMesh::makeInstance());
uint npoints = _controlPoints.size();
- mesh1.setConf(npoints, npoints, TeMesh::MeshMode_Points, 0, 0);
+ mesh1->setConf(npoints, npoints, TeMesh::MeshMode_Points, 0, 0);
for (uint i = 0; i < npoints; i++) {
- mesh1.setVertex(i, _controlPoints[i]);
- mesh1.setIndex(i, i);
+ mesh1->setVertex(i, _controlPoints[i]);
+ mesh1->setIndex(i, i);
}
- mesh2.setConf(npoints, npoints, TeMesh::MeshMode_LineStrip, 0, 0);
+ mesh2->setConf(npoints, npoints, TeMesh::MeshMode_LineStrip, 0, 0);
for (uint i = 0; i < npoints; i++) {
- mesh2.setVertex(i, _controlPoints[i]);
- mesh2.setNormal(i, TeVector3f32(0.0f, 1.0f, 0.0));
- mesh2.setIndex(i, i);
+ mesh2->setVertex(i, _controlPoints[i]);
+ mesh2->setNormal(i, TeVector3f32(0.0f, 1.0f, 0.0));
+ mesh2->setIndex(i, i);
}
TeRenderer *renderer = g_engine->getRenderer();
@@ -66,9 +66,9 @@ void TeBezierCurve::draw() {
renderer->pushMatrix();
renderer->multiplyMatrix(worldTransformationMatrix());
renderer->setCurrentColor(TeColor(0, 0xff, 0xff, 0xff));
- mesh2.draw();
+ mesh2->draw();
renderer->setCurrentColor(TeColor(0xff, 0, 0xff, 0xff));
- mesh1.draw();
+ mesh1->draw();
renderer->popMatrix();
renderer->setCurrentColor(prevColor);
}
diff --git a/engines/tetraedge/te/te_free_move_zone.cpp b/engines/tetraedge/te/te_free_move_zone.cpp
index 9302d69c309..e4043dfa5b4 100644
--- a/engines/tetraedge/te/te_free_move_zone.cpp
+++ b/engines/tetraedge/te/te_free_move_zone.cpp
@@ -274,18 +274,18 @@ void TeFreeMoveZone::draw() {
TeRenderer *renderer = g_engine->getRenderer();
renderer->enableWireFrame();
TePickMesh2::draw();
- TeMesh mesh;
- mesh.setConf(_borders.size(), _borders.size(), TeMesh::MeshMode_Lines, 0, 0);
+ Common::SharedPtr<TeMesh> mesh(TeMesh::makeInstance());
+ mesh->setConf(_borders.size(), _borders.size(), TeMesh::MeshMode_Lines, 0, 0);
for (uint i = 0; i < _borders.size(); i++) {
- mesh.setIndex(i, i);
- mesh.setVertex(i, verticies()[_borders[i]]);
+ mesh->setIndex(i, i);
+ mesh->setVertex(i, verticies()[_borders[i]]);
}
const TeColor prevColor = renderer->currentColor();
renderer->pushMatrix();
renderer->multiplyMatrix(worldTransformationMatrix());
renderer->setCurrentColor(TeColor(0, 0x80, 0xff, 0xff));
- mesh.draw();
+ mesh->draw();
renderer->popMatrix();
renderer->setCurrentColor(prevColor);
diff --git a/engines/tetraedge/te/te_light.cpp b/engines/tetraedge/te/te_light.cpp
index 74544399728..b1c4bdedaac 100644
--- a/engines/tetraedge/te/te_light.cpp
+++ b/engines/tetraedge/te/te_light.cpp
@@ -20,20 +20,19 @@
*/
#include "common/math.h"
+#include "graphics/renderer.h"
+
+#include "tetraedge/tetraedge.h"
#include "tetraedge/te/te_light.h"
+#include "tetraedge/te/te_light_opengl.h"
+#include "tetraedge/te/te_light_tinygl.h"
#include "tetraedge/te/te_color.h"
#include "tetraedge/te/te_quaternion.h"
#include "tetraedge/te/te_vector3f32.h"
-#include "graphics/opengl/system_headers.h"
-
namespace Tetraedge {
-static inline uint _toGlLight(uint lightno) {
- return GL_LIGHT0 + lightno;
-}
-
/*static*/
TeColor TeLight::_globalAmbientColor;
@@ -51,31 +50,6 @@ TeVector3f32 TeLight::directionVector() const {
return TeVector3f32(cosx * cosy, siny, sinx * cosy);
}
-void TeLight::disable(uint lightno) {
- glDisable(_toGlLight(lightno));
-}
-
-void TeLight::enable(uint lightno) {
- if (_colDiffuse.r() == 0 && _colDiffuse.g() == 0 && _colDiffuse.b() == 0)
- glDisable(_toGlLight(lightno));
- else
- glEnable(_toGlLight(lightno));
-}
-
-/*static*/
-void TeLight::disableAll() {
- glDisable(GL_LIGHTING);
-}
-
-/*static*/
-void TeLight::enableAll() {
- glEnable(GL_LIGHTING);
-}
-
-void TeLight::draw(TeCamera &camera) {
- error("TODO: Finish TeLight::draw");
-}
-
void TeLight::transformDirPoint(const TeVector3f32 &pt1, TeVector3f32 &pt2) {
const TeQuaternion q1 = TeQuaternion::fromAxisAndAngle(TeVector3f32(0, 1, 0), _positionRadial.getX() + M_PI);
const TeQuaternion q2 = TeQuaternion::fromAxisAndAngle(TeVector3f32(0, 0, -1), -_positionRadial.getY());
@@ -92,66 +66,9 @@ void TeLight::transformSpotPoint(TeVector3f32 &pt) {
pt += _position3d;
}
-void TeLight::update(uint lightno) {
- if (lightno > GL_MAX_LIGHTS)
- error("Invalid light no %d", lightno);
- const uint glLight = _toGlLight(lightno);
-
- const float ambient[4] = {_colAmbient.r() / 255.0f, _colAmbient.g() / 255.0f,
- _colAmbient.b() / 255.0f, 1.0};
- glLightfv(glLight, GL_AMBIENT, ambient);
-
- const float diff[4] = {_colDiffuse.r() / 255.0f, _colDiffuse.g() / 255.0f,
- _colDiffuse.b() / 255.0f, 1.0};
- glLightfv(glLight, GL_DIFFUSE, diff);
-
- // WORKAROUND: Original game sets 0.01 as threshold here to avoid enabling
- // the "shadow" light. However, Syberia CitStation/31130 has shadowlight with
- // values (4, 0, 0) which means it gets enabled and everything is dark.
-
- if (diff[0] < 0.02f && diff[1] < 0.02f && diff[2] < 0.02f)
- glDisable(glLight);
-
- const float spec[4] = {_colSpecular.r() / 255.0f, _colSpecular.g() / 255.0f,
- _colSpecular.b() / 255.0f, 1.0};
- glLightfv(glLight, GL_SPECULAR, spec);
-
- if (_type == LightTypeSpot || _type == LightTypePoint) {
- const float pos[4] = {_position3d.x(), _position3d.y(), _position3d.z(), 1.0f};
- glLightfv(glLight, GL_POSITION, pos);
- glLightf(glLight, GL_CONSTANT_ATTENUATION, _constAtten);
- glLightf(glLight, GL_LINEAR_ATTENUATION, _linearAtten);
- glLightf(glLight, GL_QUADRATIC_ATTENUATION, _quadraticAtten);
- }
-
- if (_type == LightTypeDirectional) {
- float cosx = cosf(_positionRadial.getX());
- float cosy = cosf(_positionRadial.getY());
- float sinx = sinf(_positionRadial.getX());
- float siny = sinf(_positionRadial.getY());
- const float pos[4] = {cosx * cosy, siny, sinx * cosy, 0.0f};
- glLightfv(glLight, GL_POSITION, pos);
- }
-
- if (_type == LightTypeSpot) {
- float cosx = cosf(_positionRadial.getX());
- float cosy = cosf(_positionRadial.getY());
- float sinx = sinf(_positionRadial.getX());
- float siny = sinf(_positionRadial.getY());
- const float pos[4] = {cosx * cosy, siny, sinx * cosy, 0.0f};
- glLightfv(glLight, GL_SPOT_DIRECTION, pos);
- glLightf(glLight, GL_SPOT_CUTOFF, (_cutoff * 180.0) / M_PI);
- glLightf(glLight, GL_SPOT_EXPONENT, _exponent);
- } else {
- glLightf(glLight, GL_SPOT_CUTOFF, 180.0);
- }
-}
-
/*static*/
void TeLight::updateGlobal() {
- const float col[4] = {_globalAmbientColor.r() / 255.0f,
- _globalAmbientColor.g() / 255.0f, _globalAmbientColor.b() / 255.0f, 1.0};
- glLightModelfv(GL_LIGHT_MODEL_AMBIENT, col);
+ // TOOD: Call correct global.
}
Common::String TeLight::dump() const {
@@ -177,5 +94,20 @@ Common::String TeLight::dump() const {
_quadraticAtten, _cutoff, _exponent, _displaySize);
}
+/*static*/
+TeLight *TeLight::makeInstance() {
+ Graphics::RendererType r = g_engine->preferredRendererType();
+
+#if defined(USE_OPENGL_GAME) || defined(USE_OPENGL_SHADERS)
+ if (r == Graphics::kRendererTypeOpenGL)
+ return new TeLightOpenGL();
+#endif
+
+#if defined(USE_TINYGL)
+ if (r == Graphics::kRendererTypeTinyGL)
+ return new TeLightTinyGL();
+#endif
+ error("Couldn't create TeLight for selected renderer");
+}
} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_light.h b/engines/tetraedge/te/te_light.h
index 38d45756e6f..e4223ebc82c 100644
--- a/engines/tetraedge/te/te_light.h
+++ b/engines/tetraedge/te/te_light.h
@@ -39,19 +39,18 @@ class TeCamera;
class TeLight {
public:
TeLight();
+ virtual ~TeLight() {};
TeVector3f32 directionVector() const;
- void disable(uint lightno);
- void enable(uint lightno);
- static void disableAll();
- static void enableAll();
+ virtual void disable(uint lightno) = 0;
+ virtual void enable(uint lightno) = 0;
- void draw(TeCamera &camera);
+ virtual void draw(TeCamera &camera) = 0;
void transformDirPoint(const TeVector3f32 &pt1, TeVector3f32 &pt2);
void transformSpotPoint(TeVector3f32 &pt1);
- void update(uint lightno);
+ virtual void update(uint lightno) = 0;
static void updateGlobal();
static void setGlobalAmbient(const TeColor &col) { _globalAmbientColor = col; }
static const TeColor &globalAmbient() { return _globalAmbientColor; }
@@ -75,7 +74,9 @@ public:
Common::String dump() const;
-private:
+ static TeLight *makeInstance();
+
+protected:
TeVector3f32 _position3d;
TeVector2f32 _positionRadial;
diff --git a/engines/tetraedge/te/te_light_opengl.cpp b/engines/tetraedge/te/te_light_opengl.cpp
new file mode 100644
index 00000000000..c0021afb485
--- /dev/null
+++ b/engines/tetraedge/te/te_light_opengl.cpp
@@ -0,0 +1,127 @@
+/* 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/math.h"
+
+#include "tetraedge/te/te_light_opengl.h"
+#include "tetraedge/te/te_color.h"
+#include "tetraedge/te/te_quaternion.h"
+#include "tetraedge/te/te_vector3f32.h"
+
+#include "graphics/opengl/system_headers.h"
+
+namespace Tetraedge {
+
+static inline uint _toGlLight(uint lightno) {
+ return GL_LIGHT0 + lightno;
+}
+
+TeLightOpenGL::TeLightOpenGL() {
+}
+
+void TeLightOpenGL::disable(uint lightno) {
+ glDisable(_toGlLight(lightno));
+}
+
+void TeLightOpenGL::enable(uint lightno) {
+ if (_colDiffuse.r() == 0 && _colDiffuse.g() == 0 && _colDiffuse.b() == 0)
+ glDisable(_toGlLight(lightno));
+ else
+ glEnable(_toGlLight(lightno));
+}
+
+/*static*/
+void TeLightOpenGL::disableAll() {
+ glDisable(GL_LIGHTING);
+}
+
+/*static*/
+void TeLightOpenGL::enableAll() {
+ glEnable(GL_LIGHTING);
+}
+
+void TeLightOpenGL::draw(TeCamera &camera) {
+ error("TODO: Finish TeLightOpenGL::draw");
+}
+
+void TeLightOpenGL::update(uint lightno) {
+ if (lightno > GL_MAX_LIGHTS)
+ error("Invalid light no %d", lightno);
+ const uint glLight = _toGlLight(lightno);
+
+ const float ambient[4] = {_colAmbient.r() / 255.0f, _colAmbient.g() / 255.0f,
+ _colAmbient.b() / 255.0f, 1.0};
+ glLightfv(glLight, GL_AMBIENT, ambient);
+
+ const float diff[4] = {_colDiffuse.r() / 255.0f, _colDiffuse.g() / 255.0f,
+ _colDiffuse.b() / 255.0f, 1.0};
+ glLightfv(glLight, GL_DIFFUSE, diff);
+
+ // WORKAROUND: Original game sets 0.01 as threshold here to avoid enabling
+ // the "shadow" light. However, Syberia CitStation/31130 has shadowlight with
+ // values (4, 0, 0) which means it gets enabled and everything is dark.
+
+ if (diff[0] < 0.02f && diff[1] < 0.02f && diff[2] < 0.02f)
+ glDisable(glLight);
+
+ const float spec[4] = {_colSpecular.r() / 255.0f, _colSpecular.g() / 255.0f,
+ _colSpecular.b() / 255.0f, 1.0};
+ glLightfv(glLight, GL_SPECULAR, spec);
+
+ if (_type == LightTypeSpot || _type == LightTypePoint) {
+ const float pos[4] = {_position3d.x(), _position3d.y(), _position3d.z(), 1.0f};
+ glLightfv(glLight, GL_POSITION, pos);
+ glLightf(glLight, GL_CONSTANT_ATTENUATION, _constAtten);
+ glLightf(glLight, GL_LINEAR_ATTENUATION, _linearAtten);
+ glLightf(glLight, GL_QUADRATIC_ATTENUATION, _quadraticAtten);
+ }
+
+ if (_type == LightTypeDirectional) {
+ float cosx = cosf(_positionRadial.getX());
+ float cosy = cosf(_positionRadial.getY());
+ float sinx = sinf(_positionRadial.getX());
+ float siny = sinf(_positionRadial.getY());
+ const float pos[4] = {cosx * cosy, siny, sinx * cosy, 0.0f};
+ glLightfv(glLight, GL_POSITION, pos);
+ }
+
+ if (_type == LightTypeSpot) {
+ float cosx = cosf(_positionRadial.getX());
+ float cosy = cosf(_positionRadial.getY());
+ float sinx = sinf(_positionRadial.getX());
+ float siny = sinf(_positionRadial.getY());
+ const float pos[4] = {cosx * cosy, siny, sinx * cosy, 0.0f};
+ glLightfv(glLight, GL_SPOT_DIRECTION, pos);
+ glLightf(glLight, GL_SPOT_CUTOFF, (_cutoff * 180.0) / M_PI);
+ glLightf(glLight, GL_SPOT_EXPONENT, _exponent);
+ } else {
+ glLightf(glLight, GL_SPOT_CUTOFF, 180.0);
+ }
+}
+
+/*static*/
+void TeLightOpenGL::updateGlobal() {
+ const float col[4] = {_globalAmbientColor.r() / 255.0f,
+ _globalAmbientColor.g() / 255.0f, _globalAmbientColor.b() / 255.0f, 1.0};
+ glLightModelfv(GL_LIGHT_MODEL_AMBIENT, col);
+}
+
+} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_light_opengl.h b/engines/tetraedge/te/te_light_opengl.h
new file mode 100644
index 00000000000..561d86cc4d8
--- /dev/null
+++ b/engines/tetraedge/te/te_light_opengl.h
@@ -0,0 +1,54 @@
+/* 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 TETRAEDGE_TE_TE_LIGHT_OPENGL_H
+#define TETRAEDGE_TE_TE_LIGHT_OPENGL_H
+
+#if defined(USE_OPENGL_GAME) || defined(USE_OPENGL_SHADERS)
+
+#include "tetraedge/te/te_light.h"
+
+namespace Tetraedge {
+
+class TeCamera;
+
+class TeLightOpenGL : public TeLight {
+public:
+ TeLightOpenGL();
+
+ void disable(uint lightno) override;
+ void enable(uint lightno) override;
+
+ void draw(TeCamera &camera) override;
+
+ void update(uint lightno) override;
+ static void updateGlobal();
+
+ static void disableAll();
+ static void enableAll();
+
+};
+
+} // end namespace Tetraedge
+
+#endif // USE_OPENGL
+
+#endif // TETRAEDGE_TE_TE_LIGHT_OPENGL_H
diff --git a/engines/tetraedge/te/te_light_tinygl.cpp b/engines/tetraedge/te/te_light_tinygl.cpp
new file mode 100644
index 00000000000..af94d4c7c50
--- /dev/null
+++ b/engines/tetraedge/te/te_light_tinygl.cpp
@@ -0,0 +1,127 @@
+/* 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/math.h"
+
+#include "tetraedge/te/te_light_tinygl.h"
+#include "tetraedge/te/te_color.h"
+#include "tetraedge/te/te_quaternion.h"
+#include "tetraedge/te/te_vector3f32.h"
+
+#include "graphics/opengl/system_headers.h"
+
+namespace Tetraedge {
+
+static inline uint _toGlLight(uint lightno) {
+ return GL_LIGHT0 + lightno;
+}
+
+TeLightTinyGL::TeLightTinyGL() {
+}
+
+void TeLightTinyGL::disable(uint lightno) {
+ glDisable(_toGlLight(lightno));
+}
+
+void TeLightTinyGL::enable(uint lightno) {
+ if (_colDiffuse.r() == 0 && _colDiffuse.g() == 0 && _colDiffuse.b() == 0)
+ glDisable(_toGlLight(lightno));
+ else
+ glEnable(_toGlLight(lightno));
+}
+
+/*static*/
+void TeLightTinyGL::disableAll() {
+ glDisable(GL_LIGHTING);
+}
+
+/*static*/
+void TeLightTinyGL::enableAll() {
+ glEnable(GL_LIGHTING);
+}
+
+void TeLightTinyGL::draw(TeCamera &camera) {
+ error("TODO: Finish TeLight::draw");
+}
+
+void TeLightTinyGL::update(uint lightno) {
+ if (lightno > GL_MAX_LIGHTS)
+ error("Invalid light no %d", lightno);
+ const uint glLight = _toGlLight(lightno);
+
+ const float ambient[4] = {_colAmbient.r() / 255.0f, _colAmbient.g() / 255.0f,
+ _colAmbient.b() / 255.0f, 1.0};
+ glLightfv(glLight, GL_AMBIENT, ambient);
+
+ const float diff[4] = {_colDiffuse.r() / 255.0f, _colDiffuse.g() / 255.0f,
+ _colDiffuse.b() / 255.0f, 1.0};
+ glLightfv(glLight, GL_DIFFUSE, diff);
+
+ // WORKAROUND: Original game sets 0.01 as threshold here to avoid enabling
+ // the "shadow" light. However, Syberia CitStation/31130 has shadowlight with
+ // values (4, 0, 0) which means it gets enabled and everything is dark.
+
+ if (diff[0] < 0.02f && diff[1] < 0.02f && diff[2] < 0.02f)
+ glDisable(glLight);
+
+ const float spec[4] = {_colSpecular.r() / 255.0f, _colSpecular.g() / 255.0f,
+ _colSpecular.b() / 255.0f, 1.0};
+ glLightfv(glLight, GL_SPECULAR, spec);
+
+ if (_type == LightTypeSpot || _type == LightTypePoint) {
+ const float pos[4] = {_position3d.x(), _position3d.y(), _position3d.z(), 1.0f};
+ glLightfv(glLight, GL_POSITION, pos);
+ glLightf(glLight, GL_CONSTANT_ATTENUATION, _constAtten);
+ glLightf(glLight, GL_LINEAR_ATTENUATION, _linearAtten);
+ glLightf(glLight, GL_QUADRATIC_ATTENUATION, _quadraticAtten);
+ }
+
+ if (_type == LightTypeDirectional) {
+ float cosx = cosf(_positionRadial.getX());
+ float cosy = cosf(_positionRadial.getY());
+ float sinx = sinf(_positionRadial.getX());
+ float siny = sinf(_positionRadial.getY());
+ const float pos[4] = {cosx * cosy, siny, sinx * cosy, 0.0f};
+ glLightfv(glLight, GL_POSITION, pos);
+ }
+
+ if (_type == LightTypeSpot) {
+ float cosx = cosf(_positionRadial.getX());
+ float cosy = cosf(_positionRadial.getY());
+ float sinx = sinf(_positionRadial.getX());
+ float siny = sinf(_positionRadial.getY());
+ const float pos[4] = {cosx * cosy, siny, sinx * cosy, 0.0f};
+ glLightfv(glLight, GL_SPOT_DIRECTION, pos);
+ glLightf(glLight, GL_SPOT_CUTOFF, (_cutoff * 180.0) / M_PI);
+ glLightf(glLight, GL_SPOT_EXPONENT, _exponent);
+ } else {
+ glLightf(glLight, GL_SPOT_CUTOFF, 180.0);
+ }
+}
+
+/*static*/
+void TeLightTinyGL::updateGlobal() {
+ const float col[4] = {_globalAmbientColor.r() / 255.0f,
+ _globalAmbientColor.g() / 255.0f, _globalAmbientColor.b() / 255.0f, 1.0};
+ glLightModelfv(GL_LIGHT_MODEL_AMBIENT, col);
+}
+
+} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_light_tinygl.h b/engines/tetraedge/te/te_light_tinygl.h
new file mode 100644
index 00000000000..a05470f86e9
--- /dev/null
+++ b/engines/tetraedge/te/te_light_tinygl.h
@@ -0,0 +1,52 @@
+/* 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 TETRAEDGE_TE_TE_LIGHT_TINYGL_H
+#define TETRAEDGE_TE_TE_LIGHT_TINYGL_H
+
+#if defined(USE_TINYGL)
+
+#include "tetraedge/te/te_light.h"
+
+namespace Tetraedge {
+
+class TeLightTinyGL : public TeLight {
+public:
+ TeLightTinyGL();
+
+ void disable(uint lightno) override;
+ void enable(uint lightno) override;
+
+ void draw(TeCamera &camera) override;
+
+ void update(uint lightno) override;
+ static void updateGlobal();
+
+ static void disableAll();
+ static void enableAll();
+
+};
+
+} // end namespace Tetraedge
+
+#endif // USE_TINYGL
+
+#endif // TETRAEDGE_TE_TE_LIGHT_TINYGL_H
diff --git a/engines/tetraedge/te/te_material.cpp b/engines/tetraedge/te/te_material.cpp
index af940165a7a..c01ca0f6839 100644
--- a/engines/tetraedge/te/te_material.cpp
+++ b/engines/tetraedge/te/te_material.cpp
@@ -20,7 +20,6 @@
*/
#include "common/textconsole.h"
-#include "graphics/opengl/system_headers.h"
#include "tetraedge/tetraedge.h"
@@ -64,99 +63,6 @@ Common::String TeMaterial::dump() const {
_shininess, _enableLights ? "on" : "off");
}
-void TeMaterial::apply() const {
- //debug("TeMaterial::apply (%s)", dump().c_str());
- static const float constColor[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
- TeRenderer *renderer = g_engine->getRenderer();
- if (renderer->shadowMode() == TeRenderer::ShadowMode0) {
- if (_enableLights)
- TeLight::enableAll();
- else
- TeLight::disableAll();
-
- if (_texture) {
- renderer->enableTexture();
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- _texture->bind();
- }
-
- glDisable(GL_ALPHA_TEST);
- if (_mode == MaterialMode0) {
- glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, constColor);
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
- glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
- glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE);
- glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
- glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
- glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_CONSTANT);
- glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
- } else {
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
- if (_mode != MaterialMode1) {
- glEnable(GL_ALPHA_TEST);
- glAlphaFunc(GL_GREATER, 0.5);
- }
- }
- const float ambient[4] = { _ambientColor.r() / 255.0f, _ambientColor.g() / 255.0f,
- _ambientColor.b() / 255.0f, _ambientColor.a() / 255.0f };
- glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambient);
-
- const float specular[4] = { _specularColor.r() / 255.0f, _specularColor.g() / 255.0f,
- _specularColor.b() / 255.0f, _specularColor.a() / 255.0f };
- glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular);
-
- const float emission[4] = { _emissionColor.r() / 255.0f, _emissionColor.g() / 255.0f,
- _emissionColor.b() / 255.0f, _emissionColor.a() / 255.0f };
- glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, emission);
-
- glMaterialf(GL_FRONT, GL_SHININESS, _shininess);
-
- const float diffuse[4] = { _diffuseColor.r() / 255.0f, _diffuseColor.g() / 255.0f,
- _diffuseColor.b() / 255.0f, _diffuseColor.a() / 255.0f };
- glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse);
-
- renderer->setCurrentColor(_diffuseColor);
- } else if (renderer->shadowMode() == TeRenderer::ShadowMode1) {
- // NOTE: Diverge from original here, it sets 255.0 but the
- // colors should be scaled -1.0 .. 1.0.
- static const float fullColor[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
- TeLight::disableAll();
- glDisable(GL_ALPHA_TEST);
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
- glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, fullColor);
- glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, fullColor);
- glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, fullColor);
- glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, fullColor);
- }
-
- //warning("TODO: Work out what TeMaterial::_enableSomethingDefault0 actually is.");
- if (!_enableSomethingDefault0) {
- glDisable(GL_TEXTURE_GEN_S);
- glDisable(GL_TEXTURE_GEN_T);
- glDisable(GL_TEXTURE_GEN_R);
- glDisable(GL_TEXTURE_GEN_Q);
- } else {
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
- glEnable(GL_TEXTURE_GEN_S);
- glEnable(GL_TEXTURE_GEN_T);
- glEnable(GL_TEXTURE_GEN_R);
- glEnable(GL_TEXTURE_GEN_Q);
- glEnable(GL_TEXTURE_2D);
- TeLight::disableAll();
- glDisable(GL_ALPHA_TEST);
- renderer->enableTexture();
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
-
- const float diffuse[4] = { _diffuseColor.r() / 255.0f, _diffuseColor.g() / 255.0f,
- _diffuseColor.b() / 255.0f, _diffuseColor.a() / 255.0f };
-
- glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, diffuse);
- glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse);
- glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, diffuse);
- glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, diffuse);
- }
-}
-
bool TeMaterial::operator==(const TeMaterial &other) const {
return (_texture == other._texture) && (_ambientColor == other._ambientColor)
&& (_diffuseColor == other._diffuseColor) && (_specularColor == other._specularColor)
diff --git a/engines/tetraedge/te/te_material.h b/engines/tetraedge/te/te_material.h
index 7e0f3eec87d..2fd060abbc3 100644
--- a/engines/tetraedge/te/te_material.h
+++ b/engines/tetraedge/te/te_material.h
@@ -43,7 +43,7 @@ public:
TeMaterial(const TeMaterial &other) = default;
TeMaterial(TeIntrusivePtr<Te3DTexture> texture, Mode mode);
- void apply() const;
+ // Note: apply() function from original moved to TeRenderer to remove OGL specific code from here
void defaultValues();
static void deserialize(Common::SeekableReadStream &stream, TeMaterial &material, const Common::Path &path);
static void serialize(Common::SeekableWriteStream &stream, TeMaterial &material);
diff --git a/engines/tetraedge/te/te_mesh.cpp b/engines/tetraedge/te/te_mesh.cpp
index 77cc00b0b04..30dbe00ecc2 100644
--- a/engines/tetraedge/te/te_mesh.cpp
+++ b/engines/tetraedge/te/te_mesh.cpp
@@ -19,18 +19,17 @@
*
*/
-#include "graphics/opengl/system_headers.h"
-
#include "tetraedge/tetraedge.h"
#include "tetraedge/te/te_renderer.h"
#include "tetraedge/te/te_light.h"
#include "tetraedge/te/te_mesh.h"
+#include "tetraedge/te/te_mesh_opengl.h"
+#include "tetraedge/te/te_mesh_tinygl.h"
#include "tetraedge/te/te_material.h"
namespace Tetraedge {
-TeMesh::TeMesh() : _matrixForced(false), _glMeshMode(GL_POINTS),
-_hasAlpha(false), _gltexEnvMode(GL_MODULATE), _initialMaterialIndexCount(0),
+TeMesh::TeMesh() : _matrixForced(false), _hasAlpha(false), _initialMaterialIndexCount(0),
_drawWires(false), _shouldDraw(true) {
}
@@ -66,158 +65,6 @@ void TeMesh::destroy() {
_matricies.clear();
}
-void TeMesh::draw() {
- if (!worldVisible())
- return;
-
- TeRenderer *renderer = g_engine->getRenderer();
- renderer->pushMatrix();
- if (_matrixForced)
- renderer->multiplyMatrix(_forcedMatrix);
- else
- renderer->multiplyMatrix(worldTransformationMatrix());
-
- /*
- debug("Draw mesh %p (%s, %d verts %d norms %d indexes %d materials %d updated)", this, name().empty() ? "no name" : name().c_str(), _verticies.size(), _normals.size(), _indexes.size(), _materials.size(), _updatedVerticies.size());
- debug(" renderMatrix %s", renderer->currentMatrix().toString().c_str());
- if (!_materials.empty())
- debug(" material %s", _materials[0].dump().c_str());
- debug(" position %s", position().dump().c_str());
- debug(" worldPos %s", worldPosition().dump().c_str());
- debug(" scale %s", scale().dump().c_str());
- debug(" worldScale %s", worldScale().dump().c_str());
- debug(" rotation %s", rotation().dump().c_str());
- debug(" worldRot %s", worldRotation().dump().c_str());
- */
-
- Common::Array<TeVector3f32> &normals = (_updatedVerticies.empty() ? _normals : _updatedNormals);
- Common::Array<TeVector3f32> &verticies = (_updatedVerticies.empty() ? _verticies : _updatedVerticies);
- if (renderer->shadowMode() != TeRenderer::ShadowMode1) {
- if (_faceCounts.empty()) {
- if (hasAlpha(0) && _shouldDraw) {
- renderer->addTransparentMesh(*this, 0, 0, 0);
- renderer->popMatrix();
- return;
- }
- } else {
- assert(_faceCounts.size() == _materials.size());
- int totalFaceCount = 0;
- for (uint i = 0; i < _faceCounts.size(); i++) {
- if (!_faceCounts[i])
- continue;
- if (hasAlpha(i)) {
- renderer->addTransparentMesh(*this, totalFaceCount, _faceCounts[i], i);
- }
- totalFaceCount += _faceCounts[i];
- }
- }
- }
-
- renderer->setMatrixMode(TeRenderer::MM_GL_MODELVIEW);
- renderer->pushMatrix();
- renderer->loadCurrentMatrixToGL();
- glEnableClientState(GL_VERTEX_ARRAY);
- if (!normals.empty())
- glEnableClientState(GL_NORMAL_ARRAY);
-
- if (!_colors.empty())
- glEnableClientState(GL_COLOR_ARRAY);
-
- glVertexPointer(3, GL_FLOAT, 12, verticies.data());
- if (!normals.empty())
- glNormalPointer(GL_FLOAT, 12, normals.data());
-
- if (!_uvs.empty() && renderer->shadowMode() != TeRenderer::ShadowMode2)
- glTexCoordPointer(2, GL_FLOAT, 8, _uvs.data());
-
- if (!_colors.empty())
- glColorPointer(4, GL_UNSIGNED_BYTE, 4, _colors.data());
-
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, _gltexEnvMode);
- if (renderer->scissorEnabled()) {
- glEnable(GL_SCISSOR_TEST);
- uint scissorx = renderer->scissorX();
- uint scissory = renderer->scissorY();
- uint scissorwidth = renderer->scissorWidth();
- uint scissorheight = renderer->scissorHeight();
- glScissor(scissorx, scissory, scissorwidth, scissorheight);
- }
-
- if (_faceCounts.empty()) {
- if (!_materials.empty())
- _materials[0].apply();
-
- glDrawElements(_glMeshMode, _indexes.size(), GL_UNSIGNED_SHORT, _indexes.data());
- if (!_materials.empty()) {
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- renderer->disableTexture();
- }
- } else {
- int totalFaceCount = 0;
- assert(_faceCounts.size() == _materials.size());
- for (uint i = 0; i < _materials.size(); i++) {
- if (!_faceCounts[i])
- continue;
- if (!hasAlpha(i) || renderer->shadowMode() == TeRenderer::ShadowMode1 || !_shouldDraw) {
- _materials[i].apply();
- glDrawElements(_glMeshMode, _faceCounts[i] * 3, GL_UNSIGNED_SHORT, _indexes.data() + totalFaceCount * 3);
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- renderer->disableTexture();
- }
- totalFaceCount += _faceCounts[i];
- }
- }
-
- if (!renderer->scissorEnabled())
- glDisable(GL_SCISSOR_TEST);
-
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
- glDisableClientState(GL_VERTEX_ARRAY);
- glDisableClientState(GL_NORMAL_ARRAY);
- glDisableClientState(GL_COLOR_ARRAY);
-
- //renderer->setCurrentColor(renderer->currentColor()); // pointless?
-
- if (_drawWires && !normals.empty()) {
- TeLight::disableAll();
- glBegin(GL_LINES);
- renderer->setCurrentColor(TeColor(255, 255, 255, 255));
- for (uint i = 0; i < verticies.size(); i++) {
- glVertex3f(verticies[i].x(), verticies[i].y(), verticies[i].z());
- glVertex3f(verticies[i].x() + normals[i].x(),
- verticies[i].y() + normals[i].y(),
- verticies[i].z() + normals[i].z());
- }
- glEnd();
- }
-
- renderer->setMatrixMode(TeRenderer::MM_GL_MODELVIEW);
- renderer->popMatrix();
- renderer->popMatrix();
-}
-
-TeMesh::Mode TeMesh::getMode() const {
- // Do the reverse translation of setConf... why? I dunno.. the game does that..
- switch(_glMeshMode) {
- case GL_POINTS:
- return MeshMode_Points;
- case GL_LINES:
- return MeshMode_Lines;
- case GL_LINE_LOOP:
- return MeshMode_LineLoop;
- case GL_LINE_STRIP:
- return MeshMode_LineStrip;
- case GL_TRIANGLES:
- return MeshMode_Triangles;
- case GL_TRIANGLE_STRIP:
- return MeshMode_TriangleStrip;
- case GL_TRIANGLE_FAN:
- return MeshMode_TriangleFan;
- default:
- return MeshMode_None;
- }
-}
-
bool TeMesh::hasAlpha(uint idx) {
// Note: I don't understand this logic, but it's what the game does..
bool hasGlobalAlpha = _hasAlpha && !_colors.empty();
@@ -248,10 +95,6 @@ void TeMesh::resizeUpdatedTables(unsigned long newSize) {
_updatedNormals.resize(newSize);
}
-void TeMesh::setglTexEnvBlend() {
- _gltexEnvMode = GL_BLEND;
-}
-
void TeMesh::setColor(const TeColor &col) {
Te3DObject2::setColor(col);
@@ -282,31 +125,7 @@ void TeMesh::setConf(unsigned long vertexCount, unsigned long indexCount, enum M
_indexes.resize(indexCount);
_materials.resize(materialCount);
_matricies.resize(vertexCount);
- switch(mode) {
- case MeshMode_Points:
- _glMeshMode = GL_POINTS;
- break;
- case MeshMode_Lines:
- _glMeshMode = GL_LINES;
- break;
- case MeshMode_LineLoop:
- _glMeshMode = GL_LINE_LOOP;
- break;
- case MeshMode_LineStrip:
- _glMeshMode = GL_LINE_STRIP;
- break;
- case MeshMode_Triangles:
- _glMeshMode = GL_TRIANGLES;
- break;
- case MeshMode_TriangleStrip:
- _glMeshMode = GL_TRIANGLE_STRIP;
- break;
- case MeshMode_TriangleFan:
- _glMeshMode = GL_TRIANGLE_FAN;
- break;
- default:
- error("Setting invalid mesh mode.");
- }
+ setMode(mode);
}
void TeMesh::setIndex(uint idx, uint val) {
@@ -403,26 +222,21 @@ void TeMesh::updateTo(const Common::Array<TeMatrix4x4> *matricies1, const Common
}
}
-/*
-TeMesh &TeMesh::operator=(const TeMesh &other) {
- copy(other);
- return *this;
-}
+/*static*/
+TeMesh *TeMesh::makeInstance() {
+ Graphics::RendererType r = g_engine->preferredRendererType();
-void TeMesh::copy(const TeMesh &other) {
- destroy();
- _drawWires = false;
- _hasAlpha = other._hasAlpha;
- _shouldDraw = other._shouldDraw;
- _verticies = other._verticies;
- _normals = other._normals;
- _uvs = other._uvs;
- _colors = other._colors;
-
- _glMeshMode = other._glMeshMode;
- _gltexEnvMode = other._gltexEnvMode;
- _matrixForced = other._matrixForced;
- _forceMatrix = other._forceMatrix;
-}*/
+#if defined(USE_OPENGL_GAME) || defined(USE_OPENGL_SHADERS)
+ if (r == Graphics::kRendererTypeOpenGL)
+ return new TeMeshOpenGL();
+#endif
+
+#if defined(USE_TINYGL)
+ if (r == Graphics::kRendererTypeTinyGL)
+ return new TeMeshTinyGL();
+#endif
+ error("Couldn't create TeMesh for selected renderer");
+
+}
} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_mesh.h b/engines/tetraedge/te/te_mesh.h
index bc71f399d7a..34211174fee 100644
--- a/engines/tetraedge/te/te_mesh.h
+++ b/engines/tetraedge/te/te_mesh.h
@@ -43,7 +43,8 @@ class TeModelVertexAnimation;
class TeMesh : public Te3DObject2 {
public:
TeMesh();
- TeMesh(const TeMesh &other) = default;
+
+ virtual ~TeMesh() {};
enum Mode {
MeshMode_None = 0,
@@ -65,12 +66,13 @@ public:
void create();
void defaultMaterial(const TeIntrusivePtr<Te3DTexture> &texture);
void destroy();
- void draw() override;
void facesPerMaterial(uint idx, unsigned short value);
unsigned short facesPerMaterial(uint idx) const { return _faceCounts[idx]; }
void forceMatrix(const TeMatrix4x4 &matrix);
byte getFaceMaterial(uint idx);
- TeMesh::Mode getMode() const;
+ virtual uint32 getTexEnvMode() const = 0;
+ virtual TeMesh::Mode getMode() const = 0;
+ virtual void setMode(enum Mode mode) = 0;
bool hasAlpha(uint idx);
bool hasColor() const { return !_colors.empty(); }
bool hasUvs() const { return !_uvs.empty(); }
@@ -83,8 +85,6 @@ public:
unsigned short matrixIndex(uint num) const { return _matricies[num]; }
TeVector3f32 normal(uint idx) const;
- TeMesh &operator=(const TeMesh &other) = default;
-
void optimizeVerticies();
void resizeUpdatedTables(unsigned long newSize);
@@ -108,10 +108,9 @@ public:
uint numIndexes() const { return _indexes.size(); }
uint numVerticies() const { return _verticies.size(); }
bool shouldDrawMaybe() const { return _shouldDraw; }
- uint32 gltexEnvMode() const { return _gltexEnvMode; }
void setShouldDraw(bool val) { _shouldDraw = val; }
- void setglTexEnvBlend();
+ virtual void setglTexEnvBlend() = 0;
void setHasAlpha(bool val) { _hasAlpha = val; }
Common::Array<TeMaterial> &materials() { return _materials; }
@@ -121,7 +120,9 @@ public:
const TeVector3f32 &preUpdatedVertex(uint idx) const { return _verticies[idx]; }
const TeVector3f32 &preUpdatedNormal(uint idx) const { return _normals[idx]; }
-private:
+ static TeMesh *makeInstance();
+
+protected:
Common::Array<unsigned char> _materialIndexes;
Common::Array<TeVector3f32> _verticies;
Common::Array<TeVector3f32> _normals;
@@ -134,8 +135,6 @@ private:
Common::Array<TeColor> _colors;
Common::Array<TeMaterial> _materials;
- uint _glMeshMode;
-
bool _matrixForced;
TeMatrix4x4 _forcedMatrix;
bool _hasAlpha;
@@ -143,8 +142,6 @@ private:
bool _drawWires;
bool _shouldDraw;
- uint32 _gltexEnvMode;
-
};
} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_mesh_opengl.cpp b/engines/tetraedge/te/te_mesh_opengl.cpp
new file mode 100644
index 00000000000..86ebdaeada5
--- /dev/null
+++ b/engines/tetraedge/te/te_mesh_opengl.cpp
@@ -0,0 +1,261 @@
+/* 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 "graphics/opengl/system_headers.h"
+
+#include "tetraedge/tetraedge.h"
+#include "tetraedge/te/te_renderer.h"
+#include "tetraedge/te/te_light.h"
+#include "tetraedge/te/te_mesh_opengl.h"
+#include "tetraedge/te/te_material.h"
+
+namespace Tetraedge {
+
+TeMeshOpenGL::TeMeshOpenGL() : _glMeshMode(GL_POINTS), _gltexEnvMode(GL_MODULATE) {
+}
+
+void TeMeshOpenGL::draw() {
+ if (!worldVisible())
+ return;
+
+ TeRenderer *renderer = g_engine->getRenderer();
+ renderer->pushMatrix();
+ if (_matrixForced)
+ renderer->multiplyMatrix(_forcedMatrix);
+ else
+ renderer->multiplyMatrix(worldTransformationMatrix());
+
+ /*
+ debug("Draw mesh %p (%s, %d verts %d norms %d indexes %d materials %d updated)", this, name().empty() ? "no name" : name().c_str(), _verticies.size(), _normals.size(), _indexes.size(), _materials.size(), _updatedVerticies.size());
+ debug(" renderMatrix %s", renderer->currentMatrix().toString().c_str());
+ if (!_materials.empty())
+ debug(" material %s", _materials[0].dump().c_str());
+ debug(" position %s", position().dump().c_str());
+ debug(" worldPos %s", worldPosition().dump().c_str());
+ debug(" scale %s", scale().dump().c_str());
+ debug(" worldScale %s", worldScale().dump().c_str());
+ debug(" rotation %s", rotation().dump().c_str());
+ debug(" worldRot %s", worldRotation().dump().c_str());
+ */
+
+ Common::Array<TeVector3f32> &normals = (_updatedVerticies.empty() ? _normals : _updatedNormals);
+ Common::Array<TeVector3f32> &verticies = (_updatedVerticies.empty() ? _verticies : _updatedVerticies);
+ if (renderer->shadowMode() != TeRenderer::ShadowMode1) {
+ if (_faceCounts.empty()) {
+ if (hasAlpha(0) && _shouldDraw) {
+ renderer->addTransparentMesh(*this, 0, 0, 0);
+ renderer->popMatrix();
+ return;
+ }
+ } else {
+ assert(_faceCounts.size() == _materials.size());
+ int totalFaceCount = 0;
+ for (uint i = 0; i < _faceCounts.size(); i++) {
+ if (!_faceCounts[i])
+ continue;
+ if (hasAlpha(i)) {
+ renderer->addTransparentMesh(*this, totalFaceCount, _faceCounts[i], i);
+ }
+ totalFaceCount += _faceCounts[i];
+ }
+ }
+ }
+
+ renderer->setMatrixMode(TeRenderer::MM_GL_MODELVIEW);
+ renderer->pushMatrix();
+ renderer->loadCurrentMatrixToGL();
+ glEnableClientState(GL_VERTEX_ARRAY);
+ if (!normals.empty())
+ glEnableClientState(GL_NORMAL_ARRAY);
+
+ if (!_colors.empty())
+ glEnableClientState(GL_COLOR_ARRAY);
+
+ glVertexPointer(3, GL_FLOAT, 12, verticies.data());
+ if (!normals.empty())
+ glNormalPointer(GL_FLOAT, 12, normals.data());
+
+ if (!_uvs.empty() && renderer->shadowMode() != TeRenderer::ShadowMode2)
+ glTexCoordPointer(2, GL_FLOAT, 8, _uvs.data());
+
+ if (!_colors.empty())
+ glColorPointer(4, GL_UNSIGNED_BYTE, 4, _colors.data());
+
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, _gltexEnvMode);
+ if (renderer->scissorEnabled()) {
+ glEnable(GL_SCISSOR_TEST);
+ uint scissorx = renderer->scissorX();
+ uint scissory = renderer->scissorY();
+ uint scissorwidth = renderer->scissorWidth();
+ uint scissorheight = renderer->scissorHeight();
+ glScissor(scissorx, scissory, scissorwidth, scissorheight);
+ }
+
+ if (_faceCounts.empty()) {
+ if (!_materials.empty())
+ renderer->applyMaterial(_materials[0]);
+
+ glDrawElements(_glMeshMode, _indexes.size(), GL_UNSIGNED_SHORT, _indexes.data());
+ if (!_materials.empty()) {
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ renderer->disableTexture();
+ }
+ } else {
+ int totalFaceCount = 0;
+ assert(_faceCounts.size() == _materials.size());
+ for (uint i = 0; i < _materials.size(); i++) {
+ if (!_faceCounts[i])
+ continue;
+ if (!hasAlpha(i) || renderer->shadowMode() == TeRenderer::ShadowMode1 || !_shouldDraw) {
+ renderer->applyMaterial(_materials[i]);
+ glDrawElements(_glMeshMode, _faceCounts[i] * 3, GL_UNSIGNED_SHORT, _indexes.data() + totalFaceCount * 3);
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ renderer->disableTexture();
+ }
+ totalFaceCount += _faceCounts[i];
+ }
+ }
+
+ if (!renderer->scissorEnabled())
+ glDisable(GL_SCISSOR_TEST);
+
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+ glDisableClientState(GL_VERTEX_ARRAY);
+ glDisableClientState(GL_NORMAL_ARRAY);
+ glDisableClientState(GL_COLOR_ARRAY);
+
+ //renderer->setCurrentColor(renderer->currentColor()); // pointless?
+
+ if (_drawWires && !normals.empty()) {
+ renderer->disableAllLights();
+ error("TODO: Properly implement _drawWires case in TeMesh::draw");
+ /*
+ // TODO: Reimplement without glBegin/glEnd
+ glBegin(GL_LINES);
+ renderer->setCurrentColor(TeColor(255, 255, 255, 255));
+ for (uint i = 0; i < verticies.size(); i++) {
+ glVertex3f(verticies[i].x(), verticies[i].y(), verticies[i].z());
+ glVertex3f(verticies[i].x() + normals[i].x(),
+ verticies[i].y() + normals[i].y(),
+ verticies[i].z() + normals[i].z());
+ }
+ glEnd();
+ */
+ }
+
+ renderer->setMatrixMode(TeRenderer::MM_GL_MODELVIEW);
+ renderer->popMatrix();
+ renderer->popMatrix();
+}
+
+TeMesh::Mode TeMeshOpenGL::getMode() const {
+ // Do the reverse translation of setConf... why? I dunno.. the game does that..
+ switch(_glMeshMode) {
+ case GL_POINTS:
+ return MeshMode_Points;
+ case GL_LINES:
+ return MeshMode_Lines;
+ case GL_LINE_LOOP:
+ return MeshMode_LineLoop;
+ case GL_LINE_STRIP:
+ return MeshMode_LineStrip;
+ case GL_TRIANGLES:
+ return MeshMode_Triangles;
+ case GL_TRIANGLE_STRIP:
+ return MeshMode_TriangleStrip;
+ case GL_TRIANGLE_FAN:
+ return MeshMode_TriangleFan;
+ default:
+ return MeshMode_None;
+ }
+}
+
+void TeMeshOpenGL::setMode(enum Mode mode) {
+ switch(mode) {
+ case MeshMode_Points:
+ _glMeshMode = GL_POINTS;
+ break;
+ case MeshMode_Lines:
+ _glMeshMode = GL_LINES;
+ break;
+ case MeshMode_LineLoop:
+ _glMeshMode = GL_LINE_LOOP;
+ break;
+ case MeshMode_LineStrip:
+ _glMeshMode = GL_LINE_STRIP;
+ break;
+ case MeshMode_Triangles:
+ _glMeshMode = GL_TRIANGLES;
+ break;
+ case MeshMode_TriangleStrip:
+ _glMeshMode = GL_TRIANGLE_STRIP;
+ break;
+ case MeshMode_TriangleFan:
+ _glMeshMode = GL_TRIANGLE_FAN;
+ break;
+ default:
+ error("Invalid mesh mode %d", (int)mode);
+ }
+}
+
+void TeMeshOpenGL::setglTexEnvBlend() {
+ _gltexEnvMode = GL_BLEND;
+}
+
+uint32 TeMeshOpenGL::getTexEnvMode() const {
+ return _gltexEnvMode;
+}
+
+void TeMeshOpenGL::setConf(unsigned long vertexCount, unsigned long indexCount, enum Mode mode, uint materialCount, uint materialIndexCount) {
+ destroy();
+ _initialMaterialIndexCount = materialIndexCount;
+ _verticies.resize(vertexCount);
+ _indexes.resize(indexCount);
+ _materials.resize(materialCount);
+ _matricies.resize(vertexCount);
+ switch(mode) {
+ case MeshMode_Points:
+ _glMeshMode = GL_POINTS;
+ break;
+ case MeshMode_Lines:
+ _glMeshMode = GL_LINES;
+ break;
+ case MeshMode_LineLoop:
+ _glMeshMode = GL_LINE_LOOP;
+ break;
+ case MeshMode_LineStrip:
+ _glMeshMode = GL_LINE_STRIP;
+ break;
+ case MeshMode_Triangles:
+ _glMeshMode = GL_TRIANGLES;
+ break;
+ case MeshMode_TriangleStrip:
+ _glMeshMode = GL_TRIANGLE_STRIP;
+ break;
+ case MeshMode_TriangleFan:
+ _glMeshMode = GL_TRIANGLE_FAN;
+ break;
+ default:
+ error("Setting invalid mesh mode.");
+ }
+}
+
+} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_mesh_opengl.h b/engines/tetraedge/te/te_mesh_opengl.h
new file mode 100644
index 00000000000..9e1b6fad2d9
--- /dev/null
+++ b/engines/tetraedge/te/te_mesh_opengl.h
@@ -0,0 +1,55 @@
+/* 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 TETRAEDGE_TE_TE_MESH_OPENGL_H
+#define TETRAEDGE_TE_TE_MESH_OPENGL_H
+
+#if defined(USE_OPENGL_GAME) || defined(USE_OPENGL_SHADERS)
+
+#include "tetraedge/te/te_mesh.h"
+
+namespace Tetraedge {
+
+class TeMeshOpenGL : public TeMesh {
+public:
+ TeMeshOpenGL();
+
+ void copy(const TeMesh &other);
+ void draw() override;
+ TeMesh::Mode getMode() const override;
+ void setMode(enum Mode mode) override;
+
+ void setConf(unsigned long vertexCount, unsigned long indexCount, enum Mode mode, uint materialCount, uint materialIndexCount);
+
+ void setglTexEnvBlend() override;
+ uint32 getTexEnvMode() const override;
+
+private:
+ uint _glMeshMode;
+ uint32 _gltexEnvMode;
+
+};
+
+} // end namespace Tetraedge
+
+#endif // USE_OPENGL
+
+#endif // TETRAEDGE_TE_TE_MESH_H
diff --git a/engines/tetraedge/te/te_mesh_tinygl.cpp b/engines/tetraedge/te/te_mesh_tinygl.cpp
new file mode 100644
index 00000000000..8863f5e5dc4
--- /dev/null
+++ b/engines/tetraedge/te/te_mesh_tinygl.cpp
@@ -0,0 +1,231 @@
+/* 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 "graphics/tinygl/tinygl.h"
+
+#include "tetraedge/tetraedge.h"
+#include "tetraedge/te/te_renderer.h"
+#include "tetraedge/te/te_light.h"
+#include "tetraedge/te/te_mesh_tinygl.h"
+
+namespace Tetraedge {
+
+TeMeshTinyGL::TeMeshTinyGL() : _glMeshMode(TGL_POINTS), _gltexEnvMode(TGL_MODULATE) {
+}
+
+void TeMeshTinyGL::draw() {
+ if (!worldVisible())
+ return;
+
+ TeRenderer *renderer = g_engine->getRenderer();
+ renderer->pushMatrix();
+ if (_matrixForced)
+ renderer->multiplyMatrix(_forcedMatrix);
+ else
+ renderer->multiplyMatrix(worldTransformationMatrix());
+
+ /*
+ debug("Draw mesh %p (%s, %d verts %d norms %d indexes %d materials %d updated)", this, name().empty() ? "no name" : name().c_str(), _verticies.size(), _normals.size(), _indexes.size(), _materials.size(), _updatedVerticies.size());
+ debug(" renderMatrix %s", renderer->currentMatrix().toString().c_str());
+ if (!_materials.empty())
+ debug(" material %s", _materials[0].dump().c_str());
+ debug(" position %s", position().dump().c_str());
+ debug(" worldPos %s", worldPosition().dump().c_str());
+ debug(" scale %s", scale().dump().c_str());
+ debug(" worldScale %s", worldScale().dump().c_str());
+ debug(" rotation %s", rotation().dump().c_str());
+ debug(" worldRot %s", worldRotation().dump().c_str());
+ */
+
+ Common::Array<TeVector3f32> &normals = (_updatedVerticies.empty() ? _normals : _updatedNormals);
+ Common::Array<TeVector3f32> &verticies = (_updatedVerticies.empty() ? _verticies : _updatedVerticies);
+ if (renderer->shadowMode() != TeRenderer::ShadowMode1) {
+ if (_faceCounts.empty()) {
+ if (hasAlpha(0) && _shouldDraw) {
+ renderer->addTransparentMesh(*this, 0, 0, 0);
+ renderer->popMatrix();
+ return;
+ }
+ } else {
+ assert(_faceCounts.size() == _materials.size());
+ int totalFaceCount = 0;
+ for (uint i = 0; i < _faceCounts.size(); i++) {
+ if (!_faceCounts[i])
+ continue;
+ if (hasAlpha(i)) {
+ renderer->addTransparentMesh(*this, totalFaceCount, _faceCounts[i], i);
+ }
+ totalFaceCount += _faceCounts[i];
+ }
+ }
+ }
+
+ renderer->setMatrixMode(TeRenderer::MM_GL_MODELVIEW);
+ renderer->pushMatrix();
+ renderer->loadCurrentMatrixToGL();
+ tglEnableClientState(TGL_VERTEX_ARRAY);
+ if (!normals.empty())
+ tglEnableClientState(TGL_NORMAL_ARRAY);
+
+ if (!_colors.empty())
+ tglEnableClientState(TGL_COLOR_ARRAY);
+
+ tglVertexPointer(3, TGL_FLOAT, 12, verticies.data());
+ if (!normals.empty())
+ tglNormalPointer(TGL_FLOAT, 12, normals.data());
+
+ if (!_uvs.empty() && renderer->shadowMode() != TeRenderer::ShadowMode2)
+ tglTexCoordPointer(2, TGL_FLOAT, 8, _uvs.data());
+
+ if (!_colors.empty())
+ tglColorPointer(4, TGL_UNSIGNED_BYTE, 4, _colors.data());
+
+ // TODO: not supported in TGL
+ //tglTexEnvi(TGL_TEXTURE_ENV, TGL_TEXTURE_ENV_MODE, _gltexEnvMode);
+ if (renderer->scissorEnabled()) {
+ tglEnable(TGL_SCISSOR_TEST);
+ // TODO: Scissor not supported by TGL
+ /*
+ uint scissorx = renderer->scissorX();
+ uint scissory = renderer->scissorY();
+ uint scissorwidth = renderer->scissorWidth();
+ uint scissorheight = renderer->scissorHeight();
+ //tglScissor(scissorx, scissory, scissorwidth, scissorheight);
+ */
+ }
+
+ if (_faceCounts.empty()) {
+ if (!_materials.empty())
+ renderer->applyMaterial(_materials[0]);
+
+ tglDrawElements(_glMeshMode, _indexes.size(), TGL_UNSIGNED_SHORT, _indexes.data());
+ if (!_materials.empty()) {
+ tglDisableClientState(TGL_TEXTURE_COORD_ARRAY);
+ renderer->disableTexture();
+ }
+ } else {
+ int totalFaceCount = 0;
+ assert(_faceCounts.size() == _materials.size());
+ for (uint i = 0; i < _materials.size(); i++) {
+ if (!_faceCounts[i])
+ continue;
+ if (!hasAlpha(i) || renderer->shadowMode() == TeRenderer::ShadowMode1 || !_shouldDraw) {
+ renderer->applyMaterial(_materials[i]);
+ tglDrawElements(_glMeshMode, _faceCounts[i] * 3, TGL_UNSIGNED_SHORT, _indexes.data() + totalFaceCount * 3);
+ tglDisableClientState(TGL_TEXTURE_COORD_ARRAY);
+ renderer->disableTexture();
+ }
+ totalFaceCount += _faceCounts[i];
+ }
+ }
+
+ if (!renderer->scissorEnabled())
+ tglDisable(TGL_SCISSOR_TEST);
+
+ // TODO: not supported in TGL
+ //tglTexEnvi(TGL_TEXTURE_ENV, TGL_TEXTURE_ENV_MODE, TGL_MODULATE);
+ tglDisableClientState(TGL_VERTEX_ARRAY);
+ tglDisableClientState(TGL_NORMAL_ARRAY);
+ tglDisableClientState(TGL_COLOR_ARRAY);
+
+ //renderer->setCurrentColor(renderer->currentColor()); // pointless?
+
+ if (_drawWires && !normals.empty()) {
+ renderer->disableAllLights();
+ error("TODO: Properly implement _drawWires case in TeMesh::draw");
+ /*
+ // TODO: Reimplement without glBegin/glEnd
+ glBegin(TGL_LINES);
+ renderer->setCurrentColor(TeColor(255, 255, 255, 255));
+ for (uint i = 0; i < verticies.size(); i++) {
+ glVertex3f(verticies[i].x(), verticies[i].y(), verticies[i].z());
+ glVertex3f(verticies[i].x() + normals[i].x(),
+ verticies[i].y() + normals[i].y(),
+ verticies[i].z() + normals[i].z());
+ }
+ glEnd();
+ */
+ }
+
+ renderer->setMatrixMode(TeRenderer::MM_GL_MODELVIEW);
+ renderer->popMatrix();
+ renderer->popMatrix();
+}
+
+TeMesh::Mode TeMeshTinyGL::getMode() const {
+ switch(_glMeshMode) {
+ case TGL_POINTS:
+ return MeshMode_Points;
+ case TGL_LINES:
+ return MeshMode_Lines;
+ case TGL_LINE_LOOP:
+ return MeshMode_LineLoop;
+ case TGL_LINE_STRIP:
+ return MeshMode_LineStrip;
+ case TGL_TRIANGLES:
+ return MeshMode_Triangles;
+ case TGL_TRIANGLE_STRIP:
+ return MeshMode_TriangleStrip;
+ case TGL_TRIANGLE_FAN:
+ return MeshMode_TriangleFan;
+ default:
+ return MeshMode_None;
+ }
+}
+
+void TeMeshTinyGL::setMode(enum Mode mode) {
+ switch(mode) {
+ case MeshMode_Points:
+ _glMeshMode = TGL_POINTS;
+ break;
+ case MeshMode_Lines:
+ _glMeshMode = TGL_LINES;
+ break;
+ case MeshMode_LineLoop:
+ _glMeshMode = TGL_LINE_LOOP;
+ break;
+ case MeshMode_LineStrip:
+ _glMeshMode = TGL_LINE_STRIP;
+ break;
+ case MeshMode_Triangles:
+ _glMeshMode = TGL_TRIANGLES;
+ break;
+ case MeshMode_TriangleStrip:
+ _glMeshMode = TGL_TRIANGLE_STRIP;
+ break;
+ case MeshMode_TriangleFan:
+ _glMeshMode = TGL_TRIANGLE_FAN;
+ break;
+ default:
+ error("Invalid mesh mode %d", (int)mode);
+ }
+}
+
+void TeMeshTinyGL::setglTexEnvBlend() {
+ _gltexEnvMode = TGL_BLEND;
+}
+
+uint32 TeMeshTinyGL::getTexEnvMode() const {
+ return _gltexEnvMode;
+}
+
+
+} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_mesh_tinygl.h b/engines/tetraedge/te/te_mesh_tinygl.h
new file mode 100644
index 00000000000..73d6e6cd8fa
--- /dev/null
+++ b/engines/tetraedge/te/te_mesh_tinygl.h
@@ -0,0 +1,54 @@
+/* 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 TETRAEDGE_TE_TE_MESH_TINYGL_H
+#define TETRAEDGE_TE_TE_MESH_TINYGL_H
+
+#if defined(USE_TINYGL)
+
+#include "tetraedge/te/te_mesh.h"
+
+namespace Tetraedge {
+
+class TeMeshTinyGL : public TeMesh {
+public:
+ TeMeshTinyGL();
+
+ void copy(const TeMesh &other);
+ void draw() override;
+ TeMesh::Mode getMode() const override;
+ void setMode(enum Mode mode) override;
+
+ void setConf(unsigned long vertexCount, unsigned long indexCount, enum Mode mode, uint materialCount, uint materialIndexCount);
+
+ void setglTexEnvBlend() override;
+ uint32 getTexEnvMode() const override;
+
+private:
+ uint _glMeshMode;
+ uint32 _gltexEnvMode;
+};
+
+} // end namespace Tetraedge
+
+#endif // USE_TINYGL
+
+#endif // TETRAEDGE_TE_TE_MESH_H
diff --git a/engines/tetraedge/te/te_model.cpp b/engines/tetraedge/te/te_model.cpp
index 919a12253ac..b80265f1701 100644
--- a/engines/tetraedge/te/te_model.cpp
+++ b/engines/tetraedge/te/te_model.cpp
@@ -113,13 +113,13 @@ void TeModel::draw() {
//debug(" rotation %s", rotation().dump().c_str());
debug(" worldRot %s", worldRotation().dump().c_str());
}*/
- for (TeMesh &mesh : _meshes) {
+ for (auto &mesh : _meshes) {
// TODO: Set some flag (_drawWires?) in mesh to this->field_0x158??
- mesh.draw();
+ mesh->draw();
}
renderer->popMatrix();
// Note: no corresponding enableAll - they can be enabled inside TeMaterial::apply
- TeLight::disableAll();
+ renderer->disableAllLights();
}
}
@@ -162,8 +162,8 @@ void TeModel::removeAnim() {
void TeModel::setColor(const TeColor &col) {
Te3DObject2::setColor(col);
- for (TeMesh &mesh : _meshes) {
- mesh.setColor(col);
+ for (auto &mesh : _meshes) {
+ mesh->setColor(col);
}
}
@@ -236,7 +236,7 @@ void TeModel::update() {
}
for (uint m = 0; m < _meshes.size(); m++) {
- TeMesh &mesh = _meshes[m];
+ TeMesh &mesh = *_meshes[m];
if (!mesh.visible())
continue;
@@ -297,14 +297,14 @@ void TeModel::update() {
}
} else {
// No bones..
- for (TeMesh &mesh : _meshes) {
+ for (auto &mesh : _meshes) {
if (!_modelVertexAnim) {
- mesh.update(nullptr, nullptr);
+ mesh->update(nullptr, nullptr);
} else {
- if (mesh.name() != _modelVertexAnim->head()) {
- mesh.update(nullptr, nullptr);
+ if (mesh->name() != _modelVertexAnim->head()) {
+ mesh->update(nullptr, nullptr);
} else {
- mesh.update(_modelVertexAnim);
+ mesh->update(_modelVertexAnim);
}
}
}
@@ -313,10 +313,10 @@ void TeModel::update() {
TeModel::MeshBlender::MeshBlender(const Common::String &name, const Common::String &meshName, float amount, TeModel *model) :
_name(name), _amount(amount) {
- Common::Array<TeMesh> &meshes = model->_meshes;
+ const auto &meshes = model->_meshes;
uint i = 0;
for (; i < meshes.size(); i++) {
- if (meshes[i].name().contains(meshName))
+ if (meshes[i]->name().contains(meshName))
break;
}
_meshNo = i;
@@ -356,6 +356,9 @@ bool TeModel::load(Common::SeekableReadStream &stream) {
if (meshCount > 100000)
error("TeModel::load: Unexpected number of meshes %d", meshCount);
_meshes.resize(meshCount);
+ for (uint i = 0; i < meshCount; i++)
+ _meshes[i].reset(TeMesh::makeInstance());
+
uint32 weightCount = stream.readUint32LE();
if (weightCount > 100000)
error("TeModel::load: Unexpected number of weights %d", weightCount);
@@ -385,7 +388,7 @@ bool TeModel::load(Common::SeekableReadStream &stream) {
}
for (uint m = 0; m < _meshes.size(); m++) {
- if (!loadMesh(stream, _meshes[m])) {
+ if (!loadMesh(stream, *_meshes[m])) {
error("[TeModel::load] Error on meshes loading.");
}
}
@@ -552,19 +555,19 @@ bool TeModel::loadMesh(Common::SeekableReadStream &stream, TeMesh &mesh) {
}
void TeModel::setQuad(const TeIntrusivePtr<Te3DTexture> &tex, const Common::Array<TeVector3f32> &verts, const TeColor &col) {
- TeMesh mesh;
- mesh.setConf(4, 4, TeMesh::MeshMode_TriangleStrip, 0, 0);
- mesh.defaultMaterial(tex);
+ Common::SharedPtr<TeMesh> mesh(TeMesh::makeInstance());
+ mesh->setConf(4, 4, TeMesh::MeshMode_TriangleStrip, 0, 0);
+ mesh->defaultMaterial(tex);
for (int i = 0; i < 2; i++) {
float f = (i == 0 ? 0.0f : 1.0f);
for (int j = 0; j < 2; j++) {
int index = i * 2 + j;
- mesh.setVertex(index, verts[i * 2 + j]);
- mesh.setTextureUV(index, TeVector2f32(f, (j == 0 ? 0.0f : 1.0f)));
- mesh.setIndex(index, index);
+ mesh->setVertex(index, verts[i * 2 + j]);
+ mesh->setTextureUV(index, TeVector2f32(f, (j == 0 ? 0.0f : 1.0f)));
+ mesh->setIndex(index, index);
if (col.a() != 0)
- mesh.setColor(index, col);
+ mesh->setColor(index, col);
}
}
@@ -573,7 +576,7 @@ void TeModel::setQuad(const TeIntrusivePtr<Te3DTexture> &tex, const Common::Arra
TeVector3f32 v3 = TeVector3f32::crossProduct(v1, v2);
v3.normalize();
for (int i = 0; i < 4; i++) {
- mesh.setNormal(i, v3);
+ mesh->setNormal(i, v3);
}
_meshes.push_back(mesh);
}
@@ -593,9 +596,9 @@ void TeModel::setVertexAnim(TeIntrusivePtr<TeModelVertexAnimation> &anim, bool r
}
void TeModel::setVisibleByName(const Common::String &name, bool vis) {
- for (TeMesh &mesh : _meshes) {
- if (mesh.name().contains(name)) {
- mesh.setVisible(vis);
+ for (auto &mesh : _meshes) {
+ if (mesh->name().contains(name)) {
+ mesh->setVisible(vis);
}
}
}
diff --git a/engines/tetraedge/te/te_model.h b/engines/tetraedge/te/te_model.h
index 60862309f79..52dfb296618 100644
--- a/engines/tetraedge/te/te_model.h
+++ b/engines/tetraedge/te/te_model.h
@@ -76,7 +76,7 @@ public:
TeModel();
virtual ~TeModel();
- void addMesh(const TeMesh &mesh) {
+ void addMesh(Common::SharedPtr<TeMesh> mesh) {
_meshes.push_back(mesh);
}
TeIntrusivePtr<TeModelAnimation> anim() {
@@ -128,7 +128,7 @@ public:
TeSignal2Param<const Common::String &, TeMatrix4x4 &> &bonesUpdatedSignal() { return _bonesUpdatedSignal; }
Common::Array<BonesBlender *> &boneBlenders() { return _boneBlenders; }
- Common::Array<TeMesh> &meshes() { return _meshes; }
+ Common::Array<Common::SharedPtr<TeMesh>> &meshes() { return _meshes; }
TeIntrusivePtr<TeTiledTexture> tiledTexture() { return _tiledTexture; }
void setEnableLights(bool val) { _enableLights = val; }
@@ -153,7 +153,7 @@ protected:
Common::Array<TeMatrix4x4> _boneMatricies;
Common::Array<TeMatrix4x4> _lerpedElements;
Common::Array<Common::Array<weightElement>> _weightElements;
- Common::Array<TeMesh> _meshes;
+ Common::Array<Common::SharedPtr<TeMesh>> _meshes;
TeQuaternion _boneRotation;
diff --git a/engines/tetraedge/te/te_pick_mesh2.cpp b/engines/tetraedge/te/te_pick_mesh2.cpp
index 4e027aa4408..284316268a1 100644
--- a/engines/tetraedge/te/te_pick_mesh2.cpp
+++ b/engines/tetraedge/te/te_pick_mesh2.cpp
@@ -39,11 +39,11 @@ void TePickMesh2::draw() {
return;
const uint nverticies = _verticies.size();
- TeMesh mesh;
- mesh.setConf(nverticies, nverticies, TeMesh::MeshMode_Triangles, 0, 0);
+ Common::SharedPtr<TeMesh> mesh(TeMesh::makeInstance());
+ mesh->setConf(nverticies, nverticies, TeMesh::MeshMode_Triangles, 0, 0);
for (uint i = 0; i < nverticies; i++) {
- mesh.setIndex(i, i);
- mesh.setVertex(i, _verticies[i]);
+ mesh->setIndex(i, i);
+ mesh->setVertex(i, _verticies[i]);
}
TeRenderer *renderer = g_engine->getRenderer();
@@ -54,7 +54,7 @@ void TePickMesh2::draw() {
renderer->setCurrentColor(TeColor(0xff, 0, 0, 0xff));
renderer->pushMatrix();
renderer->multiplyMatrix(transformationMatrix());
- mesh.draw();
+ mesh->draw();
renderer->popMatrix();
renderer->setCurrentColor(prevCol);
diff --git a/engines/tetraedge/te/te_renderer.cpp b/engines/tetraedge/te/te_renderer.cpp
index bf97c200eba..900164b320b 100644
--- a/engines/tetraedge/te/te_renderer.cpp
+++ b/engines/tetraedge/te/te_renderer.cpp
@@ -22,9 +22,12 @@
#include "common/textconsole.h"
#include "common/debug.h"
-#include "graphics/opengl/system_headers.h"
+#include "graphics/renderer.h"
+#include "tetraedge/tetraedge.h"
#include "tetraedge/te/te_renderer.h"
+#include "tetraedge/te/te_renderer_opengl.h"
+#include "tetraedge/te/te_renderer_tinygl.h"
#include "tetraedge/te/te_light.h"
namespace Tetraedge {
@@ -138,7 +141,7 @@ void TeRenderer::addTransparentMesh(const TeMesh &mesh, unsigned long i1, unsign
destProperties._material = *mesh.material(materialno);
destProperties._matrix = currentMatrix;
- destProperties._glTexEnvMode = mesh.gltexEnvMode();
+ destProperties._glTexEnvMode = mesh.getTexEnvMode();
destProperties._sourceTransparentMesh = _numTransparentMeshes * 3;
destProperties._hasColor = mesh.hasColor();
destProperties._zOrder = zOrder;
@@ -178,7 +181,7 @@ void TeRenderer::addTransparentMesh(const TeMesh &mesh, unsigned long i1, unsign
destProperties._camera = _currentCamera;
destProperties._material = *mesh.material(materialno);
- destProperties._glTexEnvMode = mesh.gltexEnvMode();
+ destProperties._glTexEnvMode = mesh.getTexEnvMode();
destProperties._sourceTransparentMesh = meshPropNo;
destProperties._hasColor = mesh.hasColor();
destProperties._zOrder = zOrder;
@@ -194,17 +197,6 @@ void TeRenderer::addTransparentMesh(const TeMesh &mesh, unsigned long i1, unsign
_pendingTransparentMeshProperties = _transparentMeshProps.size();
}
-void TeRenderer::clearBuffer(TeRenderer::Buffer buf) {
- GLenum glBuf = 0;
- if (buf & StencilBuffer)
- glBuf |= GL_STENCIL_BUFFER_BIT;
- if (buf & DepthBuffer)
- glBuf |= GL_DEPTH_BUFFER_BIT;
- if (buf & ColorBuffer)
- glBuf |= GL_COLOR_BUFFER_BIT;
- glClear(glBuf);
-}
-
void TeRenderer::create() {
_textureEnabled = false;
_currentCamera = nullptr;
@@ -217,68 +209,6 @@ TeMatrix4x4 TeRenderer::currentMatrix() {
return _matriciesStacks[_matrixMode].currentMatrix();
}
-void TeRenderer::disableTexture() {
- glDisable(GL_TEXTURE_2D);
- _textureEnabled = false;
-}
-
-void TeRenderer::disableWireFrame() {
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
-}
-
-void TeRenderer::disableZBuffer() {
- glDisable(GL_DEPTH_TEST);
- glDepthMask(GL_FALSE);
-}
-
-void TeRenderer::drawLine(const TeVector3f32 &from, const TeVector3f32 &to) {
- error("TODO: Implement TeRenderer::drawLine");
-}
-
-void TeRenderer::enableTexture() {
- glEnable(GL_TEXTURE_2D);
- _textureEnabled = true;
-}
-
-void TeRenderer::enableWireFrame() {
- glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
-}
-
-void TeRenderer::enableZBuffer() {
- glEnable(GL_DEPTH_TEST);
- glDepthMask(GL_TRUE);
-}
-
-void TeRenderer::init() {
- glDisable(GL_CULL_FACE);
- TeLight::disableAll();
- glDisable(GL_COLOR_MATERIAL);
- glEnable(GL_DEPTH_TEST);
- glDepthMask(GL_TRUE);
- glShadeModel(GL_SMOOTH);
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glDepthFunc(GL_LEQUAL);
- glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_DONT_CARE);
- glClearDepth(1.0);
- glClearStencil(0);
- _clearColor = TeColor(0, 0, 0, 255);
- glClearColor(0, 0, 0, 1.0);
- debug("[TeRenderer::init] Vendor : %s", glGetString(GL_VENDOR));
- debug("[TeRenderer::init] Renderer : %s", glGetString(GL_RENDERER));
- debug("[TeRenderer::init] Version : %s", glGetString(GL_VERSION));
- int bits;
- glGetIntegerv(GL_STENCIL_BITS, &bits);
- debug("[TeRenderer::init] Sentil buffer bits : %d", bits);
- glGetIntegerv(GL_DEPTH_BITS, &bits);
- debug("[TeRenderer::init] Depth buffer bits : %d", bits);
- //debug("[TeRenderer::init] Extensions : %s", glGetString(GL_EXTENSIONS));
- //TeOpenGLExtensions::loadExtensions(); // this does nothing in the game?
- _currentColor = TeColor(255, 255, 255, 255);
- _scissorEnabled = false;
- _scissorX = _scissorY = _scissorWidth = _scissorHeight = 0;
-}
-
void TeRenderer::loadIdentityMatrix() {
_matriciesStacks[_matrixMode].loadIdentity();
}
@@ -287,28 +217,11 @@ void TeRenderer::loadMatrix(const TeMatrix4x4 &matrix) {
_matriciesStacks[_matrixMode].loadMatrix(matrix);
}
-void TeRenderer::loadMatrixToGL(const TeMatrix4x4 &matrix) {
- //int mmode;
- //glGetIntegerv(GL_MATRIX_MODE, &mmode);
- //debug("loadMatrixToGL[0x%x]: %s", mmode, matrix.toString().c_str());
- glLoadMatrixf(matrix.getData());
-}
-
void TeRenderer::loadCurrentMatrixToGL() {
const TeMatrix4x4 current = currentMatrix();
loadMatrixToGL(current);
}
-void TeRenderer::loadProjectionMatrix(const TeMatrix4x4 &matrix) {
- glMatrixMode(GL_PROJECTION);
- _matrixMode = MM_GL_PROJECTION;
- _matriciesStacks[_matrixMode].loadIdentity();
- _matriciesStacks[_matrixMode].loadMatrix(matrix);
- glMatrixMode(GL_MODELVIEW);
- _matrixMode = MM_GL_MODELVIEW;
- _matriciesStacks[_matrixMode].loadIdentity();
-}
-
void TeRenderer::multiplyMatrix(const TeMatrix4x4 &matrix) {
_matriciesStacks[_matrixMode].multiplyMatrix(matrix);
}
@@ -346,16 +259,6 @@ void TeRenderer::pushMatrix() {
_matriciesStacks[_matrixMode].pushMatrix();
}
-Common::String TeRenderer::renderer() {
- return Common::String((const char *)glGetString(GL_RENDERER));
-}
-
-
-static bool compareTransparentMeshProperties(const TeRenderer::TransparentMeshProperties &p1,
- const TeRenderer::TransparentMeshProperties &p2) {
- return (p1._zOrder < p2._zOrder);
-}
-
void TeRenderer::dumpTransparentMeshProps() const {
debug("** Transparent MeshProps: num:%ld pending:%d **", _numTransparentMeshes, _pendingTransparentMeshProperties);
debug("draw? / nverts / source / transl / zorder");
@@ -384,122 +287,6 @@ void TeRenderer::dumpTransparentMeshData() const {
}
}
-void TeRenderer::renderTransparentMeshes() {
- if (!_numTransparentMeshes)
- return;
-
- glDepthMask(GL_FALSE);
- //dumpTransparentMeshProps();
-
- Common::sort(_transparentMeshProps.begin(), _transparentMeshProps.end(),
- compareTransparentMeshProperties);
-
- int vertsDrawn = 0;
- for (uint i = 0; i < _transparentMeshProps.size(); i++) {
- const uint vcount = _transparentMeshProps[i]._vertexCount;
- for (uint j = 0; j < vcount; j++)
- _transparentMeshVertexNums[vertsDrawn + j] = (short)(_transparentMeshProps[i]._sourceTransparentMesh + j);
- vertsDrawn += vcount;
- }
-
- optimiseTransparentMeshProperties();
-
- //dumpTransparentMeshProps();
- //dumpTransparentMeshData();
-
- glEnableClientState(GL_VERTEX_ARRAY);
- glEnableClientState(GL_NORMAL_ARRAY);
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- glEnableClientState(GL_COLOR_ARRAY);
-
- glVertexPointer(3, GL_FLOAT, 12, _transparentMeshVertexes.data());
- glNormalPointer(GL_FLOAT, 12, _transparentMeshNormals.data());
- glTexCoordPointer(2, GL_FLOAT, 8, _transparentMeshCoords.data());
- glColorPointer(4, GL_UNSIGNED_BYTE, 4, _transparentMeshColors.data());
-
- TeMaterial lastMaterial;
- TeMatrix4x4 lastMatrix;
-
- vertsDrawn = 0;
- for (uint i = 0; i < _transparentMeshProps.size(); i++) {
- const TransparentMeshProperties &meshProperties = _transparentMeshProps[i];
- if (!meshProperties._shouldDraw)
- continue;
-
- const TeMaterial &material = meshProperties._material;
-
- meshProperties._camera->applyProjection();
- glMatrixMode(GL_MODELVIEW);
- _matrixMode = MM_GL_MODELVIEW;
- glPushMatrix();
- _matriciesStacks[_matrixMode].pushMatrix();
- _matriciesStacks[_matrixMode].loadMatrix(meshProperties._matrix);
- glPushMatrix();
- loadCurrentMatrixToGL();
- if (material._texture) {
- glEnable(GL_TEXTURE_2D);
- _textureEnabled = true;
- }
- if (material._enableSomethingDefault0) {
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- glDisableClientState(GL_COLOR_ARRAY);
- }
-
- if (material != lastMaterial) {
- material.apply();
- lastMaterial = material;
- }
-
- if (meshProperties._scissorEnabled) {
- glEnable(GL_SCISSOR_TEST);
- glScissor(meshProperties._scissorX,
- meshProperties._scissorY,
- meshProperties._scissorWidth,
- meshProperties._scissorHeight);
- }
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, meshProperties._glTexEnvMode);
- glDrawElements(GL_TRIANGLES, meshProperties._vertexCount, GL_UNSIGNED_SHORT,
- _transparentMeshVertexNums.data() + vertsDrawn);
-
- vertsDrawn += meshProperties._vertexCount;
-
- if (material._enableSomethingDefault0) {
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- glEnableClientState(GL_COLOR_ARRAY);
- }
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
- if (meshProperties._scissorEnabled) {
- glDisable(GL_SCISSOR_TEST);
- }
- if (material._texture) {
- glDisable(GL_TEXTURE_2D);
- _textureEnabled = false;
- }
- glPopMatrix();
- glPopMatrix();
- _matriciesStacks[_matrixMode].popMatrix();
- TeCamera::restore();
- }
- glDisableClientState(GL_VERTEX_ARRAY);
- glDisableClientState(GL_NORMAL_ARRAY);
- glDisableClientState(GL_COLOR_ARRAY);
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- _numTransparentMeshes = 0;
- _pendingTransparentMeshProperties = 0;
- glDepthMask(GL_TRUE);
- _transparentMeshProps.clear();
-}
-
-void TeRenderer::reset() {
- clearBuffer(AllBuffers);
- glMatrixMode(GL_PROJECTION);
- _matrixMode = MM_GL_PROJECTION;
- _matriciesStacks[MM_GL_PROJECTION].loadIdentity();
- glMatrixMode(GL_MODELVIEW);
- _matrixMode = MM_GL_MODELVIEW;
- _matriciesStacks[MM_GL_MODELVIEW].loadIdentity();
-}
-
void TeRenderer::rotate(const TeQuaternion &rot) {
_matriciesStacks[_matrixMode].rotate(rot);
}
@@ -512,33 +299,6 @@ void TeRenderer::scale(float xs, float ys, float zs) {
_matriciesStacks[_matrixMode].scale(TeVector3f32(xs, ys, zs));
}
-void TeRenderer::setClearColor(const TeColor &col) {
- _clearColor = col;
- glClearColor(col.r() / 255.0f, col.g() / 255.0f, col.b() / 255.0f, col.a() / 255.0f);
-}
-
-void TeRenderer::setCurrentColor(const TeColor &col) {
- if (col == _currentColor)
- return;
-
- glColor4ub(col.r(), col.g(), col.b(), col.a());
- _currentColor = col;
-}
-
-void TeRenderer::setMatrixMode(enum MatrixMode mode) {
- GLenum glmode = 0;
- if (mode == MM_GL_TEXTURE)
- glmode = GL_TEXTURE;
- else if (mode == MM_GL_MODELVIEW)
- glmode = GL_MODELVIEW;
- else if (mode == MM_GL_PROJECTION)
- glmode = GL_PROJECTION;
-
- if (glmode)
- glMatrixMode(glmode);
- _matrixMode = mode;
-}
-
void TeRenderer::setScissor(int x, int y, int w, int h) {
_scissorX = x;
_scissorY = y;
@@ -546,36 +306,26 @@ void TeRenderer::setScissor(int x, int y, int w, int h) {
_scissorHeight = h;
}
-void TeRenderer::setViewport(int x, int y, int w, int h) {
- glViewport(x, y, w, h);
+void TeRenderer::translate(float x, float y, float z) {
+ _matriciesStacks[_matrixMode].translate(TeVector3f32(x, y, z));
}
-void TeRenderer::shadowMode(enum ShadowMode mode) {
- _shadowMode = mode;
- if (mode == ShadowMode0) {
- glDisable(GL_CULL_FACE);
- glShadeModel(GL_SMOOTH);
- return;
- }
- if (mode == ShadowMode1) {
- glEnable(GL_CULL_FACE);
- glCullFace(GL_BACK);
- } else { // ShadowMode2
- glDisable(GL_CULL_FACE);
- }
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glShadeModel(GL_FLAT);
- TeLight::disableAll();
-}
+/*static*/
+TeRenderer *TeRenderer::makeInstance() {
+ Graphics::RendererType r = g_engine->preferredRendererType();
-void TeRenderer::translate(float x, float y, float z) {
- _matriciesStacks[_matrixMode].translate(TeVector3f32(x, y, z));
-}
+#if defined(USE_OPENGL_GAME) || defined(USE_OPENGL_SHADERS)
+ if (r == Graphics::kRendererTypeOpenGL)
+ return new TeRendererOpenGL();
+#endif
-Common::String TeRenderer::vendor() {
- return Common::String((const char *)glGetString(GL_VENDOR));
+#if defined(USE_TINYGL)
+ if (r == Graphics::kRendererTypeTinyGL)
+ return new TeRendererTinyGL();
+#endif
+ error("Couldn't create TeRenderer for selected renderer");
}
+
} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_renderer.h b/engines/tetraedge/te/te_renderer.h
index a481d2f2936..c50ecb7ac95 100644
--- a/engines/tetraedge/te/te_renderer.h
+++ b/engines/tetraedge/te/te_renderer.h
@@ -33,6 +33,7 @@ namespace Tetraedge {
class TeRenderer {
public:
TeRenderer();
+ virtual ~TeRenderer() {};
enum MatrixMode {
MM_GL_PROJECTION = 0,
@@ -49,6 +50,7 @@ public:
class TransparentMeshProperties {
public:
TransparentMeshProperties() : _camera(nullptr), _vertexCount(0), _shouldDraw(false), _scissorEnabled(false), _hasColor(false) {}
+
TeCamera *_camera;
int _vertexCount;
TeMatrix4x4 _matrix;
@@ -77,29 +79,31 @@ public:
void addTransparentMesh(const TeMesh &mesh, unsigned long i1, unsigned long i2, unsigned long i3);
void checkError(const Common::String &str) {};
- void clearBuffer(Buffer buf);
+ virtual void clearBuffer(Buffer buf) = 0;
void create();
TeMatrix4x4 currentMatrix();
- void disableTexture();
- void disableWireFrame();
- void disableZBuffer();
- void drawLine(const TeVector3f32 &from, const TeVector3f32 &to);
- void enableTexture();
- void enableWireFrame();
- void enableZBuffer();
+ virtual void disableAllLights() = 0;
+ virtual void disableTexture() = 0;
+ virtual void disableWireFrame() = 0;
+ virtual void disableZBuffer() = 0;
+ virtual void drawLine(const TeVector3f32 &from, const TeVector3f32 &to) = 0;
+ virtual void enableAllLights() = 0;
+ virtual void enableTexture() = 0;
+ virtual void enableWireFrame() = 0;
+ virtual void enableZBuffer() = 0;
//void extractFrameBufferToImg(const TeVector2s32 &from, const TeVector2s32 &to, TeImage &output);
- void init();
+ virtual void init(uint width, uint height) = 0;
void loadIdentityMatrix();
void loadMatrix(const TeMatrix4x4 &matrix);
void loadCurrentMatrixToGL();
- void loadProjectionMatrix(const TeMatrix4x4 &matrix);
+ virtual void loadProjectionMatrix(const TeMatrix4x4 &matrix) = 0;
void multiplyMatrix(const TeMatrix4x4 &matrix);
void optimiseTransparentMeshProperties();
void popMatrix();
void pushMatrix();
- Common::String renderer();
- void renderTransparentMeshes();
- void reset();
+ virtual Common::String renderer() = 0;
+ virtual void renderTransparentMeshes() = 0;
+ virtual void reset() = 0;
void rotate(const TeQuaternion &rot);
void rotate(float angle, float rx, float ry, float rz);
void scale(float xs, float ys, float zs);
@@ -109,25 +113,29 @@ public:
int scissorX() const { return _scissorX; }
int scissorY() const { return _scissorY; }
void sendModelMatrix(const TeMatrix4x4 &matrix) {}
- void setClearColor(const TeColor &col);
+ virtual void setClearColor(const TeColor &col) = 0;
void setCurrentCamera(TeCamera *camera) {
_currentCamera = camera;
}
- void setCurrentColor(const TeColor &col);
- void setMatrixMode(enum MatrixMode mode);
+ virtual void setCurrentColor(const TeColor &col) = 0;
+ virtual void setMatrixMode(enum MatrixMode mode) = 0;
void setScissor(int x, int y, int w, int h);
void setScissorEnabled(bool val) { _scissorEnabled = val; }
- void setViewport(int x, int y, int w, int h);
- void shadowMode(enum ShadowMode mode);
+ virtual void setViewport(int x, int y, int w, int h) = 0;
+ virtual void shadowMode(enum ShadowMode mode) = 0;
enum ShadowMode shadowMode() const { return _shadowMode; }
void translate(float x, float y, float z);
- Common::String vendor();
+ virtual Common::String vendor() = 0;
void dumpTransparentMeshProps() const;
void dumpTransparentMeshData() const;
const TeColor ¤tColor() const { return _currentColor; }
-private:
+ virtual void applyMaterial(const TeMaterial &m) = 0;
+
+ static TeRenderer *makeInstance();
+
+protected:
TeCamera *_currentCamera;
TeColor _currentColor;
TeColor _clearColor;
@@ -154,7 +162,7 @@ private:
TeMatriciesStack _matriciesStacks[3]; // one per matrix mode.
- void loadMatrixToGL(const TeMatrix4x4 &matrix);
+ virtual void loadMatrixToGL(const TeMatrix4x4 &matrix) = 0;
};
} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_renderer_opengl.cpp b/engines/tetraedge/te/te_renderer_opengl.cpp
new file mode 100644
index 00000000000..abbf81550ae
--- /dev/null
+++ b/engines/tetraedge/te/te_renderer_opengl.cpp
@@ -0,0 +1,412 @@
+/* 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/textconsole.h"
+#include "common/debug.h"
+
+#include "graphics/opengl/system_headers.h"
+
+#include "engines/util.h"
+
+#include "tetraedge/te/te_renderer.h"
+#include "tetraedge/te/te_renderer_opengl.h"
+#include "tetraedge/te/te_light.h"
+#include "tetraedge/te/te_light_opengl.h"
+#include "tetraedge/te/te_mesh_opengl.h"
+
+namespace Tetraedge {
+
+TeRendererOpenGL::TeRendererOpenGL() {
+}
+
+void TeRendererOpenGL::clearBuffer(TeRenderer::Buffer buf) {
+ GLenum glBuf = 0;
+ if (buf & StencilBuffer)
+ glBuf |= GL_STENCIL_BUFFER_BIT;
+ if (buf & DepthBuffer)
+ glBuf |= GL_DEPTH_BUFFER_BIT;
+ if (buf & ColorBuffer)
+ glBuf |= GL_COLOR_BUFFER_BIT;
+ glClear(glBuf);
+}
+
+void TeRendererOpenGL::disableAllLights() {
+ TeLightOpenGL::disableAll();
+}
+
+void TeRendererOpenGL::disableTexture() {
+ glDisable(GL_TEXTURE_2D);
+ _textureEnabled = false;
+}
+
+void TeRendererOpenGL::disableWireFrame() {
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+}
+
+void TeRendererOpenGL::disableZBuffer() {
+ glDisable(GL_DEPTH_TEST);
+ glDepthMask(GL_FALSE);
+}
+
+void TeRendererOpenGL::drawLine(const TeVector3f32 &from, const TeVector3f32 &to) {
+ error("TODO: Implement TeRenderer::drawLine");
+}
+
+void TeRendererOpenGL::enableAllLights() {
+ TeLightOpenGL::enableAll();
+}
+
+void TeRendererOpenGL::enableTexture() {
+ glEnable(GL_TEXTURE_2D);
+ _textureEnabled = true;
+}
+
+void TeRendererOpenGL::enableWireFrame() {
+ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+}
+
+void TeRendererOpenGL::enableZBuffer() {
+ glEnable(GL_DEPTH_TEST);
+ glDepthMask(GL_TRUE);
+}
+
+void TeRendererOpenGL::init(uint width, uint height) {
+ initGraphics3d(width, height);
+ glDisable(GL_CULL_FACE);
+ TeLightOpenGL::disableAll();
+ glDisable(GL_COLOR_MATERIAL);
+ glEnable(GL_DEPTH_TEST);
+ glDepthMask(GL_TRUE);
+ glShadeModel(GL_SMOOTH);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glDepthFunc(GL_LEQUAL);
+ glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_DONT_CARE);
+ glClearDepth(1.0);
+ glClearStencil(0);
+ _clearColor = TeColor(0, 0, 0, 255);
+ glClearColor(0, 0, 0, 1.0);
+ debug("[TeRenderer::init] Vendor : %s", vendor().c_str());
+ debug("[TeRenderer::init] Renderer : %s", renderer().c_str());
+ debug("[TeRenderer::init] Version : %s", glGetString(GL_VERSION));
+ int bits;
+ glGetIntegerv(GL_STENCIL_BITS, &bits);
+ debug("[TeRenderer::init] Sentil buffer bits : %d", bits);
+ glGetIntegerv(GL_DEPTH_BITS, &bits);
+ debug("[TeRenderer::init] Depth buffer bits : %d", bits);
+ //debug("[TeRenderer::init] Extensions : %s", glGetString(GL_EXTENSIONS));
+ //TeOpenGLExtensions::loadExtensions(); // this does nothing in the game?
+ _currentColor = TeColor(255, 255, 255, 255);
+ _scissorEnabled = false;
+ _scissorX = _scissorY = _scissorWidth = _scissorHeight = 0;
+}
+
+void TeRendererOpenGL::loadMatrixToGL(const TeMatrix4x4 &matrix) {
+ //int mmode;
+ //glGetIntegerv(GL_MATRIX_MODE, &mmode);
+ //debug("loadMatrixToGL[0x%x]: %s", mmode, matrix.toString().c_str());
+ glLoadMatrixf(matrix.getData());
+}
+
+void TeRendererOpenGL::loadProjectionMatrix(const TeMatrix4x4 &matrix) {
+ glMatrixMode(GL_PROJECTION);
+ _matrixMode = MM_GL_PROJECTION;
+ _matriciesStacks[_matrixMode].loadIdentity();
+ _matriciesStacks[_matrixMode].loadMatrix(matrix);
+ glMatrixMode(GL_MODELVIEW);
+ _matrixMode = MM_GL_MODELVIEW;
+ _matriciesStacks[_matrixMode].loadIdentity();
+}
+
+Common::String TeRendererOpenGL::renderer() {
+ return Common::String((const char *)glGetString(GL_RENDERER));
+}
+
+
+static bool compareTransparentMeshProperties(const TeRenderer::TransparentMeshProperties &p1,
+ const TeRenderer::TransparentMeshProperties &p2) {
+ return (p1._zOrder < p2._zOrder);
+}
+
+void TeRendererOpenGL::renderTransparentMeshes() {
+ if (!_numTransparentMeshes)
+ return;
+
+ glDepthMask(GL_FALSE);
+ //dumpTransparentMeshProps();
+
+ Common::sort(_transparentMeshProps.begin(), _transparentMeshProps.end(),
+ compareTransparentMeshProperties);
+
+ int vertsDrawn = 0;
+ for (uint i = 0; i < _transparentMeshProps.size(); i++) {
+ const uint vcount = _transparentMeshProps[i]._vertexCount;
+ for (uint j = 0; j < vcount; j++)
+ _transparentMeshVertexNums[vertsDrawn + j] = (short)(_transparentMeshProps[i]._sourceTransparentMesh + j);
+ vertsDrawn += vcount;
+ }
+
+ optimiseTransparentMeshProperties();
+
+ //dumpTransparentMeshProps();
+ //dumpTransparentMeshData();
+
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_NORMAL_ARRAY);
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ glEnableClientState(GL_COLOR_ARRAY);
+
+ glVertexPointer(3, GL_FLOAT, 12, _transparentMeshVertexes.data());
+ glNormalPointer(GL_FLOAT, 12, _transparentMeshNormals.data());
+ glTexCoordPointer(2, GL_FLOAT, 8, _transparentMeshCoords.data());
+ glColorPointer(4, GL_UNSIGNED_BYTE, 4, _transparentMeshColors.data());
+
+ TeMaterial lastMaterial;
+ TeMatrix4x4 lastMatrix;
+
+ vertsDrawn = 0;
+ for (uint i = 0; i < _transparentMeshProps.size(); i++) {
+ const TransparentMeshProperties &meshProperties = _transparentMeshProps[i];
+ if (!meshProperties._shouldDraw)
+ continue;
+
+ const TeMaterial &material = meshProperties._material;
+
+ meshProperties._camera->applyProjection();
+ glMatrixMode(GL_MODELVIEW);
+ _matrixMode = MM_GL_MODELVIEW;
+ glPushMatrix();
+ _matriciesStacks[_matrixMode].pushMatrix();
+ _matriciesStacks[_matrixMode].loadMatrix(meshProperties._matrix);
+ glPushMatrix();
+ loadCurrentMatrixToGL();
+ if (material._texture) {
+ glEnable(GL_TEXTURE_2D);
+ _textureEnabled = true;
+ }
+ if (material._enableSomethingDefault0) {
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ glDisableClientState(GL_COLOR_ARRAY);
+ }
+
+ if (material != lastMaterial) {
+ applyMaterial(material);
+ lastMaterial = material;
+ }
+
+ if (meshProperties._scissorEnabled) {
+ glEnable(GL_SCISSOR_TEST);
+ glScissor(meshProperties._scissorX,
+ meshProperties._scissorY,
+ meshProperties._scissorWidth,
+ meshProperties._scissorHeight);
+ }
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, meshProperties._glTexEnvMode);
+ glDrawElements(GL_TRIANGLES, meshProperties._vertexCount, GL_UNSIGNED_SHORT,
+ _transparentMeshVertexNums.data() + vertsDrawn);
+
+ vertsDrawn += meshProperties._vertexCount;
+
+ if (material._enableSomethingDefault0) {
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ glEnableClientState(GL_COLOR_ARRAY);
+ }
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+ if (meshProperties._scissorEnabled) {
+ glDisable(GL_SCISSOR_TEST);
+ }
+ if (material._texture) {
+ glDisable(GL_TEXTURE_2D);
+ _textureEnabled = false;
+ }
+ glPopMatrix();
+ glPopMatrix();
+ _matriciesStacks[_matrixMode].popMatrix();
+ TeCamera::restore();
+ }
+ glDisableClientState(GL_VERTEX_ARRAY);
+ glDisableClientState(GL_NORMAL_ARRAY);
+ glDisableClientState(GL_COLOR_ARRAY);
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ _numTransparentMeshes = 0;
+ _pendingTransparentMeshProperties = 0;
+ glDepthMask(GL_TRUE);
+ _transparentMeshProps.clear();
+}
+
+void TeRendererOpenGL::reset() {
+ clearBuffer(AllBuffers);
+ glMatrixMode(GL_PROJECTION);
+ _matrixMode = MM_GL_PROJECTION;
+ _matriciesStacks[MM_GL_PROJECTION].loadIdentity();
+ glMatrixMode(GL_MODELVIEW);
+ _matrixMode = MM_GL_MODELVIEW;
+ _matriciesStacks[MM_GL_MODELVIEW].loadIdentity();
+}
+
+void TeRendererOpenGL::setClearColor(const TeColor &col) {
+ _clearColor = col;
+ glClearColor(col.r() / 255.0f, col.g() / 255.0f, col.b() / 255.0f, col.a() / 255.0f);
+}
+
+void TeRendererOpenGL::setCurrentColor(const TeColor &col) {
+ if (col == _currentColor)
+ return;
+
+ glColor4ub(col.r(), col.g(), col.b(), col.a());
+ _currentColor = col;
+}
+
+void TeRendererOpenGL::setMatrixMode(enum MatrixMode mode) {
+ GLenum glmode = 0;
+ if (mode == MM_GL_TEXTURE)
+ glmode = GL_TEXTURE;
+ else if (mode == MM_GL_MODELVIEW)
+ glmode = GL_MODELVIEW;
+ else if (mode == MM_GL_PROJECTION)
+ glmode = GL_PROJECTION;
+
+ if (glmode)
+ glMatrixMode(glmode);
+ _matrixMode = mode;
+}
+
+void TeRendererOpenGL::setViewport(int x, int y, int w, int h) {
+ glViewport(x, y, w, h);
+}
+
+void TeRendererOpenGL::shadowMode(enum ShadowMode mode) {
+ _shadowMode = mode;
+ if (mode == ShadowMode0) {
+ glDisable(GL_CULL_FACE);
+ glShadeModel(GL_SMOOTH);
+ return;
+ }
+
+ if (mode == ShadowMode1) {
+ glEnable(GL_CULL_FACE);
+ glCullFace(GL_BACK);
+ } else { // ShadowMode2
+ glDisable(GL_CULL_FACE);
+ }
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glShadeModel(GL_FLAT);
+ TeLightOpenGL::disableAll();
+}
+
+void TeRendererOpenGL::applyMaterial(const TeMaterial &m) {
+ //debug("TeMaterial::apply (%s)", dump().c_str());
+ static const float constColor[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
+ if (_shadowMode == TeRenderer::ShadowMode0) {
+ if (m._enableLights)
+ TeLightOpenGL::enableAll();
+ else
+ TeLightOpenGL::disableAll();
+
+ if (m._texture) {
+ enableTexture();
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ m._texture->bind();
+ }
+
+ glDisable(GL_ALPHA_TEST);
+ if (m._mode == TeMaterial::MaterialMode0) {
+ glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, constColor);
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
+ glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
+ glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE);
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
+ glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
+ glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_CONSTANT);
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
+ } else {
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+ if (m._mode != TeMaterial::MaterialMode1) {
+ glEnable(GL_ALPHA_TEST);
+ glAlphaFunc(GL_GREATER, 0.5);
+ }
+ }
+ const float ambient[4] = { m._ambientColor.r() / 255.0f, m._ambientColor.g() / 255.0f,
+ m._ambientColor.b() / 255.0f, m._ambientColor.a() / 255.0f };
+ glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambient);
+
+ const float specular[4] = { m._specularColor.r() / 255.0f, m._specularColor.g() / 255.0f,
+ m._specularColor.b() / 255.0f, m._specularColor.a() / 255.0f };
+ glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular);
+
+ const float emission[4] = { m._emissionColor.r() / 255.0f, m._emissionColor.g() / 255.0f,
+ m._emissionColor.b() / 255.0f, m._emissionColor.a() / 255.0f };
+ glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, emission);
+
+ glMaterialf(GL_FRONT, GL_SHININESS, m._shininess);
+
+ const float diffuse[4] = { m._diffuseColor.r() / 255.0f, m._diffuseColor.g() / 255.0f,
+ m._diffuseColor.b() / 255.0f, m._diffuseColor.a() / 255.0f };
+ glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse);
+
+ setCurrentColor(m._diffuseColor);
+ } else if (_shadowMode == TeRenderer::ShadowMode1) {
+ // NOTE: Diverge from original here, it sets 255.0 but the
+ // colors should be scaled -1.0 .. 1.0.
+ static const float fullColor[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
+ TeLightOpenGL::disableAll();
+ glDisable(GL_ALPHA_TEST);
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, fullColor);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, fullColor);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, fullColor);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, fullColor);
+ }
+
+ //warning("TODO: Work out what TeMaterial::_enableSomethingDefault0 actually is.");
+ if (!m._enableSomethingDefault0) {
+ glDisable(GL_TEXTURE_GEN_S);
+ glDisable(GL_TEXTURE_GEN_T);
+ glDisable(GL_TEXTURE_GEN_R);
+ glDisable(GL_TEXTURE_GEN_Q);
+ } else {
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+ glEnable(GL_TEXTURE_GEN_S);
+ glEnable(GL_TEXTURE_GEN_T);
+ glEnable(GL_TEXTURE_GEN_R);
+ glEnable(GL_TEXTURE_GEN_Q);
+ glEnable(GL_TEXTURE_2D);
+ TeLightOpenGL::disableAll();
+ glDisable(GL_ALPHA_TEST);
+ enableTexture();
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+
+ const float diffuse[4] = { m._diffuseColor.r() / 255.0f, m._diffuseColor.g() / 255.0f,
+ m._diffuseColor.b() / 255.0f, m._diffuseColor.a() / 255.0f };
+
+ glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, diffuse);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, diffuse);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, diffuse);
+ }
+}
+
+Common::String TeRendererOpenGL::vendor() {
+ return Common::String((const char *)glGetString(GL_VENDOR));
+}
+
+} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_renderer_opengl.h b/engines/tetraedge/te/te_renderer_opengl.h
new file mode 100644
index 00000000000..c6d7f76ab5e
--- /dev/null
+++ b/engines/tetraedge/te/te_renderer_opengl.h
@@ -0,0 +1,66 @@
+/* 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 TETRAEDGE_TE_TE_RENDERER_OPENGL_H
+#define TETRAEDGE_TE_TE_RENDERER_OPENGL_H
+
+#if defined(USE_OPENGL_GAME) || defined(USE_OPENGL_SHADERS)
+
+#include "tetraedge/te/te_renderer.h"
+
+namespace Tetraedge {
+
+class TeRendererOpenGL : public TeRenderer {
+public:
+ TeRendererOpenGL();
+ void clearBuffer(TeRenderer::Buffer buf) override;
+ void disableAllLights() override;
+ void disableTexture() override;
+ void disableWireFrame() override;
+ void disableZBuffer() override;
+ void drawLine(const TeVector3f32 &from, const TeVector3f32 &to) override;
+ void enableAllLights() override;
+ void enableTexture() override;
+ void enableWireFrame() override;
+ void enableZBuffer() override;
+ void init(uint width, uint height) override;
+ void loadProjectionMatrix(const TeMatrix4x4 &matrix) override;
+ Common::String renderer() override;
+ void renderTransparentMeshes() override;
+ void reset() override;
+ void setClearColor(const TeColor &col) override;
+ void setCurrentColor(const TeColor &col) override;
+ void setMatrixMode(enum MatrixMode mode) override;
+ void setViewport(int x, int y, int w, int h) override;
+ void shadowMode(enum ShadowMode mode) override;
+ Common::String vendor() override;
+ void applyMaterial(const TeMaterial &m) override;
+
+protected:
+
+ void loadMatrixToGL(const TeMatrix4x4 &matrix) override;
+};
+
+} // end namespace Tetraedge
+
+#endif // USE_OPENGL
+
+#endif // TETRAEDGE_TE_TE_RENDERER_OPENGL_H
diff --git a/engines/tetraedge/te/te_renderer_tinygl.cpp b/engines/tetraedge/te/te_renderer_tinygl.cpp
new file mode 100644
index 00000000000..a8eba20af17
--- /dev/null
+++ b/engines/tetraedge/te/te_renderer_tinygl.cpp
@@ -0,0 +1,431 @@
+/* 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/textconsole.h"
+#include "common/debug.h"
+#include "common/system.h"
+#include "common/config-manager.h"
+
+#include "graphics/tinygl/tinygl.h"
+
+#include "engines/util.h"
+
+#include "tetraedge/te/te_renderer_tinygl.h"
+#include "tetraedge/te/te_light.h"
+#include "tetraedge/te/te_light_tinygl.h"
+#include "tetraedge/te/te_mesh_tinygl.h"
+
+namespace Tetraedge {
+
+TeRendererTinyGL::TeRendererTinyGL() {
+}
+
+void TeRendererTinyGL::clearBuffer(TeRenderer::Buffer buf) {
+ TGLenum glBuf = 0;
+ if (buf & StencilBuffer)
+ glBuf |= TGL_STENCIL_BUFFER_BIT;
+ if (buf & DepthBuffer)
+ glBuf |= TGL_DEPTH_BUFFER_BIT;
+ if (buf & ColorBuffer)
+ glBuf |= TGL_COLOR_BUFFER_BIT;
+ tglClear(glBuf);
+}
+
+void TeRendererTinyGL::disableAllLights() {
+ TeLightTinyGL::disableAll();
+}
+
+void TeRendererTinyGL::disableTexture() {
+ tglDisable(TGL_TEXTURE_2D);
+ _textureEnabled = false;
+}
+
+void TeRendererTinyGL::disableWireFrame() {
+ tglPolygonMode(TGL_FRONT_AND_BACK, TGL_FILL);
+}
+
+void TeRendererTinyGL::disableZBuffer() {
+ tglDisable(TGL_DEPTH_TEST);
+ tglDepthMask(TGL_FALSE);
+}
+
+void TeRendererTinyGL::drawLine(const TeVector3f32 &from, const TeVector3f32 &to) {
+ error("TODO: Implement TeRenderer::drawLine");
+}
+
+void TeRendererTinyGL::enableAllLights() {
+ TeLightTinyGL::enableAll();
+}
+
+void TeRendererTinyGL::enableTexture() {
+ tglEnable(TGL_TEXTURE_2D);
+ _textureEnabled = true;
+}
+
+void TeRendererTinyGL::enableWireFrame() {
+ tglPolygonMode(TGL_FRONT_AND_BACK, TGL_LINE);
+}
+
+void TeRendererTinyGL::enableZBuffer() {
+ tglEnable(TGL_DEPTH_TEST);
+ tglDepthMask(TGL_TRUE);
+}
+
+void TeRendererTinyGL::init(uint width, uint height) {
+ Graphics::PixelFormat pixelFormat = g_system->getScreenFormat();
+ initGraphics(width, height, &pixelFormat);
+
+ debug(2, "INFO: TinyGL front buffer pixel format: %s", pixelFormat.toString().c_str());
+ TinyGL::createContext(width, height, pixelFormat, 256, true, ConfMan.getBool("dirtyrects"));
+
+ tglViewport(0, 0, width, height);
+
+ tglDisable(TGL_CULL_FACE);
+ TeLightTinyGL::disableAll();
+ tglDisable(TGL_COLOR_MATERIAL);
+ tglEnable(TGL_DEPTH_TEST);
+ tglDepthMask(TGL_TRUE);
+ tglShadeModel(TGL_SMOOTH);
+ tglEnable(TGL_BLEND);
+ tglBlendFunc(TGL_SRC_ALPHA, TGL_ONE_MINUS_SRC_ALPHA);
+ tglDepthFunc(TGL_LEQUAL);
+ tglHint(TGL_PERSPECTIVE_CORRECTION_HINT, TGL_DONT_CARE);
+ tglClearDepth(1.0);
+ tglClearStencil(0);
+ _clearColor = TeColor(0, 0, 0, 255);
+ tglClearColor(0, 0, 0, 1.0);
+ debug("[TeRenderer::init] Vendor : %s", vendor().c_str());
+ debug("[TeRenderer::init] Renderer : %s", renderer().c_str());
+ debug("[TeRenderer::init] Version : (tinygl version)");
+ debug("[TeRenderer::init] Sentil buffer bits : (not supported)");
+ debug("[TeRenderer::init] Depth buffer bits : (not supported)");
+ //debug("[TeRenderer::init] Extensions : %s", glGetString(TGL_EXTENSIONS));
+ //TeOpenGLExtensions::loadExtensions(); // this does nothing in the game?
+ _currentColor = TeColor(255, 255, 255, 255);
+ _scissorEnabled = false;
+ _scissorX = _scissorY = _scissorWidth = _scissorHeight = 0;
+}
+
+
+void TeRendererTinyGL::loadMatrixToGL(const TeMatrix4x4 &matrix) {
+ //int mmode;
+ //glGetIntegerv(TGL_MATRIX_MODE, &mmode);
+ //debug("loadMatrixToGL[0x%x]: %s", mmode, matrix.toString().c_str());
+ tglLoadMatrixf(matrix.getData());
+}
+
+void TeRendererTinyGL::loadProjectionMatrix(const TeMatrix4x4 &matrix) {
+ tglMatrixMode(TGL_PROJECTION);
+ _matrixMode = MM_GL_PROJECTION;
+ _matriciesStacks[_matrixMode].loadIdentity();
+ _matriciesStacks[_matrixMode].loadMatrix(matrix);
+ tglMatrixMode(TGL_MODELVIEW);
+ _matrixMode = MM_GL_MODELVIEW;
+ _matriciesStacks[_matrixMode].loadIdentity();
+}
+
+Common::String TeRendererTinyGL::renderer() {
+ return "TinyGL";
+}
+
+
+static bool compareTransparentMeshProperties(const TeRenderer::TransparentMeshProperties &p1,
+ const TeRenderer::TransparentMeshProperties &p2) {
+ return (p1._zOrder < p2._zOrder);
+}
+
+
+void TeRendererTinyGL::renderTransparentMeshes() {
+ if (!_numTransparentMeshes)
+ return;
+
+ tglDepthMask(TGL_FALSE);
+ //dumpTransparentMeshProps();
+
+ Common::sort(_transparentMeshProps.begin(), _transparentMeshProps.end(),
+ compareTransparentMeshProperties);
+
+ int vertsDrawn = 0;
+ for (uint i = 0; i < _transparentMeshProps.size(); i++) {
+ const uint vcount = _transparentMeshProps[i]._vertexCount;
+ for (uint j = 0; j < vcount; j++)
+ _transparentMeshVertexNums[vertsDrawn + j] = (short)(_transparentMeshProps[i]._sourceTransparentMesh + j);
+ vertsDrawn += vcount;
+ }
+
+ optimiseTransparentMeshProperties();
+
+ //dumpTransparentMeshProps();
+ //dumpTransparentMeshData();
+
+ tglEnableClientState(TGL_VERTEX_ARRAY);
+ tglEnableClientState(TGL_NORMAL_ARRAY);
+ tglEnableClientState(TGL_TEXTURE_COORD_ARRAY);
+ tglEnableClientState(TGL_COLOR_ARRAY);
+
+ tglVertexPointer(3, TGL_FLOAT, 12, _transparentMeshVertexes.data());
+ tglNormalPointer(TGL_FLOAT, 12, _transparentMeshNormals.data());
+ tglTexCoordPointer(2, TGL_FLOAT, 8, _transparentMeshCoords.data());
+ tglColorPointer(4, TGL_UNSIGNED_BYTE, 4, _transparentMeshColors.data());
+
+ TeMaterial lastMaterial;
+ TeMatrix4x4 lastMatrix;
+
+ vertsDrawn = 0;
+ for (uint i = 0; i < _transparentMeshProps.size(); i++) {
+ const TransparentMeshProperties &meshProperties = _transparentMeshProps[i];
+ if (!meshProperties._shouldDraw)
+ continue;
+
+ const TeMaterial &material = meshProperties._material;
+
+ meshProperties._camera->applyProjection();
+ tglMatrixMode(TGL_MODELVIEW);
+ _matrixMode = MM_GL_MODELVIEW;
+ tglPushMatrix();
+ _matriciesStacks[_matrixMode].pushMatrix();
+ _matriciesStacks[_matrixMode].loadMatrix(meshProperties._matrix);
+ tglPushMatrix();
+ loadCurrentMatrixToGL();
+ if (material._texture) {
+ tglEnable(TGL_TEXTURE_2D);
+ _textureEnabled = true;
+ }
+ if (material._enableSomethingDefault0) {
+ tglDisableClientState(TGL_TEXTURE_COORD_ARRAY);
+ tglDisableClientState(TGL_COLOR_ARRAY);
+ }
+
+ if (material != lastMaterial) {
+ applyMaterial(material);
+ lastMaterial = material;
+ }
+
+ if (meshProperties._scissorEnabled) {
+ tglEnable(TGL_SCISSOR_TEST);
+ // No scissoring in TGL..
+ /*
+ tglScissor(meshProperties._scissorX,
+ meshProperties._scissorY,
+ meshProperties._scissorWidth,
+ meshProperties._scissorHeight);*/
+ }
+ // TODO: not supported in TGL
+ //tglTexEnvi(TGL_TEXTURE_ENV, TGL_TEXTURE_ENV_MODE, meshProperties._glTexEnvMode);
+ tglDrawElements(TGL_TRIANGLES, meshProperties._vertexCount, TGL_UNSIGNED_SHORT,
+ _transparentMeshVertexNums.data() + vertsDrawn);
+
+ vertsDrawn += meshProperties._vertexCount;
+
+ if (material._enableSomethingDefault0) {
+ tglEnableClientState(TGL_TEXTURE_COORD_ARRAY);
+ tglEnableClientState(TGL_COLOR_ARRAY);
+ }
+ // TODO: not supported in TGL
+ //tglTexEnvi(TGL_TEXTURE_ENV, TGL_TEXTURE_ENV_MODE, TGL_MODULATE);
+ if (meshProperties._scissorEnabled) {
+ tglDisable(TGL_SCISSOR_TEST);
+ }
+ if (material._texture) {
+ tglDisable(TGL_TEXTURE_2D);
+ _textureEnabled = false;
+ }
+ tglPopMatrix();
+ tglPopMatrix();
+ _matriciesStacks[_matrixMode].popMatrix();
+ TeCamera::restore();
+ }
+ tglDisableClientState(TGL_VERTEX_ARRAY);
+ tglDisableClientState(TGL_NORMAL_ARRAY);
+ tglDisableClientState(TGL_COLOR_ARRAY);
+ tglDisableClientState(TGL_TEXTURE_COORD_ARRAY);
+ _numTransparentMeshes = 0;
+ _pendingTransparentMeshProperties = 0;
+ tglDepthMask(TGL_TRUE);
+ _transparentMeshProps.clear();
+}
+
+void TeRendererTinyGL::reset() {
+ clearBuffer(AllBuffers);
+ tglMatrixMode(TGL_PROJECTION);
+ _matrixMode = MM_GL_PROJECTION;
+ _matriciesStacks[MM_GL_PROJECTION].loadIdentity();
+ tglMatrixMode(TGL_MODELVIEW);
+ _matrixMode = MM_GL_MODELVIEW;
+ _matriciesStacks[MM_GL_MODELVIEW].loadIdentity();
+}
+
+void TeRendererTinyGL::setClearColor(const TeColor &col) {
+ _clearColor = col;
+ tglClearColor(col.r() / 255.0f, col.g() / 255.0f, col.b() / 255.0f, col.a() / 255.0f);
+}
+
+void TeRendererTinyGL::setCurrentColor(const TeColor &col) {
+ if (col == _currentColor)
+ return;
+
+ tglColor4ub(col.r(), col.g(), col.b(), col.a());
+ _currentColor = col;
+}
+
+void TeRendererTinyGL::setMatrixMode(enum MatrixMode mode) {
+ TGLenum glmode = 0;
+ if (mode == MM_GL_TEXTURE)
+ glmode = TGL_TEXTURE;
+ else if (mode == MM_GL_MODELVIEW)
+ glmode = TGL_MODELVIEW;
+ else if (mode == MM_GL_PROJECTION)
+ glmode = TGL_PROJECTION;
+
+ if (glmode)
+ tglMatrixMode(glmode);
+ _matrixMode = mode;
+}
+
+void TeRendererTinyGL::setViewport(int x, int y, int w, int h) {
+ tglViewport(x, y, w, h);
+}
+
+void TeRendererTinyGL::shadowMode(enum ShadowMode mode) {
+ _shadowMode = mode;
+ if (mode == ShadowMode0) {
+ tglDisable(TGL_CULL_FACE);
+ tglShadeModel(TGL_SMOOTH);
+ return;
+ }
+
+ if (mode == ShadowMode1) {
+ tglEnable(TGL_CULL_FACE);
+ tglCullFace(TGL_BACK);
+ } else { // ShadowMode2
+ tglDisable(TGL_CULL_FACE);
+ }
+ tglEnable(TGL_BLEND);
+ tglBlendFunc(TGL_SRC_ALPHA, TGL_ONE_MINUS_SRC_ALPHA);
+ tglShadeModel(TGL_FLAT);
+ TeLightTinyGL::disableAll();
+}
+
+void TeRendererTinyGL::applyMaterial(const TeMaterial &m) {
+ //debug("TeMaterial::apply (%s)", dump().c_str());
+ static const float constColor[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
+ if (_shadowMode == TeRenderer::ShadowMode0) {
+ if (m._enableLights)
+ TeLightTinyGL::enableAll();
+ else
+ TeLightTinyGL::disableAll();
+
+ if (m._texture) {
+ enableTexture();
+ tglEnableClientState(TGL_TEXTURE_COORD_ARRAY);
+ m._texture->bind();
+ }
+
+ tglDisable(TGL_ALPHA_TEST);
+ if (m._mode == TeMaterial::MaterialMode0) {
+ /* TODO: Find TGL equivalents for this stuff*/
+ /*
+ tglTexEnvfv(TGL_TEXTURE_ENV, TGL_TEXTURE_ENV_COLOR, constColor);
+ tglTexEnvi(TGL_TEXTURE_ENV, TGL_TEXTURE_ENV_MODE, TGL_COMBINE);
+ tglTexEnvi(TGL_TEXTURE_ENV, TGL_COMBINE_RGB, TGL_MODULATE);
+ tglTexEnvi(TGL_TEXTURE_ENV, TGL_SOURCE0_RGB, TGL_TEXTURE);
+ tglTexEnvi(TGL_TEXTURE_ENV, TGL_OPERAND0_RGB, TGL_SRC_COLOR);
+ tglTexEnvi(TGL_TEXTURE_ENV, TGL_COMBINE_ALPHA, TGL_REPLACE);
+ tglTexEnvi(TGL_TEXTURE_ENV, TGL_SOURCE0_ALPHA, TGL_CONSTANT);
+ tglTexEnvi(TGL_TEXTURE_ENV, TGL_OPERAND0_ALPHA, TGL_SRC_ALPHA);
+ */
+ } else {
+ // TODO: not supported in TGL
+ //tglTexEnvi(TGL_TEXTURE_ENV, TGL_TEXTURE_ENV_MODE, TGL_MODULATE);
+ if (m._mode != TeMaterial::MaterialMode1) {
+ tglEnable(TGL_ALPHA_TEST);
+ tglAlphaFunc(TGL_GREATER, 0.5);
+ }
+ }
+ const float ambient[4] = { m._ambientColor.r() / 255.0f, m._ambientColor.g() / 255.0f,
+ m._ambientColor.b() / 255.0f, m._ambientColor.a() / 255.0f };
+ tglMaterialfv(TGL_FRONT_AND_BACK, TGL_AMBIENT, ambient);
+
+ const float specular[4] = { m._specularColor.r() / 255.0f, m._specularColor.g() / 255.0f,
+ m._specularColor.b() / 255.0f, m._specularColor.a() / 255.0f };
+ tglMaterialfv(TGL_FRONT_AND_BACK, TGL_SPECULAR, specular);
+
+ const float emission[4] = { m._emissionColor.r() / 255.0f, m._emissionColor.g() / 255.0f,
+ m._emissionColor.b() / 255.0f, m._emissionColor.a() / 255.0f };
+ tglMaterialfv(TGL_FRONT_AND_BACK, TGL_EMISSION, emission);
+
+ tglMaterialf(TGL_FRONT, TGL_SHININESS, m._shininess);
+
+ const float diffuse[4] = { m._diffuseColor.r() / 255.0f, m._diffuseColor.g() / 255.0f,
+ m._diffuseColor.b() / 255.0f, m._diffuseColor.a() / 255.0f };
+ tglMaterialfv(TGL_FRONT_AND_BACK, TGL_DIFFUSE, diffuse);
+
+ setCurrentColor(m._diffuseColor);
+ } else if (_shadowMode == TeRenderer::ShadowMode1) {
+ // NOTE: Diverge from original here, it sets 255.0 but the
+ // colors should be scaled -1.0 .. 1.0.
+ static const float fullColor[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
+ TeLightTinyGL::disableAll();
+ tglDisable(TGL_ALPHA_TEST);
+ // TODO: not supported in TGL
+ //tglTexEnvi(TGL_TEXTURE_ENV, TGL_TEXTURE_ENV_MODE, TGL_MODULATE);
+ tglMaterialfv(TGL_FRONT_AND_BACK, TGL_AMBIENT, fullColor);
+ tglMaterialfv(TGL_FRONT_AND_BACK, TGL_DIFFUSE, fullColor);
+ tglMaterialfv(TGL_FRONT_AND_BACK, TGL_SPECULAR, fullColor);
+ tglMaterialfv(TGL_FRONT_AND_BACK, TGL_EMISSION, fullColor);
+ }
+
+ //warning("TODO: Work out what TeMaterial::_enableSomethingDefault0 actually is.");
+ if (!m._enableSomethingDefault0) {
+ tglDisable(TGL_TEXTURE_GEN_S);
+ tglDisable(TGL_TEXTURE_GEN_T);
+ tglDisable(TGL_TEXTURE_GEN_R);
+ tglDisable(TGL_TEXTURE_GEN_Q);
+ } else {
+ // TODO: not supported in TGL
+ //tglTexEnvi(TGL_TEXTURE_ENV, TGL_TEXTURE_ENV_MODE, TGL_MODULATE);
+ tglEnable(TGL_TEXTURE_GEN_S);
+ tglEnable(TGL_TEXTURE_GEN_T);
+ tglEnable(TGL_TEXTURE_GEN_R);
+ tglEnable(TGL_TEXTURE_GEN_Q);
+ tglEnable(TGL_TEXTURE_2D);
+ TeLightTinyGL::disableAll();
+ tglDisable(TGL_ALPHA_TEST);
+ enableTexture();
+ // TODO: not supported in TGL
+ //tglTexEnvi(TGL_TEXTURE_ENV, TGL_TEXTURE_ENV_MODE, TGL_MODULATE);
+
+ const float diffuse[4] = { m._diffuseColor.r() / 255.0f, m._diffuseColor.g() / 255.0f,
+ m._diffuseColor.b() / 255.0f, m._diffuseColor.a() / 255.0f };
+
+ tglMaterialfv(TGL_FRONT_AND_BACK, TGL_AMBIENT, diffuse);
+ tglMaterialfv(TGL_FRONT_AND_BACK, TGL_DIFFUSE, diffuse);
+ tglMaterialfv(TGL_FRONT_AND_BACK, TGL_SPECULAR, diffuse);
+ tglMaterialfv(TGL_FRONT_AND_BACK, TGL_EMISSION, diffuse);
+ }
+}
+
+
+Common::String TeRendererTinyGL::vendor() {
+ return "TinyGL vendor";
+}
+
+} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_renderer_tinygl.h b/engines/tetraedge/te/te_renderer_tinygl.h
new file mode 100644
index 00000000000..6599ff56a24
--- /dev/null
+++ b/engines/tetraedge/te/te_renderer_tinygl.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 TETRAEDGE_TE_TE_RENDERER_TINYGL_H
+#define TETRAEDGE_TE_TE_RENDERER_TINYGL_H
+
+#if defined(USE_TINYGL)
+
+#include "tetraedge/te/te_renderer.h"
+
+namespace Tetraedge {
+
+class TeRendererTinyGL : public TeRenderer {
+public:
+ TeRendererTinyGL();
+
+ void clearBuffer(TeRenderer::Buffer buf) override;
+ void disableAllLights() override;
+ void disableTexture() override;
+ void disableWireFrame() override;
+ void disableZBuffer() override;
+ void drawLine(const TeVector3f32 &from, const TeVector3f32 &to) override;
+ void enableAllLights() override;
+ void enableTexture() override;
+ void enableWireFrame() override;
+ void enableZBuffer() override;
+ void init(uint width, uint height) override;
+ void loadProjectionMatrix(const TeMatrix4x4 &matrix) override;
+ Common::String renderer() override;
+ void renderTransparentMeshes() override;
+ void reset() override;
+ void setClearColor(const TeColor &col) override;
+ void setCurrentColor(const TeColor &col) override;
+ void setMatrixMode(enum MatrixMode mode) override;
+ void setViewport(int x, int y, int w, int h) override;
+ void shadowMode(enum ShadowMode mode) override;
+ void applyMaterial(const TeMaterial &m) override;
+ Common::String vendor() override;
+
+protected:
+
+ void loadMatrixToGL(const TeMatrix4x4 &matrix) override;
+};
+
+} // end namespace Tetraedge
+
+#endif // USE_TINYGL
+
+#endif // TETRAEDGE_TE_TE_RENDERER_H
diff --git a/engines/tetraedge/te/te_resource_manager.h b/engines/tetraedge/te/te_resource_manager.h
index c06834cf012..b1abcd699ff 100644
--- a/engines/tetraedge/te/te_resource_manager.h
+++ b/engines/tetraedge/te/te_resource_manager.h
@@ -80,6 +80,26 @@ public:
return retval;
}
+ template<class T> TeIntrusivePtr<T> getResourceOrMakeInstance(Common::Path &path) {
+ for (TeIntrusivePtr<TeResource> &resource : this->_resources) {
+ if (resource->getAccessName() == path) {
+ return TeIntrusivePtr<T>(dynamic_cast<T *>(resource.get()));
+ }
+ }
+
+ TeIntrusivePtr<T> retval;
+ // Note: original search logic here abstracted away in our version..
+ TeCore *core = g_engine->getCore();
+ path = core->findFile(path);
+ retval = T::makeInstance();
+
+ if (retval.get()) {
+ retval->load(path);
+ addResource(retval.get());
+ }
+ return retval;
+ }
+
private:
Common::Array<TeIntrusivePtr<TeResource>> _resources;
diff --git a/engines/tetraedge/te/te_text_base2.cpp b/engines/tetraedge/te/te_text_base2.cpp
index 2f5f39e131a..5e1f56ff4c0 100644
--- a/engines/tetraedge/te/te_text_base2.cpp
+++ b/engines/tetraedge/te/te_text_base2.cpp
@@ -32,8 +32,13 @@ namespace Tetraedge {
TeTextBase2::TeTextBase2() : _drawRect(0, 0), _size(0, 0),
_alignStyle(TeFont3::AlignLeft), _interLine(0.0f), _globalColor(0xff, 0xff, 0xff, 0xff),
_wrapMode(WrapModeFixed), _strikethrough(false), _fontSize(10), _valueWasSet(true) {
- _mesh.setglTexEnvBlend();
- _mesh.setShouldDraw(true);
+ _mesh = TeMesh::makeInstance();
+ _mesh->setglTexEnvBlend();
+ _mesh->setShouldDraw(true);
+}
+
+TeTextBase2::~TeTextBase2() {
+ delete _mesh;
}
#ifdef DUMP_RENDERED_FONTS
@@ -99,7 +104,7 @@ void TeTextBase2::build() {
drawLine(img, _wrappedLines[i], lineoffsets[i]);
}
- TeIntrusivePtr<Te3DTexture> texture = new Te3DTexture();
+ TeIntrusivePtr<Te3DTexture> texture = Te3DTexture::makeInstance();
texture->load(img);
#if DUMP_RENDERED_FONTS
@@ -109,32 +114,32 @@ void TeTextBase2::build() {
Image::writePNG(dumpFile, img);
#endif
- _mesh.setConf(4, 4, TeMesh::MeshMode_TriangleStrip, 0, 0);
- _mesh.defaultMaterial(texture);
- _mesh.setglTexEnvBlend();
- _mesh.setShouldDraw(true);
- _mesh.setColor(_globalColor);
- _mesh.setVertex(0, TeVector3f32(_size._x * -0.5f, _size._y * -0.5f, 0.0f));
- _mesh.setTextureUV(0, TeVector2f32(0, 1));
- _mesh.setNormal(0, TeVector3f32(0.0f, 0.0f, 1.0f));
- _mesh.setColor(0, _globalColor);
- _mesh.setVertex(1, TeVector3f32(_size._x * 0.5f, _size._y * -0.5f, 0.0f));
- _mesh.setTextureUV(1, TeVector2f32(1, 1));
- _mesh.setNormal(1, TeVector3f32(0.0f, 0.0f, 1.0f));
- _mesh.setColor(1, _globalColor);
- _mesh.setVertex(2, TeVector3f32(_size._x * 0.5f, _size._y * 0.5f, 0.0f));
- _mesh.setTextureUV(2, TeVector2f32(1, 0));
- _mesh.setNormal(2, TeVector3f32(0.0f, 0.0f, 1.0f));
- _mesh.setColor(2, _globalColor);
- _mesh.setVertex(3, TeVector3f32(_size._x * -0.5f, _size._y * 0.5f, 0.0f));
- _mesh.setTextureUV(3, TeVector2f32(0, 0));
- _mesh.setNormal(3, TeVector3f32(0.0f, 0.0f, 1.0f));
- _mesh.setColor(3, _globalColor);
- _mesh.setIndex(0, 0);
- _mesh.setIndex(1, 1);
- _mesh.setIndex(2, 3);
- _mesh.setIndex(3, 2);
- _mesh.setHasAlpha(true);
+ _mesh->setConf(4, 4, TeMesh::MeshMode_TriangleStrip, 0, 0);
+ _mesh->defaultMaterial(texture);
+ _mesh->setglTexEnvBlend();
+ _mesh->setShouldDraw(true);
+ _mesh->setColor(_globalColor);
+ _mesh->setVertex(0, TeVector3f32(_size._x * -0.5f, _size._y * -0.5f, 0.0f));
+ _mesh->setTextureUV(0, TeVector2f32(0, 1));
+ _mesh->setNormal(0, TeVector3f32(0.0f, 0.0f, 1.0f));
+ _mesh->setColor(0, _globalColor);
+ _mesh->setVertex(1, TeVector3f32(_size._x * 0.5f, _size._y * -0.5f, 0.0f));
+ _mesh->setTextureUV(1, TeVector2f32(1, 1));
+ _mesh->setNormal(1, TeVector3f32(0.0f, 0.0f, 1.0f));
+ _mesh->setColor(1, _globalColor);
+ _mesh->setVertex(2, TeVector3f32(_size._x * 0.5f, _size._y * 0.5f, 0.0f));
+ _mesh->setTextureUV(2, TeVector2f32(1, 0));
+ _mesh->setNormal(2, TeVector3f32(0.0f, 0.0f, 1.0f));
+ _mesh->setColor(2, _globalColor);
+ _mesh->setVertex(3, TeVector3f32(_size._x * -0.5f, _size._y * 0.5f, 0.0f));
+ _mesh->setTextureUV(3, TeVector2f32(0, 0));
+ _mesh->setNormal(3, TeVector3f32(0.0f, 0.0f, 1.0f));
+ _mesh->setColor(3, _globalColor);
+ _mesh->setIndex(0, 0);
+ _mesh->setIndex(1, 1);
+ _mesh->setIndex(2, 3);
+ _mesh->setIndex(3, 2);
+ _mesh->setHasAlpha(true);
}
void TeTextBase2::clear() {
@@ -201,7 +206,7 @@ void TeTextBase2::draw() {
if (_valueWasSet)
build();
- _mesh.draw();
+ _mesh->draw();
//if (_strikethrough)
// warning("TODO: Implement TeTextBase2::draw strikethrough support");
diff --git a/engines/tetraedge/te/te_text_base2.h b/engines/tetraedge/te/te_text_base2.h
index b64f2fc757f..e862ff9e1f0 100644
--- a/engines/tetraedge/te/te_text_base2.h
+++ b/engines/tetraedge/te/te_text_base2.h
@@ -36,6 +36,7 @@ namespace Tetraedge {
class TeTextBase2 {
public:
TeTextBase2();
+ virtual ~TeTextBase2();
struct Line {
uint _startOffset;
@@ -94,7 +95,7 @@ private:
Common::String _text;
bool _strikethrough;
- TeMesh _mesh;
+ TeMesh *_mesh;
Common::Array<Common::String> _wrappedLines;
diff --git a/engines/tetraedge/te/te_tiled_surface.cpp b/engines/tetraedge/te/te_tiled_surface.cpp
index 9c9d19eb939..b9b9c7aba75 100644
--- a/engines/tetraedge/te/te_tiled_surface.cpp
+++ b/engines/tetraedge/te/te_tiled_surface.cpp
@@ -207,7 +207,9 @@ void TeTiledSurface::setColorKeyTolerence(float val) {
void TeTiledSurface::setTiledTexture(const TeIntrusivePtr<TeTiledTexture> &texture) {
_tiledTexture = texture;
if (texture) {
- _meshes.resize(texture->numberOfColumns() * texture->numberOfRow());
+ _meshes.clear();
+ for (uint i = 0; i < texture->numberOfColumns() * texture->numberOfRow(); i++)
+ _meshes.push_back(Common::SharedPtr<TeMesh>(TeMesh::makeInstance()));
setAccessName(texture->getAccessName().append(".surface"));
updateSurface();
@@ -242,7 +244,7 @@ void TeTiledSurface::updateSurface() {
int meshno = 0;
for (long row = 0; row < rows; row++) {
for (long col = 0; col < cols; col++) {
- TeMesh &mesh = _meshes[meshno];
+ TeMesh &mesh = *_meshes[meshno];
mesh.setConf(4, 4, TeMesh::MeshMode_TriangleStrip, 0, 0);
mesh.setShouldDraw(_shouldDraw);
diff --git a/engines/tetraedge/te/te_tiled_texture.cpp b/engines/tetraedge/te/te_tiled_texture.cpp
index 654225092e4..a6b9b233706 100644
--- a/engines/tetraedge/te/te_tiled_texture.cpp
+++ b/engines/tetraedge/te/te_tiled_texture.cpp
@@ -95,7 +95,7 @@ bool TeTiledTexture::load(const TeImage &img) {
Tile *tiledata = tile(TeVector2s32(row, col));
if (!_skipBlank || (int)tileimage->countPixelsOfColor(TeColor(0, 0, 0, 0)) != (tileimage->h * tileimage->w)) {
- tiledata->_texture = new Te3DTexture();
+ tiledata->_texture = Te3DTexture::makeInstance();
tiledata->_texture->load(*tileimage);
tiledata->_vec2 = TeVector3f32
((float)tiledata->_texture->width() / (float)_totalSize._x,
diff --git a/engines/tetraedge/te/te_visual_fade.cpp b/engines/tetraedge/te/te_visual_fade.cpp
index f63cc2167d7..1840c210bce 100644
--- a/engines/tetraedge/te/te_visual_fade.cpp
+++ b/engines/tetraedge/te/te_visual_fade.cpp
@@ -101,7 +101,7 @@ void TeVisualFade::init() {
if (_texturePtr) {
_texturePtr->destroy();
} else {
- _texturePtr = new Te3DTexture();
+ _texturePtr = Te3DTexture::makeInstance();
}
_texturePtr->create();
// create an image the size of the window, no palette, format 6.
diff --git a/engines/tetraedge/tetraedge.cpp b/engines/tetraedge/tetraedge.cpp
index 2c9c0302d99..7565ba429aa 100644
--- a/engines/tetraedge/tetraedge.cpp
+++ b/engines/tetraedge/tetraedge.cpp
@@ -190,13 +190,11 @@ bool TetraedgeEngine::onKeyUp(const Common::KeyState &state) {
}
Common::Error TetraedgeEngine::run() {
- initGraphics3d(getDefaultScreenWidth(), getDefaultScreenHeight());
-
configureSearchPaths();
// from BasicOpenGLView::prepareOpenGL..
_application = new Application();
- _renderer = new TeRenderer();
- _renderer->init();
+ _renderer = TeRenderer::makeInstance();
+ _renderer->init(getDefaultScreenWidth(), getDefaultScreenHeight());
_renderer->reset();
getInputMgr()->_keyUpSignal.add(this, &TetraedgeEngine::onKeyUp);
@@ -244,10 +242,39 @@ void TetraedgeEngine::openConfigDialog() {
syncSoundSettings();
}
+
+Graphics::RendererType TetraedgeEngine::preferredRendererType() const {
+ Common::String rendererConfig = ConfMan.get("renderer");
+ Graphics::RendererType desiredRendererType = Graphics::Renderer::parseTypeCode(rendererConfig);
+ uint32 availableRendererTypes = Graphics::Renderer::getAvailableTypes();
+
+ availableRendererTypes &=
+#if defined(USE_OPENGL_GAME)
+ Graphics::kRendererTypeOpenGL |
+#endif
+#if defined(USE_OPENGL_SHADERS)
+ Graphics::kRendererTypeOpenGLShaders |
+#endif
+#if defined(USE_TINYGL)
+ Graphics::kRendererTypeTinyGL |
+#endif
+ 0;
+
+ Graphics::RendererType matchingRendererType = Graphics::Renderer::getBestMatchingType(desiredRendererType, availableRendererTypes);
+ // Currently no difference between shaders and otherwise for this engine.
+ if (matchingRendererType == Graphics::kRendererTypeOpenGLShaders)
+ matchingRendererType = Graphics::kRendererTypeOpenGL;
+
+ if (matchingRendererType == 0) {
+ error("No supported renderer available.");
+ }
+
+ return matchingRendererType;
+}
+
/*static*/
void TetraedgeEngine::getSavegameThumbnail(Graphics::Surface &thumb) {
g_engine->getApplication()->getSavegameThumbnail(thumb);
}
-
} // namespace Tetraedge
diff --git a/engines/tetraedge/tetraedge.h b/engines/tetraedge/tetraedge.h
index 0ee0510fcac..e97739a411c 100644
--- a/engines/tetraedge/tetraedge.h
+++ b/engines/tetraedge/tetraedge.h
@@ -34,6 +34,7 @@
#include "engines/engine.h"
#include "engines/savestate.h"
#include "graphics/screen.h"
+#include "graphics/renderer.h"
#include "tetraedge/detection.h"
@@ -127,6 +128,10 @@ public:
bool onKeyUp(const Common::KeyState &state);
static Common::StringArray splitString(const Common::String &text, char c);
+
+ /* Pick the renderer type to use.
+ Currently will only return kRendererTypeOpenGL or kRendererTypeTinyGL */
+ Graphics::RendererType preferredRendererType() const;
private:
void configureSearchPaths();
Commit: fd496bdd55ea1c91b295aa40cb4bf29bef442b9b
https://github.com/scummvm/scummvm/commit/fd496bdd55ea1c91b295aa40cb4bf29bef442b9b
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2023-01-16T17:36:43+01:00
Commit Message:
TETRAEDGE: Remove unused variable
Changed paths:
engines/tetraedge/game/objectif.cpp
diff --git a/engines/tetraedge/game/objectif.cpp b/engines/tetraedge/game/objectif.cpp
index adf0bfb668c..213c8e8ca3f 100644
--- a/engines/tetraedge/game/objectif.cpp
+++ b/engines/tetraedge/game/objectif.cpp
@@ -80,7 +80,6 @@ void Objectif::load() {
}
void Objectif::leave() {
- Application *app = g_engine->getApplication();
TeLayout *layout;
layout = _gui1.layout("background");
if (layout)
Commit: 47739e458578d0a969902f706e7d8ad6f4d3f4b7
https://github.com/scummvm/scummvm/commit/47739e458578d0a969902f706e7d8ad6f4d3f4b7
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2023-01-16T17:36:43+01:00
Commit Message:
TETRAEDGE: Only compile openGL files when OGL is enabled
Changed paths:
engines/tetraedge/module.mk
diff --git a/engines/tetraedge/module.mk b/engines/tetraedge/module.mk
index 635dd0450d6..72a89086889 100644
--- a/engines/tetraedge/module.mk
+++ b/engines/tetraedge/module.mk
@@ -10,7 +10,6 @@ MODULE_OBJS := \
game/character.o \
game/character_settings_xml_parser.o \
game/characters_shadow.o \
- game/characters_shadow_opengl.o \
game/confirm.o \
game/credits.o \
game/dialog2.o \
@@ -43,7 +42,6 @@ MODULE_OBJS := \
te/micropather.o \
te/te_3d_object2.o \
te/te_3d_texture.o \
- te/te_3d_texture_opengl.o \
te/te_act_zone.o \
te/te_animation.o \
te/te_bezier_curve.o \
@@ -68,7 +66,6 @@ MODULE_OBJS := \
te/te_jpeg.o \
te/te_layout.o \
te/te_light.o \
- te/te_light_opengl.o \
te/te_list_layout.o \
te/te_lua_context.o \
te/te_lua_gui.o \
@@ -79,7 +76,6 @@ MODULE_OBJS := \
te/te_matricies_stack.o \
te/te_matrix4x4.o \
te/te_mesh.o \
- te/te_mesh_opengl.o \
te/te_model.o \
te/te_model_animation.o \
te/te_model_vertex_animation.o \
@@ -94,7 +90,6 @@ MODULE_OBJS := \
te/te_ray_intersection.o \
te/te_real_timer.o \
te/te_renderer.o \
- te/te_renderer_opengl.o \
te/te_resource.o \
te/te_resource_manager.o \
te/te_scene.o \
@@ -128,6 +123,14 @@ MODULE_OBJS += \
te/te_renderer_tinygl.o
endif
+ifdef USE_OPENGL
+MODULE_OBJS += \
+ game/characters_shadow_opengl.o \
+ te/te_3d_texture_opengl.o \
+ te/te_light_opengl.o \
+ te/te_mesh_opengl.o \
+ te/te_renderer_opengl.o
+endif
# This module can be built as a plugin
ifeq ($(ENABLE_TETRAEDGE), DYNAMIC_PLUGIN)
Commit: e6c805952377331b3d6d6e8764f9b8293da80c16
https://github.com/scummvm/scummvm/commit/e6c805952377331b3d6d6e8764f9b8293da80c16
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2023-01-16T17:36:43+01:00
Commit Message:
TETRAEDGE: Add TinyGL implementation for TeLight.
Changed paths:
engines/tetraedge/te/te_3d_texture.cpp
engines/tetraedge/te/te_light_tinygl.cpp
diff --git a/engines/tetraedge/te/te_3d_texture.cpp b/engines/tetraedge/te/te_3d_texture.cpp
index c3d25bcfb71..d2946022c4f 100644
--- a/engines/tetraedge/te/te_3d_texture.cpp
+++ b/engines/tetraedge/te/te_3d_texture.cpp
@@ -19,8 +19,6 @@
*
*/
-#include "graphics/opengl/system_headers.h"
-
#include "tetraedge/tetraedge.h"
#include "tetraedge/te/te_3d_texture.h"
#include "tetraedge/te/te_3d_texture_opengl.h"
diff --git a/engines/tetraedge/te/te_light_tinygl.cpp b/engines/tetraedge/te/te_light_tinygl.cpp
index af94d4c7c50..fddb0cb4783 100644
--- a/engines/tetraedge/te/te_light_tinygl.cpp
+++ b/engines/tetraedge/te/te_light_tinygl.cpp
@@ -21,41 +21,41 @@
#include "common/math.h"
+#include "graphics/tinygl/tinygl.h"
+
#include "tetraedge/te/te_light_tinygl.h"
#include "tetraedge/te/te_color.h"
#include "tetraedge/te/te_quaternion.h"
#include "tetraedge/te/te_vector3f32.h"
-#include "graphics/opengl/system_headers.h"
-
namespace Tetraedge {
static inline uint _toGlLight(uint lightno) {
- return GL_LIGHT0 + lightno;
+ return TGL_LIGHT0 + lightno;
}
TeLightTinyGL::TeLightTinyGL() {
}
void TeLightTinyGL::disable(uint lightno) {
- glDisable(_toGlLight(lightno));
+ tglDisable(_toGlLight(lightno));
}
void TeLightTinyGL::enable(uint lightno) {
if (_colDiffuse.r() == 0 && _colDiffuse.g() == 0 && _colDiffuse.b() == 0)
- glDisable(_toGlLight(lightno));
+ tglDisable(_toGlLight(lightno));
else
- glEnable(_toGlLight(lightno));
+ tglEnable(_toGlLight(lightno));
}
/*static*/
void TeLightTinyGL::disableAll() {
- glDisable(GL_LIGHTING);
+ tglDisable(TGL_LIGHTING);
}
/*static*/
void TeLightTinyGL::enableAll() {
- glEnable(GL_LIGHTING);
+ tglEnable(TGL_LIGHTING);
}
void TeLightTinyGL::draw(TeCamera &camera) {
@@ -63,35 +63,35 @@ void TeLightTinyGL::draw(TeCamera &camera) {
}
void TeLightTinyGL::update(uint lightno) {
- if (lightno > GL_MAX_LIGHTS)
+ if (lightno > TGL_MAX_LIGHTS)
error("Invalid light no %d", lightno);
const uint glLight = _toGlLight(lightno);
const float ambient[4] = {_colAmbient.r() / 255.0f, _colAmbient.g() / 255.0f,
_colAmbient.b() / 255.0f, 1.0};
- glLightfv(glLight, GL_AMBIENT, ambient);
+ tglLightfv(glLight, TGL_AMBIENT, ambient);
const float diff[4] = {_colDiffuse.r() / 255.0f, _colDiffuse.g() / 255.0f,
_colDiffuse.b() / 255.0f, 1.0};
- glLightfv(glLight, GL_DIFFUSE, diff);
+ tglLightfv(glLight, TGL_DIFFUSE, diff);
// WORKAROUND: Original game sets 0.01 as threshold here to avoid enabling
// the "shadow" light. However, Syberia CitStation/31130 has shadowlight with
// values (4, 0, 0) which means it gets enabled and everything is dark.
if (diff[0] < 0.02f && diff[1] < 0.02f && diff[2] < 0.02f)
- glDisable(glLight);
+ tglDisable(glLight);
const float spec[4] = {_colSpecular.r() / 255.0f, _colSpecular.g() / 255.0f,
_colSpecular.b() / 255.0f, 1.0};
- glLightfv(glLight, GL_SPECULAR, spec);
+ tglLightfv(glLight, TGL_SPECULAR, spec);
if (_type == LightTypeSpot || _type == LightTypePoint) {
const float pos[4] = {_position3d.x(), _position3d.y(), _position3d.z(), 1.0f};
- glLightfv(glLight, GL_POSITION, pos);
- glLightf(glLight, GL_CONSTANT_ATTENUATION, _constAtten);
- glLightf(glLight, GL_LINEAR_ATTENUATION, _linearAtten);
- glLightf(glLight, GL_QUADRATIC_ATTENUATION, _quadraticAtten);
+ tglLightfv(glLight, TGL_POSITION, pos);
+ tglLightf(glLight, TGL_CONSTANT_ATTENUATION, _constAtten);
+ tglLightf(glLight, TGL_LINEAR_ATTENUATION, _linearAtten);
+ tglLightf(glLight, TGL_QUADRATIC_ATTENUATION, _quadraticAtten);
}
if (_type == LightTypeDirectional) {
@@ -100,7 +100,7 @@ void TeLightTinyGL::update(uint lightno) {
float sinx = sinf(_positionRadial.getX());
float siny = sinf(_positionRadial.getY());
const float pos[4] = {cosx * cosy, siny, sinx * cosy, 0.0f};
- glLightfv(glLight, GL_POSITION, pos);
+ tglLightfv(glLight, TGL_POSITION, pos);
}
if (_type == LightTypeSpot) {
@@ -109,11 +109,11 @@ void TeLightTinyGL::update(uint lightno) {
float sinx = sinf(_positionRadial.getX());
float siny = sinf(_positionRadial.getY());
const float pos[4] = {cosx * cosy, siny, sinx * cosy, 0.0f};
- glLightfv(glLight, GL_SPOT_DIRECTION, pos);
- glLightf(glLight, GL_SPOT_CUTOFF, (_cutoff * 180.0) / M_PI);
- glLightf(glLight, GL_SPOT_EXPONENT, _exponent);
+ tglLightfv(glLight, TGL_SPOT_DIRECTION, pos);
+ tglLightf(glLight, TGL_SPOT_CUTOFF, (_cutoff * 180.0) / M_PI);
+ tglLightf(glLight, TGL_SPOT_EXPONENT, _exponent);
} else {
- glLightf(glLight, GL_SPOT_CUTOFF, 180.0);
+ tglLightf(glLight, TGL_SPOT_CUTOFF, 180.0);
}
}
@@ -121,7 +121,7 @@ void TeLightTinyGL::update(uint lightno) {
void TeLightTinyGL::updateGlobal() {
const float col[4] = {_globalAmbientColor.r() / 255.0f,
_globalAmbientColor.g() / 255.0f, _globalAmbientColor.b() / 255.0f, 1.0};
- glLightModelfv(GL_LIGHT_MODEL_AMBIENT, col);
+ tglLightModelfv(TGL_LIGHT_MODEL_AMBIENT, col);
}
} // end namespace Tetraedge
Commit: 8dfe5e4b887cd137501b04d21207e69a9892ba05
https://github.com/scummvm/scummvm/commit/8dfe5e4b887cd137501b04d21207e69a9892ba05
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2023-01-16T17:36:43+01:00
Commit Message:
TETRAEDGE: Clean up OGL/TGL classes slightly
Changed paths:
engines/tetraedge/te/te_3d_texture_opengl.cpp
engines/tetraedge/te/te_3d_texture_tinygl.cpp
engines/tetraedge/te/te_mesh_opengl.cpp
engines/tetraedge/te/te_mesh_tinygl.cpp
engines/tetraedge/te/te_renderer.cpp
engines/tetraedge/te/te_renderer_opengl.cpp
engines/tetraedge/te/te_renderer_tinygl.cpp
diff --git a/engines/tetraedge/te/te_3d_texture_opengl.cpp b/engines/tetraedge/te/te_3d_texture_opengl.cpp
index 492c16320a0..2d0f42bc848 100644
--- a/engines/tetraedge/te/te_3d_texture_opengl.cpp
+++ b/engines/tetraedge/te/te_3d_texture_opengl.cpp
@@ -101,12 +101,8 @@ void Te3DTextureOpenGL::destroy() {
}
void Te3DTextureOpenGL::forceTexData(uint gltexture, uint xsize, uint ysize) {
- if (_glTexture != 0xffffffff) {
- if (_createdTexture)
- glDeleteTextures(1, &_glTexture);
- _createdTexture = false;
- _loaded = false;
- }
+ if (_glTexture != 0xffffffff)
+ destroy();
_glTexture = gltexture;
_width = xsize;
_height = ysize;
@@ -144,17 +140,9 @@ bool Te3DTextureOpenGL::load(const TeImage &img) {
const void *imgdata = img.getPixels();
if (_format == TeImage::RGB8) {
- /*GLenum glpxformat = GL_RGB;
- if (_glPixelFormat != GL_INVALID_ENUM) {
- glpxformat = _glPixelFormat;
- }*/
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, _texWidth, _texHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, img.pitch / 3, img.h, GL_RGB, GL_UNSIGNED_BYTE, imgdata);
} else if (_format == TeImage::RGBA8) {
- /*GLenum glpxformat = GL_RGBA8;
- if (_glPixelFormat != GL_INVALID_ENUM) {
- glpxformat = _glPixelFormat;
- }*/
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, _texWidth, _texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, img.w, img.h, GL_RGBA, GL_UNSIGNED_BYTE, imgdata);
} else {
diff --git a/engines/tetraedge/te/te_3d_texture_tinygl.cpp b/engines/tetraedge/te/te_3d_texture_tinygl.cpp
index ab7292c46a5..f4e98a8c496 100644
--- a/engines/tetraedge/te/te_3d_texture_tinygl.cpp
+++ b/engines/tetraedge/te/te_3d_texture_tinygl.cpp
@@ -103,12 +103,8 @@ void Te3DTextureTinyGL::destroy() {
}
void Te3DTextureTinyGL::forceTexData(uint gltexture, uint xsize, uint ysize) {
- if (_glTexture != 0xffffffff) {
- if (_createdTexture)
- tglDeleteTextures(1, &_glTexture);
- _createdTexture = false;
- _loaded = false;
- }
+ if (_glTexture != 0xffffffff)
+ destroy();
_glTexture = gltexture;
_width = xsize;
_height = ysize;
@@ -145,16 +141,8 @@ bool Te3DTextureTinyGL::load(const TeImage &img) {
const void *imgdata = img.getPixels();
if (_format == TeImage::RGB8) {
- /*GLenum glpxformat = GL_RGB;
- if (_glPixelFormat != GL_INVALID_ENUM) {
- glpxformat = _glPixelFormat;
- }*/
tglTexImage2D(TGL_TEXTURE_2D, 0, TGL_RGBA, img.pitch / 3, img.h, 0, TGL_RGB, TGL_UNSIGNED_BYTE, imgdata);
} else if (_format == TeImage::RGBA8) {
- /*GLenum glpxformat = GL_RGBA8;
- if (_glPixelFormat != GL_INVALID_ENUM) {
- glpxformat = _glPixelFormat;
- }*/
tglTexImage2D(TGL_TEXTURE_2D, 0, TGL_RGBA, img.w, img.h, 0, TGL_RGBA, TGL_UNSIGNED_BYTE, imgdata);
} else {
warning("Te3DTexture::load can't send image format %d to GL.", _format);
diff --git a/engines/tetraedge/te/te_mesh_opengl.cpp b/engines/tetraedge/te/te_mesh_opengl.cpp
index 86ebdaeada5..97925714e77 100644
--- a/engines/tetraedge/te/te_mesh_opengl.cpp
+++ b/engines/tetraedge/te/te_mesh_opengl.cpp
@@ -56,8 +56,6 @@ void TeMeshOpenGL::draw() {
debug(" worldRot %s", worldRotation().dump().c_str());
*/
- Common::Array<TeVector3f32> &normals = (_updatedVerticies.empty() ? _normals : _updatedNormals);
- Common::Array<TeVector3f32> &verticies = (_updatedVerticies.empty() ? _verticies : _updatedVerticies);
if (renderer->shadowMode() != TeRenderer::ShadowMode1) {
if (_faceCounts.empty()) {
if (hasAlpha(0) && _shouldDraw) {
@@ -82,6 +80,9 @@ void TeMeshOpenGL::draw() {
renderer->setMatrixMode(TeRenderer::MM_GL_MODELVIEW);
renderer->pushMatrix();
renderer->loadCurrentMatrixToGL();
+
+ const Common::Array<TeVector3f32> &normals = (_updatedVerticies.empty() ? _normals : _updatedNormals);
+ const Common::Array<TeVector3f32> &verticies = (_updatedVerticies.empty() ? _verticies : _updatedVerticies);
glEnableClientState(GL_VERTEX_ARRAY);
if (!normals.empty())
glEnableClientState(GL_NORMAL_ARRAY);
diff --git a/engines/tetraedge/te/te_mesh_tinygl.cpp b/engines/tetraedge/te/te_mesh_tinygl.cpp
index 8863f5e5dc4..acedd32db39 100644
--- a/engines/tetraedge/te/te_mesh_tinygl.cpp
+++ b/engines/tetraedge/te/te_mesh_tinygl.cpp
@@ -55,8 +55,6 @@ void TeMeshTinyGL::draw() {
debug(" worldRot %s", worldRotation().dump().c_str());
*/
- Common::Array<TeVector3f32> &normals = (_updatedVerticies.empty() ? _normals : _updatedNormals);
- Common::Array<TeVector3f32> &verticies = (_updatedVerticies.empty() ? _verticies : _updatedVerticies);
if (renderer->shadowMode() != TeRenderer::ShadowMode1) {
if (_faceCounts.empty()) {
if (hasAlpha(0) && _shouldDraw) {
@@ -78,6 +76,9 @@ void TeMeshTinyGL::draw() {
}
}
+ const Common::Array<TeVector3f32> &normals = (_updatedVerticies.empty() ? _normals : _updatedNormals);
+ const Common::Array<TeVector3f32> &verticies = (_updatedVerticies.empty() ? _verticies : _updatedVerticies);
+
renderer->setMatrixMode(TeRenderer::MM_GL_MODELVIEW);
renderer->pushMatrix();
renderer->loadCurrentMatrixToGL();
diff --git a/engines/tetraedge/te/te_renderer.cpp b/engines/tetraedge/te/te_renderer.cpp
index 900164b320b..875de0ff9f3 100644
--- a/engines/tetraedge/te/te_renderer.cpp
+++ b/engines/tetraedge/te/te_renderer.cpp
@@ -226,10 +226,31 @@ void TeRenderer::multiplyMatrix(const TeMatrix4x4 &matrix) {
_matriciesStacks[_matrixMode].multiplyMatrix(matrix);
}
+
+static bool compareTransparentMeshProperties(const TeRenderer::TransparentMeshProperties &p1,
+ const TeRenderer::TransparentMeshProperties &p2) {
+ return (p1._zOrder < p2._zOrder);
+}
+
void TeRenderer::optimiseTransparentMeshProperties() {
if (_transparentMeshProps.size() <= 1)
return;
+ // Note: this first bit of logic is in renderTransparentMeshes in the
+ // original game, but was moved here to split out OGL-specific code.
+ //dumpTransparentMeshProps();
+
+ Common::sort(_transparentMeshProps.begin(), _transparentMeshProps.end(),
+ compareTransparentMeshProperties);
+
+ int vertTotal = 0;
+ for (uint i = 0; i < _transparentMeshProps.size(); i++) {
+ const uint vcount = _transparentMeshProps[i]._vertexCount;
+ for (uint j = 0; j < vcount; j++)
+ _transparentMeshVertexNums[vertTotal + j] = (short)(_transparentMeshProps[i]._sourceTransparentMesh + j);
+ vertTotal += vcount;
+ }
+
uint i = 0;
for (uint other = 1; other < _transparentMeshProps.size(); other++) {
uint nextI = other;
@@ -249,6 +270,9 @@ void TeRenderer::optimiseTransparentMeshProperties() {
}
i = nextI;
}
+
+ //dumpTransparentMeshProps();
+ //dumpTransparentMeshData();
}
void TeRenderer::popMatrix() {
diff --git a/engines/tetraedge/te/te_renderer_opengl.cpp b/engines/tetraedge/te/te_renderer_opengl.cpp
index abbf81550ae..83a12262aec 100644
--- a/engines/tetraedge/te/te_renderer_opengl.cpp
+++ b/engines/tetraedge/te/te_renderer_opengl.cpp
@@ -28,7 +28,6 @@
#include "tetraedge/te/te_renderer.h"
#include "tetraedge/te/te_renderer_opengl.h"
-#include "tetraedge/te/te_light.h"
#include "tetraedge/te/te_light_opengl.h"
#include "tetraedge/te/te_mesh_opengl.h"
@@ -141,34 +140,16 @@ Common::String TeRendererOpenGL::renderer() {
}
-static bool compareTransparentMeshProperties(const TeRenderer::TransparentMeshProperties &p1,
- const TeRenderer::TransparentMeshProperties &p2) {
- return (p1._zOrder < p2._zOrder);
-}
-
void TeRendererOpenGL::renderTransparentMeshes() {
if (!_numTransparentMeshes)
return;
glDepthMask(GL_FALSE);
- //dumpTransparentMeshProps();
-
- Common::sort(_transparentMeshProps.begin(), _transparentMeshProps.end(),
- compareTransparentMeshProperties);
-
- int vertsDrawn = 0;
- for (uint i = 0; i < _transparentMeshProps.size(); i++) {
- const uint vcount = _transparentMeshProps[i]._vertexCount;
- for (uint j = 0; j < vcount; j++)
- _transparentMeshVertexNums[vertsDrawn + j] = (short)(_transparentMeshProps[i]._sourceTransparentMesh + j);
- vertsDrawn += vcount;
- }
+ // Note: some code moved to optimiseTransparentMeshProperties to minimise
+ // non-OGL-speicifc code.
optimiseTransparentMeshProperties();
- //dumpTransparentMeshProps();
- //dumpTransparentMeshData();
-
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
@@ -182,7 +163,7 @@ void TeRendererOpenGL::renderTransparentMeshes() {
TeMaterial lastMaterial;
TeMatrix4x4 lastMatrix;
- vertsDrawn = 0;
+ int vertsDrawn = 0;
for (uint i = 0; i < _transparentMeshProps.size(); i++) {
const TransparentMeshProperties &meshProperties = _transparentMeshProps[i];
if (!meshProperties._shouldDraw)
@@ -377,7 +358,7 @@ void TeRendererOpenGL::applyMaterial(const TeMaterial &m) {
glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, fullColor);
}
- //warning("TODO: Work out what TeMaterial::_enableSomethingDefault0 actually is.");
+ // TODO: Work out what TeMaterial::_enableSomethingDefault0 actually is.
if (!m._enableSomethingDefault0) {
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
diff --git a/engines/tetraedge/te/te_renderer_tinygl.cpp b/engines/tetraedge/te/te_renderer_tinygl.cpp
index a8eba20af17..c5810e55443 100644
--- a/engines/tetraedge/te/te_renderer_tinygl.cpp
+++ b/engines/tetraedge/te/te_renderer_tinygl.cpp
@@ -158,24 +158,11 @@ void TeRendererTinyGL::renderTransparentMeshes() {
return;
tglDepthMask(TGL_FALSE);
- //dumpTransparentMeshProps();
-
- Common::sort(_transparentMeshProps.begin(), _transparentMeshProps.end(),
- compareTransparentMeshProperties);
-
- int vertsDrawn = 0;
- for (uint i = 0; i < _transparentMeshProps.size(); i++) {
- const uint vcount = _transparentMeshProps[i]._vertexCount;
- for (uint j = 0; j < vcount; j++)
- _transparentMeshVertexNums[vertsDrawn + j] = (short)(_transparentMeshProps[i]._sourceTransparentMesh + j);
- vertsDrawn += vcount;
- }
+ // Note: some code moved to optimiseTransparentMeshProperties to minimise
+ // non-OGL-speicifc code.
optimiseTransparentMeshProperties();
- //dumpTransparentMeshProps();
- //dumpTransparentMeshData();
-
tglEnableClientState(TGL_VERTEX_ARRAY);
tglEnableClientState(TGL_NORMAL_ARRAY);
tglEnableClientState(TGL_TEXTURE_COORD_ARRAY);
@@ -189,7 +176,7 @@ void TeRendererTinyGL::renderTransparentMeshes() {
TeMaterial lastMaterial;
TeMatrix4x4 lastMatrix;
- vertsDrawn = 0;
+ int vertsDrawn = 0;
for (uint i = 0; i < _transparentMeshProps.size(); i++) {
const TransparentMeshProperties &meshProperties = _transparentMeshProps[i];
if (!meshProperties._shouldDraw)
Commit: 91f1e17ed3ea94351852c6a9299723726801e57f
https://github.com/scummvm/scummvm/commit/91f1e17ed3ea94351852c6a9299723726801e57f
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2023-01-16T17:36:43+01:00
Commit Message:
TETRAEDGE: Fixes to get to main menu of Syberia 2
Changed paths:
engines/tetraedge/detection_tables.h
engines/tetraedge/game/application.cpp
engines/tetraedge/game/confirm.cpp
engines/tetraedge/te/te_core.cpp
diff --git a/engines/tetraedge/detection_tables.h b/engines/tetraedge/detection_tables.h
index f141b5c3510..685464a620c 100644
--- a/engines/tetraedge/detection_tables.h
+++ b/engines/tetraedge/detection_tables.h
@@ -35,7 +35,18 @@ const ADGameDescription GAME_DESCRIPTIONS[] = {
{
"syberia",
nullptr,
- AD_ENTRY1s("MacOS/Syberia", "6951fb8f71fe06f34684564625f73cd8", 10640592),
+ AD_ENTRY1s("MacOS/Syberia", "d:6951fb8f71fe06f34684564625f73cd8", 10640592),
+ Common::EN_ANY,
+ Common::kPlatformMacintosh,
+ ADGF_UNSTABLE,
+ GUIO1(GUIO_NONE)
+ },
+
+ // GOG release
+ {
+ "syberia2",
+ nullptr,
+ AD_ENTRY1s("MacOS/Syberia 2", "d:c447586a3cb3d46d6127b467e7fb9a86", 12021136),
Common::EN_ANY,
Common::kPlatformMacintosh,
ADGF_UNSTABLE,
diff --git a/engines/tetraedge/game/application.cpp b/engines/tetraedge/game/application.cpp
index f89442e05eb..b063e135ea3 100644
--- a/engines/tetraedge/game/application.cpp
+++ b/engines/tetraedge/game/application.cpp
@@ -144,7 +144,7 @@ void Application::create() {
int i = 0;
Common::Path textFilePath;
while (i < ARRAYSIZE(allLangs)) {
- textFilePath = textsPath.join(core->language() + ".xml");
+ textFilePath = core->findFile(textsPath.join(core->language() + ".xml"));
if (Common::File::exists(textFilePath))
break;
core->language(allLangs[i]);
diff --git a/engines/tetraedge/game/confirm.cpp b/engines/tetraedge/game/confirm.cpp
index ff1bbdf6da4..399d349b336 100644
--- a/engines/tetraedge/game/confirm.cpp
+++ b/engines/tetraedge/game/confirm.cpp
@@ -34,7 +34,12 @@ Confirm::Confirm() {
void Confirm::enter(const Common::String &guiPath, const Common::String &y) {
_gui.load(guiPath);
- TeLayout *backgroundLayout = _gui.layoutChecked("background");
+ TeLayout *backgroundLayout = _gui.layout("background");
+ if (!backgroundLayout) {
+ warning("confirm script not loaded, default to Yes.");
+ onButtonYes();
+ return;
+ }
backgroundLayout->setRatioMode(TeILayout::RATIO_MODE_NONE);
Application *app = g_engine->getApplication();
diff --git a/engines/tetraedge/te/te_core.cpp b/engines/tetraedge/te/te_core.cpp
index 73960d82ca2..9f6059fa01a 100644
--- a/engines/tetraedge/te/te_core.cpp
+++ b/engines/tetraedge/te/te_core.cpp
@@ -129,9 +129,13 @@ Common::Path TeCore::findFile(const Common::Path &path) {
nullptr, // no suffix
"PC-MacOSX",
"PC-PS3-Android-MacOSX",
+ "PC-MacOSX-Android-iPhone-iPad",
"PC-MacOSX-Xbox360-PS3",
"PC-MacOSX-PS3-Xbox360",
"PC-MacOSX-Xbox360-PS3/PC-MacOSX",
+ "PC-MacOSX-MacOSXAppStore-Android-iPhone-iPad",
+ "PC-MacOSX-MacOSXAppStore-Xbox360-Android-iPad-iPhone",
+ "Android-iPhone-iPad-PC-MacOSX",
"Full",
"Part1-Full",
"Part2-Full-Part1",
Commit: b310f5dea3931549f2054e6c1660c41ac4b534e9
https://github.com/scummvm/scummvm/commit/b310f5dea3931549f2054e6c1660c41ac4b534e9
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2023-01-16T17:36:43+01:00
Commit Message:
TETRAEDGE: Fix compiler guards for GL (no shaders)
Changed paths:
engines/tetraedge/game/characters_shadow.cpp
engines/tetraedge/game/characters_shadow_opengl.h
engines/tetraedge/te/te_3d_texture.cpp
engines/tetraedge/te/te_3d_texture_opengl.h
engines/tetraedge/te/te_light.cpp
engines/tetraedge/te/te_light_opengl.h
engines/tetraedge/te/te_mesh.cpp
engines/tetraedge/te/te_mesh_opengl.h
engines/tetraedge/te/te_renderer.cpp
engines/tetraedge/te/te_renderer_opengl.h
diff --git a/engines/tetraedge/game/characters_shadow.cpp b/engines/tetraedge/game/characters_shadow.cpp
index 09fc4c55537..c982e3cb4e0 100644
--- a/engines/tetraedge/game/characters_shadow.cpp
+++ b/engines/tetraedge/game/characters_shadow.cpp
@@ -87,7 +87,7 @@ void CharactersShadow::destroy() {
CharactersShadow *CharactersShadow::makeInstance() {
Graphics::RendererType r = g_engine->preferredRendererType();
-#if defined(USE_OPENGL_GAME) || defined(USE_OPENGL_SHADERS)
+#if defined(USE_OPENGL_GAME)
if (r == Graphics::kRendererTypeOpenGL)
return new CharactersShadowOpenGL();
#endif
diff --git a/engines/tetraedge/game/characters_shadow_opengl.h b/engines/tetraedge/game/characters_shadow_opengl.h
index 84d7178c0f5..fb57e8fcbc0 100644
--- a/engines/tetraedge/game/characters_shadow_opengl.h
+++ b/engines/tetraedge/game/characters_shadow_opengl.h
@@ -22,7 +22,7 @@
#ifndef TETRAEDGE_GAME_CHARACTERS_SHADOW_OPENGL_H
#define TETRAEDGE_GAME_CHARACTERS_SHADOW_OPENGL_H
-#if defined(USE_OPENGL_GAME) || defined(USE_OPENGL_SHADERS)
+#if defined(USE_OPENGL_GAME)
#include "tetraedge/game/characters_shadow.h"
diff --git a/engines/tetraedge/te/te_3d_texture.cpp b/engines/tetraedge/te/te_3d_texture.cpp
index d2946022c4f..d033dd2526b 100644
--- a/engines/tetraedge/te/te_3d_texture.cpp
+++ b/engines/tetraedge/te/te_3d_texture.cpp
@@ -106,7 +106,7 @@ TeVector2s32 Te3DTexture::optimisedSize(const TeVector2s32 &size) {
Te3DTexture *Te3DTexture::makeInstance() {
Graphics::RendererType r = g_engine->preferredRendererType();
-#if defined(USE_OPENGL_GAME) || defined(USE_OPENGL_SHADERS)
+#if defined(USE_OPENGL_GAME)
if (r == Graphics::kRendererTypeOpenGL)
return new Te3DTextureOpenGL();
#endif
diff --git a/engines/tetraedge/te/te_3d_texture_opengl.h b/engines/tetraedge/te/te_3d_texture_opengl.h
index ad2a0801f75..be1d24b4d03 100644
--- a/engines/tetraedge/te/te_3d_texture_opengl.h
+++ b/engines/tetraedge/te/te_3d_texture_opengl.h
@@ -22,7 +22,7 @@
#ifndef TETRAEDGE_TE_TE_3D_TEXTURE_OPENGL_H
#define TETRAEDGE_TE_TE_3D_TEXTURE_OPENGL_H
-#if defined(USE_OPENGL_GAME) || defined(USE_OPENGL_SHADERS)
+#if defined(USE_OPENGL_GAME)
#include "tetraedge/te/te_3d_texture.h"
diff --git a/engines/tetraedge/te/te_light.cpp b/engines/tetraedge/te/te_light.cpp
index b1c4bdedaac..afde1e45cf7 100644
--- a/engines/tetraedge/te/te_light.cpp
+++ b/engines/tetraedge/te/te_light.cpp
@@ -98,7 +98,7 @@ Common::String TeLight::dump() const {
TeLight *TeLight::makeInstance() {
Graphics::RendererType r = g_engine->preferredRendererType();
-#if defined(USE_OPENGL_GAME) || defined(USE_OPENGL_SHADERS)
+#if defined(USE_OPENGL_GAME)
if (r == Graphics::kRendererTypeOpenGL)
return new TeLightOpenGL();
#endif
diff --git a/engines/tetraedge/te/te_light_opengl.h b/engines/tetraedge/te/te_light_opengl.h
index 561d86cc4d8..1cd4085ec64 100644
--- a/engines/tetraedge/te/te_light_opengl.h
+++ b/engines/tetraedge/te/te_light_opengl.h
@@ -22,7 +22,7 @@
#ifndef TETRAEDGE_TE_TE_LIGHT_OPENGL_H
#define TETRAEDGE_TE_TE_LIGHT_OPENGL_H
-#if defined(USE_OPENGL_GAME) || defined(USE_OPENGL_SHADERS)
+#if defined(USE_OPENGL_GAME)
#include "tetraedge/te/te_light.h"
diff --git a/engines/tetraedge/te/te_mesh.cpp b/engines/tetraedge/te/te_mesh.cpp
index 30dbe00ecc2..106e7617342 100644
--- a/engines/tetraedge/te/te_mesh.cpp
+++ b/engines/tetraedge/te/te_mesh.cpp
@@ -226,7 +226,7 @@ void TeMesh::updateTo(const Common::Array<TeMatrix4x4> *matricies1, const Common
TeMesh *TeMesh::makeInstance() {
Graphics::RendererType r = g_engine->preferredRendererType();
-#if defined(USE_OPENGL_GAME) || defined(USE_OPENGL_SHADERS)
+#if defined(USE_OPENGL_GAME)
if (r == Graphics::kRendererTypeOpenGL)
return new TeMeshOpenGL();
#endif
diff --git a/engines/tetraedge/te/te_mesh_opengl.h b/engines/tetraedge/te/te_mesh_opengl.h
index 9e1b6fad2d9..e8ea7d85140 100644
--- a/engines/tetraedge/te/te_mesh_opengl.h
+++ b/engines/tetraedge/te/te_mesh_opengl.h
@@ -22,7 +22,7 @@
#ifndef TETRAEDGE_TE_TE_MESH_OPENGL_H
#define TETRAEDGE_TE_TE_MESH_OPENGL_H
-#if defined(USE_OPENGL_GAME) || defined(USE_OPENGL_SHADERS)
+#if defined(USE_OPENGL_GAME)
#include "tetraedge/te/te_mesh.h"
diff --git a/engines/tetraedge/te/te_renderer.cpp b/engines/tetraedge/te/te_renderer.cpp
index 875de0ff9f3..153bf7a650c 100644
--- a/engines/tetraedge/te/te_renderer.cpp
+++ b/engines/tetraedge/te/te_renderer.cpp
@@ -339,7 +339,7 @@ void TeRenderer::translate(float x, float y, float z) {
TeRenderer *TeRenderer::makeInstance() {
Graphics::RendererType r = g_engine->preferredRendererType();
-#if defined(USE_OPENGL_GAME) || defined(USE_OPENGL_SHADERS)
+#if defined(USE_OPENGL_GAME)
if (r == Graphics::kRendererTypeOpenGL)
return new TeRendererOpenGL();
#endif
diff --git a/engines/tetraedge/te/te_renderer_opengl.h b/engines/tetraedge/te/te_renderer_opengl.h
index c6d7f76ab5e..a04f383c05a 100644
--- a/engines/tetraedge/te/te_renderer_opengl.h
+++ b/engines/tetraedge/te/te_renderer_opengl.h
@@ -22,7 +22,7 @@
#ifndef TETRAEDGE_TE_TE_RENDERER_OPENGL_H
#define TETRAEDGE_TE_TE_RENDERER_OPENGL_H
-#if defined(USE_OPENGL_GAME) || defined(USE_OPENGL_SHADERS)
+#if defined(USE_OPENGL_GAME)
#include "tetraedge/te/te_renderer.h"
Commit: dbe6da9980dd2e836bc656e721c65138fdc39fd7
https://github.com/scummvm/scummvm/commit/dbe6da9980dd2e836bc656e721c65138fdc39fd7
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2023-01-16T17:36:43+01:00
Commit Message:
TETRAEDGE: Remove compile warnings
Changed paths:
engines/tetraedge/game/document.cpp
engines/tetraedge/game/document.h
engines/tetraedge/game/game.cpp
engines/tetraedge/game/how_to.h
engines/tetraedge/te/te_3d_texture_tinygl.cpp
engines/tetraedge/te/te_camera.cpp
engines/tetraedge/te/te_camera.h
engines/tetraedge/te/te_color.cpp
engines/tetraedge/te/te_color.h
engines/tetraedge/te/te_font3.cpp
engines/tetraedge/te/te_image.cpp
engines/tetraedge/te/te_image.h
engines/tetraedge/te/te_light.cpp
engines/tetraedge/te/te_light.h
engines/tetraedge/te/te_light_opengl.cpp
engines/tetraedge/te/te_light_tinygl.cpp
engines/tetraedge/te/te_object.cpp
engines/tetraedge/te/te_renderer_tinygl.cpp
engines/tetraedge/te/te_sprite_layout.h
engines/tetraedge/te/te_text_base2.cpp
engines/tetraedge/te/te_tiled_surface.cpp
engines/tetraedge/te/te_tiled_texture.cpp
engines/tetraedge/te/te_visual_fade.cpp
diff --git a/engines/tetraedge/game/document.cpp b/engines/tetraedge/game/document.cpp
index e31e7b29a44..75bf42ff255 100644
--- a/engines/tetraedge/game/document.cpp
+++ b/engines/tetraedge/game/document.cpp
@@ -23,7 +23,7 @@
namespace Tetraedge {
-Document::Document(DocumentsBrowser *browser) : _browser(browser) {
+Document::Document(DocumentsBrowser *browser) /*: _browser(browser)*/ {
}
diff --git a/engines/tetraedge/game/document.h b/engines/tetraedge/game/document.h
index 307e1f4f882..60771eb3156 100644
--- a/engines/tetraedge/game/document.h
+++ b/engines/tetraedge/game/document.h
@@ -53,7 +53,7 @@ public:
void unload();
private:
- DocumentsBrowser *_browser;
+ //DocumentsBrowser *_browser;
TeLuaGUI _gui;
TeSignal1Param<Document &> _onButtonDownSignal;
};
diff --git a/engines/tetraedge/game/game.cpp b/engines/tetraedge/game/game.cpp
index ae01a2294ef..f6fbdc39958 100644
--- a/engines/tetraedge/game/game.cpp
+++ b/engines/tetraedge/game/game.cpp
@@ -1123,6 +1123,7 @@ bool Game::onMouseClick(const Common::Point &pt) {
return false;
}
+#if ENABLE_CUSTOM_CURSOR_CHECKS
// Note: None of these cursor files seem to be actually shipped with the game
// but the logic is reproduced here just in case there's some different
// version that uses them.
@@ -1144,6 +1145,7 @@ static const char cursorsTable[][2][80] = {
{"Type04", "pictures/Type04.png"},
{"Type05", "pictures/Type05.png"}
};
+#endif
bool Game::onMouseMove() {
if (!_entered)
diff --git a/engines/tetraedge/game/how_to.h b/engines/tetraedge/game/how_to.h
index d4ce9211887..79a252f704b 100644
--- a/engines/tetraedge/game/how_to.h
+++ b/engines/tetraedge/game/how_to.h
@@ -39,7 +39,7 @@ private:
bool updateDisplay(uint oldval, uint newval);
bool _entered;
- uint _val;
+ //uint _val;
};
} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_3d_texture_tinygl.cpp b/engines/tetraedge/te/te_3d_texture_tinygl.cpp
index f4e98a8c496..4b00e9f5b29 100644
--- a/engines/tetraedge/te/te_3d_texture_tinygl.cpp
+++ b/engines/tetraedge/te/te_3d_texture_tinygl.cpp
@@ -192,7 +192,7 @@ void Te3DTextureTinyGL::update(const TeImage &img, uint xoff, uint yoff) {
tglPixelStorei(TGL_UNPACK_SKIP_PIXELS, 0);
tglPixelStorei(TGL_UNPACK_ALIGNMENT, 1);
- const void *imgdata = img.getPixels();
+ //const void *imgdata = img.getPixels();
if (_format == TeImage::RGB8) {
//TODO: Come up with equivalent for TGL.
//tglTexSubImage2D(TGL_TEXTURE_2D, 0, xoff, yoff, img.w, img.h, TGL_RGB, TGL_UNSIGNED_BYTE, imgdata);
diff --git a/engines/tetraedge/te/te_camera.cpp b/engines/tetraedge/te/te_camera.cpp
index 3183ab78b5e..4065f354ca9 100644
--- a/engines/tetraedge/te/te_camera.cpp
+++ b/engines/tetraedge/te/te_camera.cpp
@@ -31,7 +31,7 @@ namespace Tetraedge {
TeCamera::TeCamera() : _projectionMatrixType(0), _orthogonalParamL(0.0f),
_orthogonalParamR(1.0f), _orthogonalParamT(1.0f), _orthogonalParamB(0.0f),
- _orthNearVal(10.0f), _orthFarVal(4000.0f), _transformA(0), _transformB(0),
+ _orthNearVal(10.0f), _orthFarVal(4000.0f), _transformA(0), /*_transformB(0),*/
_fov(40.0f), _somePerspectiveVal(1.0f)
{
}
diff --git a/engines/tetraedge/te/te_camera.h b/engines/tetraedge/te/te_camera.h
index 1afc99d426c..39c337ca908 100644
--- a/engines/tetraedge/te/te_camera.h
+++ b/engines/tetraedge/te/te_camera.h
@@ -96,7 +96,7 @@ private:
uint _viewportH;
int _transformA;
- int _transformB;
+ //int _transformB; // never used?
float _orthogonalParamL;
float _orthogonalParamR;
diff --git a/engines/tetraedge/te/te_color.cpp b/engines/tetraedge/te/te_color.cpp
index ee57a87ab90..0714779a7b4 100644
--- a/engines/tetraedge/te/te_color.cpp
+++ b/engines/tetraedge/te/te_color.cpp
@@ -43,10 +43,14 @@ TeColor::TeColor(uint16 shortcol) {
TeColor::TeColor(byte r, byte g, byte b, byte a) : _c{r, g, b, a} {
}
-uint32 TeColor::getPacked() {
+uint32 TeColor::getPacked() const {
return (g() & 0xf8) << 2 | (r() & 0xf8) << 7 | (b() >> 3);
}
+uint32 TeColor::getPacked32() const {
+ return (r() << 24) | (g() << 16) | (b() << 8) | a();
+}
+
bool TeColor::serialize(Common::WriteStream &stream) const {
for (int i = 0; i < 4; i++)
stream.writeByte(_c[i]);
diff --git a/engines/tetraedge/te/te_color.h b/engines/tetraedge/te/te_color.h
index 99704bca302..537a75d8f1a 100644
--- a/engines/tetraedge/te/te_color.h
+++ b/engines/tetraedge/te/te_color.h
@@ -44,7 +44,8 @@ public:
const byte &b() const { return _c[2]; };
const byte &a() const { return _c[3]; };
- uint32 getPacked();
+ uint32 getPacked() const;
+ uint32 getPacked32() const;
bool serialize(Common::WriteStream &stream) const;
bool deserialize(Common::ReadStream &stream);
diff --git a/engines/tetraedge/te/te_font3.cpp b/engines/tetraedge/te/te_font3.cpp
index 18c03a031cc..5a697c0cb04 100644
--- a/engines/tetraedge/te/te_font3.cpp
+++ b/engines/tetraedge/te/te_font3.cpp
@@ -99,7 +99,7 @@ TeFont3::GlyphData TeFont3::glyph(uint pxSize, uint charcode) {
Common::Rect bbox = font->getBoundingBox(charcode);
TeImage *img = new TeImage();
Common::SharedPtr<TePalette> nullpal;
- img->create(bbox.width(), bbox.height(), nullpal, TeImage::RGBA8);
+ img->createImg(bbox.width(), bbox.height(), nullpal, TeImage::RGBA8);
font->drawChar(img, charcode, 0, 0, 0xffffffff);
GlyphData retval;
retval._charcode = charcode;
diff --git a/engines/tetraedge/te/te_image.cpp b/engines/tetraedge/te/te_image.cpp
index 01d5a638eaf..72cba1e30ff 100644
--- a/engines/tetraedge/te/te_image.cpp
+++ b/engines/tetraedge/te/te_image.cpp
@@ -43,12 +43,13 @@ unsigned long TeImage::countPixelsOfColor(const TeColor &col) const {
error("TODO: Implement TeImage::countPixelsOfColor");
}
+/*
void TeImage::create() {
// Never used, but in original seems to do the same as destroy??
destroy();
-}
+}*/
-void TeImage::create(uint xsize, uint ysize, Common::SharedPtr<TePalette> &pal,
+void TeImage::createImg(uint xsize, uint ysize, Common::SharedPtr<TePalette> &pal,
Format teformat, uint bufxsize, uint bufysize) {
_teFormat = teformat;
Graphics::PixelFormat pxformat = ((teformat == TeImage::RGB8) ?
@@ -99,7 +100,7 @@ bool TeImage::load(const Common::Path &path) {
}
Common::SharedPtr<TePalette> nullpal;
- create(codec->width(), codec->height(), nullpal, codec->imageFormat(), codec->width(), codec->height());
+ createImg(codec->width(), codec->height(), nullpal, codec->imageFormat(), codec->width(), codec->height());
if (!codec->update(0, *this)) {
error("TeImage::load: Failed to update from %s.", path.toString().c_str());
diff --git a/engines/tetraedge/te/te_image.h b/engines/tetraedge/te/te_image.h
index e363ef3d574..c0ec7d241fa 100644
--- a/engines/tetraedge/te/te_image.h
+++ b/engines/tetraedge/te/te_image.h
@@ -57,11 +57,11 @@ public:
void copy(TeImage &dest, const TeVector2s32 &vec1, const TeVector2s32 &vec2,
const TeVector2s32 &vec3) const;
unsigned long countPixelsOfColor(const TeColor &col) const;
- void create();
- void create(uint xsize, uint ysize, Common::SharedPtr<TePalette> &palette, Format newformat) {
- create(xsize, ysize, palette, newformat, xsize, ysize);
+ //void create(); // never used?
+ void createImg(uint xsize, uint ysize, Common::SharedPtr<TePalette> &palette, Format newformat) {
+ createImg(xsize, ysize, palette, newformat, xsize, ysize);
}
- void create(uint xsize, uint ysize, Common::SharedPtr<TePalette> &pal,
+ void createImg(uint xsize, uint ysize, Common::SharedPtr<TePalette> &pal,
Format format, uint bufxsize, uint bufysize);
void deserialize(Common::ReadStream &stream);
void destroy();
diff --git a/engines/tetraedge/te/te_light.cpp b/engines/tetraedge/te/te_light.cpp
index afde1e45cf7..2f648b547de 100644
--- a/engines/tetraedge/te/te_light.cpp
+++ b/engines/tetraedge/te/te_light.cpp
@@ -34,7 +34,7 @@
namespace Tetraedge {
/*static*/
-TeColor TeLight::_globalAmbientColor;
+uint32 TeLight::_globalAmbientColor;
TeLight::TeLight() : _colAmbient(0, 0, 0, 0xff), _colDiffuse(0, 0, 0, 0xff), _colSpecular(0xff, 0xff, 0xff, 0xff),
_constAtten(1.0f), _linearAtten(0.0f), _quadraticAtten(0.0f), _cutoff(0.0f), _exponent(0.0f), _type(LightTypePoint),
diff --git a/engines/tetraedge/te/te_light.h b/engines/tetraedge/te/te_light.h
index e4223ebc82c..919b5ed4ad4 100644
--- a/engines/tetraedge/te/te_light.h
+++ b/engines/tetraedge/te/te_light.h
@@ -52,8 +52,8 @@ public:
virtual void update(uint lightno) = 0;
static void updateGlobal();
- static void setGlobalAmbient(const TeColor &col) { _globalAmbientColor = col; }
- static const TeColor &globalAmbient() { return _globalAmbientColor; }
+ static void setGlobalAmbient(const TeColor &col) { _globalAmbientColor = col.getPacked32(); }
+ static TeColor globalAmbient() { return TeColor(_globalAmbientColor); }
void setSpecular(const TeColor &col) { _colSpecular = col; }
void setDiffuse(const TeColor &col) { _colDiffuse = col; }
@@ -86,7 +86,7 @@ protected:
enum TeLightType _type;
- static TeColor _globalAmbientColor;
+ static uint32 _globalAmbientColor;
float _constAtten;
float _linearAtten;
diff --git a/engines/tetraedge/te/te_light_opengl.cpp b/engines/tetraedge/te/te_light_opengl.cpp
index c0021afb485..2ea36871092 100644
--- a/engines/tetraedge/te/te_light_opengl.cpp
+++ b/engines/tetraedge/te/te_light_opengl.cpp
@@ -119,8 +119,9 @@ void TeLightOpenGL::update(uint lightno) {
/*static*/
void TeLightOpenGL::updateGlobal() {
- const float col[4] = {_globalAmbientColor.r() / 255.0f,
- _globalAmbientColor.g() / 255.0f, _globalAmbientColor.b() / 255.0f, 1.0};
+ const TeColor globalAmbient(_globalAmbientColor);
+ const float col[4] = {globalAmbient.r() / 255.0f,
+ globalAmbient.g() / 255.0f, globalAmbient.b() / 255.0f, 1.0};
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, col);
}
diff --git a/engines/tetraedge/te/te_light_tinygl.cpp b/engines/tetraedge/te/te_light_tinygl.cpp
index fddb0cb4783..64ebaafcb2f 100644
--- a/engines/tetraedge/te/te_light_tinygl.cpp
+++ b/engines/tetraedge/te/te_light_tinygl.cpp
@@ -119,8 +119,9 @@ void TeLightTinyGL::update(uint lightno) {
/*static*/
void TeLightTinyGL::updateGlobal() {
- const float col[4] = {_globalAmbientColor.r() / 255.0f,
- _globalAmbientColor.g() / 255.0f, _globalAmbientColor.b() / 255.0f, 1.0};
+ const TeColor globalAmbient(_globalAmbientColor);
+ const float col[4] = {globalAmbient.r() / 255.0f,
+ globalAmbient.g() / 255.0f, globalAmbient.b() / 255.0f, 1.0};
tglLightModelfv(TGL_LIGHT_MODEL_AMBIENT, col);
}
diff --git a/engines/tetraedge/te/te_object.cpp b/engines/tetraedge/te/te_object.cpp
index ac63db8e899..da5e228719c 100644
--- a/engines/tetraedge/te/te_object.cpp
+++ b/engines/tetraedge/te/te_object.cpp
@@ -56,7 +56,7 @@ void TeObject::cleanup() {
if (_pendingDeleteList && _pendingDeleteList->size()) {
warning("Leaking %d objects on shutdown.", _pendingDeleteList->size());
for (auto *obj : (*_pendingDeleteList)) {
- debug("Leaked %p", obj);
+ debug("Leaked %p", (void *)obj);
}
}
delete _pendingDeleteList;
diff --git a/engines/tetraedge/te/te_renderer_tinygl.cpp b/engines/tetraedge/te/te_renderer_tinygl.cpp
index c5810e55443..6a40e503057 100644
--- a/engines/tetraedge/te/te_renderer_tinygl.cpp
+++ b/engines/tetraedge/te/te_renderer_tinygl.cpp
@@ -147,12 +147,6 @@ Common::String TeRendererTinyGL::renderer() {
}
-static bool compareTransparentMeshProperties(const TeRenderer::TransparentMeshProperties &p1,
- const TeRenderer::TransparentMeshProperties &p2) {
- return (p1._zOrder < p2._zOrder);
-}
-
-
void TeRendererTinyGL::renderTransparentMeshes() {
if (!_numTransparentMeshes)
return;
@@ -313,7 +307,7 @@ void TeRendererTinyGL::shadowMode(enum ShadowMode mode) {
void TeRendererTinyGL::applyMaterial(const TeMaterial &m) {
//debug("TeMaterial::apply (%s)", dump().c_str());
- static const float constColor[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
+ //static const float constColor[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
if (_shadowMode == TeRenderer::ShadowMode0) {
if (m._enableLights)
TeLightTinyGL::enableAll();
diff --git a/engines/tetraedge/te/te_sprite_layout.h b/engines/tetraedge/te/te_sprite_layout.h
index 4784cabb8e2..1f2058b804f 100644
--- a/engines/tetraedge/te/te_sprite_layout.h
+++ b/engines/tetraedge/te/te_sprite_layout.h
@@ -64,7 +64,7 @@ public:
private:
bool _sizeSet;
- bool _allowFloatTranslate;
+ //bool _allowFloatTranslate;
};
diff --git a/engines/tetraedge/te/te_text_base2.cpp b/engines/tetraedge/te/te_text_base2.cpp
index 5e1f56ff4c0..c87b7808c5a 100644
--- a/engines/tetraedge/te/te_text_base2.cpp
+++ b/engines/tetraedge/te/te_text_base2.cpp
@@ -97,7 +97,7 @@ void TeTextBase2::build() {
TeImage img;
Common::SharedPtr<TePalette> nullpal;
- img.create(_size._x, _size._y, nullpal, TeImage::RGBA8);
+ img.createImg(_size._x, _size._y, nullpal, TeImage::RGBA8);
img.fill(_globalColor.r(), _globalColor.g(), _globalColor.b(), 0);
for (uint i = 0; i < _wrappedLines.size(); i++) {
diff --git a/engines/tetraedge/te/te_tiled_surface.cpp b/engines/tetraedge/te/te_tiled_surface.cpp
index b9b9c7aba75..ae07f11a0f7 100644
--- a/engines/tetraedge/te/te_tiled_surface.cpp
+++ b/engines/tetraedge/te/te_tiled_surface.cpp
@@ -103,7 +103,7 @@ bool TeTiledSurface::load(const Common::Path &path) {
}
Common::SharedPtr<TePalette> nullpal;
- img.create(_codec->width(), _codec->height(), nullpal, _imgFormat, bufx, bufy);
+ img.createImg(_codec->width(), _codec->height(), nullpal, _imgFormat, bufx, bufy);
if (_codec->update(0, img)) {
#if DUMP_LOADED_IMAGES
@@ -168,7 +168,7 @@ bool TeTiledSurface::onFrameAnimCurrentFrameChanged() {
int bufxsize = MIN(vidSize._x + 4, optimisedSize._x);
Common::SharedPtr<TePalette> nullPal;
- img.create(vidSize._x, vidSize._y, nullPal, _imgFormat, bufxsize, bufysize);
+ img.createImg(vidSize._x, vidSize._y, nullPal, _imgFormat, bufxsize, bufysize);
if (_codec->update(_frameAnim.lastFrameShown(), img))
update(img);
return _codec->isAtEnd();
diff --git a/engines/tetraedge/te/te_tiled_texture.cpp b/engines/tetraedge/te/te_tiled_texture.cpp
index a6b9b233706..2c4de242da9 100644
--- a/engines/tetraedge/te/te_tiled_texture.cpp
+++ b/engines/tetraedge/te/te_tiled_texture.cpp
@@ -152,7 +152,7 @@ TeImage *TeTiledTexture::optimisedTileImage(Common::Array<TeImage> &images, cons
images.resize(images.size() + 1);
TeImage &newImg = images.back();
Common::SharedPtr<TePalette> nullPal;
- newImg.create((uint)size._x, (uint)size._y, nullPal, format);
+ newImg.createImg((uint)size._x, (uint)size._y, nullPal, format);
return &newImg;
}
diff --git a/engines/tetraedge/te/te_visual_fade.cpp b/engines/tetraedge/te/te_visual_fade.cpp
index 1840c210bce..3eaf7f30dc2 100644
--- a/engines/tetraedge/te/te_visual_fade.cpp
+++ b/engines/tetraedge/te/te_visual_fade.cpp
@@ -108,7 +108,7 @@ void TeVisualFade::init() {
Common::SharedPtr<TePalette> nullpal;
_image.destroy();
// TODO: should this get actual window size instead of default?
- _image.create(g_engine->getDefaultScreenWidth(),
+ _image.createImg(g_engine->getDefaultScreenWidth(),
g_engine->getDefaultScreenHeight(), nullpal, TeImage::RGBA8);
_texturePtr->load(_image);
g_engine->getRenderer()->enableTexture();
Commit: 8591ae2260ec6c6a202a6d6893a1ebde0164c011
https://github.com/scummvm/scummvm/commit/8591ae2260ec6c6a202a6d6893a1ebde0164c011
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2023-01-16T17:36:43+01:00
Commit Message:
TETRAEDGE: Fix updating of global light value
Changed paths:
engines/tetraedge/game/in_game_scene.cpp
engines/tetraedge/te/te_light.cpp
engines/tetraedge/te/te_light.h
engines/tetraedge/te/te_renderer.h
engines/tetraedge/te/te_renderer_opengl.cpp
engines/tetraedge/te/te_renderer_opengl.h
engines/tetraedge/te/te_renderer_tinygl.cpp
engines/tetraedge/te/te_renderer_tinygl.h
diff --git a/engines/tetraedge/game/in_game_scene.cpp b/engines/tetraedge/game/in_game_scene.cpp
index 0e1416d0f44..d3e4ccc0128 100644
--- a/engines/tetraedge/game/in_game_scene.cpp
+++ b/engines/tetraedge/game/in_game_scene.cpp
@@ -367,7 +367,7 @@ void InGameScene::draw() {
}
#endif
- TeLight::updateGlobal();
+ g_engine->getRenderer()->updateGlobalLight();
for (uint i = 0; i < _lights.size(); i++)
_lights[i]->update(i);
diff --git a/engines/tetraedge/te/te_light.cpp b/engines/tetraedge/te/te_light.cpp
index 2f648b547de..fc47f6b319a 100644
--- a/engines/tetraedge/te/te_light.cpp
+++ b/engines/tetraedge/te/te_light.cpp
@@ -66,11 +66,6 @@ void TeLight::transformSpotPoint(TeVector3f32 &pt) {
pt += _position3d;
}
-/*static*/
-void TeLight::updateGlobal() {
- // TOOD: Call correct global.
-}
-
Common::String TeLight::dump() const {
const char *ltype;
switch (_type) {
diff --git a/engines/tetraedge/te/te_light.h b/engines/tetraedge/te/te_light.h
index 919b5ed4ad4..64b75f5c31c 100644
--- a/engines/tetraedge/te/te_light.h
+++ b/engines/tetraedge/te/te_light.h
@@ -51,7 +51,6 @@ public:
void transformSpotPoint(TeVector3f32 &pt1);
virtual void update(uint lightno) = 0;
- static void updateGlobal();
static void setGlobalAmbient(const TeColor &col) { _globalAmbientColor = col.getPacked32(); }
static TeColor globalAmbient() { return TeColor(_globalAmbientColor); }
diff --git a/engines/tetraedge/te/te_renderer.h b/engines/tetraedge/te/te_renderer.h
index c50ecb7ac95..3f7c964adee 100644
--- a/engines/tetraedge/te/te_renderer.h
+++ b/engines/tetraedge/te/te_renderer.h
@@ -131,6 +131,7 @@ public:
void dumpTransparentMeshData() const;
const TeColor ¤tColor() const { return _currentColor; }
+ virtual void updateGlobalLight() = 0;
virtual void applyMaterial(const TeMaterial &m) = 0;
static TeRenderer *makeInstance();
diff --git a/engines/tetraedge/te/te_renderer_opengl.cpp b/engines/tetraedge/te/te_renderer_opengl.cpp
index 83a12262aec..4aeaf16632e 100644
--- a/engines/tetraedge/te/te_renderer_opengl.cpp
+++ b/engines/tetraedge/te/te_renderer_opengl.cpp
@@ -386,6 +386,10 @@ void TeRendererOpenGL::applyMaterial(const TeMaterial &m) {
}
}
+void TeRendererOpenGL::updateGlobalLight() {
+ TeLightOpenGL::updateGlobal();
+}
+
Common::String TeRendererOpenGL::vendor() {
return Common::String((const char *)glGetString(GL_VENDOR));
}
diff --git a/engines/tetraedge/te/te_renderer_opengl.h b/engines/tetraedge/te/te_renderer_opengl.h
index a04f383c05a..7bdd43ab1c2 100644
--- a/engines/tetraedge/te/te_renderer_opengl.h
+++ b/engines/tetraedge/te/te_renderer_opengl.h
@@ -53,6 +53,7 @@ public:
void shadowMode(enum ShadowMode mode) override;
Common::String vendor() override;
void applyMaterial(const TeMaterial &m) override;
+ void updateGlobalLight() override;
protected:
diff --git a/engines/tetraedge/te/te_renderer_tinygl.cpp b/engines/tetraedge/te/te_renderer_tinygl.cpp
index 6a40e503057..9654f530c3b 100644
--- a/engines/tetraedge/te/te_renderer_tinygl.cpp
+++ b/engines/tetraedge/te/te_renderer_tinygl.cpp
@@ -404,6 +404,9 @@ void TeRendererTinyGL::applyMaterial(const TeMaterial &m) {
}
}
+void TeRendererTinyGL::updateGlobalLight() {
+ TeLightTinyGL::updateGlobal();
+}
Common::String TeRendererTinyGL::vendor() {
return "TinyGL vendor";
diff --git a/engines/tetraedge/te/te_renderer_tinygl.h b/engines/tetraedge/te/te_renderer_tinygl.h
index 6599ff56a24..60db224e5b0 100644
--- a/engines/tetraedge/te/te_renderer_tinygl.h
+++ b/engines/tetraedge/te/te_renderer_tinygl.h
@@ -53,6 +53,7 @@ public:
void setViewport(int x, int y, int w, int h) override;
void shadowMode(enum ShadowMode mode) override;
void applyMaterial(const TeMaterial &m) override;
+ void updateGlobalLight() override;
Common::String vendor() override;
protected:
More information about the Scummvm-git-logs
mailing list