[Scummvm-git-logs] scummvm master -> 31862a6847bbb894dbe31f1178b7fa97cd9ce490

mduggan noreply at scummvm.org
Sat Feb 4 23:20:42 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:
894a24dd63 JANITORIAL: Clarify comments about screenFormat
7a782f5b24 TETRAEDGE: Fixes for TinyGL rendering, almost works
fc86b54e75 TETRAEDGE: Refactor to use FSNode instead of Path
c6c91025c7 TETRAEDGE: Note direction of logic in showMarkers
31862a6847 TETRAEDGE: Limit head rotation in both directions


Commit: 894a24dd63514b0445abfbc6b378adf2003a3464
    https://github.com/scummvm/scummvm/commit/894a24dd63514b0445abfbc6b378adf2003a3464
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2023-02-05T08:02:12+09:00

Commit Message:
JANITORIAL: Clarify comments about screenFormat

Changed paths:
    common/system.h
    engines/util.h


diff --git a/common/system.h b/common/system.h
index 75ec497bdd5..1d99f746c2b 100644
--- a/common/system.h
+++ b/common/system.h
@@ -681,7 +681,11 @@ public:
 
 #ifdef USE_RGB_COLOR
 	/**
-	 * Determine the pixel format currently in use for screen rendering.
+	 * Fetch the pixel format currently in use for screen rendering.
+	 *
+	 * This is not neccessarily the native format for the system - if unset
+	 * it defaults toCLUT8.  To set a different format, engines should set
+	 * their preferred format using ::initGraphics().
 	 *
 	 * @return the active screen pixel format.
 	 *
diff --git a/engines/util.h b/engines/util.h
index ed3187e753b..d84ddbc4822 100644
--- a/engines/util.h
+++ b/engines/util.h
@@ -58,11 +58,12 @@ void initGraphicsModes(const Graphics::ModeList &modes);
  * Shows various warnings on certain backend graphics
  * transaction failures (aspect switch, fullscreen switch, etc.).
  *
- * Errors are returned when the backend is not able to switch to the specified
- * mode.
+ * An error dialog will be generated when the backend is not able to switch
+ * to the specified mode.
  *
- * Defaults to 256 color palette mode if no graphics format is provided.
- * Uses the preferred format of the backend if graphics format pointer is NULL.
+ * Defaults to CLUT8 (256 color palette) if only width and height provided.
+ * If graphics format is explicitly set to nullptr, uses the preferred format of
+ * the backend.
  * Finds the best compatible format if a list of graphics formats is provided.
  */
 void initGraphics(int width, int height);


Commit: 7a782f5b24fe8b618ac582edc41deeda6689435d
    https://github.com/scummvm/scummvm/commit/7a782f5b24fe8b618ac582edc41deeda6689435d
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2023-02-05T08:02:12+09:00

Commit Message:
TETRAEDGE: Fixes for TinyGL rendering, almost works

Changed paths:
    engines/tetraedge/te/te_3d_texture_opengl.cpp
    engines/tetraedge/te/te_3d_texture_tinygl.cpp
    engines/tetraedge/te/te_mesh_tinygl.cpp
    engines/tetraedge/te/te_renderer.h
    engines/tetraedge/te/te_renderer_opengl.cpp
    engines/tetraedge/te/te_renderer_opengl.h
    engines/tetraedge/te/te_renderer_tinygl.cpp
    engines/tetraedge/te/te_renderer_tinygl.h


diff --git a/engines/tetraedge/te/te_3d_texture_opengl.cpp b/engines/tetraedge/te/te_3d_texture_opengl.cpp
index efb352aa3c8..004baa8e471 100644
--- a/engines/tetraedge/te/te_3d_texture_opengl.cpp
+++ b/engines/tetraedge/te/te_3d_texture_opengl.cpp
@@ -195,8 +195,8 @@ void Te3DTextureOpenGL::update(const TeImage &img, uint xoff, uint yoff) {
 
 	setAccessName(img.getAccessName().append(".3dtex"));
 	glBindTexture(GL_TEXTURE_2D, _glTexture);
-	glPixelStorei(GL_UNPACK_SWAP_BYTES, 0);
-	glPixelStorei(GL_UNPACK_LSB_FIRST, 0);
+	glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
+	glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE);
 	glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
 	glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
 	glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
