From c27dca6b829268fdeb2c83a9d936343ab2ec8015 Mon Sep 17 00:00:00 2001
From: Matthew Duggan <mgithub@guarana.org>
Date: Sat, 26 Nov 2022 22:49:00 +0900
Subject: [PATCH] TETRAEDGE: More WIP. Lots of progress

Many pieces of the first room of the game are now working.
---
 engines/tetraedge/game/application.cpp        |  34 ++++-
 engines/tetraedge/game/billboard.cpp          |   7 +-
 engines/tetraedge/game/character.cpp          |  81 +++++++++--
 engines/tetraedge/game/character.h            |   9 +-
 engines/tetraedge/game/dialog2.cpp            |   3 +-
 engines/tetraedge/game/dialog2.h              |   3 +-
 engines/tetraedge/game/documents_browser.cpp  | 135 +++++++++++++++---
 engines/tetraedge/game/documents_browser.h    |  12 +-
 engines/tetraedge/game/game.cpp               |  47 +++---
 engines/tetraedge/game/game.h                 |  11 +-
 engines/tetraedge/game/in_game_scene.cpp      |  10 +-
 engines/tetraedge/game/inventory.cpp          |   6 +-
 engines/tetraedge/game/lua_binds.cpp          |  95 ++++++++++--
 engines/tetraedge/game/question2.h            |   1 +
 engines/tetraedge/te/te_3d_object2.cpp        |   6 +
 engines/tetraedge/te/te_3d_texture.cpp        |  15 +-
 engines/tetraedge/te/te_3d_texture.h          |   2 +-
 engines/tetraedge/te/te_button_layout.cpp     |  30 ++--
 engines/tetraedge/te/te_camera.cpp            |  24 ++--
 engines/tetraedge/te/te_checkbox_layout.cpp   |  12 +-
 engines/tetraedge/te/te_curve_anim2.h         |   1 +
 engines/tetraedge/te/te_font3.cpp             |  10 +-
 engines/tetraedge/te/te_font3.h               |   1 +
 engines/tetraedge/te/te_image.cpp             |   5 +-
 engines/tetraedge/te/te_image.h               |   2 +-
 engines/tetraedge/te/te_layout.cpp            |  74 +++++-----
 engines/tetraedge/te/te_layout.h              |   5 +-
 .../tetraedge/te/te_lua_gui_lua_callbacks.cpp |   6 +-
 engines/tetraedge/te/te_lua_thread.cpp        |   9 +-
 .../te/te_model_vertex_animation.cpp          |   9 +-
 engines/tetraedge/te/te_renderer.cpp          |  75 ++++++----
 engines/tetraedge/te/te_renderer.h            |   5 +-
 engines/tetraedge/te/te_scrolling_layout.cpp  |   9 ++
 engines/tetraedge/te/te_scrolling_layout.h    |   3 +
 engines/tetraedge/te/te_sprite_layout.cpp     |  21 ++-
 engines/tetraedge/te/te_text_base2.cpp        |   8 +-
 engines/tetraedge/te/te_tiled_surface.cpp     |  10 +-
 engines/tetraedge/te/te_tiled_texture.cpp     |   4 +
 engines/tetraedge/te/te_vector3f32.h          |   2 +-
 engines/tetraedge/te/te_xml_gui.cpp           |   3 +-
 40 files changed, 581 insertions(+), 224 deletions(-)

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;
+	_curPage = setPage;
 
-	error("TODO: Implement DocumentsBrowser::currentPage");
+	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 &currentColor() 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