[Scummvm-git-logs] scummvm master -> 60fd2c4ed3ac00c138940ccb6dac26cb86964668
mduggan
noreply at scummvm.org
Sat Feb 11 09:09:00 UTC 2023
This automated email contains information about 5 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
b181fb344e TETRAEDGE: Implement more functions for Syberia 2
c0ae694d0f TETRAEDGE: Add xml parsing features for Syberia 2
8688b32625 TETRAEDGE: Implement a few more lua callbacks for Syberia 2
543657e1a0 TETRAEDGE: Revert color scaling hack now TGL is fixed
60fd2c4ed3 TETRAEDGE: Many fixes for Syberia 2 scene loading
Commit: b181fb344ef663daeb77b82434585f0843371b0f
https://github.com/scummvm/scummvm/commit/b181fb344ef663daeb77b82434585f0843371b0f
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2023-02-11T18:08:28+09:00
Commit Message:
TETRAEDGE: Implement more functions for Syberia 2
Changed paths:
engines/tetraedge/game/documents_browser.cpp
engines/tetraedge/game/documents_browser.h
engines/tetraedge/game/in_game_scene.cpp
engines/tetraedge/game/lua_binds.cpp
engines/tetraedge/game/object3d.h
diff --git a/engines/tetraedge/game/documents_browser.cpp b/engines/tetraedge/game/documents_browser.cpp
index dea5f663947..f4d2a9bef77 100644
--- a/engines/tetraedge/game/documents_browser.cpp
+++ b/engines/tetraedge/game/documents_browser.cpp
@@ -165,6 +165,18 @@ bool DocumentsBrowser::onZoomedButton() {
return false;
}
+int DocumentsBrowser::addDocument(Document *document) {
+ error("TODO: Implement DocumentsBrowser::addDocument");
+}
+
+void DocumentsBrowser::addDocument(const Common::String &str) {
+ Document *doc = new Document(this);
+ doc->load(str);
+ if (!addDocument(doc))
+ delete doc;
+}
+
+
void DocumentsBrowser::showDocument(const Common::String &docName, int startPage) {
_curPage = startPage;
_startPage = startPage;
diff --git a/engines/tetraedge/game/documents_browser.h b/engines/tetraedge/game/documents_browser.h
index f438fd17afb..eadf96b0a8c 100644
--- a/engines/tetraedge/game/documents_browser.h
+++ b/engines/tetraedge/game/documents_browser.h
@@ -32,7 +32,7 @@ class DocumentsBrowser : public TeLayout {
public:
DocumentsBrowser();
- void addDocument(Document *document);
+ int addDocument(Document *document);
void addDocument(const Common::String &str);
void currentPage(int page);
diff --git a/engines/tetraedge/game/in_game_scene.cpp b/engines/tetraedge/game/in_game_scene.cpp
index f86627a3069..5b48c25092c 100644
--- a/engines/tetraedge/game/in_game_scene.cpp
+++ b/engines/tetraedge/game/in_game_scene.cpp
@@ -1182,13 +1182,14 @@ void InGameScene::update() {
obj->model()->setPosition(trans);
}
if (obj->_rotateTime >= 0) {
- // Never actually used in the game.
- error("TODO: handle _rotateTime > 0 in InGameScene::update");
+ float time = MIN((float)(obj->_rotateTimer.getTimeFromStart() / 1000000.0), obj->_rotateTime);
+ TeVector3f32 rot = (obj->_rotateAmount * (time / obj->_rotateTime));
+ TeQuaternion rotq = TeQuaternion::fromEuler(rot);
+ obj->model()->setRotation(obj->_rotateStart * rotq);
}
}
}
-
bool InGameScene::AnimObject::onFinished() {
Game *game = g_engine->getGame();
for (uint i = 0; i < game->yieldedCallbacks().size(); i++) {
diff --git a/engines/tetraedge/game/lua_binds.cpp b/engines/tetraedge/game/lua_binds.cpp
index e73ba461535..bb13f8e7017 100644
--- a/engines/tetraedge/game/lua_binds.cpp
+++ b/engines/tetraedge/game/lua_binds.cpp
@@ -206,6 +206,24 @@ static int tolua_ExportedFunctions_TakeObject00(lua_State *L) {
error("#ferror in function 'TakeObject': %d %d %s", err.index, err.array, err.type);
}
+static void TakeObjectInHand(const Common::String &obj) {
+ Game *game = g_engine->getGame();
+ // TODO: Set global _lastHitObjectName?? How is it used?
+ //game->luaContext().setGlobal(_lastHitObjectName, true);
+ if (!obj.empty())
+ game->addToHand(obj);
+}
+
+static int tolua_ExportedFunctions_TakeObjectInHand00(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));
+ TakeObjectInHand(s1);
+ return 0;
+ }
+ error("#ferror in function 'TakeObjectInHand': %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);
@@ -267,6 +285,35 @@ static int tolua_ExportedFunctions_ShowDocument00(lua_State *L) {
error("#ferror in function 'ShowDocument': %d %d %s", err.index, err.array, err.type);
}
+static void HideDocument() {
+ Game *game = g_engine->getGame();
+ game->documentsBrowser().hideDocument();
+}
+
+static int tolua_ExportedFunctions_HideDocument00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isnoobj(L, 1, &err)) {
+ HideDocument();
+ return 0;
+ }
+ error("#ferror in function 'HideDocument': %d %d %s", err.index, err.array, err.type);
+}
+
+static void AddDocument(const Common::String &name) {
+ Game *game = g_engine->getGame();
+ game->documentsBrowser().addDocument(name);
+}
+
+static int tolua_ExportedFunctions_AddDocument00(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));
+ AddDocument(s1);
+ return 0;
+ }
+ error("#ferror in function 'AddDocument': %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();
@@ -457,6 +504,51 @@ static int tolua_ExportedFunctions_AddCallbackPlayer00(lua_State *L) {
error("#ferror in function 'AddCallbackPlayer': %d %d %s", err.index, err.array, err.type);
}
+static void DeleteCallback(const Common::String &charName, const Common::String &animName, const Common::String &fnName, float triggerFrame) {
+ Game *game = g_engine->getGame();
+ Character *c = game->scene().character(charName);
+ if (c) {
+ c->deleteCallback(animName, fnName, triggerFrame);
+ } else {
+ warning("[DeleteCallback] Character's \"%s\" doesn't exist", charName.c_str());
+ }
+}
+
+static int tolua_ExportedFunctions_DeleteCallback00(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_isnoobj(L, 5, &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));
+ double n1 = tolua_tonumber(L, 4, 0.0);
+ DeleteCallback(s1, s2, s3, n1);
+ return 0;
+ }
+ error("#ferror in function 'DeleteCallback': %d %d %s", err.index, err.array, err.type);
+}
+
+static void DeleteCallbackPlayer(const Common::String &animName, const Common::String &fnName, float triggerFrame) {
+ Game *game = g_engine->getGame();
+ Character *c = game->scene()._character;
+ assert(c);
+ c->deleteCallback(animName, fnName, triggerFrame);
+}
+
+static int tolua_ExportedFunctions_DeleteCallbackPlayer00(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_isnoobj(L, 4, &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);
+ DeleteCallbackPlayer(s2, s3, n1);
+ return 0;
+ }
+ error("#ferror in function 'DeleteCallbackPlayer': %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();
@@ -1007,6 +1099,34 @@ static int tolua_ExportedFunctions_TranslateGroundObject00(lua_State *L) {
error("#ferror in function 'TranslateGroundObject': %d %d %s", err.index, err.array, err.type);
}
+static void RotateGroundObject(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("[RotateGroundObject] Object not found %s", name.c_str());
+ TeQuaternion rot = obj->model()->rotation();
+ obj->_rotateStart = rot;
+ obj->_rotateAmount = TeVector3f32(x, y, z);
+ obj->_rotateTimer.start();
+ obj->_rotateTime = time;
+}
+
+static int tolua_ExportedFunctions_RotateGroundObject00(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);
+ RotateGroundObject(s1, f1, f2, f3, f4);
+ return 0;
+ }
+ error("#ferror in function 'RotateGroundObject': %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()) {
@@ -2150,14 +2270,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); // Unused
+ tolua_function(L, "TakeObjectInHand", tolua_ExportedFunctions_TakeObjectInHand00); // Only used in Syberia 2
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
- // tolua_function(L, "HideDocument", tolua_ExportedFunctions_HideDocument00); // Unused
- // tolua_function(L, "AddDocument", tolua_ExportedFunctions_AddDocument00); // Unused
+ tolua_function(L, "HideDocument", tolua_ExportedFunctions_HideDocument00); // Only used in Syberia 2
+ tolua_function(L, "AddDocument", tolua_ExportedFunctions_AddDocument00); // Only used in Syberia 2
tolua_function(L, "LoadCharacter", tolua_ExportedFunctions_LoadCharacter00);
tolua_function(L, "UnloadCharacter", tolua_ExportedFunctions_UnloadCharacter00);
// tolua_function(L, "GetRotationCharacter", tolua_ExportedFunctions_GetRotationCharacter00); // Unused
@@ -2193,8 +2313,8 @@ void LuaOpenBinds(lua_State *L) {
tolua_function(L, "AddCallback", tolua_ExportedFunctions_AddCallback00);
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, "DeleteCallback", tolua_ExportedFunctions_DeleteCallback00); // Only used in Syberia 2
+ tolua_function(L, "DeleteCallbackPlayer", tolua_ExportedFunctions_DeleteCallbackPlayer00); // Only used in Syberia 2
// tolua_function(L, "DeleteCallbackAnimation2D", tolua_ExportedFunctions_DeleteCallbackAnimation2D00); // Unused
tolua_function(L, "SetObjectOnCharacter", tolua_ExportedFunctions_SetObjectOnCharacter00);
tolua_function(L, "SetObjectRotation", tolua_ExportedFunctions_SetObjectRotation00);
@@ -2206,7 +2326,7 @@ void LuaOpenBinds(lua_State *L) {
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); // Unused
+ tolua_function(L, "RotateGroundObject", tolua_ExportedFunctions_RotateGroundObject00); // Only used in Syberia 2
// tolua_function(L, "SetLightPlayerCharacter", tolua_ExportedFunctions_SetLightPlayerCharacter00); // Unused
// tolua_function(L, "SetLightPos", tolua_ExportedFunctions_SetLightPos00); // Unused
tolua_function(L, "EnableLight", tolua_ExportedFunctions_EnableLight00);
@@ -2251,6 +2371,29 @@ void LuaOpenBinds(lua_State *L) {
tolua_function(L, "EnableRunMode", tolua_ExportedFunctions_EnableRunMode00);
tolua_function(L, "SetModelPlayer", tolua_ExportedFunctions_SetModelPlayer00);
+ // TODO Syberia 2 functions..
+ //tolua_function(L,"BlendCharacterPlayerAnimation", tolua_ExportedFunctions_BlendCharacterPlayerAnimation00);
+ //tolua_function(L,"CurrentCharacterPlayerAnimation", tolua_ExportedFunctions_CurrentCharacterPlayerAnimation00);
+ //tolua_function(L,"SetCharacterPlayerRotation", tolua_ExportedFunctions_SetCharacterPlayerRotation00);
+ //tolua_function(L,"SetCharacterPlayerPosition", tolua_ExportedFunctions_SetCharacterPlayerPosition00);
+ //tolua_function(L,"PlaySnow", tolua_ExportedFunctions_PlaySnow00);
+ //tolua_function(L,"PlaySnowCustom", tolua_ExportedFunctions_PlaySnowCustom00);
+ //tolua_function(L,"SnowCustomVisible", tolua_ExportedFunctions_SnowCustomVisible00);
+ //tolua_function(L,"AddUnlockedAnim", tolua_ExportedFunctions_AddUnlockedAnim00);
+ //tolua_function(L,"RemoveRandomSound", tolua_ExportedFunctions_RemoveRandomSound00);
+ //tolua_function(L,"SetCharacterPlayerAnimation", tolua_ExportedFunctions_SetCharacterPlayerAnimation00);
+ //tolua_function(L,"SetYoukiFollowKate", tolua_ExportedFunctions_SetYoukiFollowKate00);
+ //tolua_function(L,"PlaySmoke", tolua_ExportedFunctions_PlaySmoke00);
+ //tolua_function(L,"SmokeVisible", tolua_ExportedFunctions_SmokeVisible00);
+ //tolua_function(L,"ActivateMask", tolua_ExportedFunctions_ActivateMask00);
+ //tolua_function(L,"AddRandomAnimation", tolua_ExportedFunctions_AddRandomAnimation00);
+ //tolua_function(L,"PlayRandomAnimation", tolua_ExportedFunctions_PlayRandomAnimation00);
+ //tolua_function(L,"SetObjectMoveDest", tolua_ExportedFunctions_SetObjectMoveDest00);
+ //tolua_function(L,"SetObjectMoveTime", tolua_ExportedFunctions_SetObjectMoveTime00);
+ //tolua_function(L,"PlayVerticalScrolling", tolua_ExportedFunctions_PlayVerticalScrolling00);
+ //tolua_function(L,"GetParticleIndex", tolua_GetParticleIndex);
+ //tolua_function(L,"EnableParticle", tolua_EnableParticle);
+
tolua_endmodule(L);
}
diff --git a/engines/tetraedge/game/object3d.h b/engines/tetraedge/game/object3d.h
index 1cf9ef28343..c3bff423aef 100644
--- a/engines/tetraedge/game/object3d.h
+++ b/engines/tetraedge/game/object3d.h
@@ -54,7 +54,7 @@ public:
float _rotateTime;
TeTimer _rotateTimer;
- TeVector3f32 _rotateStart;
+ TeQuaternion _rotateStart;
TeVector3f32 _rotateAmount;
float _translateTime;
Commit: c0ae694d0f4571453d59c9d8bc5c526c648afa2c
https://github.com/scummvm/scummvm/commit/c0ae694d0f4571453d59c9d8bc5c526c648afa2c
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2023-02-11T18:08:28+09:00
Commit Message:
TETRAEDGE: Add xml parsing features for Syberia 2
Changed paths:
engines/tetraedge/game/character_settings_xml_parser.cpp
engines/tetraedge/game/character_settings_xml_parser.h
engines/tetraedge/game/object_settings_xml_parser.cpp
engines/tetraedge/game/object_settings_xml_parser.h
diff --git a/engines/tetraedge/game/character_settings_xml_parser.cpp b/engines/tetraedge/game/character_settings_xml_parser.cpp
index abb8fc55d68..0ced45aa8d9 100644
--- a/engines/tetraedge/game/character_settings_xml_parser.cpp
+++ b/engines/tetraedge/game/character_settings_xml_parser.cpp
@@ -132,6 +132,11 @@ bool CharacterSettingsXmlParser::parserCallback_body(ParserNode *node) {
return true;
}
+bool CharacterSettingsXmlParser::parserCallback_invertNormals(ParserNode *node) {
+ _curCharacter->_invertNormals = true;
+ return true;
+}
+
bool CharacterSettingsXmlParser::textCallback(const Common::String &val) {
switch (_curTextTag) {
case TagModelFileName:
@@ -164,4 +169,9 @@ bool CharacterSettingsXmlParser::textCallback(const Common::String &val) {
return true;
}
+bool CharacterSettingsXmlParser::handleUnknownKey(ParserNode *node) {
+ warning("TODO: CharacterSettingsXmlParser handle unknown key %s", node->name.c_str());
+ 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
index f7b41b58402..919135a8ea3 100644
--- a/engines/tetraedge/game/character_settings_xml_parser.h
+++ b/engines/tetraedge/game/character_settings_xml_parser.h
@@ -43,6 +43,8 @@ public:
KEY_END()
XML_KEY(defaultScale)
KEY_END()
+ XML_KEY(invertNormals)
+ KEY_END()
XML_KEY(walk)
XML_KEY(animationFileName)
KEY_END()
@@ -60,9 +62,13 @@ public:
KEY_END()
XML_KEY(endD)
XML_PROP(file, true)
+ XML_PROP(stepRight, false)
+ XML_PROP(stepLeft, false)
KEY_END()
XML_KEY(endG)
XML_PROP(file, true)
+ XML_PROP(stepRight, false)
+ XML_PROP(stepLeft, false)
KEY_END()
KEY_END()
XML_KEY(speed)
@@ -105,7 +111,10 @@ public:
bool parserCallback_eyes(ParserNode *node);
bool parserCallback_mouth(ParserNode *node);
bool parserCallback_body(ParserNode *node);
+ bool parserCallback_invertNormals(ParserNode *node);
+
bool textCallback(const Common::String &val) override;
+ bool handleUnknownKey(ParserNode *node) override;
private:
Character::AnimSettings parseWalkAnimSettings(const ParserNode *node) const;
diff --git a/engines/tetraedge/game/object_settings_xml_parser.cpp b/engines/tetraedge/game/object_settings_xml_parser.cpp
index d5d617212b8..df1f6455faa 100644
--- a/engines/tetraedge/game/object_settings_xml_parser.cpp
+++ b/engines/tetraedge/game/object_settings_xml_parser.cpp
@@ -51,6 +51,16 @@ bool ObjectSettingsXmlParser::parserCallback_defaultScale(ParserNode *node) {
return true;
}
+bool ObjectSettingsXmlParser::parserCallback_originOffset(ParserNode *node) {
+ _textTagType = TagOriginOffset;
+ return true;
+}
+
+bool ObjectSettingsXmlParser::parserCallback_invertNormals(ParserNode *node) {
+ _curObject._invertNormals = true;
+ return true;
+}
+
bool ObjectSettingsXmlParser::textCallback(const Common::String &val) {
switch (_textTagType) {
case TagModelFileName:
@@ -63,6 +73,13 @@ bool ObjectSettingsXmlParser::textCallback(const Common::String &val) {
warning("Failed to parse Object defaultScale from %s", val.c_str());
break;
}
+ case TagOriginOffset:
+ {
+ bool result = _curObject._originOffset.parse(val);
+ if (!result)
+ warning("Failed to parse Object originOffset from %s", val.c_str());
+ break;
+ }
default:
error("should only see text for model file name or scale");
}
diff --git a/engines/tetraedge/game/object_settings_xml_parser.h b/engines/tetraedge/game/object_settings_xml_parser.h
index 328b4a04236..52b87d7231b 100644
--- a/engines/tetraedge/game/object_settings_xml_parser.h
+++ b/engines/tetraedge/game/object_settings_xml_parser.h
@@ -45,6 +45,10 @@ public:
KEY_END()
XML_KEY(defaultScale)
KEY_END()
+ XML_KEY(originOffset)
+ KEY_END()
+ XML_KEY(invertNormals)
+ KEY_END()
KEY_END()
KEY_END()
} PARSER_END()
@@ -55,11 +59,14 @@ private:
bool parserCallback_Object(ParserNode *node);
bool parserCallback_modelFileName(ParserNode *node);
bool parserCallback_defaultScale(ParserNode *node);
+ bool parserCallback_originOffset(ParserNode *node);
+ bool parserCallback_invertNormals(ParserNode *node);
bool textCallback(const Common::String &val) override;
enum TextTagType {
TagModelFileName,
- TagDefaultScale
+ TagDefaultScale,
+ TagOriginOffset
};
TextTagType _textTagType;
Commit: 8688b32625023b8a22ab51cfbaf1ffb4f7a75660
https://github.com/scummvm/scummvm/commit/8688b32625023b8a22ab51cfbaf1ffb4f7a75660
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2023-02-11T18:08:29+09:00
Commit Message:
TETRAEDGE: Implement a few more lua callbacks for Syberia 2
Changed paths:
engines/tetraedge/game/in_game_scene.cpp
engines/tetraedge/game/lua_binds.cpp
diff --git a/engines/tetraedge/game/in_game_scene.cpp b/engines/tetraedge/game/in_game_scene.cpp
index 5b48c25092c..22ef1940d21 100644
--- a/engines/tetraedge/game/in_game_scene.cpp
+++ b/engines/tetraedge/game/in_game_scene.cpp
@@ -1175,7 +1175,6 @@ void InGameScene::update() {
}
for (Object3D *obj : _object3Ds) {
- // TODO: update object3ds if they are translating or rotating.
if (obj->_translateTime >= 0) {
float time = MIN((float)(obj->_translateTimer.getTimeFromStart() / 1000000.0), obj->_translateTime);
TeVector3f32 trans = obj->_translateStart + (obj->_translateAmount * (time / obj->_translateTime));
diff --git a/engines/tetraedge/game/lua_binds.cpp b/engines/tetraedge/game/lua_binds.cpp
index bb13f8e7017..7b29235c5d1 100644
--- a/engines/tetraedge/game/lua_binds.cpp
+++ b/engines/tetraedge/game/lua_binds.cpp
@@ -84,7 +84,7 @@ static void PlayMovie(const Common::String &vidpath, const Common::String &music
static void PlayMovie(const Common::String &vidpath, const Common::String &musicpath, double f) {
Game *game = g_engine->getGame();
- warning("TODO: handle float value in PlayMovie for Syberia 2");
+ warning("TODO: handle float value %f in PlayMovie for Syberia 2", f);
if (!game->playMovie(vidpath, musicpath)) {
warning("[PlayMovie] Movie \"%s\" doesn\'t exist.", vidpath.c_str());
@@ -435,7 +435,7 @@ static int tolua_ExportedFunctions_SetRunMode200(lua_State *L) {
SetRunMode2(s1, s2);
return 0;
}
- error("#ferror in function 'AddMarker': %d %d %s", err.index, err.array, err.type);
+ error("#ferror in function 'SetRunMode2': %d %d %s", err.index, err.array, err.type);
}
static void SetCharacterShadow(const Common::String &charName, bool val) {
@@ -560,13 +560,20 @@ static int tolua_ExportedFunctions_AddMarker00(lua_State *L) {
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)) {
+ && tolua_isnumber(L, 7, 1, &err) && tolua_isnumber(L, 8, 1, &err)
+ && tolua_isnoobj(L, 9, &err)) {
+ // Syberia 1 version
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, ""));
+ double n3 = tolua_tonumber(L, 7, 0.0);
+ double n4 = tolua_tonumber(L, 8, 0.0);
+ if (n3 || n4) {
+ warning("TODO: handle extra params for AddMarker %f %f", n3, n4);
+ }
AddMarker(s1, s2, n1, n2, s3, s4);
return 0;
}
@@ -2178,6 +2185,8 @@ static int tolua_ExportedFunctions_MoveCharacterPlayerTo00(lua_State *L) {
}
static void EnableRunMode(bool val) {
+ //Game *game = g_engine->getGame();
+ //game->setRunMode(val);
warning("TODO: EnableRunMode %s", val ? "true" : "false");
}
@@ -2186,6 +2195,7 @@ static int tolua_ExportedFunctions_EnableRunMode00(lua_State *L) {
if (tolua_isboolean(L, 1, 0, &err) && tolua_isnoobj(L, 2, &err)) {
bool b1 = tolua_toboolean(L, 1, 0);
EnableRunMode(b1);
+ return 0;
}
error("#ferror in function 'EnableRunMode': %d %d %s", err.index, err.array, err.type);
}
@@ -2213,10 +2223,120 @@ static int tolua_ExportedFunctions_SetModelPlayer00(lua_State *L) {
if (tolua_isstring(L, 1, 0, &err) && tolua_isnoobj(L, 2, &err)) {
Common::String s1(tolua_tostring(L, 1, 0));
SetModelPlayer(s1);
+ return 0;
}
error("#ferror in function 'SetModelPlayer': %d %d %s", err.index, err.array, err.type);
}
+static void BlendCharacterPlayerAnimation(const Common::String &anim, float amount, bool repeat, bool returnToIdle) {
+ Game *game = g_engine->getGame();
+ Character *character = game->scene()._character;
+ if (character) {
+ character->blendAnimation(anim, amount, repeat, returnToIdle);
+ } else {
+ warning("[BlendCharacterPlayerAnimation] Character doesn't exist");
+ }
+
+}
+
+static int tolua_ExportedFunctions_BlendCharacterPlayerAnimation00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isnumber(L, 2, 0, &err)
+ && tolua_isboolean(L, 3, 0, &err) && tolua_isboolean(L, 4, 0, &err)
+ && tolua_isnoobj(L, 6, &err)) {
+ Common::String s1(tolua_tostring(L, 1, nullptr));
+ float f1 = tolua_tonumber(L, 2, 0.0);
+ float b1 = tolua_toboolean(L, 3, 0.0);
+ float b2 = tolua_toboolean(L, 4, 0.0);
+ BlendCharacterPlayerAnimation(s1, f1, b1, b2);
+ return 0;
+ }
+ error("#ferror in function 'BlendCharacterPlayerAnimation': %d %d %s", err.index, err.array, err.type);
+}
+
+static bool CurrentCharacterPlayerAnimation(const Common::String &anim) {
+ Game *game = g_engine->getGame();
+ Character *character = game->scene()._character;
+ if (character) {
+ return character->curAnimName() == anim;
+ } else {
+ warning("[CurrentCharacterPlayerAnimation] Character doesn't exist");
+ return false;
+ }
+}
+
+static int tolua_ExportedFunctions_CurrentCharacterPlayerAnimation00(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 = CurrentCharacterPlayerAnimation(s1);
+ tolua_pushboolean(L, result);
+ return 1;
+ }
+ error("#ferror in function 'CurrentCharacterPlayerAnimation': %d %d %s", err.index, err.array, err.type);
+}
+
+static void SetCharacterPlayerPosition(float x, float y, float z) {
+ Game *game = g_engine->getGame();
+ Character *character = game->scene()._character;
+ if (character) {
+ SetCharacterRotation(character->_model->name(), x, y, z);
+ }
+}
+
+static int tolua_ExportedFunctions_SetCharacterPlayerRotation00(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_isnoobj(L, 4, &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);
+ SetCharacterPlayerPosition(f1, f2, f3);
+ return 0;
+ }
+ error("#ferror in function 'SetCharacterPlayerRotation': %d %d %s", err.index, err.array, err.type);
+}
+
+static void SetCharacterPlayerPosition(const Common::String &zone, float x, float y, float z) {
+ Game *game = g_engine->getGame();
+ Character *character = game->scene()._character;
+ if (character) {
+ SetCharacterPosition(character->_model->name(), zone, x, y, z);
+ }
+}
+
+static int tolua_ExportedFunctions_SetCharacterPlayerPosition00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isnumber(L, 2, 0, &err)
+ && tolua_isnumber(L, 2, 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);
+ SetCharacterPlayerPosition(s1, f1, f2, f3);
+ return 0;
+ }
+ error("#ferror in function 'SetCharacterPlayerPosition': %d %d %s", err.index, err.array, err.type);
+}
+
+static void AddUnlockedAnim(const Common::String &name) {
+ // Note: does nothing, but we needed to add it..
+}
+
+static int tolua_ExportedFunctions_AddUnlockedAnim00(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, 0));
+ AddUnlockedAnim(s1);
+ return 0;
+ }
+ error("#ferror in function 'AddUnlockedAnim': %d %d %s", err.index, err.array, err.type);
+}
+
+
+
+
// ////////////////////////////////////////////////////////////////////////
@@ -2370,29 +2490,29 @@ void LuaOpenBinds(lua_State *L) {
// Syberia 2 specific functions.
tolua_function(L, "EnableRunMode", tolua_ExportedFunctions_EnableRunMode00);
tolua_function(L, "SetModelPlayer", tolua_ExportedFunctions_SetModelPlayer00);
+ tolua_function(L, "BlendCharacterPlayerAnimation", tolua_ExportedFunctions_BlendCharacterPlayerAnimation00);
+ tolua_function(L, "CurrentCharacterPlayerAnimation", tolua_ExportedFunctions_CurrentCharacterPlayerAnimation00);
+ tolua_function(L, "SetCharacterPlayerRotation", tolua_ExportedFunctions_SetCharacterPlayerRotation00);
+ tolua_function(L, "SetCharacterPlayerPosition", tolua_ExportedFunctions_SetCharacterPlayerPosition00);
+ tolua_function(L, "AddUnlockedAnim", tolua_ExportedFunctions_AddUnlockedAnim00);
// TODO Syberia 2 functions..
- //tolua_function(L,"BlendCharacterPlayerAnimation", tolua_ExportedFunctions_BlendCharacterPlayerAnimation00);
- //tolua_function(L,"CurrentCharacterPlayerAnimation", tolua_ExportedFunctions_CurrentCharacterPlayerAnimation00);
- //tolua_function(L,"SetCharacterPlayerRotation", tolua_ExportedFunctions_SetCharacterPlayerRotation00);
- //tolua_function(L,"SetCharacterPlayerPosition", tolua_ExportedFunctions_SetCharacterPlayerPosition00);
- //tolua_function(L,"PlaySnow", tolua_ExportedFunctions_PlaySnow00);
- //tolua_function(L,"PlaySnowCustom", tolua_ExportedFunctions_PlaySnowCustom00);
- //tolua_function(L,"SnowCustomVisible", tolua_ExportedFunctions_SnowCustomVisible00);
- //tolua_function(L,"AddUnlockedAnim", tolua_ExportedFunctions_AddUnlockedAnim00);
- //tolua_function(L,"RemoveRandomSound", tolua_ExportedFunctions_RemoveRandomSound00);
- //tolua_function(L,"SetCharacterPlayerAnimation", tolua_ExportedFunctions_SetCharacterPlayerAnimation00);
- //tolua_function(L,"SetYoukiFollowKate", tolua_ExportedFunctions_SetYoukiFollowKate00);
- //tolua_function(L,"PlaySmoke", tolua_ExportedFunctions_PlaySmoke00);
- //tolua_function(L,"SmokeVisible", tolua_ExportedFunctions_SmokeVisible00);
- //tolua_function(L,"ActivateMask", tolua_ExportedFunctions_ActivateMask00);
- //tolua_function(L,"AddRandomAnimation", tolua_ExportedFunctions_AddRandomAnimation00);
- //tolua_function(L,"PlayRandomAnimation", tolua_ExportedFunctions_PlayRandomAnimation00);
- //tolua_function(L,"SetObjectMoveDest", tolua_ExportedFunctions_SetObjectMoveDest00);
- //tolua_function(L,"SetObjectMoveTime", tolua_ExportedFunctions_SetObjectMoveTime00);
- //tolua_function(L,"PlayVerticalScrolling", tolua_ExportedFunctions_PlayVerticalScrolling00);
- //tolua_function(L,"GetParticleIndex", tolua_GetParticleIndex);
- //tolua_function(L,"EnableParticle", tolua_EnableParticle);
+ //tolua_function(L, "PlaySnow", tolua_ExportedFunctions_PlaySnow00);
+ //tolua_function(L, "PlaySnowCustom", tolua_ExportedFunctions_PlaySnowCustom00);
+ //tolua_function(L, "SnowCustomVisible", tolua_ExportedFunctions_SnowCustomVisible00);
+ //tolua_function(L, "RemoveRandomSound", tolua_ExportedFunctions_RemoveRandomSound00);
+ //tolua_function(L, "SetCharacterPlayerAnimation", tolua_ExportedFunctions_SetCharacterPlayerAnimation00);
+ //tolua_function(L, "SetYoukiFollowKate", tolua_ExportedFunctions_SetYoukiFollowKate00);
+ //tolua_function(L, "PlaySmoke", tolua_ExportedFunctions_PlaySmoke00);
+ //tolua_function(L, "SmokeVisible", tolua_ExportedFunctions_SmokeVisible00);
+ //tolua_function(L, "ActivateMask", tolua_ExportedFunctions_ActivateMask00);
+ //tolua_function(L, "AddRandomAnimation", tolua_ExportedFunctions_AddRandomAnimation00);
+ //tolua_function(L, "PlayRandomAnimation", tolua_ExportedFunctions_PlayRandomAnimation00);
+ //tolua_function(L, "SetObjectMoveDest", tolua_ExportedFunctions_SetObjectMoveDest00);
+ //tolua_function(L, "SetObjectMoveTime", tolua_ExportedFunctions_SetObjectMoveTime00);
+ //tolua_function(L, "PlayVerticalScrolling", tolua_ExportedFunctions_PlayVerticalScrolling00);
+ //tolua_function(L, "GetParticleIndex", tolua_GetParticleIndex);
+ //tolua_function(L, "EnableParticle", tolua_EnableParticle);
tolua_endmodule(L);
}
Commit: 543657e1a0ee34bda4e22d4ddff3ee004d641971
https://github.com/scummvm/scummvm/commit/543657e1a0ee34bda4e22d4ddff3ee004d641971
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2023-02-11T18:08:29+09:00
Commit Message:
TETRAEDGE: Revert color scaling hack now TGL is fixed
Changed paths:
engines/tetraedge/te/te_renderer_tinygl.cpp
diff --git a/engines/tetraedge/te/te_renderer_tinygl.cpp b/engines/tetraedge/te/te_renderer_tinygl.cpp
index 055316911d9..a82b25a1055 100644
--- a/engines/tetraedge/te/te_renderer_tinygl.cpp
+++ b/engines/tetraedge/te/te_renderer_tinygl.cpp
@@ -160,13 +160,7 @@ void TeRendererTinyGL::renderTransparentMeshes() {
tglVertexPointer(3, TGL_FLOAT, sizeof(TeVector3f32), _transparentMeshVertexes.data());
tglNormalPointer(TGL_FLOAT, sizeof(TeVector3f32), _transparentMeshNormals.data());
tglTexCoordPointer(2, TGL_FLOAT, sizeof(TeVector2f32), _transparentMeshCoords.data());
- // TinyGL doesn't correctly scale BYTE color data, so provide it pre-scaled.
- Common::Array<float> colorVals(_transparentMeshColors.size() * 4);
- const byte *coldata = reinterpret_cast<const byte *>(_transparentMeshColors.data());
- for (unsigned int i = 0; i < colorVals.size(); i++) {
- colorVals[i] = (float)coldata[i] / 255.0f;
- }
- tglColorPointer(4, TGL_FLOAT, sizeof(float) * 4, colorVals.data());
+ tglColorPointer(4, TGL_UNSIGNED_BYTE, sizeof(TeColor), _transparentMeshColors.data());
TeMaterial lastMaterial;
TeMatrix4x4 lastMatrix;
Commit: 60fd2c4ed3ac00c138940ccb6dac26cb86964668
https://github.com/scummvm/scummvm/commit/60fd2c4ed3ac00c138940ccb6dac26cb86964668
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2023-02-11T18:08:29+09:00
Commit Message:
TETRAEDGE: Many fixes for Syberia 2 scene loading
Changed paths:
A engines/tetraedge/game/in_game_scene_xml_parser.cpp
A engines/tetraedge/game/in_game_scene_xml_parser.h
A engines/tetraedge/te/te_camera_xml_parser.cpp
A engines/tetraedge/te/te_camera_xml_parser.h
engines/tetraedge/game/characters_shadow.cpp
engines/tetraedge/game/game.cpp
engines/tetraedge/game/in_game_scene.cpp
engines/tetraedge/game/in_game_scene.h
engines/tetraedge/game/lua_binds.cpp
engines/tetraedge/module.mk
engines/tetraedge/te/te_3d_object2.cpp
engines/tetraedge/te/te_3d_object2.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_lua_thread.cpp
engines/tetraedge/te/te_vector2f32.cpp
engines/tetraedge/te/te_vector2f32.h
diff --git a/engines/tetraedge/game/characters_shadow.cpp b/engines/tetraedge/game/characters_shadow.cpp
index 14be1f105c4..0a13a353115 100644
--- a/engines/tetraedge/game/characters_shadow.cpp
+++ b/engines/tetraedge/game/characters_shadow.cpp
@@ -44,7 +44,7 @@ void CharactersShadow::create(InGameScene *scene) {
renderer->enableTexture();
_camera = new TeCamera();
_camera->setProjMatrixType(2);
- _camera->setPerspectiveVal(1.0);
+ _camera->setAspectRatio(1.0);
_camera->setName("_shadowCam");
_camera->viewport(0, 0, _texSize, _texSize);
diff --git a/engines/tetraedge/game/game.cpp b/engines/tetraedge/game/game.cpp
index 905c540563d..ec69c08b21f 100644
--- a/engines/tetraedge/game/game.cpp
+++ b/engines/tetraedge/game/game.cpp
@@ -544,7 +544,14 @@ bool Game::initWarp(const Common::String &zone, const Common::String &scene, boo
_scene.hitObjectGui().unload();
Common::Path geomPath(Common::String::format("scenes/%s/Geometry%s.bin",
zone.c_str(), zone.c_str()));
- _scene.load(core->findFile(geomPath));
+ Common::FSNode geomFile = core->findFile(geomPath);
+ if (geomFile.isReadable()) {
+ // Syberia 1, load geom bin
+ _scene.load(geomFile);
+ } else {
+ // Syberia 2, load from xml
+ _scene.loadXml(zone, scene);
+ }
_scene.loadBackground(setLuaNode);
Application *app = g_engine->getApplication();
@@ -920,6 +927,7 @@ bool Game::onCharacterAnimationPlayerFinished(const Common::String &anim) {
}
if (callScripts) {
_luaScript.execute("OnCharacterAnimationFinished", "Kate");
+ _luaScript.execute("OnCharacterAnimationPlayerFinished", anim);
_luaScript.execute("OnCellCharacterAnimationPlayerFinished", anim);
}
diff --git a/engines/tetraedge/game/in_game_scene.cpp b/engines/tetraedge/game/in_game_scene.cpp
index 22ef1940d21..7d4418a6acf 100644
--- a/engines/tetraedge/game/in_game_scene.cpp
+++ b/engines/tetraedge/game/in_game_scene.cpp
@@ -28,6 +28,7 @@
#include "tetraedge/game/billboard.h"
#include "tetraedge/game/game.h"
#include "tetraedge/game/in_game_scene.h"
+#include "tetraedge/game/in_game_scene_xml_parser.h"
#include "tetraedge/game/character.h"
#include "tetraedge/game/characters_shadow.h"
#include "tetraedge/game/object3d.h"
@@ -47,6 +48,9 @@
namespace Tetraedge {
+/*static*/
+bool InGameScene::_collisionSlide = false;
+
InGameScene::InGameScene() : _character(nullptr), _charactersShadow(nullptr),
_shadowLightNo(-1), _waitTime(-1.0f), _shadowColor(0, 0, 0, 0x80), _shadowFov(20.0f),
_shadowFarPlane(1000), _shadowNearPlane(1)
@@ -90,14 +94,14 @@ void InGameScene::addAnchorZone(const Common::String &s1, const Common::String &
_anchorZones.push_back(zone);
}
-bool InGameScene::addMarker(const Common::String &markerName, const Common::String &imgPath, float x, float y, const Common::String &locType, const Common::String &markerVal) {
+bool InGameScene::addMarker(const Common::String &markerName, const Common::String &imgPath, float x, float y, const Common::String &locType, const Common::String &markerVal, float anchorX, float anchorY) {
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->setAnchor(TeVector3f32(anchorX, anchorY, 0.0f));
markerSprite->load(imgPath);
markerSprite->setSizeType(TeILayout::RELATIVE_TO_PARENT);
markerSprite->setPositionType(TeILayout::RELATIVE_TO_PARENT);
@@ -286,7 +290,7 @@ void InGameScene::deserializeCam(Common::ReadStream &stream, TeIntrusivePtr<TeCa
// load name/position/rotation/scale
Te3DObject2::deserialize(stream, *cam);
cam->setFov(stream.readFloatLE());
- cam->setPerspectiveVal(stream.readFloatLE());
+ cam->setAspectRatio(stream.readFloatLE());
// Original loads the second val then ignores it and sets 3000.
cam->setOrthoPlanes(stream.readFloatLE(), 3000.0);
stream.readFloatLE();
@@ -440,6 +444,7 @@ void InGameScene::freeGeometry() {
_dummies.clear();
cameras().clear();
_zoneModels.clear();
+ _masks.clear();
if (_charactersShadow) {
delete _charactersShadow;
_charactersShadow = nullptr;
@@ -541,24 +546,9 @@ bool InGameScene::isObjectBlocking(const Common::String &name) {
}
bool InGameScene::load(const Common::FSNode &sceneNode) {
- _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 (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++)
- TeVector2f32::deserialize(actzonefile, _actZones[i]._points[j]);
- _actZones[i]._flag1 = (actzonefile.readByte() != 0);
- _actZones[i]._flag2 = true;
- }
- }
- }
+ // Syberia 1 has loadActZones function contents inline.
+ loadActZones();
+
if (!_lights.empty()) {
g_engine->getRenderer()->disableAllLights();
for (uint i = 0; i < _lights.size(); i++) {
@@ -674,6 +664,72 @@ bool InGameScene::load(const Common::FSNode &sceneNode) {
return true;
}
+bool InGameScene::loadXml(const Common::String &zone, const Common::String &scene) {
+ _zoneName = zone;
+ _sceneName = scene;
+ _blockers.clear();
+ _rectBlockers.clear();
+ _collisionSlide = 0;
+ loadActZones();
+ loadBlockers();
+
+ Common::Path xmlpath = Common::Path("scenes").joinInPlace(zone).joinInPlace(scene).joinInPlace("Scene")
+ .appendInPlace(scene).appendInPlace(".xml");
+ Common::FSNode node = g_engine->getCore()->findFile(xmlpath);
+ InGameSceneXmlParser parser;
+ parser._scene = this;
+ parser.setAllowText();
+ if (!parser.loadFile(node))
+ error("InGameScene::loadXml: Can't load %s", node.getPath().c_str());
+ if (!parser.parse())
+ error("InGameScene::loadXml: Can't parse %s", node.getPath().c_str());
+
+ return true;
+}
+
+void InGameScene::loadActZones() {
+ _actZones.clear();
+ Common::File actzonefile;
+ if (actzonefile.open(getActZoneFileName())) {
+ if (Te3DObject2::loadAndCheckFourCC(actzonefile, "ACT0")) {
+ uint32 count = actzonefile.readUint32LE();
+ if (count > 1000000)
+ error("Improbable number of actzones %d", count);
+ _actZones.resize(count);
+ 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++)
+ TeVector2f32::deserialize(actzonefile, _actZones[i]._points[j]);
+ _actZones[i]._flag1 = (actzonefile.readByte() != 0);
+ _actZones[i]._flag2 = true;
+ }
+ } else {
+ warning("loadActZones: Incorrect header in %s", actzonefile.getName());
+ }
+ }
+}
+
+static Common::Path _sceneFileNameBase() {
+ Game *game = g_engine->getGame();
+ Common::Path retval("scenes");
+ retval.joinInPlace(game->currentZone());
+ retval.joinInPlace(game->currentScene());
+ return retval;
+}
+
+bool InGameScene::loadCamera(const Common::String &name) {
+ Common::Path p = _sceneFileNameBase().joinInPlace(name).appendInPlace(".xml");
+ TeCamera *cam = new TeCamera();
+ cam->loadXml(p);
+ // Original doesn't do this? but we seem to need it
+ cam->setName(name);
+ TeVector3f32 winSize = g_engine->getApplication()->getMainWindow().size();
+ cam->viewport(0, 0, winSize.x(), winSize.y());
+ cameras().push_back(TeIntrusivePtr<TeCamera>(cam));
+ return true;
+}
+
bool InGameScene::loadCharacter(const Common::String &name) {
Character *c = character(name);
if (!c) {
@@ -691,6 +747,16 @@ bool InGameScene::loadCharacter(const Common::String &name) {
return true;
}
+bool InGameScene::loadFreeMoveZone(const Common::String &name, TeVector2f32 &gridSize) {
+ TeFreeMoveZone *zone = new TeFreeMoveZone();
+ zone->setName(name);
+ Common::Path p = _sceneFileNameBase().joinInPlace(name).appendInPlace(".bin");
+ zone->loadBin(p, &_blockers, &_rectBlockers, &_actZones, gridSize);
+ _freeMoveZones.push_back(zone);
+ zone->setVisible(false);
+ return true;
+}
+
bool InGameScene::loadLights(const Common::FSNode &node) {
SceneLightsXmlParser parser;
@@ -793,12 +859,105 @@ bool InGameScene::loadPlayerCharacter(const Common::String &name) {
return true;
}
-static Common::Path _sceneFileNameBase() {
- Game *game = g_engine->getGame();
- Common::Path retval("scenes");
- retval.joinInPlace(game->currentZone());
- retval.joinInPlace(game->currentScene());
- return retval;
+bool InGameScene::loadDynamicLightBloc(const Common::String &name, const Common::String &texture, const Common::String &zone, const Common::String &scene) {
+ const Common::Path pdat = Common::Path(zone).joinInPlace(scene).joinInPlace(name).appendInPlace(".bin");
+ const Common::Path ptex = Common::Path(zone).joinInPlace(scene).joinInPlace(texture);
+ Common::FSNode datnode = g_engine->getCore()->findFile(pdat);
+ Common::FSNode texnode = g_engine->getCore()->findFile(ptex);
+ if (!datnode.isReadable()) {
+ warning("[InGameScene::loadDynamicLightBloc] Can't open file : %s.", pdat.toString().c_str());
+ return false;
+ }
+
+ Common::File file;
+ file.open(datnode);
+
+ TeModel *model = new TeModel();
+ model->meshes().resize(1);
+ model->setName(datnode.getName());
+
+ TeVector3f32 vec;
+ TeVector2f32 vec2;
+ TeVector3f32::deserialize(file, vec);
+ // Read position/rotation/scale.
+ model->deserialize(file, *model);
+
+ uint32 verts = file.readUint32LE();
+ uint32 tricount = file.readUint32LE();
+ if (verts > 100000 || tricount > 10000)
+ error("Improbable number of verts (%d) or triangles (%d)", verts, tricount);
+
+ TeMesh *mesh = model->meshes()[0].get();
+ mesh->setConf(verts, tricount * 3, TeMesh::MeshMode_Triangles, 0, 0);
+
+ for (uint i = 0; i < verts; i++) {
+ TeVector3f32::deserialize(file, vec);
+ mesh->setVertex(i, vec);
+ mesh->setNormal(i, TeVector3f32(0, 0, 1));
+ }
+ for (uint i = 0; i < verts; i++) {
+ TeVector2f32::deserialize(file, vec2);
+ vec.y() = 1.0 - vec.y();
+ mesh->setTextureUV(i, vec2);
+ }
+
+ for (uint i = 0; i < tricount; i++)
+ mesh->setIndex(i, file.readUint16LE());
+
+ file.close();
+
+ if (texnode.isReadable()) {
+ TeIntrusivePtr<Te3DTexture> tex = Te3DTexture::makeInstance();
+ tex->load2(texnode, 0x500);
+ mesh->defaultMaterial(tex);
+ } else if (texture.size()) {
+ warning("loadDynamicLightBloc: Failed to load texture %s", texture.c_str());
+ }
+
+ model->setVisible(false);
+
+ _zoneModels.push_back(TeIntrusivePtr<TeModel>(model));
+ return true;
+}
+
+bool InGameScene::loadLight(const Common::String &fname, const Common::String &zone, const Common::String &scene) {
+ warning("TODO: Implement InGameScene::loadLight");
+ return true;
+}
+
+bool InGameScene::loadMask(const Common::String &name, const Common::String &texture, const Common::String &zone, const Common::String &scene) {
+ warning("TODO: Implement InGameScene::loadMask");
+ return true;
+}
+
+bool InGameScene::loadRBB(const Common::String &fname, const Common::String &zone, const Common::String &scene) {
+ warning("TODO: Implement InGameScene::loadRBB");
+ return true;
+}
+
+bool InGameScene::loadRippleMask(const Common::String &name, const Common::String &texture, const Common::String &zone, const Common::String &scene) {
+ warning("TODO: Implement InGameScene::loadRippleMask");
+ return true;
+}
+
+bool InGameScene::loadRObject(const Common::String &fname, const Common::String &zone, const Common::String &scene) {
+ warning("TODO: Implement InGameScene::loadRObject");
+ return true;
+}
+
+bool InGameScene::loadShadowMask(const Common::String &name, const Common::String &texture, const Common::String &zone, const Common::String &scene) {
+ warning("TODO: Implement InGameScene::loadShadowMask");
+ return true;
+}
+
+bool InGameScene::loadShadowReceivingObject(const Common::String &fname, const Common::String &zone, const Common::String &scene) {
+ warning("TODO: Implement InGameScene::loadShadowReceivingObject");
+ return true;
+}
+
+bool InGameScene::loadZBufferObject(const Common::String &fname, const Common::String &zone, const Common::String &scene) {
+ warning("TODO: Implement InGameScene::loadZBufferObject");
+ return true;
}
Common::Path InGameScene::getLightsFileName() const {
diff --git a/engines/tetraedge/game/in_game_scene.h b/engines/tetraedge/game/in_game_scene.h
index 183dd82dc57..7ff1955db76 100644
--- a/engines/tetraedge/game/in_game_scene.h
+++ b/engines/tetraedge/game/in_game_scene.h
@@ -45,6 +45,8 @@ class TeLayout;
class InGameScene : public TeScene {
public:
+ friend class InGameSceneXmlParser;
+
InGameScene();
struct AnimObject {
@@ -94,7 +96,7 @@ public:
_blockingObjects.push_back(obj);
}
void addCallbackAnimation2D(const Common::String ¶m_1, const Common::String ¶m_2, float param_3);
- bool 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, float anchorX, float anchorY);
static float angularDistance(float a1, float a2);
bool aroundAnchorZone(const AnchorZone *zone);
TeLayout *background();
@@ -147,6 +149,25 @@ public:
bool loadObjectMaterials(const Common::String &path, const Common::String &name);
bool loadPlayerCharacter(const Common::String &cname);
+ // Syberia 2 specific data..
+ void loadActZones();
+ bool loadCamera(const Common::String &name);
+ bool loadDynamicLightBloc(const Common::String &name, const Common::String &texture, const Common::String &zone, const Common::String &scene);
+ // loadFlamme uses the xml doc
+ bool loadFreeMoveZone(const Common::String &name, TeVector2f32 &gridSize);
+ bool loadLight(const Common::String &fname, const Common::String &zone, const Common::String &scene);
+ bool loadMask(const Common::String &name, const Common::String &texture, const Common::String &zone, const Common::String &scene);
+ bool loadRBB(const Common::String &fname, const Common::String &zone, const Common::String &scene);
+ bool loadRippleMask(const Common::String &name, const Common::String &texture, const Common::String &zone, const Common::String &scene);
+ bool loadRObject(const Common::String &fname, const Common::String &zone, const Common::String &scene);
+ //bool loadSBB(const Common::String &fname, const Common::String &zone, const Common::String &scene); // Unused?
+ bool loadShadowMask(const Common::String &name, const Common::String &texture, const Common::String &zone, const Common::String &scene);
+ bool loadShadowReceivingObject(const Common::String &fname, const Common::String &zone, const Common::String &scene);
+ //bool loadSnowCone(const Common::String &fname, const Common::String &zone, const Common::String &scene) { return false; } // Unused?
+ //bool loadSnowCustom() // todo: from xml file?
+ bool loadXml(const Common::String &zone, const Common::String &scene);
+ bool loadZBufferObject(const Common::String &fname, const Common::String &zone, const Common::String &scene);
+
void moveCharacterTo(const Common::String &charName, const Common::String &curveName, float curveOffset, float curveEnd);
int object(const Common::String &oname);
Object3D *object3D(const Common::String &oname);
@@ -199,6 +220,11 @@ public:
TeTimer &waitTimeTimer() { return _waitTimeTimer; }
Common::Array<Common::SharedPtr<TeLight>> &lights() { return _lights; }
+ // Note: Zone name and scene name are only set in Syberia 2
+ const Common::String getZoneName() const { return _zoneName; }
+ const Common::String getSceneName() const { return _sceneName; }
+
+ void setCollisionSlide(bool val) { _collisionSlide = val; }
private:
int _shadowLightNo;
@@ -231,6 +257,7 @@ private:
Common::Array<TeIntrusivePtr<TeBezierCurve>> _bezierCurves;
Common::Array<Dummy> _dummies;
Common::Array<TeIntrusivePtr<TeModel>> _zoneModels;
+ Common::Array<TeIntrusivePtr<TeModel>> _masks;
TeIntrusivePtr<TeModel> _playerCharacterModel;
TeIntrusivePtr<TeBezierCurve> _curve;
@@ -245,6 +272,13 @@ private:
TeVector2f32 _viewportSize;
Common::Path _loadedPath;
+
+ // Syberia 2 specific items
+ static bool _collisionSlide;
+ Common::String _sceneName;
+ Common::String _zoneName;
+
+
};
} // end namespace Tetraedge
diff --git a/engines/tetraedge/game/in_game_scene_xml_parser.cpp b/engines/tetraedge/game/in_game_scene_xml_parser.cpp
new file mode 100644
index 00000000000..3d29262a168
--- /dev/null
+++ b/engines/tetraedge/game/in_game_scene_xml_parser.cpp
@@ -0,0 +1,159 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "tetraedge/game/in_game_scene_xml_parser.h"
+#include "tetraedge/game/in_game_scene.h"
+
+namespace Tetraedge {
+
+bool InGameSceneXmlParser::parserCallback_camera(ParserNode *node) {
+ _scene->loadCamera(node->values["name"]);
+ return true;
+}
+
+bool InGameSceneXmlParser::parserCallback_pathZone(ParserNode *node) {
+ _fmzGridSize = TeVector2f32();
+ // Handled in closedKeyCallback
+ return true;
+}
+
+bool InGameSceneXmlParser::parserCallback_gridSize(ParserNode *node) {
+ _textNodeType = TextNodeGridSize;
+ return true;
+}
+
+bool InGameSceneXmlParser::parserCallback_curve(ParserNode *node) {
+ warning("TODO: handle curve tag in InGameSceneXmlParser");
+ return true;
+}
+
+bool InGameSceneXmlParser::parserCallback_dummy(ParserNode *node) {
+ warning("TODO: handle dummy tag in InGameSceneXmlParser");
+ return true;
+}
+
+bool InGameSceneXmlParser::parserCallback_position(ParserNode *node) {
+ _textNodeType = TextNodePosition;
+ return true;
+}
+
+bool InGameSceneXmlParser::parserCallback_mask(ParserNode *node) {
+ _scene->loadMask(node->values["name"], node->values["texture"],
+ _scene->getZoneName(), _scene->getSceneName());
+ return true;
+}
+
+bool InGameSceneXmlParser::parserCallback_dynamicLight(ParserNode *node) {
+ _scene->loadDynamicLightBloc(node->values["name"], node->values["texture"],
+ _scene->getZoneName(), _scene->getSceneName());
+ return true;
+}
+
+bool InGameSceneXmlParser::parserCallback_rippleMask(ParserNode *node) {
+ _scene->loadRippleMask(node->values["name"], node->values["texture"],
+ _scene->getZoneName(), _scene->getSceneName());
+ return true;
+}
+
+bool InGameSceneXmlParser::parserCallback_snowCone(ParserNode *node) {
+ // doesn't call the function in the game..
+ /*_scene->loadSnowCone(node->values["name"], node->values["texture"],
+ _scene->getZoneName(), _scene->getSceneName());*/
+ return true;
+}
+
+bool InGameSceneXmlParser::parserCallback_shadowMask(ParserNode *node) {
+ _scene->loadShadowMask(node->values["name"], node->values["texture"],
+ _scene->getZoneName(), _scene->getSceneName());
+ return true;
+}
+
+bool InGameSceneXmlParser::parserCallback_shadowReceivingObject(ParserNode *node) {
+ return true;
+}
+
+bool InGameSceneXmlParser::parserCallback_zBufferObject(ParserNode *node) {
+ _scene->loadZBufferObject(node->values["name"], _scene->getZoneName(), _scene->getSceneName());
+ return true;
+}
+
+bool InGameSceneXmlParser::parserCallback_rObject(ParserNode *node) {
+ _scene->loadRObject(node->values["name"], _scene->getZoneName(), _scene->getSceneName());
+ return true;
+}
+
+bool InGameSceneXmlParser::parserCallback_rBB(ParserNode *node) {
+ _scene->loadRBB(node->values["name"], _scene->getZoneName(), _scene->getSceneName());
+ return true;
+}
+
+bool InGameSceneXmlParser::parserCallback_light(ParserNode *node) {
+ _scene->loadLight(node->values["name"], _scene->getZoneName(), _scene->getSceneName());
+ return true;
+}
+
+bool InGameSceneXmlParser::parserCallback_collisionSlide(ParserNode *node) {
+ _scene->setCollisionSlide(true);
+ return true;
+}
+
+bool InGameSceneXmlParser::parserCallback_noCollisionSlide(ParserNode *node) {
+ _scene->setCollisionSlide(false);
+ return true;
+}
+
+bool InGameSceneXmlParser::closedKeyCallback(ParserNode *node) {
+ _textNodeType = TextNodeNone;
+ if (node->name == "pathZone") {
+ _scene->loadFreeMoveZone(node->values["name"], _fmzGridSize);
+ }
+ return true;
+}
+
+bool InGameSceneXmlParser::textCallback(const Common::String &val) {
+ switch (_textNodeType) {
+ case TextNodePosition: {
+ TeVector3f32 pos;
+ if (!pos.parse(val)) {
+ parserError("Can't parse dummy position");
+ return false;
+ }
+ _scene->_dummies.back()._position = pos;
+ break;
+ }
+ case TextNodeGridSize: {
+ TeVector2f32 sz;
+ if (!sz.parse(val)) {
+ parserError("Can't parse gridSize");
+ return false;
+ }
+ _fmzGridSize = sz;
+ }
+ default:
+ parserError("Unexpected text block");
+ return false;
+ break;
+ }
+ return true;
+}
+
+
+} // end namespace Tetraedge
diff --git a/engines/tetraedge/game/in_game_scene_xml_parser.h b/engines/tetraedge/game/in_game_scene_xml_parser.h
new file mode 100644
index 00000000000..d895d4418be
--- /dev/null
+++ b/engines/tetraedge/game/in_game_scene_xml_parser.h
@@ -0,0 +1,136 @@
+/* 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/formats/xmlparser.h"
+#include "tetraedge/game/in_game_scene.h"
+
+#ifndef TETRAEDGE_GAME_IN_GAME_SCENE_XML_PARSER_H
+#define TETRAEDGE_GAME_IN_GAME_SCENE_XML_PARSER_H
+
+namespace Tetraedge {
+
+class InGameSceneXmlParser : public Common::XMLParser {
+public:
+ // Parser
+ CUSTOM_XML_PARSER(InGameSceneXmlParser) {
+ XML_KEY(scene)
+ XML_KEY(camera)
+ XML_PROP(name, true)
+ KEY_END()
+ XML_KEY(pathZone)
+ XML_PROP(name, true)
+ XML_KEY(gridSize)
+ KEY_END()
+ KEY_END()
+ XML_KEY(curve)
+ XML_PROP(name, true)
+ KEY_END()
+ XML_KEY(dummy)
+ XML_PROP(name, true)
+ XML_KEY(position)
+ KEY_END()
+ KEY_END()
+ XML_KEY(mask)
+ XML_PROP(name, true)
+ XML_PROP(texture, true)
+ KEY_END()
+ XML_KEY(dynamicLight)
+ XML_PROP(name, true)
+ XML_PROP(texture, true)
+ KEY_END()
+ XML_KEY(rippleMask)
+ XML_PROP(name, true)
+ XML_PROP(texture, true)
+ KEY_END()
+ XML_KEY(snowCone)
+ XML_PROP(name, true)
+ KEY_END()
+ XML_KEY(shadowMask)
+ XML_PROP(name, true)
+ XML_PROP(texture, true)
+ KEY_END()
+ XML_KEY(shadowReceivingObject)
+ XML_PROP(name, true)
+ KEY_END()
+ XML_KEY(zBufferObject)
+ XML_PROP(name, true)
+ KEY_END()
+ XML_KEY(rObject)
+ XML_PROP(name, true)
+ KEY_END()
+ XML_KEY(rBB)
+ XML_PROP(name, true)
+ KEY_END()
+ XML_KEY(light)
+ XML_PROP(name, true)
+ KEY_END()
+ XML_KEY(collisionSlide)
+ KEY_END()
+ XML_KEY(noCollisionSlide)
+ KEY_END()
+ KEY_END()
+ } PARSER_END()
+
+ bool parserCallback_scene(ParserNode *node) { return true; }
+ bool parserCallback_camera(ParserNode *node);
+ bool parserCallback_pathZone(ParserNode *node);
+ bool parserCallback_gridSize(ParserNode *node);
+ bool parserCallback_curve(ParserNode *node);
+ bool parserCallback_dummy(ParserNode *node);
+ bool parserCallback_position(ParserNode *node);
+ bool parserCallback_mask(ParserNode *node);
+ bool parserCallback_dynamicLight(ParserNode *node);
+ bool parserCallback_rippleMask(ParserNode *node);
+ bool parserCallback_snowCone(ParserNode *node);
+ bool parserCallback_shadowMask(ParserNode *node);
+ bool parserCallback_shadowReceivingObject(ParserNode *node);
+ bool parserCallback_zBufferObject(ParserNode *node);
+ bool parserCallback_rObject(ParserNode *node);
+ bool parserCallback_rBB(ParserNode *node);
+ bool parserCallback_light(ParserNode *node);
+ bool parserCallback_collisionSlide(ParserNode *node);
+ bool parserCallback_noCollisionSlide(ParserNode *node);
+
+ virtual bool closedKeyCallback(ParserNode *node) override;
+ virtual bool textCallback(const Common::String &val) override;
+
+public:
+ InGameScene *_scene;
+
+ // Free Move Zones have to be handled separately just to handle a single
+ // corner case where the grid size is overridden.
+ TeVector2f32 _fmzGridSize;
+
+ enum TextNodeType {
+ TextNodeNone,
+ TextNodePosition,
+ TextNodeGridSize
+ };
+
+ TextNodeType _textNodeType;
+
+};
+
+} // end namespace Tetraedge
+
+#endif // TETRAEDGE_GAME_IN_GAME_SCENE_XML_PARSER_H
diff --git a/engines/tetraedge/game/lua_binds.cpp b/engines/tetraedge/game/lua_binds.cpp
index 7b29235c5d1..4b533ad5aab 100644
--- a/engines/tetraedge/game/lua_binds.cpp
+++ b/engines/tetraedge/game/lua_binds.cpp
@@ -550,9 +550,9 @@ static int tolua_ExportedFunctions_DeleteCallbackPlayer00(lua_State *L) {
}
static void AddMarker(const Common::String &markerName, const Common::String &imgPath, float x, float y,
- const Common::String &loctype, const Common::String &markerVal) {
+ const Common::String &loctype, const Common::String &markerVal, float anchorX, float anchorY) {
Game *game = g_engine->getGame();
- game->scene().addMarker(markerName, imgPath, x, y, loctype, markerVal);
+ game->scene().addMarker(markerName, imgPath, x, y, loctype, markerVal, anchorX, anchorY);
}
static int tolua_ExportedFunctions_AddMarker00(lua_State *L) {
@@ -562,7 +562,6 @@ static int tolua_ExportedFunctions_AddMarker00(lua_State *L) {
&& tolua_isstring(L, 5, 1, &err) && tolua_isstring(L, 6, 1, &err)
&& tolua_isnumber(L, 7, 1, &err) && tolua_isnumber(L, 8, 1, &err)
&& tolua_isnoobj(L, 9, &err)) {
- // Syberia 1 version
Common::String s1(tolua_tostring(L, 1, nullptr));
Common::String s2(tolua_tostring(L, 2, nullptr));
double n1 = tolua_tonumber(L, 3, 0.0);
@@ -571,10 +570,7 @@ static int tolua_ExportedFunctions_AddMarker00(lua_State *L) {
Common::String s4(tolua_tostring(L, 6, ""));
double n3 = tolua_tonumber(L, 7, 0.0);
double n4 = tolua_tonumber(L, 8, 0.0);
- if (n3 || n4) {
- warning("TODO: handle extra params for AddMarker %f %f", n3, n4);
- }
- AddMarker(s1, s2, n1, n2, s3, s4);
+ AddMarker(s1, s2, n1, n2, s3, s4, n3, n4);
return 0;
}
error("#ferror in function 'AddMarker': %d %d %s", err.index, err.array, err.type);
@@ -2320,6 +2316,38 @@ static int tolua_ExportedFunctions_SetCharacterPlayerPosition00(lua_State *L) {
error("#ferror in function 'SetCharacterPlayerPosition': %d %d %s", err.index, err.array, err.type);
}
+static void SetCharacterPlayerAnimation(const Common::String &animname, bool repeat, bool returnToIdle, int startframe, int endframe) {
+ Game *game = g_engine->getGame();
+ Character *c = game->scene()._character;
+ if (!c) {
+ warning("SetCharacterPlayerAnimation: no active character");
+ return;
+ }
+
+ bool result = c->setAnimation(animname, repeat, returnToIdle, false, startframe, endframe);
+ if (!result) {
+ warning("[SetCharacterPlayerAnimation] Character's animation \"%s\" doesn't exist",
+ animname.c_str());
+ }
+}
+
+static int tolua_ExportedFunctions_SetCharacterPlayerAnimation00(lua_State *L) {
+ tolua_Error err;
+ if (tolua_isstring(L, 1, 0, &err) && tolua_isboolean(L, 2, 1, &err)
+ && tolua_isboolean(L, 3, 1, &err) && tolua_isnumber(L, 4, 1, &err)
+ && tolua_isnumber(L, 5, 1, &err) && tolua_isnoobj(L, 6, &err)) {
+ Common::String s1(tolua_tostring(L, 1, nullptr));
+ bool b1 = tolua_toboolean(L, 2, 1);
+ bool b2 = tolua_toboolean(L, 3, 0);
+ double f3 = tolua_tonumber(L, 4, -1.0);
+ double f4 = tolua_tonumber(L, 5, 9999.0);
+ SetCharacterPlayerAnimation(s1, b1, b2, (int)f3, (int)f4);
+ return 0;
+ }
+ warning("#ferror in function 'SetCharacterPlayerAnimation': %d %d %s", err.index, err.array, err.type);
+ return 0;
+}
+
static void AddUnlockedAnim(const Common::String &name) {
// Note: does nothing, but we needed to add it..
}
@@ -2494,6 +2522,7 @@ void LuaOpenBinds(lua_State *L) {
tolua_function(L, "CurrentCharacterPlayerAnimation", tolua_ExportedFunctions_CurrentCharacterPlayerAnimation00);
tolua_function(L, "SetCharacterPlayerRotation", tolua_ExportedFunctions_SetCharacterPlayerRotation00);
tolua_function(L, "SetCharacterPlayerPosition", tolua_ExportedFunctions_SetCharacterPlayerPosition00);
+ tolua_function(L, "SetCharacterPlayerAnimation", tolua_ExportedFunctions_SetCharacterPlayerAnimation00);
tolua_function(L, "AddUnlockedAnim", tolua_ExportedFunctions_AddUnlockedAnim00);
// TODO Syberia 2 functions..
@@ -2501,7 +2530,6 @@ void LuaOpenBinds(lua_State *L) {
//tolua_function(L, "PlaySnowCustom", tolua_ExportedFunctions_PlaySnowCustom00);
//tolua_function(L, "SnowCustomVisible", tolua_ExportedFunctions_SnowCustomVisible00);
//tolua_function(L, "RemoveRandomSound", tolua_ExportedFunctions_RemoveRandomSound00);
- //tolua_function(L, "SetCharacterPlayerAnimation", tolua_ExportedFunctions_SetCharacterPlayerAnimation00);
//tolua_function(L, "SetYoukiFollowKate", tolua_ExportedFunctions_SetYoukiFollowKate00);
//tolua_function(L, "PlaySmoke", tolua_ExportedFunctions_PlaySmoke00);
//tolua_function(L, "SmokeVisible", tolua_ExportedFunctions_SmokeVisible00);
diff --git a/engines/tetraedge/module.mk b/engines/tetraedge/module.mk
index 2ffb78d875b..500b51585c1 100644
--- a/engines/tetraedge/module.mk
+++ b/engines/tetraedge/module.mk
@@ -23,6 +23,7 @@ MODULE_OBJS := \
game/help_option_menu.o \
game/how_to.o \
game/in_game_scene.o \
+ game/in_game_scene_xml_parser.o \
game/inventory.o \
game/inventory_menu.o \
game/inventory_object.o \
@@ -47,6 +48,7 @@ MODULE_OBJS := \
te/te_bezier_curve.o \
te/te_button_layout.o \
te/te_camera.o \
+ te/te_camera_xml_parser.o \
te/te_checkbox_layout.o \
te/te_clip_layout.o \
te/te_color.o \
diff --git a/engines/tetraedge/te/te_3d_object2.cpp b/engines/tetraedge/te/te_3d_object2.cpp
index d9f78e4bd0d..51b2a7f7894 100644
--- a/engines/tetraedge/te/te_3d_object2.cpp
+++ b/engines/tetraedge/te/te_3d_object2.cpp
@@ -90,9 +90,11 @@ int Te3DObject2::childIndex(Te3DObject2 *c) const {
}
/*static*/
-void Te3DObject2::deserialize(Common::ReadStream &stream, Te3DObject2 &dest) {
- Common::String str = deserializeString(stream);
- dest.setName(str);
+void Te3DObject2::deserialize(Common::ReadStream &stream, Te3DObject2 &dest, bool includesName /* = true */) {
+ if (includesName) {
+ Common::String str = deserializeString(stream);
+ dest.setName(str);
+ }
TeVector3f32 vect;
TeVector3f32::deserialize(stream, vect);
diff --git a/engines/tetraedge/te/te_3d_object2.h b/engines/tetraedge/te/te_3d_object2.h
index efce9d64989..0af3b054ca1 100644
--- a/engines/tetraedge/te/te_3d_object2.h
+++ b/engines/tetraedge/te/te_3d_object2.h
@@ -64,7 +64,9 @@ public:
return _colorInheritance;
}
- static void deserialize(Common::ReadStream &stream, Te3DObject2 &dest);
+ /* Note: Added control for includesName not in original as Syberia 2 data format uses
+ the file name as the model name. */
+ static void deserialize(Common::ReadStream &stream, Te3DObject2 &dest, bool includesName = true);
static void serialize(Common::WriteStream &stream, Te3DObject2 &src);
virtual void draw() {}
diff --git a/engines/tetraedge/te/te_camera.cpp b/engines/tetraedge/te/te_camera.cpp
index 13177cf3eb4..67ea2b658ce 100644
--- a/engines/tetraedge/te/te_camera.cpp
+++ b/engines/tetraedge/te/te_camera.cpp
@@ -24,6 +24,8 @@
#include "tetraedge/tetraedge.h"
#include "tetraedge/te/te_camera.h"
+#include "tetraedge/te/te_camera_xml_parser.h"
+#include "tetraedge/te/te_core.h"
#include "tetraedge/te/te_matrix4x4.h"
#include "tetraedge/te/te_renderer.h"
@@ -32,7 +34,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),*/
- _fov(40.0f), _somePerspectiveVal(1.0f), _viewportX(0), _viewportY(0), _viewportW(0),
+ _fov(40.0f), _aspectRatio(1.0f), _viewportX(0), _viewportY(0), _viewportW(0),
_viewportH(0)
{
}
@@ -116,7 +118,7 @@ void 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(1, 1, _aspectRatio / f);
_projectionMatrix.setValue(2, 2, -(_orthNearVal + _orthFarVal) / (_orthNearVal - _orthFarVal));
_projectionMatrix.setValue(3, 2, 1.0);
_projectionMatrix.setValue(2, 3, (_orthFarVal * 2) * _orthNearVal / (_orthNearVal - _orthFarVal));
@@ -126,7 +128,7 @@ void TeCamera::buildPerspectiveMatrix2() {
void TeCamera::buildPerspectiveMatrix3() {
_projectionMatrix = TeMatrix4x4();
float f = tanf(_fov * 0.5);
- _projectionMatrix.setValue(0, 0, (1.0 / f) / _somePerspectiveVal);
+ _projectionMatrix.setValue(0, 0, (1.0 / f) / _aspectRatio);
_projectionMatrix.setValue(1, 1, 1.0 / f);
_projectionMatrix.setValue(2, 2, -(_orthNearVal + _orthFarVal) / (_orthNearVal - _orthFarVal));
_projectionMatrix.setValue(3, 2, 1.0);
@@ -163,13 +165,31 @@ Math::Ray TeCamera::getRay(const TeVector2s32 &pxloc) {
return ray;
}
-void TeCamera::loadBin(const Common::String &path) {
+void TeCamera::loadXml(const Common::Path &path) {
+ setName(path.getLastComponent().toString());
+ _projectionMatrixType = 3;
+ TeCore *core = g_engine->getCore();
+ Common::FSNode node = core->findFile(path);
+ if (!node.isReadable()) {
+ warning("Can't open camera data %s", path.toString().c_str());
+ }
+ TeCameraXmlParser parser;
+ parser._cam = this;
+ if (!parser.loadFile(node))
+ error("TeCamera::loadXml: can't load file %s", node.getPath().c_str());
+ if (!parser.parse())
+ error("TeCamera::loadXml: error parsing %s", node.getPath().c_str());
+}
+
+/*
+void TeCamera::loadBin(const Common::Path &path) {
error("TODO: Implement TeCamera::loadBin");
}
void TeCamera::loadBin(const Common::ReadStream &stream) {
error("TODO: Implement TeCamera::loadBin");
}
+*/
void TeCamera::orthogonalParams(float left, float right, float top, float bottom) {
_orthogonalParamL = left;
diff --git a/engines/tetraedge/te/te_camera.h b/engines/tetraedge/te/te_camera.h
index 39c337ca908..320189e003c 100644
--- a/engines/tetraedge/te/te_camera.h
+++ b/engines/tetraedge/te/te_camera.h
@@ -49,8 +49,13 @@ public:
Math::Ray getRay(const TeVector2s32 &pxloc);
- void loadBin(const Common::String &path);
- void loadBin(const Common::ReadStream &stream);
+ // Syberia 2 redefines loadBin to actually load XML.
+ // We just have a separate function.
+ void loadXml(const Common::Path &path);
+
+ // Unused in Syberia 1.
+ //void loadBin(const Common::Path &path);
+ //void loadBin(const Common::ReadStream &stream);
//void lookAt(const TeVector3f32 &point) {} // empty and unused?
@@ -77,9 +82,11 @@ public:
}
void setProjMatrixType(int matrixType) { _projectionMatrixType = matrixType; }
int projMatrixType() const { return _projectionMatrixType; }
- void setPerspectiveVal(float val) { _somePerspectiveVal = val; }
+ void setAspectRatio(float val) { _aspectRatio = val; }
float orthoNearPlane() const { return _orthNearVal; }
float orthoFarPlane() const { return _orthFarVal; }
+ void setOrthoNear(float f) { _orthNearVal = f; }
+ void setOrthoFar(float f) { _orthFarVal = f; }
private:
void updateProjectionMatrix();
@@ -88,7 +95,7 @@ private:
float _orthNearVal;
float _orthFarVal;
float _fov;
- float _somePerspectiveVal;
+ float _aspectRatio;
int _viewportX;
int _viewportY;
diff --git a/engines/tetraedge/te/te_camera_xml_parser.cpp b/engines/tetraedge/te/te_camera_xml_parser.cpp
new file mode 100644
index 00000000000..22749f87bd5
--- /dev/null
+++ b/engines/tetraedge/te/te_camera_xml_parser.cpp
@@ -0,0 +1,72 @@
+/* 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_camera_xml_parser.h"
+
+namespace Tetraedge {
+
+bool TeCameraXmlParser::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());
+ _cam->setPosition(TeVector3f32(x, y, z));
+ return true;
+}
+
+bool TeCameraXmlParser::parserCallback_rotation(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());
+ float w = atof(node->values["w"].c_str());
+ _cam->setRotation(TeQuaternion(x, y, z, w));
+ return true;
+
+}
+
+bool TeCameraXmlParser::parserCallback_scale(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());
+ _cam->setScale(TeVector3f32(x, y, z));
+ return true;
+}
+
+bool TeCameraXmlParser::parserCallback_fov(ParserNode *node) {
+ _cam->setFov(atof(node->values["value"].c_str()));
+ return true;
+}
+
+bool TeCameraXmlParser::parserCallback_aspect(ParserNode *node) {
+ _cam->setAspectRatio(atof(node->values["value"].c_str()));
+ return true;
+}
+
+bool TeCameraXmlParser::parserCallback_near(ParserNode *node) {
+ _cam->setOrthoNear(atof(node->values["value"].c_str()));
+ return true;
+}
+
+bool TeCameraXmlParser::parserCallback_far(ParserNode *node) {
+ _cam->setOrthoFar(atof(node->values["value"].c_str()));
+ return true;
+}
+
+} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_camera_xml_parser.h b/engines/tetraedge/te/te_camera_xml_parser.h
new file mode 100644
index 00000000000..51da23e6707
--- /dev/null
+++ b/engines/tetraedge/te/te_camera_xml_parser.h
@@ -0,0 +1,83 @@
+/* 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_CAMERA_XML_PARSER_H
+#define TETRAEDGE_TE_TE_CAMERA_XML_PARSER_H
+
+#include "common/str.h"
+#include "common/formats/xmlparser.h"
+
+#include "tetraedge/te/te_camera.h"
+
+namespace Tetraedge {
+
+class TeCameraXmlParser : public Common::XMLParser {
+public:
+ // Parser
+ CUSTOM_XML_PARSER(TeCameraXmlParser) {
+ XML_KEY(camera)
+ XML_KEY(position)
+ XML_PROP(x, true)
+ XML_PROP(y, true)
+ XML_PROP(z, true)
+ KEY_END()
+ XML_KEY(rotation)
+ XML_PROP(x, true)
+ XML_PROP(y, true)
+ XML_PROP(z, true)
+ XML_PROP(w, true)
+ KEY_END()
+ XML_KEY(scale)
+ XML_PROP(x, true)
+ XML_PROP(y, true)
+ XML_PROP(z, true)
+ KEY_END()
+ XML_KEY(fov)
+ XML_PROP(value, true)
+ KEY_END()
+ XML_KEY(aspect)
+ XML_PROP(value, true)
+ KEY_END()
+ XML_KEY(near)
+ XML_PROP(value, true)
+ KEY_END()
+ XML_KEY(far)
+ XML_PROP(value, true)
+ KEY_END()
+ KEY_END()
+ } PARSER_END()
+
+public:
+ bool parserCallback_camera(ParserNode *node) { return true; }
+ bool parserCallback_position(ParserNode *node);
+ bool parserCallback_rotation(ParserNode *node);
+ bool parserCallback_scale(ParserNode *node);
+ bool parserCallback_fov(ParserNode *node);
+ bool parserCallback_aspect(ParserNode *node);
+ bool parserCallback_near(ParserNode *node);
+ bool parserCallback_far(ParserNode *node);
+
+ TeCamera *_cam;
+};
+
+} // end namespace Tetraedge
+
+#endif // TETRAEDGE_TE_TE_CAMERA_XML_PARSER_H
diff --git a/engines/tetraedge/te/te_free_move_zone.cpp b/engines/tetraedge/te/te_free_move_zone.cpp
index bfa55b8d9a6..9935ca83aea 100644
--- a/engines/tetraedge/te/te_free_move_zone.cpp
+++ b/engines/tetraedge/te/te_free_move_zone.cpp
@@ -21,10 +21,14 @@
#include "tetraedge/tetraedge.h"
+#include "common/file.h"
+#include "common/compression/zlib.h"
+
#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"
+#include "tetraedge/te/te_core.h"
namespace Tetraedge {
@@ -104,6 +108,13 @@ void TeFreeMoveZone::buildAStar() {
if (graphSize._x == 0 || graphSize._y == 0)
return;
+ bool regenerate = true;
+ if (!_aszGridPath.empty()) {
+ regenerate = !loadAStar(_aszGridPath, graphSize);
+ }
+ if (!regenerate)
+ return;
+
if (!_loadedFromBin) {
for (int x = 0; x < graphSize._x; x++) {
for (int y = 0; y < graphSize._y; y++) {
@@ -141,8 +152,67 @@ void TeFreeMoveZone::buildAStar() {
}
}
+bool TeFreeMoveZone::loadAStar(const Common::Path &path, const TeVector2s32 &size) {
+ Common::FSNode node = g_engine->getCore()->findFile(path);
+ Common::File file;
+ if (!node.isReadable() || !file.open(node)) {
+ warning("[TeFreeMoveZone::loadAStar] Can't open file : %s.", path.toString().c_str());
+ return false;
+ }
+ TeVector2s32 readSize;
+ readSize.deserialize(file, readSize);
+ if (size != readSize) {
+ warning("[TeFreeMoveZone::loadAStar] Wrong file : %s.", path.toString().c_str());
+ return false;
+ }
+ uint32 bytes = file.readUint32LE();
+ if (bytes > 100000)
+ error("Improbable size %d for compressed astar data", bytes);
+
+ unsigned long decompBytes = size._x * size._y;
+ byte *buf = new byte[bytes];
+ byte *outBuf = new byte[decompBytes];
+ file.read(buf, bytes);
+ bool result = Common::uncompress(outBuf, &decompBytes, buf, bytes);
+ delete [] buf;
+ if (result) {
+ for (uint i = 0; i < decompBytes; i++)
+ _graph->_flags.data()[i] = outBuf[i];
+ }
+ delete [] outBuf;
+ return result;
+}
+
+
void TeFreeMoveZone::calcGridMatrix() {
- error("TODO: Implement TeFreeMoveZone::calcGridMatrix");
+ float angle = 0.0f;
+ float mul = 0.0f;
+ for (uint i = 0; i < _borders.size() - 1; i += 2) {
+ const TeVector3f32 &v1 = _verticies[_borders[i]];
+ const TeVector3f32 &v2 = _verticies[_borders[i + 1]];
+ const TeVector3f32 diff = v2 - v1;
+ const TeVector2f32 diff2(diff.x(), diff.z());
+ float len = diff2.length();
+ float f = fmod(atan2(diff.z(), diff.x()), M_PI_2);
+ if (f < 0)
+ f += M_PI_2;
+
+ if (f - angle < -M_PI_4) {
+ angle -= M_PI_2;
+ } else if (f - angle > M_PI_4) {
+ f -= M_PI_2;
+ }
+
+ angle *= mul;
+ mul += len;
+ angle = fmod((f * len + angle) / mul, M_PI_2);
+ if (angle < 0)
+ angle += M_PI_2;
+ }
+
+ const TeQuaternion rot = TeQuaternion::fromAxisAndAngle(TeVector3f32(0, 1, 0), angle);
+ const TeMatrix4x4 rotMatrix = rot.toTeMatrix();
+ _gridMatrix = TeMatrix4x4() * rotMatrix;
}
void TeFreeMoveZone::clear() {
@@ -239,8 +309,8 @@ 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) {
+void TeFreeMoveZone::deserialize(Common::ReadStream &stream, TeFreeMoveZone &dest, const Common::Array<TeBlocker> *blockers,
+ const Common::Array<TeRectBlocker> *rectblockers, const Common::Array<TeActZone> *actzones) {
dest.clear();
TePickMesh2::deserialize(stream, dest);
TeVector2f32::deserialize(stream, dest._gridSquareSize);
@@ -330,7 +400,6 @@ static int segmentIntersection(const TeVector2f32 &s1start, const TeVector2f32 &
return result;
}
-
byte TeFreeMoveZone::hasBlockerIntersection(const TeVector2s32 &pt) {
TeVector2f32 borders[4];
@@ -417,6 +486,59 @@ TeActZone *TeFreeMoveZone::isInZone(const TeVector3f32 &pt) {
error("TODO: Implement TeFreeMoveZone::isInZone");
}
+bool TeFreeMoveZone::loadBin(const Common::Path &path, const Common::Array<TeBlocker> *blockers,
+ const Common::Array<TeRectBlocker> *rectblockers, const Common::Array<TeActZone> *actzones,
+ const TeVector2f32 &gridSize) {
+ Common::FSNode node = g_engine->getCore()->findFile(path);
+ if (!node.isReadable()) {
+ warning("[TeFreeMoveZone::loadBin] Can't open file : %s.", node.getName().c_str());
+ return false;
+ }
+ _aszGridPath = path.append(".aszgrid");
+ Common::File file;
+ file.open(node);
+ return loadBin(file, blockers, rectblockers, actzones, gridSize);
+}
+
+bool TeFreeMoveZone::loadBin(Common::ReadStream &stream, const Common::Array<TeBlocker> *blockers,
+ const Common::Array<TeRectBlocker> *rectblockers, const Common::Array<TeActZone> *actzones,
+ const TeVector2f32 &gridSize) {
+ _loadGridSize = gridSize;
+ _loadedFromBin = true;
+
+ // Load position, rotation, scale (not name)
+ Te3DObject2::deserialize(stream, *this, false);
+
+ Common::Array<TeVector3f32> vecs;
+ Te3DObject2::deserializeVectorArray(stream, vecs);
+
+ uint32 triangles = stream.readUint32LE();
+ _freeMoveZoneVerticies.resize(triangles * 3);
+ _gridDirty = true;
+ _transformedVerticiesDirty = true;
+ _bordersDirty = true;
+ _pickMeshDirty = true;
+ _projectedPointsDirty = true;
+
+ for (uint v = 0; v < triangles * 3; v++) {
+ uint16 s = stream.readUint16LE();
+ if (s >= vecs.size())
+ error("Invalid vertex offset %d (of %d) loading TeFreeMoveZone", s, vecs.size());
+ _freeMoveZoneVerticies[v] = vecs[s];
+ }
+ updateTransformedVertices();
+ updatePickMesh();
+
+ _blockers = blockers;
+ _rectBlockers = rectblockers;
+ _actzones = actzones;
+ updateGrid(false);
+ Common::Path p(name());
+ setName(p.getLastComponent().toString());
+
+ return true;
+}
+
bool TeFreeMoveZone::onViewportChanged() {
_projectedPointsDirty = true;
return false;
@@ -443,6 +565,7 @@ void TeFreeMoveZone::preUpdateGrid() {
_gridTopLeft.setX(newVec.x());
_gridTopLeft.setY(newVec.z());
+ _gridBottomRight = _gridTopLeft;
_gridWorldY = newVec.y();
}
@@ -454,18 +577,16 @@ void TeFreeMoveZone::preUpdateGrid() {
else
newVec = gridInverse * _freeMoveZoneVerticies[vertNo];
- if (_gridTopLeft.getX() <= newVec.x()) {
- if (_gridBottomRight.getX() < newVec.x())
- _gridBottomRight.setX(newVec.x());
- } else {
+ if (_gridTopLeft.getX() > newVec.x()) {
_gridTopLeft.setX(newVec.x());
+ } else if (_gridBottomRight.getX() < newVec.x()) {
+ _gridBottomRight.setX(newVec.x());
}
- if (_gridTopLeft.getY() <= newVec.z()) {
- if (_gridBottomRight.getY() < newVec.z())
- _gridBottomRight.setY(newVec.z());
- } else {
+ if (_gridTopLeft.getY() > newVec.z()) {
_gridTopLeft.setY(newVec.z());
+ } else if (_gridBottomRight.getY() < newVec.z()) {
+ _gridBottomRight.setY(newVec.z());
}
if (newVec.y() < _gridWorldY)
@@ -478,17 +599,15 @@ void TeFreeMoveZone::preUpdateGrid() {
else
_gridSquareSize = TeVector2f32(2.0f, 2.0f);
} else {
+ /* Syberia 1 code, never actually used..
const TeVector2f32 gridVecDiff = _gridBottomRight - _gridTopLeft;
float minSide = MIN(gridVecDiff.getX(), gridVecDiff.getY()) / 20.0f;
_gridSquareSize.setX(minSide);
_gridSquareSize.setY(minSide);
-
- error("FIXME: Finish preUpdateGrid for loaded-from-bin case.");
- /*
- // what's this field?
- if (_field_0x414.x != 0.0)
- _gridOffsetSomething = _field_0x414;
+ if (_loadGridSize.getX())
+ _gridSquareSize = _loadGridSize;
*/
+ _gridSquareSize = TeVector2f32(20.0f, 20.0f);
}
TeMatrix4x4 worldTrans = worldTransformationMatrix();
@@ -501,7 +620,11 @@ TeVector2s32 TeFreeMoveZone::projectOnAStarGrid(const TeVector3f32 &pt) {
if (!_loadedFromBin) {
offsetpt = TeVector2f32(pt.x() - _gridTopLeft.getX(), pt.z() - _gridTopLeft.getY());
} else {
- error("TODO: Implement TeFreeMoveZone::projectOnAStarGrid for _loadedFromBin");
+ TeMatrix4x4 invGrid = _gridMatrix;
+ invGrid.inverse();
+ TeVector3f32 transPt = invGrid * (_inverseWorldTransform * pt);
+ offsetpt.setX(transPt.x() - _gridTopLeft.getX());
+ offsetpt.setY(transPt.y() - _gridTopLeft.getY());
}
const TeVector2f32 projected = offsetpt / _gridSquareSize;
return TeVector2s32((int)projected.getX(), (int)projected.getY());
@@ -613,36 +736,34 @@ void TeFreeMoveZone::updateBorders() {
updatePickMesh();
- if (_verticies.size() > 2) {
- 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 (uint triNo2 = 0; triNo2 < _verticies.size() / 3; triNo2++) {
- if (skip)
- break;
+ 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];
- for (uint vecNo2 = 0; vecNo2 < 3; vecNo2++) {
- if (triNo2 == triNo1)
- continue;
- 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) {
- skip = true;
- break;
- }
+ bool skip = false;
+ for (uint triNo2 = 0; triNo2 < _verticies.size() / 3; triNo2++) {
+ if (skip)
+ break;
+ if (triNo2 == triNo1)
+ continue;
+
+ for (uint vecNo2 = 0; vecNo2 < 3; vecNo2++) {
+ uint right1 = triNo2 * 3 + vecNo2;
+ uint right2 = triNo2 * 3 + (vecNo2 == 2 ? 0 : vecNo2 + 1);
+ const TeVector3f32 vright1 = _verticies[right1];
+ const 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);
- }
+ }
+ if (!skip) {
+ _borders.push_back(left1);
+ _borders.push_back(left2);
}
}
}
@@ -674,7 +795,7 @@ void TeFreeMoveZone::updatePickMesh() {
_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);
diff --git a/engines/tetraedge/te/te_free_move_zone.h b/engines/tetraedge/te/te_free_move_zone.h
index 3dd60bd6f52..e2b77ce7660 100644
--- a/engines/tetraedge/te/te_free_move_zone.h
+++ b/engines/tetraedge/te/te_free_move_zone.h
@@ -81,6 +81,14 @@ public:
TeActZone *isInZone(const TeVector3f32 &pt);
+ bool loadAStar(const Common::Path &path, const TeVector2s32 &size);
+ bool loadBin(const Common::Path &path, const Common::Array<TeBlocker> *blockers,
+ const Common::Array<TeRectBlocker> *rectblockers, const Common::Array<TeActZone> *actzones,
+ const TeVector2f32 &gridSize);
+ bool loadBin(Common::ReadStream &stream, const Common::Array<TeBlocker> *blockers,
+ const Common::Array<TeRectBlocker> *rectblockers, const Common::Array<TeActZone> *actzones,
+ const TeVector2f32 &gridSize);
+
// loadBin() 2 versions, seem unused
// name(), onPositionChanged(), position(), rotate(), rotation(), scale(),
@@ -107,8 +115,8 @@ public:
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 deserialize(Common::ReadStream &stream, TeFreeMoveZone &dest, const Common::Array<TeBlocker> *blockers,
+ const Common::Array<TeRectBlocker> *rectblockers, const Common::Array<TeActZone> *actzones);
static void serialize(Common::WriteStream &stream, const TeFreeMoveZone &src, bool updateFirst);
static TePickMesh2 *findNearestMesh(TeIntrusivePtr<TeCamera> &camera, const TeVector2s32 &frompt,
@@ -119,9 +127,9 @@ public:
private:
TeVector2s32 aStarResolution() const;
- Common::Array<TeActZone> *_actzones;
- Common::Array<TeBlocker> *_blockers;
- Common::Array<TeRectBlocker> *_rectBlockers;
+ const Common::Array<TeActZone> *_actzones;
+ const Common::Array<TeBlocker> *_blockers;
+ const Common::Array<TeRectBlocker> *_rectBlockers;
Common::Array<TeVector3f32> _freeMoveZoneVerticies;
Common::Array<uint> _pickMesh;
@@ -131,6 +139,7 @@ private:
TeVector2f32 _gridSquareSize;
TeVector2f32 _gridTopLeft;
TeVector2f32 _gridBottomRight;
+ TeVector2f32 _loadGridSize; // At least, it seems unused?
TeMatrix4x4 _gridMatrix;
TeMatrix4x4 _inverseWorldTransform;
@@ -151,6 +160,8 @@ private:
micropather::MicroPather *_micropather;
TeTimer _updateTimer;
+
+ Common::Path _aszGridPath;
};
} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_lua_thread.cpp b/engines/tetraedge/te/te_lua_thread.cpp
index 45bc41a5861..417a5ad8ff0 100644
--- a/engines/tetraedge/te/te_lua_thread.cpp
+++ b/engines/tetraedge/te/te_lua_thread.cpp
@@ -92,7 +92,11 @@ void TeLuaThread::execute(const Common::String &fname, const TeVariant &p1) {
pushValue(p1);
_resume(1);
} else {
- if (!fname.contains("Update"))
+ // Don't report Update (as original) or some other functions which are not
+ // implemented in both games
+ if (!fname.contains("Update") && !fname.equals("OnCellCharacterAnimationPlayerFinished")
+ && !fname.equals("OnCharacterAnimationFinished") && !fname.equals("OnCellDialogFinished")
+ && !fname.equals("OnCellFreeSoundFinished"))
debug("[TeLuaThread::Execute1] Function: \"%s\" does not exist", fname.c_str());
lua_settop(_luaThread, -2);
}
diff --git a/engines/tetraedge/te/te_vector2f32.cpp b/engines/tetraedge/te/te_vector2f32.cpp
index 5cc007f5413..2aaaaa328c0 100644
--- a/engines/tetraedge/te/te_vector2f32.cpp
+++ b/engines/tetraedge/te/te_vector2f32.cpp
@@ -22,6 +22,7 @@
#include "tetraedge/te/te_vector2f32.h"
#include "tetraedge/te/te_vector2s32.h"
#include "tetraedge/te/te_vector3f32.h"
+#include "tetraedge/tetraedge.h"
namespace Tetraedge {
@@ -30,5 +31,14 @@ TeVector2f32::TeVector2f32(const TeVector2s32 &other) {
setY(other._y);
}
+bool TeVector2f32::parse(const Common::String &val) {
+ const Common::StringArray parts = TetraedgeEngine::splitString(val, ',');
+ if (parts.size() != 2)
+ return false;
+ setX(atof(parts[0].c_str()));
+ setY(atof(parts[1].c_str()));
+ return true;
+}
+
} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_vector2f32.h b/engines/tetraedge/te/te_vector2f32.h
index 66408fce170..a86dc3c8e84 100644
--- a/engines/tetraedge/te/te_vector2f32.h
+++ b/engines/tetraedge/te/te_vector2f32.h
@@ -61,6 +61,8 @@ public:
return sqrt(getX() * getX() + getY() * getY());
}
+ bool parse(const Common::String &val);
+
/*
TODO: do we need anything that isn't already in Vector2d here?
TeVector2f32(const TeVector2f32 &other);
More information about the Scummvm-git-logs
mailing list