diff --git a/engines/tetraedge/te/te_3d_texture_tinygl.cpp b/engines/tetraedge/te/te_3d_texture_tinygl.cpp
index 4b00e9f5b29..71116ecb606 100644
--- a/engines/tetraedge/te/te_3d_texture_tinygl.cpp
+++ b/engines/tetraedge/te/te_3d_texture_tinygl.cpp
@@ -132,12 +132,13 @@ bool Te3DTextureTinyGL::load(const TeImage &img) {
 	_texHeight = _height;
 
 	tglBindTexture(TGL_TEXTURE_2D, _glTexture);
+	// Note: these are unsupported in TGL but should be the defaults?
 	//tglPixelStorei(TGL_UNPACK_SWAP_BYTES, TGL_FALSE);
 	//tglPixelStorei(TGL_UNPACK_LSB_FIRST, TGL_FALSE);
 	//tglPixelStorei(TGL_UNPACK_ROW_LENGTH, 0);
 	//tglPixelStorei(TGL_UNPACK_SKIP_ROWS, 0);
 	//tglPixelStorei(TGL_UNPACK_SKIP_PIXELS, 0);
-	//tglPixelStorei(TGL_UNPACK_ALIGNMENT, 1);
+	tglPixelStorei(TGL_UNPACK_ALIGNMENT, 1);
 
 	const void *imgdata = img.getPixels();
 	if (_format == TeImage::RGB8) {
@@ -185,11 +186,12 @@ void Te3DTextureTinyGL::update(const TeImage &img, uint xoff, uint yoff) {
 
 	setAccessName(img.getAccessName().append(".3dtex"));
 	tglBindTexture(TGL_TEXTURE_2D, _glTexture);
-	tglPixelStorei(TGL_UNPACK_SWAP_BYTES, 0);
-	tglPixelStorei(TGL_UNPACK_LSB_FIRST, 0);
-	tglPixelStorei(TGL_UNPACK_ROW_LENGTH, 0);
-	tglPixelStorei(TGL_UNPACK_SKIP_ROWS, 0);
-	tglPixelStorei(TGL_UNPACK_SKIP_PIXELS, 0);
+	// Note: these are unsupported in TGL but should be the defaults?
+	//tglPixelStorei(TGL_UNPACK_SWAP_BYTES, TGL_FALSE);
+	//tglPixelStorei(TGL_UNPACK_LSB_FIRST, TGL_FALSE);
+	//tglPixelStorei(TGL_UNPACK_ROW_LENGTH, 0);
+	//tglPixelStorei(TGL_UNPACK_SKIP_ROWS, 0);
+	//tglPixelStorei(TGL_UNPACK_SKIP_PIXELS, 0);
 	tglPixelStorei(TGL_UNPACK_ALIGNMENT, 1);
 
 	//const void *imgdata = img.getPixels();
diff --git a/engines/tetraedge/te/te_mesh_tinygl.cpp b/engines/tetraedge/te/te_mesh_tinygl.cpp
index 3f9db8ea0ca..f100363eebe 100644
--- a/engines/tetraedge/te/te_mesh_tinygl.cpp
+++ b/engines/tetraedge/te/te_mesh_tinygl.cpp
@@ -28,7 +28,7 @@
 
 namespace Tetraedge {
 
-TeMeshTinyGL::TeMeshTinyGL() : _glMeshMode(TGL_POINTS), _gltexEnvMode(TGL_MODULATE) {
+TeMeshTinyGL::TeMeshTinyGL() : _glMeshMode(TGL_POINTS), _gltexEnvMode(TGL_DECAL) {
 }
 
 void TeMeshTinyGL::draw() {
@@ -141,8 +141,8 @@ void TeMeshTinyGL::draw() {
 	if (!renderer->scissorEnabled())
 		tglDisable(TGL_SCISSOR_TEST);
 
-	// TODO: not supported in TGL
-	//tglTexEnvi(TGL_TEXTURE_ENV, TGL_TEXTURE_ENV_MODE, TGL_MODULATE);
+	// TODO: GL_MODULATE not supported in TGL
+	//tglTexEnvi(TGL_TEXTURE_ENV, TGL_TEXTURE_ENV_MODE, TGL_DECAL);
 	tglDisableClientState(TGL_VERTEX_ARRAY);
 	tglDisableClientState(TGL_NORMAL_ARRAY);
 	tglDisableClientState(TGL_COLOR_ARRAY);
@@ -151,19 +151,19 @@ void TeMeshTinyGL::draw() {
 
 	if (_drawWires && !normals.empty()) {
 		renderer->disableAllLights();
-		error("TODO: Properly implement _drawWires case in TeMesh::draw");
-		/*
+		//error("TODO: Properly implement _drawWires case in TeMesh::draw");
+		///*
 		// TODO: Reimplement without glBegin/glEnd
-		glBegin(TGL_LINES);
+		tglBegin(TGL_LINES);
 		renderer->setCurrentColor(TeColor(255, 255, 255, 255));
 		for (uint i = 0; i < verticies.size(); i++) {
-			glVertex3f(verticies[i].x(), verticies[i].y(), verticies[i].z());
-			glVertex3f(verticies[i].x() + normals[i].x(),
+			tglVertex3f(verticies[i].x(), verticies[i].y(), verticies[i].z());
+			tglVertex3f(verticies[i].x() + normals[i].x(),
 					verticies[i].y() + normals[i].y(),
 					verticies[i].z() + normals[i].z());
 		}
-		glEnd();
-		*/
+		tglEnd();
+		//*/
 	}
 
 	renderer->setMatrixMode(TeRenderer::MM_GL_MODELVIEW);
diff --git a/engines/tetraedge/te/te_renderer.h b/engines/tetraedge/te/te_renderer.h
index 4b72f6e6ca1..edb46d14c5d 100644
--- a/engines/tetraedge/te/te_renderer.h
+++ b/engines/tetraedge/te/te_renderer.h
@@ -134,6 +134,7 @@ public:
 	void dumpTransparentMeshData() const;
 	const TeColor &currentColor() const { return _currentColor; }
 
+	virtual void updateScreen() = 0;
 	virtual void updateGlobalLight() = 0;
 	virtual void applyMaterial(const TeMaterial &m) = 0;
 
diff --git a/engines/tetraedge/te/te_renderer_opengl.cpp b/engines/tetraedge/te/te_renderer_opengl.cpp
index a4be743d8c0..4a14b3dc2f2 100644
--- a/engines/tetraedge/te/te_renderer_opengl.cpp
+++ b/engines/tetraedge/te/te_renderer_opengl.cpp
@@ -21,6 +21,7 @@
 
 #include "common/textconsole.h"
 #include "common/debug.h"
+#include "common/system.h"
 
 #include "graphics/opengl/system_headers.h"
 
@@ -99,7 +100,8 @@ void TeRendererOpenGL::init(uint width, uint height) {
 	// Note: original doesn't separate but blends are nicer that way.
 	glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
 	glDepthFunc(GL_LEQUAL);
-	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_DONT_CARE);
+	// Original does this, probably not needed?
+	//glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_DONT_CARE);
 	glClearDepth(1.0);
 	glClearStencil(0);
 	_clearColor = TeColor(0, 0, 0, 255);
@@ -382,6 +384,10 @@ void TeRendererOpenGL::updateGlobalLight() {
 	TeLightOpenGL::updateGlobal();
 }
 
+void TeRendererOpenGL::updateScreen() {
+	g_system->updateScreen();
+}
+
 Common::String TeRendererOpenGL::vendor() {
 	return Common::String((const char *)glGetString(GL_VENDOR));
 }
diff --git a/engines/tetraedge/te/te_renderer_opengl.h b/engines/tetraedge/te/te_renderer_opengl.h
index 7bdd43ab1c2..128bce82663 100644
--- a/engines/tetraedge/te/te_renderer_opengl.h
+++ b/engines/tetraedge/te/te_renderer_opengl.h
@@ -54,6 +54,7 @@ public:
 	Common::String vendor() override;
 	void applyMaterial(const TeMaterial &m) override;
 	void updateGlobalLight() override;
+	void updateScreen() override;
 
 protected:
 
diff --git a/engines/tetraedge/te/te_renderer_tinygl.cpp b/engines/tetraedge/te/te_renderer_tinygl.cpp
index 8bd830f305c..a82b25a1055 100644
--- a/engines/tetraedge/te/te_renderer_tinygl.cpp
+++ b/engines/tetraedge/te/te_renderer_tinygl.cpp
@@ -90,9 +90,9 @@ void TeRendererTinyGL::enableZBuffer() {
 }
 
 void TeRendererTinyGL::init(uint width, uint height) {
-	Graphics::PixelFormat pixelFormat = g_system->getScreenFormat();
-	initGraphics(width, height, &pixelFormat);
+	initGraphics(width, height, nullptr);
 
+	const Graphics::PixelFormat pixelFormat = g_system->getScreenFormat();
 	debug(2, "INFO: TinyGL front buffer pixel format: %s", pixelFormat.toString().c_str());
 	TinyGL::createContext(width, height, pixelFormat, 256, true, ConfMan.getBool("dirtyrects"));
 
@@ -107,9 +107,10 @@ void TeRendererTinyGL::init(uint width, uint height) {
 	tglEnable(TGL_BLEND);
 	tglBlendFunc(TGL_SRC_ALPHA, TGL_ONE_MINUS_SRC_ALPHA);
 	tglDepthFunc(TGL_LEQUAL);
-	tglHint(TGL_PERSPECTIVE_CORRECTION_HINT, TGL_DONT_CARE);
+	// Original does this, probably not needed?
+	//tglHint(TGL_PERSPECTIVE_CORRECTION_HINT, TGL_DONT_CARE);
 	tglClearDepth(1.0);
-	tglClearStencil(0);
+	//tglClearStencil(0);
 	_clearColor = TeColor(0, 0, 0, 255);
 	tglClearColor(0, 0, 0, 1.0);
 	//TeOpenGLExtensions::loadExtensions(); // this does nothing in the game?
@@ -196,7 +197,7 @@ void TeRendererTinyGL::renderTransparentMeshes() {
 
 		if (meshProperties._scissorEnabled) {
 			tglEnable(TGL_SCISSOR_TEST);
-			// No scissoring in TGL..
+			// TODO: No scissoring in TGL..
 			/*
 			tglScissor(meshProperties._scissorX,
 					  meshProperties._scissorY,
@@ -204,7 +205,7 @@ void TeRendererTinyGL::renderTransparentMeshes() {
 					  meshProperties._scissorHeight);*/
 		}
 		// TODO: not supported in TGL
-		//tglTexEnvi(TGL_TEXTURE_ENV, TGL_TEXTURE_ENV_MODE, meshProperties._glTexEnvMode);
+		//tglTexEnvi(TGL_TEXTURE_ENV, TGL_TEXTURE_ENV_MODE, TGL_DECAL/*meshProperties._glTexEnvMode*/);
 		tglDrawElements(TGL_TRIANGLES, meshProperties._vertexCount, TGL_UNSIGNED_SHORT,
 				   _transparentMeshVertexNums.data() + vertsDrawn);
 
@@ -215,7 +216,7 @@ void TeRendererTinyGL::renderTransparentMeshes() {
 			tglEnableClientState(TGL_COLOR_ARRAY);
 		}
 		// TODO: not supported in TGL
-		//tglTexEnvi(TGL_TEXTURE_ENV, TGL_TEXTURE_ENV_MODE, TGL_MODULATE);
+		//tglTexEnvi(TGL_TEXTURE_ENV, TGL_TEXTURE_ENV_MODE, TGL_DECAL);
 		if (meshProperties._scissorEnabled) {
 			tglDisable(TGL_SCISSOR_TEST);
 		}
@@ -328,8 +329,8 @@ void TeRendererTinyGL::applyMaterial(const TeMaterial &m) {
 			tglTexEnvi(TGL_TEXTURE_ENV, TGL_OPERAND0_ALPHA, TGL_SRC_ALPHA);
 			*/
 		} else {
-			// TODO: not supported in TGL
-			//tglTexEnvi(TGL_TEXTURE_ENV, TGL_TEXTURE_ENV_MODE, TGL_MODULATE);
+			// TODO: GL_MODULATE supported in TGL
+			//tglTexEnvi(TGL_TEXTURE_ENV, TGL_TEXTURE_ENV_MODE, TGL_DECAL);
 			if (m._mode != TeMaterial::MaterialMode1) {
 				tglEnable(TGL_ALPHA_TEST);
 				tglAlphaFunc(TGL_GREATER, 0.5);
@@ -360,8 +361,8 @@ void TeRendererTinyGL::applyMaterial(const TeMaterial &m) {
 		static const float fullColor[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
 		TeLightTinyGL::disableAll();
 		tglDisable(TGL_ALPHA_TEST);
-		// TODO: not supported in TGL
-		//tglTexEnvi(TGL_TEXTURE_ENV, TGL_TEXTURE_ENV_MODE, TGL_MODULATE);
+		// TODO: GL_MODULATE not supported in TGL
+		//tglTexEnvi(TGL_TEXTURE_ENV, TGL_TEXTURE_ENV_MODE, TGL_DECAL);
 		tglMaterialfv(TGL_FRONT_AND_BACK, TGL_AMBIENT, fullColor);
 		tglMaterialfv(TGL_FRONT_AND_BACK, TGL_DIFFUSE, fullColor);
 		tglMaterialfv(TGL_FRONT_AND_BACK, TGL_SPECULAR, fullColor);
@@ -374,8 +375,8 @@ void TeRendererTinyGL::applyMaterial(const TeMaterial &m) {
 		tglDisable(TGL_TEXTURE_GEN_R);
 		tglDisable(TGL_TEXTURE_GEN_Q);
 	} else {
-		// TODO: not supported in TGL
-		//tglTexEnvi(TGL_TEXTURE_ENV, TGL_TEXTURE_ENV_MODE, TGL_MODULATE);
+		// TODO: GL_MODULATE not supported in TGL
+		//tglTexEnvi(TGL_TEXTURE_ENV, TGL_TEXTURE_ENV_MODE, TGL_DECAL);
 		tglEnable(TGL_TEXTURE_GEN_S);
 		tglEnable(TGL_TEXTURE_GEN_T);
 		tglEnable(TGL_TEXTURE_GEN_R);
@@ -384,8 +385,8 @@ void TeRendererTinyGL::applyMaterial(const TeMaterial &m) {
 		TeLightTinyGL::disableAll();
 		tglDisable(TGL_ALPHA_TEST);
 		enableTexture();
-		// TODO: not supported in TGL
-		//tglTexEnvi(TGL_TEXTURE_ENV, TGL_TEXTURE_ENV_MODE, TGL_MODULATE);
+		// TODO: GL_MODULATE not supported in TGL
+		//tglTexEnvi(TGL_TEXTURE_ENV, TGL_TEXTURE_ENV_MODE, TGL_DECAL);
 
 		const float diffuse[4] = { m._diffuseColor.r() / 255.0f, m._diffuseColor.g() / 255.0f,
 			m._diffuseColor.b() / 255.0f, m._diffuseColor.a() / 255.0f };
@@ -401,6 +402,23 @@ void TeRendererTinyGL::updateGlobalLight() {
 	TeLightTinyGL::updateGlobal();
 }
 
+void TeRendererTinyGL::updateScreen() {
+      Common::List<Common::Rect> dirtyAreas;
+      TinyGL::presentBuffer(dirtyAreas);
+
+      Graphics::Surface glBuffer;
+      TinyGL::getSurfaceRef(glBuffer);
+
+      if (!dirtyAreas.empty()) {
+          for (Common::List<Common::Rect>::iterator itRect = dirtyAreas.begin(); itRect != dirtyAreas.end(); ++itRect) {
+              g_system->copyRectToScreen(glBuffer.getBasePtr((*itRect).left, (*itRect).top), glBuffer.pitch,
+                                         (*itRect).left, (*itRect).top, (*itRect).width(), (*itRect).height());
+          }
+      }
+
+      g_system->updateScreen();
+}
+
 Common::String TeRendererTinyGL::vendor() {
 	return "TinyGL vendor";
 }
diff --git a/engines/tetraedge/te/te_renderer_tinygl.h b/engines/tetraedge/te/te_renderer_tinygl.h
index 60db224e5b0..209591e5224 100644
--- a/engines/tetraedge/te/te_renderer_tinygl.h
+++ b/engines/tetraedge/te/te_renderer_tinygl.h
@@ -54,6 +54,7 @@ public:
 	void shadowMode(enum ShadowMode mode) override;
 	void applyMaterial(const TeMaterial &m) override;
 	void updateGlobalLight() override;
+	void updateScreen() override;
 	Common::String vendor() override;
 
 protected:


Commit: fc86b54e755227ceaa128a8544036cf531972756
    https://github.com/scummvm/scummvm/commit/fc86b54e755227ceaa128a8544036cf531972756
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2023-02-05T08:02:12+09:00

Commit Message:
TETRAEDGE: Refactor to use FSNode instead of Path

Most places which previously used a Path, I actually wanted to record an FSNode
for better cross-platform compatibility.

Changed paths:
    engines/tetraedge/game/application.cpp
    engines/tetraedge/game/billboard.cpp
    engines/tetraedge/game/character.cpp
    engines/tetraedge/game/documents_browser.cpp
    engines/tetraedge/game/game.cpp
    engines/tetraedge/game/game.h
    engines/tetraedge/game/in_game_scene.cpp
    engines/tetraedge/game/in_game_scene.h
    engines/tetraedge/game/inventory.cpp
    engines/tetraedge/game/inventory_object.cpp
    engines/tetraedge/game/inventory_object.h
    engines/tetraedge/game/loc_file.cpp
    engines/tetraedge/game/loc_file.h
    engines/tetraedge/game/object3d.cpp
    engines/tetraedge/game/owner_error_menu.cpp
    engines/tetraedge/te/te_3d_texture.cpp
    engines/tetraedge/te/te_3d_texture.h
    engines/tetraedge/te/te_3d_texture_opengl.cpp
    engines/tetraedge/te/te_3d_texture_tinygl.cpp
    engines/tetraedge/te/te_core.cpp
    engines/tetraedge/te/te_core.h
    engines/tetraedge/te/te_font3.cpp
    engines/tetraedge/te/te_font3.h
    engines/tetraedge/te/te_i_codec.h
    engines/tetraedge/te/te_image.cpp
    engines/tetraedge/te/te_image.h
    engines/tetraedge/te/te_images_sequence.cpp
    engines/tetraedge/te/te_images_sequence.h
    engines/tetraedge/te/te_interpolation.cpp
    engines/tetraedge/te/te_interpolation.h
    engines/tetraedge/te/te_lua_gui.cpp
    engines/tetraedge/te/te_lua_gui.h
    engines/tetraedge/te/te_lua_gui_lua_callbacks.cpp
    engines/tetraedge/te/te_lua_script.cpp
    engines/tetraedge/te/te_lua_script.h
    engines/tetraedge/te/te_lua_thread.cpp
    engines/tetraedge/te/te_lua_thread.h
    engines/tetraedge/te/te_material.cpp
    engines/tetraedge/te/te_material.h
    engines/tetraedge/te/te_model.h
    engines/tetraedge/te/te_model_animation.cpp
    engines/tetraedge/te/te_music.cpp
    engines/tetraedge/te/te_music.h
    engines/tetraedge/te/te_resource.h
    engines/tetraedge/te/te_resource_manager.cpp
    engines/tetraedge/te/te_resource_manager.h
    engines/tetraedge/te/te_scene.h
    engines/tetraedge/te/te_scummvm_codec.cpp
    engines/tetraedge/te/te_scummvm_codec.h
    engines/tetraedge/te/te_sound_manager.cpp
    engines/tetraedge/te/te_sprite_layout.cpp
    engines/tetraedge/te/te_sprite_layout.h
    engines/tetraedge/te/te_text_layout.cpp
    engines/tetraedge/te/te_theora.cpp
    engines/tetraedge/te/te_theora.h
    engines/tetraedge/te/te_tiled_surface.cpp
    engines/tetraedge/te/te_tiled_surface.h
    engines/tetraedge/te/te_tiled_texture.cpp
    engines/tetraedge/te/te_tiled_texture.h


diff --git a/engines/tetraedge/game/application.cpp b/engines/tetraedge/game/application.cpp
index 9de4362532f..7edb7be1396 100644
--- a/engines/tetraedge/game/application.cpp
+++ b/engines/tetraedge/game/application.cpp
@@ -98,18 +98,13 @@ void Application::create() {
 	_mainWindow.setPosition(TeVector3f32(0.0f, 0.0f, 0.0f));
 
 	TeResourceManager *resmgr = g_engine->getResourceManager();
-	_fontComic = resmgr->getResourceNoSearch<TeFont3>("Common/Fonts/ComicRelief.ttf");
-	_fontComic->load("Common/Fonts/ComicRelief.ttf");
-	_fontArgh = resmgr->getResourceNoSearch<TeFont3>("Common/Fonts/Argh.ttf");
-	_fontArgh->load("Common/Fonts/Argh.ttf");
-	_fontArial = resmgr->getResourceNoSearch<TeFont3>("Common/Fonts/arial.ttf");
-	_fontArial->load("Common/Fonts/arial.ttf");
-	_fontChaucer = resmgr->getResourceNoSearch<TeFont3>("Common/Fonts/CHAUCER.TTF");
-	_fontChaucer->load("Common/Fonts/CHAUCER.ttf");
-	_fontColaborate = resmgr->getResourceNoSearch<TeFont3>("Common/Fonts/Colaborate-Regular.otf");
-	_fontColaborate->load("Common/Fonts/Colaborate-Regular.ttf");
-	_fontProDisplay = resmgr->getResourceNoSearch<TeFont3>("Common/Fonts/ProDisplay.ttf");
-	_fontProDisplay->load("Common/Fonts/ProDisplay.ttf");
+	TeCore *core = g_engine->getCore();
+	_fontComic = resmgr->getResource<TeFont3>(core->findFile("Common/Fonts/ComicRelief.ttf"));
+	_fontArgh = resmgr->getResource<TeFont3>(core->findFile("Common/Fonts/Argh.ttf"));
+	_fontArial = resmgr->getResource<TeFont3>(core->findFile("Common/Fonts/arial.ttf"));
+	_fontChaucer = resmgr->getResource<TeFont3>(core->findFile("Common/Fonts/CHAUCER.TTF"));
+	_fontColaborate = resmgr->getResource<TeFont3>(core->findFile("Common/Fonts/Colaborate-Regular.otf"));
+	_fontProDisplay = resmgr->getResource<TeFont3>(core->findFile("Common/Fonts/ProDisplay.ttf"));
 
 	// The app prebuilds some fonts.. cover letters, numbers, a few accented chars, and punctuation.
 	// Skip that here.
@@ -136,16 +131,15 @@ void Application::create() {
 	textBase.build();
 	 */
 
-	TeCore *core = g_engine->getCore();
 	static const char allLangs[][3] = {"en", "fr", "de", "es", "it", "ru"};
 	const Common::Path textsPath("texts");
 
 	// Try alternate langs..
 	int i = 0;
-	Common::Path textFilePath;
+	Common::FSNode textFileNode;
 	while (i < ARRAYSIZE(allLangs)) {
-		textFilePath = core->findFile(textsPath.join(core->language() + ".xml"));
-		if (Common::File::exists(textFilePath))
+		textFileNode = core->findFile(textsPath.join(core->language() + ".xml"));
+		if (textFileNode.isReadable())
 			break;
 		core->language(allLangs[i]);
 		i++;
@@ -154,7 +148,7 @@ void Application::create() {
 		error("Couldn't find texts/[lang].xml for any language.");
 	}
 
-	_loc.load(textFilePath);
+	_loc.load(textFileNode);
 	core->addLoc(&_loc);
 
 	const Common::Path helpMenuPath("menus/help/help_");
@@ -208,8 +202,7 @@ void Application::create() {
 	// Note: The games do some loading of a "version.ver" file here to add a
 	// watermark to the backLayout, but that file doesn't exist in any of the
 	// GOG games so it was probably only used during development.
-	const Common::Path verFilePath("version.ver");
-	if (Common::File::exists(verFilePath)) {
+	if (Common::File::exists("version.ver")) {
 		warning("Skipping doing anything with version.ver file");
 	}
 
@@ -461,7 +454,7 @@ void Application::performRender() {
 	drawFront();
 	renderer->renderTransparentMeshes();
 	game->scene().drawPath();
-	g_system->updateScreen();
+	renderer->updateScreen();
 
 #ifdef TETRAEDGE_DUMP_LAYOUTS
 	renderCount++;
diff --git a/engines/tetraedge/game/billboard.cpp b/engines/tetraedge/game/billboard.cpp
index 466fc059650..94b36bec1e3 100644
--- a/engines/tetraedge/game/billboard.cpp
+++ b/engines/tetraedge/game/billboard.cpp
@@ -25,6 +25,8 @@
 #include "tetraedge/game/billboard.h"
 #include "tetraedge/game/game.h"
 
+#include "tetraedge/te/te_core.h"
+
 namespace Tetraedge {
 
 Billboard::Billboard() : _hasPos2(false) {
@@ -34,8 +36,9 @@ bool Billboard::load(const Common::String &path) {
 	_model = new TeModel();
 	TeIntrusivePtr<Te3DTexture> texture = Te3DTexture::makeInstance();
 	Game *game = g_engine->getGame();
-	Common::Path texpath = game->sceneZonePath().join(path);
-	texture->load(texpath);
+	TeCore *core = g_engine->getCore();
+	Common::FSNode texnode = core->findFile(game->sceneZonePath().join(path));
+	texture->load(texnode);
 	_model->setName(path);
 	Common::Array<TeVector3f32> quad;
 	quad.resize(4);
diff --git a/engines/tetraedge/game/character.cpp b/engines/tetraedge/game/character.cpp
index 849d204e263..467e48e42a6 100644
--- a/engines/tetraedge/game/character.cpp
+++ b/engines/tetraedge/game/character.cpp
@@ -363,10 +363,10 @@ bool Character::loadModel(const Common::String &mname, bool unused) {
 	_characterSettings = _globalCharacterSettings->getVal(mname);
 	_model->setTexturePath("models/Textures");
 	_model->setEnableLights(true);
-	Common::Path modelPath("models");
-	modelPath.joinInPlace(_characterSettings._modelFileName);
-	if (!_model->load(modelPath))
+	if (!_model->load(Common::Path("models").join(_characterSettings._modelFileName))) {
+		warning("Failed to load character model %s", _characterSettings._modelFileName.c_str());
 		return false;
+	}
 
 	_model->setName(mname);
 	_model->setScale(_characterSettings._defaultScale);
@@ -391,7 +391,8 @@ bool Character::loadModel(const Common::String &mname, bool unused) {
 	_walkLoopAnimLen = animLengthFromFile(walkAnim(WalkPart_Loop), &_walkLoopAnimFrameCount);
 
 	TeIntrusivePtr<Te3DTexture> shadow = Te3DTexture::makeInstance();
-	shadow->load("models/Textures/simple_shadow_alpha.tga");
+	TeCore *core = g_engine->getCore();
+	shadow->load(core->findFile("models/Textures/simple_shadow_alpha.tga"));
 
 	for (int i = 0; i < 2; i++) {
 		TeModel *pmodel = new TeModel();
diff --git a/engines/tetraedge/game/documents_browser.cpp b/engines/tetraedge/game/documents_browser.cpp
index 2a7297a01d2..dea5f663947 100644
--- a/engines/tetraedge/game/documents_browser.cpp
+++ b/engines/tetraedge/game/documents_browser.cpp
@@ -173,11 +173,11 @@ void DocumentsBrowser::showDocument(const Common::String &docName, int startPage
 	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)) {
+	Common::FSNode docNode = core->findFile(docPath);
+	if (!docNode.exists()) {
 		docPath = docPathBase.append(".jpg");
-		docPath = core->findFile(docPath);
-		if (!Common::File::exists(docPath)) {
+		docNode = core->findFile(docPath);
+		if (!docNode.exists()) {
 			// Probably the end of the doc
 			if (startPage == 0)
 				warning("Can't find first page of doc named %s", docName.c_str());
@@ -189,7 +189,7 @@ void DocumentsBrowser::showDocument(const Common::String &docName, int startPage
 	app->captureFade();
 	TeSpriteLayout *sprite = _gui1.spriteLayoutChecked("zoomedSprite");
 	//sprite->setSizeType(ABSOLUTE);
-	sprite->load(docPath);
+	sprite->load(docNode);
 	TeVector2s32 spriteSize = sprite->_tiledSurfacePtr->tiledTexture()->totalSize();
 	sprite->setSizeType(RELATIVE_TO_PARENT);
 	TeVector3f32 winSize = app->getMainWindow().size();
@@ -200,10 +200,9 @@ void DocumentsBrowser::showDocument(const Common::String &docName, int startPage
 		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);
+	Common::FSNode luaNode = core->findFile(docPathBase.append(".lua"));
+	if (luaNode.exists()) {
+		_gui2.load(luaNode);
 		error("Finish DocumentsBrowser::showDocument");
 	}
 	_gui1.layoutChecked("zoomed")->setVisible(true);
diff --git a/engines/tetraedge/game/game.cpp b/engines/tetraedge/game/game.cpp
index 90b3946b216..8fb0cac712f 100644
--- a/engines/tetraedge/game/game.cpp
+++ b/engines/tetraedge/game/game.cpp
@@ -500,23 +500,23 @@ bool Game::initWarp(const Common::String &zone, const Common::String &scene, boo
 
 	TeCore *core = g_engine->getCore();
 
-	const Common::Path intLuaPath = core->findFile(scenePath.join(Common::String::format("Int%s.lua", scene.c_str())));
-	const Common::Path logicLuaPath = core->findFile(scenePath.join(Common::String::format("Logic%s.lua", scene.c_str())));
-	const Common::Path setLuaPath = core->findFile(scenePath.join(Common::String::format("Set%s.lua", scene.c_str())));
-	Common::Path forLuaPath = core->findFile(scenePath.join(Common::String::format("For%s.lua", scene.c_str())));
-	const Common::Path markerLuaPath = core->findFile(scenePath.join(Common::String::format("Marker%s.lua", scene.c_str())));
-
-	bool intLuaExists = Common::File::exists(intLuaPath);
-	bool logicLuaExists = Common::File::exists(logicLuaPath);
-	bool setLuaExists = Common::File::exists(setLuaPath);
-	bool forLuaExists = Common::File::exists(forLuaPath);
+	const Common::FSNode intLuaNode = core->findFile(scenePath.join(Common::String::format("Int%s.lua", scene.c_str())));
+	const Common::FSNode logicLuaNode = core->findFile(scenePath.join(Common::String::format("Logic%s.lua", scene.c_str())));
+	const Common::FSNode setLuaNode = core->findFile(scenePath.join(Common::String::format("Set%s.lua", scene.c_str())));
+	Common::FSNode forLuaNode = core->findFile(scenePath.join(Common::String::format("For%s.lua", scene.c_str())));
+	const Common::FSNode markerLuaNode = core->findFile(scenePath.join(Common::String::format("Marker%s.lua", scene.c_str())));
+
+	bool intLuaExists = intLuaNode.exists();
+	bool logicLuaExists = logicLuaNode.exists();
+	bool setLuaExists = setLuaNode.exists();
+	bool forLuaExists = forLuaNode.exists();
 	if (!forLuaExists) {
 		// slight hack.. try an alternate For lua path.
-		forLuaPath = scenePath.join("Android-MacOSX").join(Common::String::format("For%s.lua", scene.c_str()));
-		forLuaExists = Common::File::exists(forLuaPath);
-		debug("searched for %s", forLuaPath.toString().c_str());
+		forLuaNode = core->findFile(scenePath.join("Android-MacOSX").join(Common::String::format("For%s.lua", scene.c_str())));
+		forLuaExists = forLuaNode.exists();
+		debug("searched for %s", forLuaNode.getName().c_str());
 	}
-	bool markerLuaExists = Common::File::exists(markerLuaPath);
+	bool markerLuaExists = markerLuaNode.exists();
 
 	if (!intLuaExists && !logicLuaExists && !setLuaExists && !forLuaExists && !markerLuaExists) {
 		debug("No lua scripts for scene %s zone %s", scene.c_str(), zone.c_str());
@@ -530,9 +530,9 @@ bool Game::initWarp(const Common::String &zone, const Common::String &scene, boo
 	if (logicLuaExists) {
 		_luaContext.addBindings(LuaBinds::LuaOpenBinds);
 		_luaScript.attachToContext(&_luaContext);
-		_luaScript.load("menus/help/help.lua");
+		_luaScript.load(core->findFile("menus/help/help.lua"));
 		_luaScript.execute();
-		_luaScript.load(logicLuaPath);
+		_luaScript.load(logicLuaNode);
 	}
 
 	if (_forGui.loaded())
@@ -544,12 +544,12 @@ 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(geomPath);
-	_scene.loadBackground(setLuaPath);
+	_scene.load(core->findFile(geomPath));
+	_scene.loadBackground(setLuaNode);
 
 	Application *app = g_engine->getApplication();
 	if (forLuaExists) {
-		_forGui.load(forLuaPath);
+		_forGui.load(forLuaNode);
 		TeLayout *bg = _forGui.layoutChecked("background");
 		bg->setRatioMode(TeILayout::RATIO_MODE_NONE);
 		app->frontLayout().addChild(bg);
@@ -562,7 +562,7 @@ bool Game::initWarp(const Common::String &zone, const Common::String &scene, boo
 	}
 
 	if (intLuaExists) {
-		_scene.loadInteractions(intLuaPath);
+		_scene.loadInteractions(intLuaNode);
 		TeLuaGUI::StringMap<TeButtonLayout *> &blayouts = _scene.hitObjectGui().buttonLayouts();
 		for (auto &entry : blayouts) {
 			HitObject *hobj = new HitObject();
@@ -608,7 +608,7 @@ bool Game::initWarp(const Common::String &zone, const Common::String &scene, boo
 	}
 
 	TeCheckboxLayout *markersCheckbox = _inGameGui.checkboxLayout("markersVisibleButton");
-	markersCheckbox->setState(_markersVisible? TeCheckboxLayout::CheckboxStateActive : TeCheckboxLayout::CheckboxStateUnactive);
+	markersCheckbox->setState(_markersVisible ? TeCheckboxLayout::CheckboxStateActive : TeCheckboxLayout::CheckboxStateUnactive);
 	markersCheckbox->onStateChangedSignal().add(this, &Game::onMarkersVisible);
 
 	initNoScale();
@@ -860,7 +860,8 @@ bool Game::loadPlayerCharacter(const Common::String &name) {
 }
 
 bool Game::loadScene(const Common::String &name) {
-	_gameEnterScript.load("scenes/OnGameEnter.lua");
+	TeCore *core = g_engine->getCore();
+	_gameEnterScript.load(core->findFile("scenes/OnGameEnter.lua"));
 	_gameEnterScript.execute();
 	Character *character = _scene._character;
 	if (character && character->_model->visible()) {
@@ -1037,8 +1038,8 @@ bool Game::onLockVideoButtonValidated() {
 }
 
 bool Game::onMarkersVisible(TeCheckboxLayout::State state) {
-	_markersVisible = (state == 0);
-	showMarkers(state == 0);
+	_markersVisible = (state == TeCheckboxLayout::CheckboxStateActive);
+	showMarkers(state == TeCheckboxLayout::CheckboxStateActive);
 	return false;
 }
 
@@ -1178,7 +1179,7 @@ bool Game::onMouseMove() {
 	if (!_entered)
 		return false;
 
-	const Common::Path DEFAULT_CURSOR("pictures/cursor.png");
+	const Common::String DEFAULT_CURSOR("pictures/cursor.png");
 
 	Application *app = g_engine->getApplication();
 
@@ -1260,7 +1261,7 @@ bool Game::onVideoFinished() {
 	app->captureFade();
 
 	TeSpriteLayout *video = _inGameGui.spriteLayoutChecked("video");
-	Common::String vidPath = video->_tiledSurfacePtr->path().toString();
+	Common::String vidPath = video->_tiledSurfacePtr->loadedPath();
 	TeButtonLayout *btn = _inGameGui.buttonLayoutChecked("videoBackgroundButton");
 	btn->setVisible(false);
 	btn = _inGameGui.buttonLayoutChecked("skipVideoButton");
@@ -1392,7 +1393,7 @@ void Game::playSound(const Common::String &name, int repeats, float volume) {
 		}
 	} else if (repeats == -1) {
 		for (GameSound *snd : _gameSounds) {
-			const Common::String accessName = snd->getAccessName().toString();
+			const Common::String accessName = snd->getAccessName();
 			if (accessName == name) {
 				snd->setRetain(true);
 				return;
@@ -1476,7 +1477,7 @@ bool Game::setBackground(const Common::String &name) {
 	return _scene.changeBackground(name);
 }
 
-void Game::setCurrentObjectSprite(const Common::Path &spritePath) {
+void Game::setCurrentObjectSprite(const Common::String &spritePath) {
 	TeSpriteLayout *currentSprite = _inGameGui.spriteLayout("currentObjectSprite");
 	if (currentSprite) {
 		if (spritePath.empty())
diff --git a/engines/tetraedge/game/game.h b/engines/tetraedge/game/game.h
index dde72dff733..97546d61949 100644
--- a/engines/tetraedge/game/game.h
+++ b/engines/tetraedge/game/game.h
@@ -156,7 +156,7 @@ public:
 	void resumeSounds() {}; // does nothing?
 	void saveBackup(const Common::String &saveName);
 	bool setBackground(const Common::String &name);
-	void setCurrentObjectSprite(const Common::Path &spritePath);
+	void setCurrentObjectSprite(const Common::String &spritePath);
 	bool showMarkers(bool val);
 	bool startAnimation(const Common::String &animName, int loopcount, bool reversed);
 	void startAnimationPart(const Common::String &param_1, int param_2, int param_3, int param_4, bool param_5) {};
diff --git a/engines/tetraedge/game/in_game_scene.cpp b/engines/tetraedge/game/in_game_scene.cpp
index dbbe1e2aac3..9d5c2509d12 100644
--- a/engines/tetraedge/game/in_game_scene.cpp
+++ b/engines/tetraedge/game/in_game_scene.cpp
@@ -68,6 +68,7 @@ void InGameScene::addAnchorZone(const Common::String &s1, const Common::String &
 		}
 	}
 
+	assert(currentCamera());
 	currentCamera()->apply();
 	AnchorZone *zone = new AnchorZone();
 	zone->_name = name;
@@ -513,7 +514,7 @@ Common::String InGameScene::imagePathMarker(const Common::String &name) {
 	for (Te3DObject2 *child : bg->childList()) {
 		TeSpriteLayout *spritelayout = dynamic_cast<TeSpriteLayout *>(child);
 		if (spritelayout && spritelayout->name() == name) {
-			return spritelayout->_tiledSurfacePtr->path().toString();
+			return spritelayout->_tiledSurfacePtr->loadedPath();
 		}
 	}
 	return Common::String();
@@ -539,7 +540,7 @@ bool InGameScene::isObjectBlocking(const Common::String &name) {
 	return false;
 }
 
-bool InGameScene::load(const Common::Path &path) {
+bool InGameScene::load(const Common::FSNode &sceneNode) {
 	_actZones.clear();
 	Common::File actzonefile;
 	if (actzonefile.open(getActZoneFileName())) {
@@ -568,16 +569,18 @@ bool InGameScene::load(const Common::Path &path) {
 	_shadowLightNo = -1;
 
 	const Common::Path lightspath = getLightsFileName();
-	if (Common::File::exists(lightspath))
-		loadLights(lightspath);
+	TeCore *core = g_engine->getCore();
+	const Common::FSNode lightsNode(core->findFile(lightspath));
+	if (lightsNode.isReadable())
+		loadLights(lightsNode);
 
-	if (!Common::File::exists(path))
+	if (!sceneNode.isReadable())
 		return false;
 
 	close();
-	_loadedPath = path;
+	_loadedPath = sceneNode.getPath();
 	Common::File scenefile;
-	if (!scenefile.open(path))
+	if (!scenefile.open(sceneNode))
 		return false;
 
 	uint32 ncameras = scenefile.readUint32LE();
@@ -688,15 +691,15 @@ bool InGameScene::loadCharacter(const Common::String &name) {
 	return true;
 }
 
-bool InGameScene::loadLights(const Common::Path &path) {
+bool InGameScene::loadLights(const Common::FSNode &node) {
 	SceneLightsXmlParser parser;
 
 	parser.setLightArray(&_lights);
 
-	if (!parser.loadFile(path.toString()))
-		error("InGameScene::loadLights: Can't load %s", path.toString().c_str());
+	if (!parser.loadFile(node))
+		error("InGameScene::loadLights: Can't load %s", node.getPath().c_str());
 	if (!parser.parse())
-		error("InGameScene::loadLights: Can't parse %s", path.toString().c_str());
+		error("InGameScene::loadLights: Can't parse %s", node.getPath().c_str());
 
 	_shadowColor = parser.getShadowColor();
 	_shadowLightNo = parser.getShadowLightNo();
@@ -722,8 +725,8 @@ bool InGameScene::loadLights(const Common::Path &path) {
 	return true;
 }
 
-void InGameScene::loadMarkers(const Common::Path &path) {
-	_markerGui.load(path);
+void InGameScene::loadMarkers(const Common::FSNode &node) {
+	_markerGui.load(node);
 	TeLayout *bg = _bgGui.layoutChecked("background");
 	TeSpriteLayout *root = Game::findSpriteLayoutByName(bg, "root");
 	bg->setRatioMode(TeILayout::RATIO_MODE_NONE);
@@ -749,12 +752,13 @@ bool InGameScene::loadObject(const Common::String &name) {
 bool InGameScene::loadObjectMaterials(const Common::String &name) {
 	TeImage img;
 	bool retval = false;
+	TeCore *core = g_engine->getCore();
 	for (auto &obj : _objects) {
 		if (obj._name.empty())
 			continue;
 
 		Common::Path mpath = _loadedPath.getParent().join(name).join(obj._name + ".png");
-		if (img.load(mpath)) {
+		if (img.load(core->findFile(mpath))) {
 			Te3DTexture *tex = Te3DTexture::makeInstance();
 			tex->load(img);
 			obj._model->meshes()[0]->defaultMaterial(tex);
@@ -852,8 +856,8 @@ void InGameScene::loadBlockers() {
 	}
 }
 
-void InGameScene::loadBackground(const Common::Path &path) {
-	_bgGui.load(path);
+void InGameScene::loadBackground(const Common::FSNode &node) {
+	_bgGui.load(node);
 	TeLayout *bg = _bgGui.layout("background");
 	TeLayout *root = _bgGui.layout("root");
 	bg->setRatioMode(TeILayout::RATIO_MODE_NONE);
@@ -887,8 +891,8 @@ bool InGameScene::loadBillboard(const Common::String &name) {
 	}
 }
 
-void InGameScene::loadInteractions(const Common::Path &path) {
-	_hitObjectGui.load(path);
+void InGameScene::loadInteractions(const Common::FSNode &node) {
+	_hitObjectGui.load(node);
 	TeLayout *bgbackground = _bgGui.layoutChecked("background");
 	Game *game = g_engine->getGame();
 	TeSpriteLayout *root = game->findSpriteLayoutByName(bgbackground, "root");
diff --git a/engines/tetraedge/game/in_game_scene.h b/engines/tetraedge/game/in_game_scene.h
index 7f799b6059c..183dd82dc57 100644
--- a/engines/tetraedge/game/in_game_scene.h
+++ b/engines/tetraedge/game/in_game_scene.h
@@ -134,14 +134,14 @@ public:
 	bool isVisibleMarker(const Common::String &name);
 	TeVector2f32 layerSize();
 
-	virtual bool load(const Common::Path &path) override;
-	void loadBackground(const Common::Path &path);
+	virtual bool load(const Common::FSNode &node) override;
+	void loadBackground(const Common::FSNode &node);
 	bool loadBillboard(const Common::String &name);
 	void loadBlockers();
 	bool loadCharacter(const Common::String &name);
-	void loadInteractions(const Common::Path &path);
-	bool loadLights(const Common::Path &path);
-	void loadMarkers(const Common::Path &path);
+	void loadInteractions(const Common::FSNode &node);
+	bool loadLights(const Common::FSNode &node);
+	void loadMarkers(const Common::FSNode &node);
 	bool loadObject(const Common::String &oname);
 	bool loadObjectMaterials(const Common::String &name);
 	bool loadObjectMaterials(const Common::String &path, const Common::String &name);
diff --git a/engines/tetraedge/game/inventory.cpp b/engines/tetraedge/game/inventory.cpp
index 422e46e7c58..dd499915b73 100644
--- a/engines/tetraedge/game/inventory.cpp
+++ b/engines/tetraedge/game/inventory.cpp
@@ -426,7 +426,8 @@ void Inventory::selectedObject(InventoryObject *obj) {
 					objectDescription(objId).c_str());
 		_gui.textLayout("text")->setText(text);
 		_gui.buttonLayoutChecked("lire")->setEnable(isDocument(objId));
-		game->setCurrentObjectSprite(obj->spritePath());
+		const Common::String spritePathStr = obj->spritePath();
+		game->setCurrentObjectSprite(spritePathStr);
 		TeLayout *textObj = _gui.layout("textObject");
 		for (int i = 0; i < textObj->childCount(); i++) {
 			if (textObj->child(i)->name() == obj->name()) {
@@ -436,7 +437,7 @@ void Inventory::selectedObject(InventoryObject *obj) {
 				textObj->child(i)->setVisible(false);
 			}
 		}
-		game->inGameGui().spriteLayoutChecked("selectedObject")->load(obj->spritePath());
+		game->inGameGui().spriteLayoutChecked("selectedObject")->load(spritePathStr);
 	}
 }
 
diff --git a/engines/tetraedge/game/inventory_object.cpp b/engines/tetraedge/game/inventory_object.cpp
index 8bf17bc5662..8e4ce0f9d0e 100644
--- a/engines/tetraedge/game/inventory_object.cpp
+++ b/engines/tetraedge/game/inventory_object.cpp
@@ -38,8 +38,8 @@ void InventoryObject::load(const Common::String &newName) {
 	// TODO: btn->setDoubleValidationProtectionEnabled(false)
 }
 
-Common::Path InventoryObject::spritePath() {
-	return Common::Path("Inventory/Objects").join(name()).append(".png");
+Common::String InventoryObject::spritePath() {
+	return Common::Path("Inventory/Objects").join(name()).append(".png").toString();
 }
 
 bool InventoryObject::onButtonDown() {
diff --git a/engines/tetraedge/game/inventory_object.h b/engines/tetraedge/game/inventory_object.h
index ccee9fe5a14..0a9c4c782d8 100644
--- a/engines/tetraedge/game/inventory_object.h
+++ b/engines/tetraedge/game/inventory_object.h
@@ -33,7 +33,7 @@ public:
 	InventoryObject();
 
 	void load(const Common::String &name);
-	Common::Path spritePath();
+	Common::String spritePath();
 	bool onButtonDown();
 	TeSignal1Param<InventoryObject&> &selectedSignal() { return _selectedSignal; };
 
diff --git a/engines/tetraedge/game/loc_file.cpp b/engines/tetraedge/game/loc_file.cpp
index c89f69502d9..1019e6e82f3 100644
--- a/engines/tetraedge/game/loc_file.cpp
+++ b/engines/tetraedge/game/loc_file.cpp
@@ -31,12 +31,13 @@ namespace Tetraedge {
 LocFile::LocFile() {
 }
 
-void LocFile::load(const Common::Path &path) {
+void LocFile::load(const Common::FSNode &fsnode) {
 	TeNameValXmlParser parser;
 	const Common::String xmlHeader("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
 	Common::File locFile;
-	if (!locFile.open(path))
-		error("LocFile::load: failed to open %s.", path.toString().c_str());
+	const Common::String path = fsnode.getName();
+	if (!locFile.open(fsnode))
+		error("LocFile::load: failed to open %s.", path.c_str());
 
 	int64 fileLen = locFile.size();
 	char *buf = new char[fileLen + 1];
@@ -46,10 +47,10 @@ void LocFile::load(const Common::Path &path) {
 	delete [] buf;
 	locFile.close();
 	if (!parser.loadBuffer((const byte *)xmlContents.c_str(), xmlContents.size()))
-		error("LocFile::load: failed to load %s.", path.toString().c_str());
+		error("LocFile::load: failed to load %s.", path.c_str());
 
 	if (!parser.parse())
-		error("LocFile::load: failed to parse %s.", path.toString().c_str());
+		error("LocFile::load: failed to parse %s.", path.c_str());
 
 	_map = parser.getMap();
 }
diff --git a/engines/tetraedge/game/loc_file.h b/engines/tetraedge/game/loc_file.h
index 77051a5b2f4..f1e182b995d 100644
--- a/engines/tetraedge/game/loc_file.h
+++ b/engines/tetraedge/game/loc_file.h
@@ -23,7 +23,7 @@
 #define TETRAEDGE_GAME_LOC_FILE_H
 
 #include "common/str.h"
-#include "common/path.h"
+#include "common/fs.h"
 
 #include "tetraedge/te/te_i_loc.h"
 
@@ -34,7 +34,7 @@ public:
 	LocFile();
 
 	//const Common::String *avatar(const Common::String &key);
-	void load(const Common::Path &path);
+	void load(const Common::FSNode &fsnode);
 	const Common::String *value(const Common::String &key) const;
 
 };
diff --git a/engines/tetraedge/game/object3d.cpp b/engines/tetraedge/game/object3d.cpp
index 4006e12ee71..c4b3e51809a 100644
--- a/engines/tetraedge/game/object3d.cpp
+++ b/engines/tetraedge/game/object3d.cpp
@@ -49,7 +49,7 @@ bool Object3D::loadModel(const Common::String &name) {
 		_modelFileName = settings->_value._modelFileName;
 		_defaultScale = settings->_value._defaultScale;
 		_modelPtr->setTexturePath("objects/Textures");
-		bool loaded = _modelPtr->load(Common::Path("objects").join(_modelFileName));
+		bool loaded = _modelPtr->load(Common::Path("objects").join(_modelFileName).toString());
 		if (loaded) {
 			_modelPtr->setName(name);
 			_modelPtr->setScale(_defaultScale);
diff --git a/engines/tetraedge/game/owner_error_menu.cpp b/engines/tetraedge/game/owner_error_menu.cpp
index f2adc7e179b..6d2797b04e0 100644
--- a/engines/tetraedge/game/owner_error_menu.cpp
+++ b/engines/tetraedge/game/owner_error_menu.cpp
@@ -34,8 +34,7 @@ OwnerErrorMenu::OwnerErrorMenu() : _entered(false) {
 
 void OwnerErrorMenu::enter() {
 	_entered = true;
-	const Common::Path luaPath("menus/ownerError/ownerError.lua");
-	load(luaPath);
+	load("menus/ownerError/ownerError.lua");
 	Application *app = g_engine->getApplication();
 	TeLayout *menuLayout = layoutChecked("menu");
 	app->frontLayout().addChild(menuLayout);
diff --git a/engines/tetraedge/te/te_3d_texture.cpp b/engines/tetraedge/te/te_3d_texture.cpp
index 65b96d4f984..8a9e5517128 100644
--- a/engines/tetraedge/te/te_3d_texture.cpp
+++ b/engines/tetraedge/te/te_3d_texture.cpp
@@ -44,28 +44,31 @@ bool Te3DTexture::hasAlpha() const {
 }
 
 /*static*/
-TeIntrusivePtr<Te3DTexture> Te3DTexture::load2(const Common::Path &path, uint size) {
-	Common::Path fullPath = path.append(".3dtex");
+TeIntrusivePtr<Te3DTexture> Te3DTexture::load2(const Common::FSNode &node, uint size) {
+	const Common::String fullPath = node.getPath() + ".3dtex";
 
 	TeResourceManager *resMgr = g_engine->getResourceManager();
 	if (!resMgr->exists(fullPath)) {
 		TeIntrusivePtr<Te3DTexture> retval(makeInstance());
-		retval->load(path);
+		if (!node.isReadable())
+			warning("Request to load unreadable texture %s", node.getPath().c_str());
+		bool result = retval->load(node);
+		if (!result)
+			warning("Failed loading texture %s", node.getPath().c_str());
 		retval->setAccessName(fullPath);
 		resMgr->addResource(retval.get());
 		return retval;
 	} else {
-		return resMgr->getResourceOrMakeInstance<Te3DTexture>(fullPath);
+		return resMgr->getResourceByName<Te3DTexture>(fullPath);
 	}
 }
 
-bool Te3DTexture::load(const Common::Path &path) {
+bool Te3DTexture::load(const Common::FSNode &node) {
 	TeResourceManager *resmgr = g_engine->getResourceManager();
-	Common::Path resPath = path;
-	TeIntrusivePtr<TeImage> img = resmgr->getResource<TeImage>(resPath);
-	load(*img);
-	setAccessName(resPath.append(".3dtex"));
-	return true;
+	TeIntrusivePtr<TeImage> img = resmgr->getResource<TeImage>(node);
+	bool result = load(*img);
+	setAccessName(node.getPath() + ".3dtex");
+	return result;
 }
 
 /*static*/
diff --git a/engines/tetraedge/te/te_3d_texture.h b/engines/tetraedge/te/te_3d_texture.h
index 3182853e967..fa146c7bc33 100644
--- a/engines/tetraedge/te/te_3d_texture.h
+++ b/engines/tetraedge/te/te_3d_texture.h
@@ -48,9 +48,9 @@ public:
 	TeImage::Format getFormat() const { return _format; }
 	bool hasAlpha() const;
 
-	bool load(const Common::Path &path);
+	bool load(const Common::FSNode &path);
 	virtual bool load(const TeImage &img) = 0;
-	static TeIntrusivePtr<Te3DTexture> load2(const Common::Path &path, uint size);
+	static TeIntrusivePtr<Te3DTexture> load2(const Common::FSNode &node, uint size);
 
 	static TeVector2s32 optimisedSize(const TeVector2s32 &size);
 
diff --git a/engines/tetraedge/te/te_3d_texture_opengl.cpp b/engines/tetraedge/te/te_3d_texture_opengl.cpp
index 004baa8e471..4436ffd1b49 100644
--- a/engines/tetraedge/te/te_3d_texture_opengl.cpp
+++ b/engines/tetraedge/te/te_3d_texture_opengl.cpp
@@ -111,8 +111,7 @@ void Te3DTextureOpenGL::forceTexData(uint gltexture, uint xsize, uint ysize) {
 }
 
 bool Te3DTextureOpenGL::load(const TeImage &img) {
-	Common::Path accessName = img.getAccessName();
-	setAccessName(accessName.append(".3dtex"));
+	setAccessName(img.getAccessName() + ".3dtex");
 
 	_width = img.w;
 	_height = img.h;
@@ -193,7 +192,7 @@ void Te3DTextureOpenGL::update(const TeImage &img, uint xoff, uint yoff) {
 	if (!img.w || !img.h)
 		return;
 
-	setAccessName(img.getAccessName().append(".3dtex"));
+	setAccessName(img.getAccessName() + ".3dtex");
 	glBindTexture(GL_TEXTURE_2D, _glTexture);
 	glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
 	glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE);
diff --git a/engines/tetraedge/te/te_3d_texture_tinygl.cpp b/engines/tetraedge/te/te_3d_texture_tinygl.cpp
index 71116ecb606..2f14d170933 100644
--- a/engines/tetraedge/te/te_3d_texture_tinygl.cpp
+++ b/engines/tetraedge/te/te_3d_texture_tinygl.cpp
@@ -113,8 +113,7 @@ void Te3DTextureTinyGL::forceTexData(uint gltexture, uint xsize, uint ysize) {
 }
 
 bool Te3DTextureTinyGL::load(const TeImage &img) {
-	Common::Path accessName = img.getAccessName();
-	setAccessName(accessName.append(".3dtex"));
+	setAccessName(img.getAccessName() + ".3dtex");
 
 	_width = img.w;
 	_height = img.h;
@@ -184,7 +183,7 @@ void Te3DTextureTinyGL::update(const TeImage &img, uint xoff, uint yoff) {
 	if (!img.w || !img.h)
 		return;
 
-	setAccessName(img.getAccessName().append(".3dtex"));
+	setAccessName(img.getAccessName() + ".3dtex");
 	tglBindTexture(TGL_TEXTURE_2D, _glTexture);
 	// Note: these are unsupported in TGL but should be the defaults?
 	//tglPixelStorei(TGL_UNPACK_SWAP_BYTES, TGL_FALSE);
diff --git a/engines/tetraedge/te/te_core.cpp b/engines/tetraedge/te/te_core.cpp
index 9f6059fa01a..638a47e341d 100644
--- a/engines/tetraedge/te/te_core.cpp
+++ b/engines/tetraedge/te/te_core.cpp
@@ -111,16 +111,34 @@ bool TeCore::onActivityTrackingAlarm() {
 	error("TODO: Implement TeCore::onActivityTrackingAlarm");
 }
 
+static Common::FSNode _findSubPath(const Common::FSNode &parent, const Common::Path &childPath) {
+	if (childPath.empty())
+		return parent;
+	Common::FSNode childNode = parent;
+	const Common::StringArray comps = childPath.splitComponents();
+	unsigned int i;
+	for (i = 0; i < comps.size(); i++) {
+		childNode = childNode.getChild(comps[i]);
+		if (!childNode.exists())
+			break;
+	}
+	if (i == comps.size())
+		return childNode;
+	return Common::FSNode();
+}
+
 
-Common::Path TeCore::findFile(const Common::Path &path) {
-	if (Common::File::exists(path))
-		return path;
+Common::FSNode TeCore::findFile(const Common::Path &path) {
+	Common::FSNode node(path);
+	if (node.exists())
+		return node;
 
-	const Common::String gamePath = ConfMan.get("path");
-	const Common::Path resPath = Common::Path(gamePath).join("Resources");
-	const Common::Path absolutePath = resPath.join(path);
-	if (Common::FSNode(absolutePath).isDirectory())
-		return absolutePath;
+	const Common::FSNode gameRoot(ConfMan.get("path"));
+	if (!gameRoot.isDirectory())
+		error("Game directory should be a directory");
+	const Common::FSNode resNode = gameRoot.getChild("Resources");
+	if (!resNode.isDirectory())
+		error("Resources directory should exist in game");
 
 	const Common::Path fname = path.getLastComponent();
 	const Common::Path dir = path.getParent();
@@ -168,21 +186,23 @@ Common::Path TeCore::findFile(const Common::Path &path) {
 			if (!lang.empty())
 				testPath.joinInPlace(lang);
 			testPath.joinInPlace(fname);
-			if (Common::File::exists(testPath) || Common::FSNode(testPath).exists())
-				return testPath;
+			node = _findSubPath(resNode, testPath);
+			if (node.exists())
+				return node;
 
 			// also try the other way around
 			if (!lang.empty() && suffix) {
 				testPath = dir.join(lang).joinInPlace(suffix).join(fname);
-				if (Common::File::exists(testPath) || Common::FSNode(testPath).exists())
-					return testPath;
+				node = _findSubPath(resNode, testPath);
+				if (node.exists())
+					return node;
 			}
 		}
 	}
 
 	// Didn't find it at all..
-	warning("TeCore::findFile Searched but didn't find %s", path.toString().c_str());
-	return path;
+	debug("TeCore::findFile Searched but didn't find %s", path.toString().c_str());
+	return Common::FSNode(path);
 }
 
 } // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_core.h b/engines/tetraedge/te/te_core.h
index ec0f518d981..431ff9743c8 100644
--- a/engines/tetraedge/te/te_core.h
+++ b/engines/tetraedge/te/te_core.h
@@ -61,7 +61,7 @@ public:
 	// Note: this is not in the original, but it's not clear how the original
 	// adds things like "PC-MacOSX" to the path, and there is not clear logic
 	// to them, so here we are.
-	Common::Path findFile(const Common::Path &path);
+	Common::FSNode findFile(const Common::Path &path);
 
 	bool _coreNotReady;
 
diff --git a/engines/tetraedge/te/te_font3.cpp b/engines/tetraedge/te/te_font3.cpp
index 5a697c0cb04..a42abbf783f 100644
--- a/engines/tetraedge/te/te_font3.cpp
+++ b/engines/tetraedge/te/te_font3.cpp
@@ -83,12 +83,12 @@ Graphics::Font *TeFont3::getAtSize(uint size) {
 		load(getAccessName());
 
 	if (!_fontFile.isOpen())
-		error("TeFont3::: Couldn't open font file %s.", getAccessName().toString().c_str());
+		error("TeFont3::: Couldn't open font file %s.", getAccessName().c_str());
 
 	_fontFile.seek(0);
 	Graphics::Font *newFont = Graphics::loadTTFFont(_fontFile, size, Graphics::kTTFSizeModeCharacter, 0, Graphics::kTTFRenderModeNormal);
 	if (!newFont) {
-		error("TeFont3::: Couldn't load font %s at size %d.", _loadedPath.toString().c_str(), size);
+		error("TeFont3::: Couldn't load font %s at size %d.", _loadedPath.c_str(), size);
 	}
 	_fonts.setVal(size, newFont);
 	return newFont;
@@ -147,24 +147,33 @@ void TeFont3::draw(TeImage &destImage, const Common::String &str, int fontSize,
 	font->drawString(&destImage, str, 0, yoff, destImage.w, uintcol, talign);
 }
 
+bool TeFont3::load(const Common::String &path) {
+	if (_loadedPath == path && _fontFile.isOpen())
+		return true; // already open
+
+	TeCore *core = g_engine->getCore();
+	Common::FSNode node = core->findFile(path);
+	return load(node);
+}
 
-bool TeFont3::load(const Common::Path &path) {
+bool TeFont3::load(const Common::FSNode &node) {
+	const Common::String path = node.getPath();
 	if (_loadedPath == path && _fontFile.isOpen())
 		return true; // already open
 
 	setAccessName(path);
 	_loadedPath = path;
 
-	if (!Common::File::exists(path)) {
-		warning("TeFont3::load: File %s doesn't exist", path.toString().c_str());
+	if (!node.exists()) {
+		warning("TeFont3::load: File %s doesn't exist", path.c_str());
 		return false;
 	}
 
 	if (_fontFile.isOpen())
 		_fontFile.close();
 
-	if (!_fontFile.open(path)) {
-		warning("TeFont3::load: can't open %s", path.toString().c_str());
+	if (!_fontFile.open(node)) {
+		warning("TeFont3::load: can't open %s", path.c_str());
 		return false;
 	}
 	return true;
diff --git a/engines/tetraedge/te/te_font3.h b/engines/tetraedge/te/te_font3.h
index 44876c3393c..a4fcd44f3d8 100644
--- a/engines/tetraedge/te/te_font3.h
+++ b/engines/tetraedge/te/te_font3.h
@@ -62,7 +62,8 @@ public:
 		TeIntrusivePtr<TeImage> _img;
 	};
 
-	bool load(const Common::Path &path);
+	bool load(const Common::String &path);
+	bool load(const Common::FSNode &node);
 	void unload();
 
 	GlyphData glyph(uint size, uint charcode);
@@ -88,7 +89,7 @@ private:
 
 	Common::File _fontFile;
 	Common::HashMap<uint, Graphics::Font *> _fonts;
-	Common::Path _loadedPath;
+	Common::String _loadedPath;
 	Common::HashMap<uint, TeIntrusivePtr<Te3DTexture>> _fontSizeData;
 };
 
diff --git a/engines/tetraedge/te/te_i_codec.h b/engines/tetraedge/te/te_i_codec.h
index 29909d34290..1c92aa35142 100644
--- a/engines/tetraedge/te/te_i_codec.h
+++ b/engines/tetraedge/te/te_i_codec.h
@@ -36,7 +36,7 @@ public:
 	TeICodec() {};
 
 	virtual ~TeICodec() {};
-	virtual bool load(const Common::Path &path) = 0;
+	virtual bool load(const Common::FSNode &node) = 0;
 	virtual uint width() = 0;
 	virtual uint height() = 0;
 	virtual int nbFrames() = 0;
diff --git a/engines/tetraedge/te/te_image.cpp b/engines/tetraedge/te/te_image.cpp
index 8d297a19b13..b598d93e42b 100644
--- a/engines/tetraedge/te/te_image.cpp
+++ b/engines/tetraedge/te/te_image.cpp
@@ -92,11 +92,12 @@ bool TeImage::isExtensionSupported(const Common::Path &path) {
 	error("TODO: Implement TeImage::isExtensionSupported");
 }
 
-bool TeImage::load(const Common::Path &path) {
+bool TeImage::load(const Common::FSNode &node) {
 	TeCore *core = g_engine->getCore();
-	TeICodec *codec = core->createVideoCodec(path);
-	if (!codec->load(path)) {
-		warning("TeImage::load: Failed to load %s.", path.toString().c_str());
+	TeICodec *codec = core->createVideoCodec(node.getPath());
+	if (!node.isReadable() || !codec->load(node)) {
+		warning("TeImage::load: Failed to load %s.", node.getPath().c_str());
+		delete codec;
 		return false;
 	}
 
@@ -104,8 +105,9 @@ bool TeImage::load(const Common::Path &path) {
 	createImg(codec->width(), codec->height(), nullpal, codec->imageFormat(), codec->width(), codec->height());
 
 	if (!codec->update(0, *this)) {
-		error("TeImage::load: Failed to update from %s.", path.toString().c_str());
+		error("TeImage::load: Failed to update from %s.", node.getPath().c_str());
 	}
+	delete codec;
 	return true;
 }
 
diff --git a/engines/tetraedge/te/te_image.h b/engines/tetraedge/te/te_image.h
index 4f9b6379d3b..4417169e525 100644
--- a/engines/tetraedge/te/te_image.h
+++ b/engines/tetraedge/te/te_image.h
@@ -73,7 +73,7 @@ public:
 	void fill(byte r, byte g, byte b, byte a);
 	void getBuff(uint x, uint y, byte *pout, uint w, uint h);
 	bool isExtensionSupported(const Common::Path &path);
-	bool load(const Common::Path &path);
+	bool load(const Common::FSNode &node);
 	bool load(Common::ReadStream &stream, const Common::Path &path);
 	bool save(const Common::Path &path, enum Type type);
 	int serialize(Common::WriteStream &stream);
diff --git a/engines/tetraedge/te/te_images_sequence.cpp b/engines/tetraedge/te/te_images_sequence.cpp
index 1d993ea28a4..b8bf32a680d 100644
--- a/engines/tetraedge/te/te_images_sequence.cpp
+++ b/engines/tetraedge/te/te_images_sequence.cpp
@@ -47,42 +47,40 @@ static bool compareNodes(const Common::FSNode &left, const Common::FSNode &right
 	return left.getPath() < right.getPath();
 }
 
-bool TeImagesSequence::load(const Common::Path &path) {
-	Common::FSNode directory(path);
+bool TeImagesSequence::load(const Common::FSNode &directory) {
+	const Common::String path = directory.getPath();
 	if (!directory.isDirectory()) {
-		warning("TeImagesSequence::load:: not a directory %s", path.toString().c_str());
+		warning("TeImagesSequence::load:: not a directory %s", path.c_str());
 		return false;
 	}
 
 	Common::FSList children;
 	if (!directory.getChildren(children, Common::FSNode::kListFilesOnly) || children.empty()) {
-		warning("TeImagesSequence::load:: couldn't get children of %s", path.toString().c_str());
+		warning("TeImagesSequence::load:: couldn't get children of %s", path.c_str());
 		return false;
 	}
 
 	Common::sort(children.begin(), children.end(), compareNodes);
-	if (!SearchMan.hasArchive(path.toString()))
-		SearchMan.addDirectory(path.toString(), directory);
+	if (!SearchMan.hasArchive(path))
+		SearchMan.addDirectory(path, directory);
 
 	for (Common::FSNode &child : children) {
-		Common::String filePathStr = child.getPath();
+		const Common::String fileName = child.getName();
 
-		if (filePathStr.size() <= 10 || filePathStr.substr(filePathStr.size() - 7) != "fps.png")
+		if (fileName.size() <= 10 || fileName.substr(fileName.size() - 7) != "fps.png")
 			continue;
 
-		Common::Path filePath(filePathStr);
-		Common::String fname = filePath.getLastComponent().toString();
-		Common::String fstart = fname.substr(0, fname.size() - 7);
+		Common::String fstart = fileName.substr(0, fileName.size() - 7);
 		int frameno = 0;
 		int fps = 0;
 		if (sscanf(fstart.c_str(), "%d-%d", &frameno, &fps) != 2) {
-			warning("TeImagesSequence::load can't match %s", fname.c_str());
+			warning("TeImagesSequence::load can't match %s", fileName.c_str());
 			continue;
 		}
 
 		Common::SeekableReadStream *stream = child.createReadStream();
 		if (!stream) {
-			warning("TeImagesSequence::load can't open %s", filePath.toString().c_str());
+			warning("TeImagesSequence::load can't open %s", child.getPath().c_str());
 			continue;
 		}
 
@@ -91,7 +89,7 @@ bool TeImagesSequence::load(const Common::Path &path) {
 		if (!_width || (_width < 100 && _height < 100)) {
 			Image::PNGDecoder png;
 			if (!png.loadStream(*stream)) {
-				warning("Image sequence failed to load png %s", filePath.toString().c_str());
+				warning("Image sequence failed to load png %s", child.getPath().c_str());
 				delete stream;
 				return false;
 			}
diff --git a/engines/tetraedge/te/te_images_sequence.h b/engines/tetraedge/te/te_images_sequence.h
index 92b004c1f12..78bc7661402 100644
--- a/engines/tetraedge/te/te_images_sequence.h
+++ b/engines/tetraedge/te/te_images_sequence.h
@@ -37,7 +37,7 @@ public:
 	TeImagesSequence();
 	virtual ~TeImagesSequence();
 
-	virtual bool load(const Common::Path &path) override;
+	virtual bool load(const Common::FSNode &node) override;
 	virtual uint width() override { return _width; }
 	virtual uint height() override { return _height; }
 	virtual int nbFrames() override { return _files.size(); }
diff --git a/engines/tetraedge/te/te_interpolation.cpp b/engines/tetraedge/te/te_interpolation.cpp
index 11a82fac83c..0eb8b8c1ee5 100644
--- a/engines/tetraedge/te/te_interpolation.cpp
+++ b/engines/tetraedge/te/te_interpolation.cpp
@@ -37,10 +37,10 @@ void TeInterpolation::load(Common::ReadStream &stream) {
 		_array[i] = stream.readFloatLE();
 }
 
-void TeInterpolation::load(Common::Path &path) {
+void TeInterpolation::load(Common::FSNode &node) {
 	Common::File f;
-	if (!f.open(path))
-		error("Couldn't open %s", path.toString().c_str());
+	if (!f.open(node))
+		error("Couldn't open %s", node.getPath().c_str());
 
 	load(f);
 }
diff --git a/engines/tetraedge/te/te_interpolation.h b/engines/tetraedge/te/te_interpolation.h
index 58a7d1cacca..98efed325df 100644
--- a/engines/tetraedge/te/te_interpolation.h
+++ b/engines/tetraedge/te/te_interpolation.h
@@ -24,7 +24,7 @@
 
 #include "common/array.h"
 #include "common/stream.h"
-#include "common/path.h"
+#include "common/fs.h"
 
 namespace Tetraedge {
 
@@ -33,7 +33,7 @@ public:
 	TeInterpolation();
 
 	void load(Common::ReadStream &stream);
-	void load(Common::Path &path);
+	void load(Common::FSNode &node);
 
 	// Note: this function is not in the original but simplifies
 	// the code for TeCurveAnim2 a lot.
diff --git a/engines/tetraedge/te/te_lua_gui.cpp b/engines/tetraedge/te/te_lua_gui.cpp
index 0c61c3e01cd..d975b165d5b 100644
--- a/engines/tetraedge/te/te_lua_gui.cpp
+++ b/engines/tetraedge/te/te_lua_gui.cpp
@@ -154,7 +154,7 @@ TeButtonLayout *TeLuaGUI::buttonLayoutChecked(const Common::String &name) {
 	TeButtonLayout *l = buttonLayout(name);
 	if (!l) {
 		error("No button '%s' in gui data '%s'", name.c_str(),
-			  _scriptPath.toString().c_str());
+			  _scriptPath.c_str());
 	}
 	return l;
 }
@@ -163,7 +163,7 @@ TeLayout *TeLuaGUI::layoutChecked(const Common::String &name) {
 	TeLayout *l = layout(name);
 	if (!l) {
 		error("No layout '%s' in gui data '%s'", name.c_str(),
-			  _scriptPath.toString().c_str());
+			  _scriptPath.c_str());
 	}
 	return l;
 }
@@ -172,18 +172,20 @@ TeSpriteLayout *TeLuaGUI::spriteLayoutChecked(const Common::String &name) {
 	TeSpriteLayout *l = spriteLayout(name);
 	if (!l) {
 		error("No sprite layout '%s' in gui data '%s'", name.c_str(),
-			  _scriptPath.toString().c_str());
+			  _scriptPath.c_str());
 	}
 	return l;
 }
 
-bool TeLuaGUI::load(const Common::Path &path_) {
-	unload();
-	_scriptPath = Common::Path(path_);
+bool TeLuaGUI::load(const Common::String &subPath) {
 	TeCore *core = g_engine->getCore();
-	Common::Path path(path_);
+	return load(core->findFile(subPath));
+}
+
+bool TeLuaGUI::load(const Common::FSNode &node) {
+	unload();
+	_scriptPath = node.getPath();
 	// Not the same as original, we abstract the search logic a bit.
-	path = core->findFile(path);
 	_luaContext.setGlobal("Pixel", 0);
 	_luaContext.setGlobal("Percent", 1);
 	_luaContext.setGlobal("None", 0);
@@ -208,7 +210,7 @@ bool TeLuaGUI::load(const Common::Path &path_) {
 	_luaContext.registerCFunction("TeExtendedTextLayout", extendedTextLayoutBindings);
 	_luaContext.setInRegistry("__TeLuaGUIThis", this);
 	_luaScript.attachToContext(&_luaContext);
-	_luaScript.load(path);
+	_luaScript.load(node);
 	_luaScript.execute();
 	_luaScript.unload();
 	_loaded = true;
diff --git a/engines/tetraedge/te/te_lua_gui.h b/engines/tetraedge/te/te_lua_gui.h
index d5eccc4efbf..9232669f17f 100644
--- a/engines/tetraedge/te/te_lua_gui.h
+++ b/engines/tetraedge/te/te_lua_gui.h
@@ -77,11 +77,11 @@ public:
 	TeButtonLayout *buttonLayoutChecked(const Common::String &name);
 	TeSpriteLayout *spriteLayoutChecked(const Common::String &name);
 
-
-	bool load(const Common::Path &path);
+	bool load(const Common::String &subPath);
+	bool load(const Common::FSNode &node);
 	void unload();
 
-	TeVariant value(const Common::String &path);
+	TeVariant value(const Common::String &key);
 
 	template <typename T> using StringMap = Common::HashMap<Common::String, T>;
 
@@ -99,13 +99,13 @@ public:
 	StringMap<TeCurveAnim2<Te3DObject2, TeColor> *> &colorLinearAnimations() { return _colorLinearAnimations; }
 
 	bool loaded() const { return _loaded; }
-	const Common::Path &scriptPath() const { return _scriptPath; }
+	const Common::String &scriptPath() const { return _scriptPath; }
 
 protected:
 	bool _loaded;
 
 private:
-	Common::Path _scriptPath;
+	Common::String _scriptPath;
 
 	TeLuaContext _luaContext;
 	TeLuaScript _luaScript;
diff --git a/engines/tetraedge/te/te_lua_gui_lua_callbacks.cpp b/engines/tetraedge/te/te_lua_gui_lua_callbacks.cpp
index 8bd9152cbd3..dfa0af98a78 100644
--- a/engines/tetraedge/te/te_lua_gui_lua_callbacks.cpp
+++ b/engines/tetraedge/te/te_lua_gui_lua_callbacks.cpp
@@ -350,7 +350,12 @@ int spriteLayoutBindings(lua_State *L) {
 				}
 				if (imgPath.substr(0, 2) == "./") {
 					imgPath = imgPath.substr(0, 2);
-					imgFullPath = gui->scriptPath().getParent().join(imgPath);
+					// NOTE: This is bad.. the scriptPath is a system-local path so the
+					// separator may not be '/', we can't just make a Path from it like
+					// this.  Fortunately it seems this is never actually used? No sprites
+					// use './' in their data.
+					warning("Taking non-portable code path to load image in spriteLayoutBindings");
+					imgFullPath = Common::Path(gui->scriptPath()).getParent().join(imgPath);
 				} else {
 					imgFullPath = imgPath;
 				}
@@ -384,8 +389,8 @@ int spriteLayoutBindings(lua_State *L) {
 		lua_settop(L, -2);
 	}
 
-	if (!imgFullPath.empty()) {}
-		layout->load(imgFullPath);
+	if (!imgFullPath.empty())
+		layout->load(imgFullPath.toString());
 
 	lua_pushnil(L);
 	while (lua_next(L, -2) != 0) {
diff --git a/engines/tetraedge/te/te_lua_script.cpp b/engines/tetraedge/te/te_lua_script.cpp
index c2568451de3..28a08c815fd 100644
--- a/engines/tetraedge/te/te_lua_script.cpp
+++ b/engines/tetraedge/te/te_lua_script.cpp
@@ -37,11 +37,11 @@ void TeLuaScript::attachToContext(TeLuaContext *context) {
 
 void TeLuaScript::execute() {
 	if (_luaContext) {
-		//debug("TeLuaScript::execute %s", _scriptPath.toString().c_str());
+		//debug("TeLuaScript::execute %s", _scriptNode.getPath().c_str());
 		lua_State *state = _luaContext->luaState();
 		if (state) {
 			TeLuaThread *thread = TeLuaThread::create(_luaContext);
-			thread->executeFile(_scriptPath);
+			thread->executeFile(_scriptNode);
 			thread->release();
 			_started = true;
 		}
@@ -50,7 +50,7 @@ void TeLuaScript::execute() {
 
 void TeLuaScript::execute(const Common::String &fname) {
 	if (_luaContext) {
-		//debug("TeLuaScript::execute %s %s", _scriptPath.toString().c_str(), fname.c_str());
+		//debug("TeLuaScript::execute %s %s", _scriptNode.getPath().c_str(), fname.c_str());
 		TeLuaThread *thread = TeLuaThread::create(_luaContext);
 		thread->execute(fname);
 		thread->release();
@@ -59,7 +59,7 @@ void TeLuaScript::execute(const Common::String &fname) {
 
 void TeLuaScript::execute(const Common::String &fname, const TeVariant &p1) {
 	if (_luaContext) {
-		//debug("TeLuaScript::execute %s %s(%s)", _scriptPath.toString().c_str(), fname.c_str(), p1.toString().c_str());
+		//debug("TeLuaScript::execute %s %s(%s)", _scriptNode.getPath().c_str(), fname.c_str(), p1.toString().c_str());
 		TeLuaThread *thread = TeLuaThread::create(_luaContext);
 		thread->execute(fname, p1);
 		thread->release();
@@ -82,13 +82,13 @@ void TeLuaScript::execute(const Common::String &fname, const TeVariant &p1, cons
 	}
 }
 
-void TeLuaScript::load(const Common::Path &path) {
+void TeLuaScript::load(const Common::FSNode &node) {
 	_started = false;
-	_scriptPath = path;
+	_scriptNode = node;
 }
 
 void TeLuaScript::unload() {
-	_scriptPath.set("");
+	_scriptNode = Common::FSNode();
 	_started = false;
 }
 
diff --git a/engines/tetraedge/te/te_lua_script.h b/engines/tetraedge/te/te_lua_script.h
index 450d3c5d6fd..e7641796e60 100644
--- a/engines/tetraedge/te/te_lua_script.h
+++ b/engines/tetraedge/te/te_lua_script.h
@@ -42,13 +42,13 @@ public:
 	void execute(const Common::String &fname, const TeVariant &p1, const TeVariant &p2);
 	void execute(const Common::String &fname, const TeVariant &p1, const TeVariant &p2, const TeVariant &p3);
 
-	void load(const Common::Path &path);
+	void load(const Common::FSNode &node);
 	void unload();
 
 private:
 	TeLuaContext *_luaContext;
 
-	Common::Path _scriptPath;
+	Common::FSNode _scriptNode;
 	bool _started;
 };
 
diff --git a/engines/tetraedge/te/te_lua_thread.cpp b/engines/tetraedge/te/te_lua_thread.cpp
index 36b58928e4f..45bc41a5861 100644
--- a/engines/tetraedge/te/te_lua_thread.cpp
+++ b/engines/tetraedge/te/te_lua_thread.cpp
@@ -131,10 +131,10 @@ void TeLuaThread::execute(const Common::String &fname, const TeVariant &p1, cons
 	}
 }
 
-void TeLuaThread::executeFile(const Common::Path &path) {
+void TeLuaThread::executeFile(const Common::FSNode &node) {
 	Common::File scriptFile;
-	if (!scriptFile.open(path)) {
-		warning("TeLuaThread::executeFile: File %s can't be opened", path.toString().c_str());
+	if (!scriptFile.open(node)) {
+		warning("TeLuaThread::executeFile: File %s can't be opened", node.getName().c_str());
 		return;
 	}
 
@@ -148,7 +148,7 @@ void TeLuaThread::executeFile(const Common::Path &path) {
 	if (fixline)
 		fixline[2] = '\t';
 
-	_lastResumeResult = luaL_loadbuffer(_luaThread, buf, fileLen, path.toString().c_str());
+	_lastResumeResult = luaL_loadbuffer(_luaThread, buf, fileLen, node.getPath().c_str());
 	if (_lastResumeResult) {
 		const char *msg = lua_tostring(_luaThread, -1);
 		warning("TeLuaThread::executeFile: %s", msg);
diff --git a/engines/tetraedge/te/te_lua_thread.h b/engines/tetraedge/te/te_lua_thread.h
index e5e4c5cf648..1982e1fee67 100644
--- a/engines/tetraedge/te/te_lua_thread.h
+++ b/engines/tetraedge/te/te_lua_thread.h
@@ -24,7 +24,7 @@
 
 #include "common/array.h"
 #include "common/str.h"
-#include "common/path.h"
+#include "common/fs.h"
 
 struct lua_State;
 
@@ -46,7 +46,7 @@ public:
 	void execute(const Common::String &str, const TeVariant &p1, const TeVariant &p2);
 	void execute(const Common::String &str, const TeVariant &p1, const TeVariant &p2, const TeVariant &p3);
 
-	void executeFile(const Common::Path &path);
+	void executeFile(const Common::FSNode &node);
 	void pushValue(const TeVariant &val);
 
 	void release();
diff --git a/engines/tetraedge/te/te_material.cpp b/engines/tetraedge/te/te_material.cpp
index 8a6a27e7207..e5c45ad7dbc 100644
--- a/engines/tetraedge/te/te_material.cpp
+++ b/engines/tetraedge/te/te_material.cpp
@@ -23,6 +23,7 @@
 
 #include "tetraedge/tetraedge.h"
 
+#include "tetraedge/te/te_core.h"
 #include "tetraedge/te/te_light.h"
 #include "tetraedge/te/te_material.h"
 #include "tetraedge/te/te_model.h"
@@ -59,7 +60,7 @@ Common::String TeMaterial::dump() const {
 			  _specularColor.dump().c_str(),
 			  _emissionColor.dump().c_str(),
 			  (int)_mode,
-			 _texture ? _texture->getAccessName().toString().c_str() : "None",
+			 _texture ? _texture->getAccessName().c_str() : "None",
 			  _shininess, _enableLights ? "on" : "off");
 }
 
@@ -88,15 +89,19 @@ TeMaterial &TeMaterial::operator=(const TeMaterial &other) {
 	return *this;
 }
 
-/*static*/ void TeMaterial::deserialize(Common::SeekableReadStream &stream, TeMaterial &material, const Common::Path &texPath) {
-	Common::String nameStr = Te3DObject2::deserializeString(stream);
+/*static*/
+void TeMaterial::deserialize(Common::SeekableReadStream &stream, TeMaterial &material, const Common::String &texPath) {
+	const Common::String nameStr = Te3DObject2::deserializeString(stream);
 
 	TeModel::loadAlign(stream);
 	material._mode = static_cast<TeMaterial::Mode>(stream.readUint32LE());
 
 	if (nameStr.size()) {
-		Common::Path fullTexPath = texPath.join(nameStr);
-		material._texture = Te3DTexture::load2(fullTexPath, 0x500);
+		TeCore *core = g_engine->getCore();
+		Common::FSNode texNode = core->findFile(Common::Path(texPath).join(nameStr));
+		material._texture = Te3DTexture::load2(texNode, 0x500);
+		if (!material._texture)
+			warning("failed to load texture %s (texpath %s)", nameStr.c_str(), texPath.c_str());
 	}
 
 	material._ambientColor.deserialize(stream);
@@ -114,7 +119,7 @@ TeMaterial &TeMaterial::operator=(const TeMaterial &other) {
 	Te3DTexture *tex = material._texture.get();
 	Common::String texName;
 	if (tex) {
-		texName = tex->getAccessName().toString();
+		texName = tex->getAccessName();
 		// "Remove extension" twice for some reason..
 		size_t offset = texName.rfind('.');
 		if (offset != Common::String::npos) {
diff --git a/engines/tetraedge/te/te_material.h b/engines/tetraedge/te/te_material.h
index 1e8fab6b365..86648a08ff0 100644
--- a/engines/tetraedge/te/te_material.h
+++ b/engines/tetraedge/te/te_material.h
@@ -45,7 +45,7 @@ public:
 
 	// Note: apply() function from original moved to TeRenderer to remove OGL specific code from here
 	void defaultValues();
-	static void deserialize(Common::SeekableReadStream &stream, TeMaterial &material, const Common::Path &path);
+	static void deserialize(Common::SeekableReadStream &stream, TeMaterial &material, const Common::String &path);
 	static void serialize(Common::SeekableWriteStream &stream, TeMaterial &material);
 
 	bool operator==(const TeMaterial &other) const;
diff --git a/engines/tetraedge/te/te_model.h b/engines/tetraedge/te/te_model.h
index 5448003b9ec..3e7e66d8d8a 100644
--- a/engines/tetraedge/te/te_model.h
+++ b/engines/tetraedge/te/te_model.h
@@ -133,13 +133,13 @@ public:
 	TeIntrusivePtr<TeTiledTexture> tiledTexture() { return _tiledTexture; }
 
 	void setEnableLights(bool val) { _enableLights = val; }
-	void setTexturePath(const Common::Path &path) { _texturePath = path; }
+	void setTexturePath(const Common::String &path) { _texturePath = path; }
 
 protected:
 	TeMatrix4x4 lerpElementsMatrix(uint weightNum, const Common::Array<TeMatrix4x4> &matricies);
 	void optimize();
 
-	Common::Path _texturePath;
+	Common::String _texturePath;
 	TeIntrusivePtr<TeTiledTexture> _tiledTexture;
 
 	bool _enableLights;
diff --git a/engines/tetraedge/te/te_model_animation.cpp b/engines/tetraedge/te/te_model_animation.cpp
index a56b369f63f..d5cac67fd04 100644
--- a/engines/tetraedge/te/te_model_animation.cpp
+++ b/engines/tetraedge/te/te_model_animation.cpp
@@ -181,9 +181,9 @@ int TeModelAnimation::lastFrame() const {
 }
 
 bool TeModelAnimation::load(const Common::Path &path) {
-	Common::Path foundPath = g_engine->getCore()->findFile(path);
+	Common::FSNode foundFile = g_engine->getCore()->findFile(path);
 	Common::File modelFile;
-	if (!modelFile.open(foundPath)) {
+	if (!modelFile.open(foundFile)) {
 		warning("[TeModel::load] Can't open file : %s.", path.toString().c_str());
 		return false;
 	}
diff --git a/engines/tetraedge/te/te_music.cpp b/engines/tetraedge/te/te_music.cpp
index 59d93cce780..9dfcc9a9bc3 100644
--- a/engines/tetraedge/te/te_music.cpp
+++ b/engines/tetraedge/te/te_music.cpp
@@ -60,11 +60,11 @@ void TeMusic::pause() {
 bool TeMusic::play() {
 	if (isPlaying())
 		return true;
-	if (_actualPath.empty() || !Common::File::exists(_actualPath))
+	if (!_fileNode.exists())
 		return false;
 
 	Common::File *streamfile = new Common::File();
-	if (!streamfile->open(_actualPath)) {
+	if (!streamfile->open(_fileNode)) {
 		delete streamfile;
 		return false;
 	}
@@ -82,7 +82,7 @@ bool TeMusic::play() {
 		soundType = Audio::Mixer::kMusicSoundType;
 	}
 
-	//debug("playing %s on channel %s at vol %d", _actualPath.toString().c_str(), _channelName.c_str(), vol);
+	//debug("playing %s on channel %s at vol %d", _fileNode.getPath().c_str(), _channelName.c_str(), vol);
 	mixer->playStream(soundType, &_sndHandle, stream, -1, vol);
 	_sndHandleValid = true;
 	_isPaused = false;
@@ -190,10 +190,8 @@ void TeMusic::setFilePath(const Common::String &name) {
 	setAccessName(name);
 	_rawPath = name;
 	TeCore *core = g_engine->getCore();
-	const Common::Path namePath(name);
 	// Note: original search logic here abstracted away in our version..
-	Common::Path modPath = core->findFile(namePath);
-	_actualPath = modPath;
+	_fileNode = core->findFile(name);
 }
 
 void TeMusic::update() {
diff --git a/engines/tetraedge/te/te_music.h b/engines/tetraedge/te/te_music.h
index c05793f0f98..691dbd3cd81 100644
--- a/engines/tetraedge/te/te_music.h
+++ b/engines/tetraedge/te/te_music.h
@@ -24,7 +24,7 @@
 
 #include "audio/mixer.h"
 #include "common/mutex.h"
-#include "common/path.h"
+#include "common/fs.h"
 #include "common/str.h"
 
 #include "tetraedge/te/te_resource.h"
@@ -76,7 +76,7 @@ public:
 
 private:
 	Common::String _rawPath; // Plain name of file requested
-	Common::Path _actualPath; // actual path after finding it
+	Common::FSNode _fileNode; // file after finding it
 	Common::String _channelName;
 
 	bool _repeat;
diff --git a/engines/tetraedge/te/te_resource.h b/engines/tetraedge/te/te_resource.h
index 3c98ceccf4d..025b99d6165 100644
--- a/engines/tetraedge/te/te_resource.h
+++ b/engines/tetraedge/te/te_resource.h
@@ -35,16 +35,16 @@ public:
 
 	void generateAccessName();
 
-	const Common::Path &getAccessName() const {
+	const Common::String &getAccessName() const {
 		return _accessName;
 	}
 
-	void setAccessName(const Common::Path &name) {
+	void setAccessName(const Common::String &name) {
 		_accessName = name;
 	}
 
 private:
-	Common::Path _accessName;
+	Common::String _accessName;
 	static uint32 _idCounter;
 };
 
diff --git a/engines/tetraedge/te/te_resource_manager.cpp b/engines/tetraedge/te/te_resource_manager.cpp
index 4443c63832c..cf3a3c8f03d 100644
--- a/engines/tetraedge/te/te_resource_manager.cpp
+++ b/engines/tetraedge/te/te_resource_manager.cpp
@@ -43,10 +43,9 @@ void TeResourceManager::addResource(TeResource *resource) {
 	_resources.insert_at(0, TeIntrusivePtr<TeResource>(resource));
 }
 
-bool TeResourceManager::exists(const Common::Path &path) {
-	Common::String pathstr = path.toString();
+bool TeResourceManager::exists(const Common::String &path) {
 	for (auto &resource : _resources) {
-		if (resource->getAccessName() == pathstr)
+		if (resource->getAccessName() == path)
 			return true;
 	}
 	return false;
diff --git a/engines/tetraedge/te/te_resource_manager.h b/engines/tetraedge/te/te_resource_manager.h
index b1abcd699ff..fb63789fb60 100644
--- a/engines/tetraedge/te/te_resource_manager.h
+++ b/engines/tetraedge/te/te_resource_manager.h
@@ -45,22 +45,22 @@ public:
 
 	void addResource(const TeIntrusivePtr<TeResource> &resource);
 	void addResource(TeResource *resource);
-	bool exists(const Common::Path &path);
+	bool exists(const Common::String &path);
 	void removeResource(const TeIntrusivePtr<TeResource> &resource);
 	void removeResource(const TeResource *resource);
 
-	template<class T> TeIntrusivePtr<T> getResourceNoSearch(const Common::Path &path) {
+	template<class T> TeIntrusivePtr<T> getResourceByName(const Common::String &path) {
 		for (TeIntrusivePtr<TeResource> &resource : this->_resources) {
 			if (resource->getAccessName() == path) {
 				return TeIntrusivePtr<T>(dynamic_cast<T *>(resource.get()));
 			}
 		}
-		TeIntrusivePtr<T> retval = new T();
-		addResource(retval.get());
-		return retval;
+		debug("getResourceByName: didn't find resource %s", path.c_str());
+		return TeIntrusivePtr<T>();
 	}
 
-	template<class T> TeIntrusivePtr<T> getResource(Common::Path &path) {
+	template<class T> TeIntrusivePtr<T> getResource(const Common::FSNode &node) {
+		Common::String path = node.getPath();
 		for (TeIntrusivePtr<TeResource> &resource : this->_resources) {
 			if (resource->getAccessName() == path) {
 				return TeIntrusivePtr<T>(dynamic_cast<T *>(resource.get()));
@@ -68,19 +68,19 @@ public:
 		}
 
 		TeIntrusivePtr<T> retval;
-		// Note: original search logic here abstracted away in our version..
-		TeCore *core = g_engine->getCore();
-		path = core->findFile(path);
 		retval = new T();
 
 		if (retval.get()) {
-			retval->load(path);
+			if (!node.isReadable())
+				warning("getResource: asked to fetch unreadable resource %s", node.getPath().c_str());
+			retval->load(node);
 			addResource(retval.get());
 		}
 		return retval;
 	}
 
-	template<class T> TeIntrusivePtr<T> getResourceOrMakeInstance(Common::Path &path) {
+	template<class T> TeIntrusivePtr<T> getResourceOrMakeInstance(const Common::FSNode &node) {
+		Common::String path = node.getPath();
 		for (TeIntrusivePtr<TeResource> &resource : this->_resources) {
 			if (resource->getAccessName() == path) {
 				return TeIntrusivePtr<T>(dynamic_cast<T *>(resource.get()));
@@ -88,13 +88,12 @@ public:
 		}
 
 		TeIntrusivePtr<T> retval;
-		// Note: original search logic here abstracted away in our version..
-		TeCore *core = g_engine->getCore();
-		path = core->findFile(path);
 		retval = T::makeInstance();
 
 		if (retval.get()) {
-			retval->load(path);
+			if (!node.isReadable())
+				warning("getResourceOrMakeInstance: asked to fetch unreadable resource %s", node.getPath().c_str());
+			retval->load(node);
 			addResource(retval.get());
 		}
 		return retval;
diff --git a/engines/tetraedge/te/te_scene.h b/engines/tetraedge/te/te_scene.h
index 8a5174ae7f8..a7b213e47a2 100644
--- a/engines/tetraedge/te/te_scene.h
+++ b/engines/tetraedge/te/te_scene.h
@@ -47,7 +47,7 @@ public:
 	Common::String currentCameraName() const;
 
 	virtual void draw();
-	virtual bool load(const Common::Path &path) { return false; };
+	virtual bool load(const Common::FSNode &node) { return false; };
 
 	void removeModel(const Common::String &mname);
 	void setCurrentCamera(const Common::String &cname);
diff --git a/engines/tetraedge/te/te_scummvm_codec.cpp b/engines/tetraedge/te/te_scummvm_codec.cpp
index a89465fdf45..fe1a0121b24 100644
--- a/engines/tetraedge/te/te_scummvm_codec.cpp
+++ b/engines/tetraedge/te/te_scummvm_codec.cpp
@@ -37,10 +37,10 @@ TeScummvmCodec::~TeScummvmCodec() {
 	}
 }
 
-bool TeScummvmCodec::load(const Common::Path &path) {
+bool TeScummvmCodec::load(const Common::FSNode &node) {
 	Common::File file;
-	if (file.open(path) && load(static_cast<Common::SeekableReadStream&>(file))) {
-		_path = path;
+	if (file.open(node) && load(static_cast<Common::SeekableReadStream&>(file))) {
+		_loadedPath = node.getPath();
 		return true;
 	}
 	return false;
@@ -66,8 +66,8 @@ bool TeScummvmCodec::update(uint i, TeImage &imgout) {
 	if (!_loadedSurface)
 		return false;
 
-	if (!_path.empty())
-		imgout.setAccessName(_path);
+	if (!_loadedPath.empty())
+		imgout.setAccessName(_loadedPath);
 
 	if (imgout.w == _loadedSurface->w && imgout.h == _loadedSurface->h && imgout.format == _loadedSurface->format) {
 		imgout.copyFrom(*_loadedSurface);
diff --git a/engines/tetraedge/te/te_scummvm_codec.h b/engines/tetraedge/te/te_scummvm_codec.h
index a4ec0541dc9..72112febf5e 100644
--- a/engines/tetraedge/te/te_scummvm_codec.h
+++ b/engines/tetraedge/te/te_scummvm_codec.h
@@ -32,7 +32,7 @@ public:
 	TeScummvmCodec();
 	virtual ~TeScummvmCodec();
 
-	virtual bool load(const Common::Path &path) override;
+	virtual bool load(const Common::FSNode &node) override;
 	virtual bool load(Common::SeekableReadStream &stream) = 0;
 	virtual uint width() override;
 	virtual uint height() override;
@@ -55,7 +55,7 @@ public:
 
 protected:
 	Graphics::Surface *_loadedSurface;
-	Common::Path _path;
+	Common::String _loadedPath;
 
 };
 
diff --git a/engines/tetraedge/te/te_sound_manager.cpp b/engines/tetraedge/te/te_sound_manager.cpp
index e10ce8d495a..3ac1b616b8b 100644
--- a/engines/tetraedge/te/te_sound_manager.cpp
+++ b/engines/tetraedge/te/te_sound_manager.cpp
@@ -38,11 +38,11 @@ TeSoundManager::TeSoundManager() {
 
 void TeSoundManager::playFreeSound(const Common::Path &path, float vol, const Common::String &channel) {
 	TeCore *core = g_engine->getCore();
-	Common::Path modPath = core->findFile(path);
+	Common::FSNode sndNode = core->findFile(path);
 
 	Common::File *streamfile = new Common::File();
-	if (!streamfile->open(modPath)) {
-		warning("TeSoundManager::playFreeSound: couldn't open %s", path.toString().c_str());
+	if (!sndNode.isReadable() || !streamfile->open(sndNode)) {
+		warning("TeSoundManager::playFreeSound: couldn't open %s", sndNode.getPath().c_str());
 		delete streamfile;
 		return;
 	}
diff --git a/engines/tetraedge/te/te_sprite_layout.cpp b/engines/tetraedge/te/te_sprite_layout.cpp
index 42a4d4b7b81..c23d4f45be6 100644
--- a/engines/tetraedge/te/te_sprite_layout.cpp
+++ b/engines/tetraedge/te/te_sprite_layout.cpp
@@ -20,6 +20,7 @@
  */
 
 #include "tetraedge/tetraedge.h"
+#include "tetraedge/te/te_core.h"
 #include "tetraedge/te/te_matrix4x4.h"
 #include "tetraedge/te/te_renderer.h"
 #include "tetraedge/te/te_sprite_layout.h"
@@ -72,16 +73,31 @@ bool TeSpriteLayout::onParentWorldColorChanged() {
 	return false;
 }
 
-bool TeSpriteLayout::load(const Common::Path &path) {
+bool TeSpriteLayout::load(const Common::String &path) {
 	if (path.empty()) {
 		_tiledSurfacePtr = new TeTiledSurface();
 		return true;
 	}
 
+	TeCore *core = g_engine->getCore();
+	Common::FSNode node = core->findFile(path);
+	if (load(node)) {
+		_tiledSurfacePtr->setLoadedPath(path);
+		return true;
+	}
+	return false;
+}
+
+bool TeSpriteLayout::load(const Common::FSNode &node) {
+	if (!node.exists()) {
+		_tiledSurfacePtr = new TeTiledSurface();
+		return true;
+	}
+
 	stop();
 	unload();
 
-	if (_tiledSurfacePtr->load(path)) {
+	if (_tiledSurfacePtr->load(node)) {
 		const TeVector2s32 texSize = _tiledSurfacePtr->tiledTexture()->totalSize();
 		if (texSize._y <= 0) {
 			setRatio(1.0);
@@ -93,7 +109,7 @@ bool TeSpriteLayout::load(const Common::Path &path) {
 		}
 		updateMesh();
 	} else {
-		debug("Failed to load TeSpriteLayout %s", path.toString().c_str());
+		debug("Failed to load TeSpriteLayout %s", node.getPath().c_str());
 	}
 	return true;
 }
@@ -115,7 +131,7 @@ bool TeSpriteLayout::load(TeIntrusivePtr<Te3DTexture> &texture) {
 		updateMesh();
 		return true;
 	} else {
-		debug("Failed to load TeSpriteLayout from texture %s", texture->getAccessName().toString().c_str());
+		debug("Failed to load TeSpriteLayout from texture %s", texture->getAccessName().c_str());
 	}
 	return false;
 }
@@ -137,7 +153,7 @@ bool TeSpriteLayout::load(TeImage &img) {
 		updateMesh();
 		return true;
 	} else {
-		debug("Failed to load TeSpriteLayout from texture %s", img.getAccessName().toString().c_str());
+		debug("Failed to load TeSpriteLayout from texture %s", img.getAccessName().c_str());
 	}
 	return false;
 }
diff --git a/engines/tetraedge/te/te_sprite_layout.h b/engines/tetraedge/te/te_sprite_layout.h
index e2621cb27bb..bc4e9f7f338 100644
--- a/engines/tetraedge/te/te_sprite_layout.h
+++ b/engines/tetraedge/te/te_sprite_layout.h
@@ -37,7 +37,8 @@ public:
 
 	virtual bool onParentWorldColorChanged() override;
 
-	bool load(const Common::Path &path);
+	bool load(const Common::String &path);
+	bool load(const Common::FSNode &node);
 	bool load(TeImage &img);
 	bool load(TeIntrusivePtr<Te3DTexture> &texture);
 
diff --git a/engines/tetraedge/te/te_text_layout.cpp b/engines/tetraedge/te/te_text_layout.cpp
index 2b55b0e4b8b..981db3c83d4 100644
--- a/engines/tetraedge/te/te_text_layout.cpp
+++ b/engines/tetraedge/te/te_text_layout.cpp
@@ -118,8 +118,8 @@ void TeTextLayout::setText(const Common::String &val) {
 
 	if (parser.fontFile().size()) {
 		Common::Path fontPath(parser.fontFile());
-		fontPath = g_engine->getCore()->findFile(fontPath);
-		TeIntrusivePtr<TeFont3> font = g_engine->getResourceManager()->getResource<TeFont3>(fontPath);
+		Common::FSNode fontNode = g_engine->getCore()->findFile(fontPath);
+		TeIntrusivePtr<TeFont3> font = g_engine->getResourceManager()->getResource<TeFont3>(fontNode);
 		//font->load(fontPath); // lazy load this later.
 		_base.setFont(0, font);
 	}
diff --git a/engines/tetraedge/te/te_theora.cpp b/engines/tetraedge/te/te_theora.cpp
index d6bd959d707..3cee78a3f48 100644
--- a/engines/tetraedge/te/te_theora.cpp
+++ b/engines/tetraedge/te/te_theora.cpp
@@ -38,9 +38,9 @@ bool TeTheora::matchExtension(const Common::String &extn) {
 	return extn == "ogv";
 }
 
-bool TeTheora::load(const Common::Path &path) {
-	_path = path;
-	return _decoder->loadFile(path);
+bool TeTheora::load(const Common::FSNode &node) {
+	_loadedNode = node;
+	return _decoder->loadStream(node.createReadStream());
 }
 
 uint TeTheora::width() {
@@ -98,10 +98,10 @@ float TeTheora::frameRate() {
 }
 
 bool TeTheora::update(uint i, TeImage &imgout) {
-	if (_decoder->getCurFrame() > (int)i && !_path.empty()) {
+	if (_decoder->getCurFrame() > (int)i && _loadedNode.isReadable()) {
 		// rewind.. no good way to do that, but it should
 		// only happen on loop.
-		load(_path);
+		load(_loadedNode);
 	}
 
 	const Graphics::Surface *frame = nullptr;
@@ -114,9 +114,9 @@ bool TeTheora::update(uint i, TeImage &imgout) {
 		//debug("TeTheora: %s %ld", _path.toString().c_str(), i);
 		imgout.copyFrom(*frame);
 		return true;
-	} else if (_hitEnd && !_path.empty()) {
+	} else if (_hitEnd && _loadedNode.isReadable()) {
 		// Loop to the start.
-		load(_path);
+		load(_loadedNode);
 		frame = _decoder->decodeNextFrame();
 		if (frame) {
 			imgout.copyFrom(*frame);
diff --git a/engines/tetraedge/te/te_theora.h b/engines/tetraedge/te/te_theora.h
index d59dd60d8fc..9715bc1ea23 100644
--- a/engines/tetraedge/te/te_theora.h
+++ b/engines/tetraedge/te/te_theora.h
@@ -36,7 +36,7 @@ public:
 	TeTheora();
 	virtual ~TeTheora();
 
-	virtual bool load(const Common::Path &path) override;
+	virtual bool load(const Common::FSNode &node) override;
 	virtual uint width() override;
 	virtual uint height() override;
 	virtual int nbFrames() override;
@@ -61,7 +61,7 @@ public:
 private:
 	Video::TheoraDecoder *_decoder;
 
-	Common::Path _path;
+	Common::FSNode _loadedNode;
 	bool _hitEnd;
 
 };
diff --git a/engines/tetraedge/te/te_tiled_surface.cpp b/engines/tetraedge/te/te_tiled_surface.cpp
index 9d8b66b3be2..c865f9763ea 100644
--- a/engines/tetraedge/te/te_tiled_surface.cpp
+++ b/engines/tetraedge/te/te_tiled_surface.cpp
@@ -60,35 +60,33 @@ byte TeTiledSurface::isLoaded() {
 	return _tiledTexture && _tiledTexture->isLoaded();
 }
 
-bool TeTiledSurface::load(const Common::Path &path) {
+bool TeTiledSurface::load(const Common::FSNode &node) {
 	unload();
 
 	TeResourceManager *resmgr = g_engine->getResourceManager();
-	_path = path;
+	_loadedPath = node.getPath();
 
 	TeIntrusivePtr<TeTiledTexture> texture;
-	if (resmgr->exists(path.append(".tt"))) {
-		texture = resmgr->getResourceNoSearch<TeTiledTexture>(path.append(".tt"));
+	if (resmgr->exists(_loadedPath + ".tt")) {
+		texture = resmgr->getResourceByName<TeTiledTexture>(_loadedPath + ".tt");
 		// we don't own this one..
 	}
 
 	if (!texture) {
 		TeCore *core = g_engine->getCore();
-
-		Common::Path foundPath = core->findFile(path);
-		_codec = core->createVideoCodec(foundPath);
+		_codec = core->createVideoCodec(_loadedPath);
 		if (!_codec)
 			return false;
 
 		texture = new TeTiledTexture();
 
-		if (_codec->load(foundPath)) {
-			texture->setAccessName(path.append(".tt"));
+		if (_codec->load(node)) {
+			texture->setAccessName(_loadedPath + ".tt");
 			resmgr->addResource(texture.get());
 			_imgFormat = _codec->imageFormat();
 
 			if (_imgFormat == TeImage::INVALID) {
-				warning("TeTiledSurface::load: Wrong image format on file %s", path.toString().c_str());
+				warning("TeTiledSurface::load: Wrong image format on file %s", _loadedPath.c_str());
 				delete _codec;
 				_codec = nullptr;
 				return false;
@@ -118,7 +116,7 @@ bool TeTiledSurface::load(const Common::Path &path) {
 				texture->load(img);
 			}
 		} else {
-			warning("TeTiledSurface::load: failed to load %s", path.toString().c_str());
+			warning("TeTiledSurface::load: failed to load %s", _loadedPath.c_str());
 			delete _codec;
 			_codec = nullptr;
 		}
@@ -138,10 +136,10 @@ bool TeTiledSurface::load(const TeIntrusivePtr<Te3DTexture> &texture) {
 	TeResourceManager *resmgr = g_engine->getResourceManager();
 	TeIntrusivePtr<TeTiledTexture> tiledTexture;
 
-	const Common::Path ttPath = texture->getAccessName().append(".tt");
+	const Common::String ttPath = texture->getAccessName() + ".tt";
 
 	if (resmgr->exists(ttPath)) {
-		tiledTexture = resmgr->getResourceNoSearch<TeTiledTexture>(ttPath);
+		tiledTexture = resmgr->getResourceByName<TeTiledTexture>(ttPath);
 	}
 
 	if (!tiledTexture) {
@@ -160,7 +158,7 @@ bool TeTiledSurface::onFrameAnimCurrentFrameChanged() {
 		return false;
 
 	if (_imgFormat == TeImage::INVALID) {
-		warning("TeTiledSurface::load: Wrong image format on file %s", _path.toString().c_str());
+		warning("TeTiledSurface::load: Wrong image format on file %s", _loadedPath.c_str());
 		return false;
 	}
 
@@ -215,7 +213,7 @@ void TeTiledSurface::setTiledTexture(const TeIntrusivePtr<TeTiledTexture> &textu
 		for (uint i = 0; i < texture->numberOfColumns() * texture->numberOfRow(); i++)
 			_meshes.push_back(Common::SharedPtr<TeMesh>(TeMesh::makeInstance()));
 
-		setAccessName(texture->getAccessName().append(".surface"));
+		setAccessName(texture->getAccessName() + ".surface");
 		updateSurface();
 	} else {
 		_meshes.clear();
diff --git a/engines/tetraedge/te/te_tiled_surface.h b/engines/tetraedge/te/te_tiled_surface.h
index d9c9d14e9e7..2cb3a79e7d8 100644
--- a/engines/tetraedge/te/te_tiled_surface.h
+++ b/engines/tetraedge/te/te_tiled_surface.h
@@ -45,7 +45,7 @@ public:
 	void draw() override;
 	virtual void entry() {};
 	byte isLoaded();
-	bool load(const Common::Path &path);
+	bool load(const Common::FSNode &node);
 	bool load(const TeImage &image);
 	bool load(const TeIntrusivePtr<Te3DTexture> &texture);
 
@@ -83,7 +83,8 @@ public:
 	void updateSurface();
 	void updateVideoProperties();
 
-	const Common::Path &path() const { return _path; }
+	const Common::String &loadedPath() const { return _loadedPath; }
+	void setLoadedPath(const Common::String &p) { _loadedPath = p; }
 
 	TeFrameAnim _frameAnim;
 
@@ -105,7 +106,7 @@ private:
 
 	TeImage::Format _imgFormat;
 
-	Common::Path _path;
+	Common::String _loadedPath;
 
 };
 
diff --git a/engines/tetraedge/te/te_tiled_texture.cpp b/engines/tetraedge/te/te_tiled_texture.cpp
index b70c9ffb79e..2a1c4bc02b2 100644
--- a/engines/tetraedge/te/te_tiled_texture.cpp
+++ b/engines/tetraedge/te/te_tiled_texture.cpp
@@ -41,15 +41,16 @@ bool TeTiledTexture::isLoaded() {
 }
 
 
-bool TeTiledTexture::load(const Common::Path &path) {
+bool TeTiledTexture::load(const Common::String &path) {
 	release();
 	TeIntrusivePtr<TeImage> img;
 	TeResourceManager *resmgr = g_engine->getResourceManager();
 	if (resmgr->exists(path)) {
-		img = resmgr->getResourceNoSearch<TeImage>(path);
+		img = resmgr->getResourceByName<TeImage>(path);
 	} else {
 		img = new TeImage();
-		if (!img->load(path))
+		TeCore *core = g_engine->getCore();
+		if (!img->load(core->findFile(path)))
 			return false;
 	}
 	load(*img);
@@ -86,7 +87,7 @@ bool TeTiledTexture::load(const TeImage &img) {
 				TeImage *optimizedimg = optimisedTileImage(imgArray, newTileSize, Common::SharedPtr<TePalette>(), img.teFormat());
 				img.copy(*optimizedimg, TeVector2s32(0, 0), TeVector2s32(_tileSize._x * row, _tileSize._y * col), newTileSize);
 				//optimizedimg->_flipY = img._flipY;
-				Common::String accessName = Common::String::format("%s.Tile%dx%d", img.getAccessName().toString().c_str(), row, col);
+				Common::String accessName = Common::String::format("%s.Tile%dx%d", img.getAccessName().c_str(), row, col);
 				optimizedimg->setAccessName(accessName);
 				tileimage = optimizedimg;
 			} else {
@@ -115,7 +116,7 @@ bool TeTiledTexture::load(const TeImage &img) {
 		_somethingSize._x = _somethingSize._x / cols;
 	if (rows)
 		_somethingSize._y = _somethingSize._y / rows;
-	setAccessName(img.getAccessName().append(".tt"));
+	setAccessName(img.getAccessName() + ".tt");
 	return true;
 }
 
@@ -129,7 +130,7 @@ bool TeTiledTexture::load(const TeIntrusivePtr<Te3DTexture> &texture) {
 	tileData->_texture = texture;
 	tileData->_vec2 = TeVector3f32(1, 1, 0);
 	tileData->_vec1 = TeVector3f32(0, 0, 0);
-	setAccessName(texture->getAccessName().append(".tt"));
+	setAccessName(texture->getAccessName() + ".tt");
 	return true;
 }
 
diff --git a/engines/tetraedge/te/te_tiled_texture.h b/engines/tetraedge/te/te_tiled_texture.h
index 8a0b4e81b8f..203030f1c32 100644
--- a/engines/tetraedge/te/te_tiled_texture.h
+++ b/engines/tetraedge/te/te_tiled_texture.h
@@ -46,7 +46,7 @@ public:
 
 	uint imageFormat();
 	bool isLoaded();
-	bool load(const Common::Path &path);
+	bool load(const Common::String &path);
 	bool load(const TeImage &image);
 	bool load(const TeIntrusivePtr<Te3DTexture> &texture);
 	uint32 numberOfColumns() const;


Commit: c6c91025c74d259e3d7d7c10f68e0ecca00efebc
    https://github.com/scummvm/scummvm/commit/c6c91025c74d259e3d7d7c10f68e0ecca00efebc
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2023-02-05T08:07:39+09:00

Commit Message:
TETRAEDGE: Note direction of logic in showMarkers

Changed paths:
    engines/tetraedge/game/game.cpp


diff --git a/engines/tetraedge/game/game.cpp b/engines/tetraedge/game/game.cpp
index 8fb0cac712f..dce51c5f036 100644
--- a/engines/tetraedge/game/game.cpp
+++ b/engines/tetraedge/game/game.cpp
@@ -1487,6 +1487,8 @@ void Game::setCurrentObjectSprite(const Common::String &spritePath) {
 	}
 }
 
+// Note: The naming of this function is bad, but follows the original..
+// we really set the visibility to the *opposite* of the parameter.
 bool Game::showMarkers(bool val) {
 	if (!_forGui.loaded())
 		return false;


Commit: 31862a6847bbb894dbe31f1178b7fa97cd9ce490
    https://github.com/scummvm/scummvm/commit/31862a6847bbb894dbe31f1178b7fa97cd9ce490
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2023-02-05T08:07:46+09:00

Commit Message:
TETRAEDGE: Limit head rotation in both directions

As amusing as it was for Kate to have such a flexible neck..

Changed paths:
    engines/tetraedge/game/in_game_scene.cpp


diff --git a/engines/tetraedge/game/in_game_scene.cpp b/engines/tetraedge/game/in_game_scene.cpp
index 9d5c2509d12..f86627a3069 100644
--- a/engines/tetraedge/game/in_game_scene.cpp
+++ b/engines/tetraedge/game/in_game_scene.cpp
@@ -1106,7 +1106,7 @@ void InGameScene::update() {
 			if (aroundAnchorZone(zone)) {
 				TeVector2f32 headRot(getHeadHorizontalRotation(_character, zone->_loc),
 					getHeadVerticalRotation(_character, zone->_loc));
-				if (headRot.getX() * 180.0 / M_PI > 90.0 || headRot.getY() * 180.0 / M_PI > 45.0) {
+				if (fabs(headRot.getX() * 180.0 / M_PI) > 90.0 || fabs(headRot.getY() * 180.0 / M_PI) > 45.0) {
 					_character->setHasAnchor(false);
 					_character->setLastHeadRotation(_character->headRotation());
 				} else {




More information about the Scummvm-git-logs mailing list