[Scummvm-git-logs] scummvm master -> 8d813f5dcac80565efb59fd7baee12d401904b54

bluegr noreply at scummvm.org
Tue Apr 26 21:33:23 UTC 2022


This automated email contains information about 10 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
08b500b5e9 TINSEL: Work around PCM playback deadlock in Noir
467706cbd8 TINSEL: Implement v3 path in HoldItem
a40cc7053d TINSEL: Implement HELDOBJECTORTOPIC libcall
70d1dbb00f TINSEL: Add barebones Notebook subsystem
31d4dfa351 TINSEL: Implement GetLanguageSceneHandle
5d50b5861f TINSEL: Remap special PID values for v3
c44ec28e2b TINSEL: Implement SystemReel subsystem
b71545857b TINSEL: Remap special inv indexes for v3
99c1ea5ea0 TINSEL: Implement DECINVMAIN libcall
8d813f5dca TINSEL: Fix comment formatting


Commit: 08b500b5e984154658a49f123d4996c4419eaccb
    https://github.com/scummvm/scummvm/commit/08b500b5e984154658a49f123d4996c4419eaccb
Author: Jakob Wagner (wobakj at web.de)
Date: 2022-04-27T00:33:15+03:00

Commit Message:
TINSEL: Work around PCM playback deadlock in Noir

This workaround disables PCM playback.

The PCMPlayers _chunk is NULL but _state is S_MID.
As a result getNextChunk always return 1, leading to readBuffer in
the playback thread never unlocking _mutex.

Changed paths:
    engines/tinsel/music.cpp


diff --git a/engines/tinsel/music.cpp b/engines/tinsel/music.cpp
index 23c63fced50..6bfa3a015ec 100644
--- a/engines/tinsel/music.cpp
+++ b/engines/tinsel/music.cpp
@@ -693,6 +693,10 @@ PCMMusicPlayer::PCMMusicPlayer() {
 
 	_vm->_mixer->playStream(Audio::Mixer::kMusicSoundType,
 			&_handle, this, -1, _volume, 0, DisposeAfterUse::NO, true);
+
+	if (TinselVersion == 3) {
+		warning("Todo: remove workaround when deadlock in readBuffer is fixed");
+	}
 }
 
 PCMMusicPlayer::~PCMMusicPlayer() {
@@ -726,6 +730,10 @@ void PCMMusicPlayer::stopPlay() {
 int PCMMusicPlayer::readBuffer(int16 *buffer, const int numSamples) {
 	Common::StackLock slock(_mutex);
 
+	// Workaround for v3 to prevent deadlock due to missing chunk
+	if ((TinselVersion == 3) && !_curChunk && _state == S_MID)
+		return 0;
+
 	if (!_curChunk && ((_state == S_IDLE) || (_state == S_STOP)))
 		return 0;
 


Commit: 467706cbd8f16d8bcd1b602cdd400054bb9646eb
    https://github.com/scummvm/scummvm/commit/467706cbd8f16d8bcd1b602cdd400054bb9646eb
Author: Jakob Wagner (wobakj at web.de)
Date: 2022-04-27T00:33:15+03:00

Commit Message:
TINSEL: Implement v3 path in HoldItem

Changed paths:
    engines/tinsel/dialogs.cpp
    engines/tinsel/dialogs.h
    engines/tinsel/tinsel.h


diff --git a/engines/tinsel/dialogs.cpp b/engines/tinsel/dialogs.cpp
index 59241d82d43..1d63240b4c5 100644
--- a/engines/tinsel/dialogs.cpp
+++ b/engines/tinsel/dialogs.cpp
@@ -1618,9 +1618,12 @@ void Dialogs::HoldItem(int item, bool bKeepFilm) {
 					AddToInventory(INV_1, _heldItem);
 				else if (invObj->attribute & DEFINV2)
 					AddToInventory(INV_2, _heldItem);
-				else
-					// Hook for definable default inventory
-					AddToInventory(INV_1, _heldItem);
+				else {
+					if ((TinselVersion < 3) || (!(invObj->attribute & V3ATTR_X200) && !(invObj->attribute & V3ATTR_X400))) {
+						// Hook for definable default inventory
+						AddToInventory(INV_1, _heldItem);
+					}
+				}
 			}
 
 		} else if (TinselVersion <= 1) {
diff --git a/engines/tinsel/dialogs.h b/engines/tinsel/dialogs.h
index 6475c835471..0033a887667 100644
--- a/engines/tinsel/dialogs.h
+++ b/engines/tinsel/dialogs.h
@@ -85,6 +85,10 @@ enum InvCursorFN { IC_AREA,
 #define DEFINV2 0x10
 #define PERMACONV 0x20
 #define CONVENDITEM 0x40
+// Noir only
+#define V3ATTR_X200 0x200
+#define V3ATTR_X400 0x400
+
 #define sliderRange (_sliderYmax - _sliderYmin)
 #define MAXSLIDES 4
 #define MAX_PERMICONS 10 // Max permanent conversation icons
diff --git a/engines/tinsel/tinsel.h b/engines/tinsel/tinsel.h
index 3b50aa4712f..63cddfa919b 100644
--- a/engines/tinsel/tinsel.h
+++ b/engines/tinsel/tinsel.h
@@ -99,7 +99,6 @@ typedef bool (*KEYFPTR)(const Common::KeyState &);
 #define GAME_FRAME_DELAY (1000 / ONE_SECOND)
 
 #define TinselVersion (_vm->getVersion())
-#define TinselV3 (TinselVersion == 3)
 #define TinselV2Demo (TinselVersion == 2 && _vm->getIsADGFDemo())
 #define TinselV1PSX (TinselVersion == 1 && _vm->getPlatform() == Common::kPlatformPSX)
 #define TinselV1Mac (TinselVersion == 1 && _vm->getPlatform() == Common::kPlatformMacintosh)


Commit: a40cc7053d947edc8b40b781b6c752b1cf3d3ce3
    https://github.com/scummvm/scummvm/commit/a40cc7053d947edc8b40b781b6c752b1cf3d3ce3
Author: Jakob Wagner (wobakj at web.de)
Date: 2022-04-27T00:33:15+03:00

Commit Message:
TINSEL: Implement HELDOBJECTORTOPIC libcall

Changed paths:
    engines/tinsel/dialogs.cpp
    engines/tinsel/dialogs.h
    engines/tinsel/tinlib.cpp


diff --git a/engines/tinsel/dialogs.cpp b/engines/tinsel/dialogs.cpp
index 1d63240b4c5..5cd5ba3c81a 100644
--- a/engines/tinsel/dialogs.cpp
+++ b/engines/tinsel/dialogs.cpp
@@ -5398,6 +5398,13 @@ void Dialogs::Redraw() {
 	}
 }
 
+// Noir
+bool Dialogs::IsConvAndNotMove() {
+	// TODO: Ensure that the used global is correct
+	// If this is the right mapping, the variable is reversed in Noir
+	return IsConvWindow() && !_bMoveOnUnHide;
+}
+
 /**************************************************************************/
 /************************ The inventory process ***************************/
 /**************************************************************************/
diff --git a/engines/tinsel/dialogs.h b/engines/tinsel/dialogs.h
index 0033a887667..98ad101fa6a 100644
--- a/engines/tinsel/dialogs.h
+++ b/engines/tinsel/dialogs.h
@@ -353,6 +353,9 @@ public:
 	const FILM *GetWindowData();
 	void Redraw();
 
+	// Noir
+	bool IsConvAndNotMove();
+
 	bool _noLanguage;
 	int _glitterIndex;
 	volatile int _pointedWaitCount; // used by ObjectProcess - fix the 'repeated pressing bug'
diff --git a/engines/tinsel/tinlib.cpp b/engines/tinsel/tinlib.cpp
index 8a6227b6412..1c082bf449c 100644
--- a/engines/tinsel/tinlib.cpp
+++ b/engines/tinsel/tinlib.cpp
@@ -152,7 +152,7 @@ enum MASTER_LIB_CODES {
 	TRYPLAYSAMPLE, UNDIMMUSIC, UNHOOKSCENE, UNTAGACTOR, VIBRATE, WAITFRAME, WAITKEY,
 	WAITSCROLL, WAITTIME, WALK, WALKED, WALKEDPOLY, WALKEDTAG, WALKINGACTOR, WALKPOLY,
 	WALKTAG, WALKXPOS, WALKYPOS, WHICHCD, WHICHINVENTORY, ZZZZZZ, DEC3D, DECINVMAIN,
-	ADDNOTEBOOK, ADDINV3, ADDCONV, SET3DTEXTURE, FADEMUSIC, VOICEOVER, SETVIEW, HIGHEST_LIBCODE
+	ADDNOTEBOOK, ADDINV3, ADDCONV, SET3DTEXTURE, FADEMUSIC, VOICEOVER, SETVIEW, HELDOBJECTORTOPIC, HIGHEST_LIBCODE
 };
 
 static const MASTER_LIB_CODES DW1DEMO_CODES[] = {
@@ -4598,8 +4598,10 @@ NoirMapping translateNoirLibCode(int libCode, int32 *pp) {
 		pp -= mapping.numArgs - 1;
 		debug(7, "%s(%d)", mapping.name, pp[0]);
 		break;
-	case 75: // 0 parameters, returns icon of topic or held object
-		error("Unsupported libCode %d", libCode);
+	case 75:
+		mapping = NoirMapping{"HELDOBJECTORTOPIC", HELDOBJECTORTOPIC, 0};
+		debug(7, "%s()", mapping.name);
+		break;
 	case 76: // 0 parameters, returns enum depending on a bitfield value on held object
 		error("Unsupported libCode %d", libCode);
 	case 77:
@@ -5809,6 +5811,15 @@ int CallLibraryRoutine(CORO_PARAM, int operand, int32 *pp, const INT_CONTEXT *pi
 		pp[0] = HeldObject();
 		return 0;
 
+	case HELDOBJECTORTOPIC:
+		// Noir
+		if (_vm->_dialogs->IsConvAndNotMove()) {
+			pp[0] = HeldObject();
+		} else {
+			pp[0] = Topic();
+		}
+		return 0;
+
 	case HIDEACTOR:
 		// Common to DW1 / DW2 / Noir
 		if (TinselVersion <= 1)


Commit: 70d1dbb00f8afadc7e66d61c93efa0e48286ffbd
    https://github.com/scummvm/scummvm/commit/70d1dbb00f8afadc7e66d61c93efa0e48286ffbd
Author: Jakob Wagner (wobakj at web.de)
Date: 2022-04-27T00:33:15+03:00

Commit Message:
TINSEL: Add barebones Notebook subsystem

And implement the BOOKADDHYPERLINK libcall.
The subsystem contains known fields and constants.

Changed paths:
  A engines/tinsel/noir/notebook.cpp
  A engines/tinsel/noir/notebook.h
    engines/tinsel/dialogs.h
    engines/tinsel/module.mk
    engines/tinsel/tinlib.cpp
    engines/tinsel/tinsel.cpp
    engines/tinsel/tinsel.h


diff --git a/engines/tinsel/dialogs.h b/engines/tinsel/dialogs.h
index 98ad101fa6a..af334ca41c4 100644
--- a/engines/tinsel/dialogs.h
+++ b/engines/tinsel/dialogs.h
@@ -86,8 +86,11 @@ enum InvCursorFN { IC_AREA,
 #define PERMACONV 0x20
 #define CONVENDITEM 0x40
 // Noir only
+#define V3ATTR_X80 0x80
 #define V3ATTR_X200 0x200
 #define V3ATTR_X400 0x400
+#define NOTEBOOK_TITLE 0x800 // is a notebook title
+#define V3ATTR_X2000 0x2000
 
 #define sliderRange (_sliderYmax - _sliderYmin)
 #define MAXSLIDES 4
@@ -124,6 +127,10 @@ struct INV_OBJECT {
 	SCNHANDLE hIconFilm;	// inventory objects animation film
 	SCNHANDLE hScript;	// inventory objects event handling script
 	int32 attribute;		// inventory object's attribute
+
+	// Noir
+	int32 unknown;
+	int32 title;	// id of associated notebook title
 };
 
 struct INV_DEF {
diff --git a/engines/tinsel/module.mk b/engines/tinsel/module.mk
index 82eab89fe15..9c4729f2953 100644
--- a/engines/tinsel/module.mk
+++ b/engines/tinsel/module.mk
@@ -46,7 +46,8 @@ MODULE_OBJS := \
 	timers.o \
 	tinlib.o \
 	tinsel.o \
-	token.o
+	token.o \
+	noir/notebook.o \
 
 # This module can be built as a plugin
 ifeq ($(ENABLE_TINSEL), DYNAMIC_PLUGIN)
diff --git a/engines/tinsel/noir/notebook.cpp b/engines/tinsel/noir/notebook.cpp
new file mode 100644
index 00000000000..7a2d988b6d2
--- /dev/null
+++ b/engines/tinsel/noir/notebook.cpp
@@ -0,0 +1,62 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "tinsel/noir/notebook.h"
+
+#include "tinsel/dialogs.h"
+
+namespace Tinsel {
+
+void Notebook::AddHyperlink(int32 id1, int32 id2) {
+	INV_OBJECT *invObject = _vm->_dialogs->GetInvObject(id1);
+	if (invObject->title != 0) {
+		error("A clue can only be hyperlinked if it only has one title!");
+		return;
+	}
+
+	invObject = _vm->_dialogs->GetInvObject(id2);
+	if (invObject->title != 0) {
+		error("A clue can only be hyperlinked if it only has one title!");
+		return;
+	}
+
+	uint32 i;
+	for (i = 0; i < MAX_HYPERS; ++i) {
+		int32 curr_id1 = _hyperlinks[i].id1;
+		if (curr_id1 == 0) {
+			_hyperlinks[i].id1 = id1;
+			_hyperlinks[i].id2 = id2;
+			return;
+		}
+
+		if ((curr_id1 == id1) || (id1 == _hyperlinks[i].id2)) {
+			if ((curr_id1 != id2) && (id2 != _hyperlinks[i].id2)) {
+				error("A clue/title can only be hyperlinked to one other clue/title!");
+			}
+			return;
+		}
+	}
+
+	// No free hyperlink entry was found
+	error("Too many hyperlinks");
+}
+
+} // End of namespace Tinsel
diff --git a/engines/tinsel/noir/notebook.h b/engines/tinsel/noir/notebook.h
new file mode 100644
index 00000000000..229e9aae6ec
--- /dev/null
+++ b/engines/tinsel/noir/notebook.h
@@ -0,0 +1,83 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef TINSEL_NOTEBOOK_H // prevent multiple includes
+#define TINSEL_NOTEBOOK_H
+
+#include "common/scummsys.h"
+
+#include "tinsel/events.h"
+
+namespace Tinsel {
+// links two clue/title objects together
+struct HYPERLINK {
+	int32 id1;
+	int32 id2;
+};
+
+// 6 bytes large
+struct ENTRY {
+	int32 id;
+	bool active;
+	int32 page1;
+	int32 indexOnPage1;
+	int32 page2;
+	int32 indexOnPage2;
+};
+
+enum class BOOKSTATE {
+	CLOSED = 0,
+	OPEN_UNKNOWN = 1,
+	OPEN_ANIMATING = 2,
+	OPENED = 3
+};
+
+class Notebook {
+public:
+	Notebook() = default;
+
+	// can be a title or clue
+	void AddEntry(int32 entryIdx, int32 page1, int32 page2);
+	// Adds a connection between a clue/title
+	void AddHyperlink(int32 id1, int32 id2);
+	// Called within InventoryProcess loop
+	void Redraw();
+	// Called by EventToInventory
+	void EventToNotebook(PLR_EVENT event, bool p2, bool p3);
+
+private:
+	const static uint32 MAX_ENTRIES = 100;
+	const static uint32 MAX_PAGES = 0x15;
+	const static uint32 MAX_HYPERS = 0xf;
+	const static uint32 MAX_ENTRIES_PER_PAGE = 8;
+
+	HYPERLINK _hyperlinks[MAX_HYPERS];
+
+	const static uint32 _numEntries = 0;
+
+	ENTRY _entries[MAX_ENTRIES];
+
+	BOOKSTATE _state;
+};
+
+} // End of namespace Tinsel
+
+#endif
diff --git a/engines/tinsel/tinlib.cpp b/engines/tinsel/tinlib.cpp
index 1c082bf449c..99f62338e9c 100644
--- a/engines/tinsel/tinlib.cpp
+++ b/engines/tinsel/tinlib.cpp
@@ -65,6 +65,7 @@
 #include "tinsel/tinlib.h"
 #include "tinsel/tinsel.h"
 #include "tinsel/token.h"
+#include "tinsel/noir/notebook.h"
 
 #include "common/textconsole.h"
 
@@ -152,7 +153,8 @@ enum MASTER_LIB_CODES {
 	TRYPLAYSAMPLE, UNDIMMUSIC, UNHOOKSCENE, UNTAGACTOR, VIBRATE, WAITFRAME, WAITKEY,
 	WAITSCROLL, WAITTIME, WALK, WALKED, WALKEDPOLY, WALKEDTAG, WALKINGACTOR, WALKPOLY,
 	WALKTAG, WALKXPOS, WALKYPOS, WHICHCD, WHICHINVENTORY, ZZZZZZ, DEC3D, DECINVMAIN,
-	ADDNOTEBOOK, ADDINV3, ADDCONV, SET3DTEXTURE, FADEMUSIC, VOICEOVER, SETVIEW, HELDOBJECTORTOPIC, HIGHEST_LIBCODE
+	ADDNOTEBOOK, ADDINV3, ADDCONV, SET3DTEXTURE, FADEMUSIC, VOICEOVER, SETVIEW,
+	HELDOBJECTORTOPIC, BOOKADDHYPERLINK, HIGHEST_LIBCODE
 };
 
 static const MASTER_LIB_CODES DW1DEMO_CODES[] = {
@@ -4647,8 +4649,7 @@ NoirMapping translateNoirLibCode(int libCode, int32 *pp) {
 		debug(7, "%s(0x%08X, 0x%08X, 0x%08X)", mapping.name, pp[0], pp[1], pp[2]);
 		break;
 	case 86: // 2 parameters
-		warning("TODO: Implement notebook_add_hyperlink");
-		mapping = NoirMapping{"NODEBOOKADDHYPERLINK", ZZZZZZ, 2};
+		mapping = NoirMapping{"BOOKADDHYPERLINK", BOOKADDHYPERLINK, 2};
 		pp -= mapping.numArgs - 1;
 		debug(7, "%s(0x%08X, 0x%08X)", mapping.name, pp[0], pp[1]);
 		break;
@@ -5418,6 +5419,12 @@ int CallLibraryRoutine(CORO_PARAM, int operand, int32 *pp, const INT_CONTEXT *pi
 		startBackground(coroParam, pp[0]);
 		return -1;
 
+	case BOOKADDHYPERLINK:
+		// Noir
+		pp -= 1; // 2 parameters
+		_vm->_notebook->AddHyperlink(pp[0], pp[1]);
+		return -2;
+
 	case BLOCKING:
 		// DW2 only
 		Blocking(pp[0]);
diff --git a/engines/tinsel/tinsel.cpp b/engines/tinsel/tinsel.cpp
index b44523788b3..ce783b9978b 100644
--- a/engines/tinsel/tinsel.cpp
+++ b/engines/tinsel/tinsel.cpp
@@ -59,6 +59,7 @@
 #include "tinsel/sysvar.h"
 #include "tinsel/timers.h"
 #include "tinsel/tinsel.h"
+#include "tinsel/noir/notebook.h"
 
 namespace Tinsel {
 
@@ -1013,6 +1014,10 @@ Common::Error TinselEngine::run() {
 	_scroll = new Scroll();
 	_dialogs = new Dialogs();
 
+	if (TinselVersion == 3) {
+		_notebook = new Notebook();
+	}
+
 	// Initialize backend
 	if (getGameID() == GID_NOIR) {
 		int width = 640;
diff --git a/engines/tinsel/tinsel.h b/engines/tinsel/tinsel.h
index 63cddfa919b..138b93227b4 100644
--- a/engines/tinsel/tinsel.h
+++ b/engines/tinsel/tinsel.h
@@ -64,6 +64,7 @@ class Actor;
 class Handle;
 class Scroll;
 class Dialogs;
+class Notebook;
 
 typedef Common::List<Common::Rect> RectList;
 
@@ -175,6 +176,7 @@ public:
 	Config *_config;
 	Scroll *_scroll;
 	Dialogs *_dialogs;
+	Notebook *_notebook = nullptr;
 
 	KEYFPTR _keyHandler;
 


Commit: 31d4dfa3519b835242d40fb30358929e99dc9ab0
    https://github.com/scummvm/scummvm/commit/31d4dfa3519b835242d40fb30358929e99dc9ab0
Author: Jakob Wagner (wobakj at web.de)
Date: 2022-04-27T00:33:15+03:00

Commit Message:
TINSEL: Implement GetLanguageSceneHandle

Needed for INVMAIN implementation for noir.

Changed paths:
    engines/tinsel/handle.cpp
    engines/tinsel/handle.h
    engines/tinsel/tinsel.cpp
    engines/tinsel/tinsel.h


diff --git a/engines/tinsel/handle.cpp b/engines/tinsel/handle.cpp
index 4815eb499b5..5388cf21fdc 100644
--- a/engines/tinsel/handle.cpp
+++ b/engines/tinsel/handle.cpp
@@ -25,6 +25,7 @@
 #include "common/file.h"
 #include "common/memstream.h"
 #include "common/textconsole.h"
+#include "common/str.h"
 
 #include "tinsel/actors.h"
 #include "tinsel/background.h"
@@ -608,4 +609,20 @@ int Handle::CdNumber(SCNHANDLE offset) {
 	return GetCD(pH->flags2 & fAllCds);
 }
 
+/**
+  * Searches for a resource by name and returns the handle to it.
+  *
+  * @param fileName Name of the resource to search for
+  */
+SCNHANDLE Handle::FindLanguageSceneHandle(const char *fileName) {
+	Common::String nameString{fileName};
+
+	for (uint i = 0; i < _numHandles; ++i) {
+		if (nameString == Common::String{_handleTable[i].szName}) {
+			return i << SCNHANDLE_SHIFT;
+		}
+	}
+	error("Can't find handle for language scene\n");
+}
+
 } // End of namespace Tinsel
diff --git a/engines/tinsel/handle.h b/engines/tinsel/handle.h
index f8edd2f65f3..73091cefcdd 100644
--- a/engines/tinsel/handle.h
+++ b/engines/tinsel/handle.h
@@ -75,6 +75,9 @@ public:
 
 	int CdNumber(SCNHANDLE offset);
 
+	// Noir
+	SCNHANDLE FindLanguageSceneHandle(const char *fileName);
+
 #ifdef BODGE
 	bool ValidHandle(SCNHANDLE offset);
 #endif
diff --git a/engines/tinsel/tinsel.cpp b/engines/tinsel/tinsel.cpp
index ce783b9978b..5998eec4560 100644
--- a/engines/tinsel/tinsel.cpp
+++ b/engines/tinsel/tinsel.cpp
@@ -903,7 +903,17 @@ const char *const TinselEngine::_textFiles[][3] = {
 	{ "japanese.txt", "japanese1.txt", "japanese2.txt" },	// Japanese
 	{ "us.txt", "us1.txt", "us2.txt" }					// US English
 };
-
+const char *const TinselEngine::_sceneFiles[] = {
+	"english.scn", // English
+	"french.scn", // French
+	"german.scn", // German
+	"italian.scn", // Italian
+	"spanish.scn", // Spanish
+	"english.scn", // Hebrew (FIXME: not sure if this is correct)
+	"english.scn", // Hungarian (FIXME: not sure if this is correct)
+	"japanese.scn", // Japanese
+	"us.scn"  // US English
+};
 
 TinselEngine::TinselEngine(OSystem *syst, const TinselGameDescription *gameDesc) :
 		Engine(syst), _gameDescription(gameDesc), _random("tinsel"),
@@ -1408,4 +1418,18 @@ const char *TinselEngine::getTextFile(LANGUAGE lang) {
 	return _textFiles[lang][cd];
 }
 
+/**
+ * Return the loading screen(?) scene file specific to the given language.
+ *
+ * @param lang index of the language
+ */
+const char *TinselEngine::getSceneFile(LANGUAGE lang) {
+	assert(((unsigned int) lang) < NUM_LANGUAGES);
+
+	if (!Common::File::exists(_sceneFiles[lang]))
+		lang = TXT_ENGLISH; // fallback to ENGLISH.SCN if <LANG>.IDX is not found
+
+	return _sceneFiles[lang];
+}
+
 } // End of namespace Tinsel
diff --git a/engines/tinsel/tinsel.h b/engines/tinsel/tinsel.h
index 138b93227b4..acee3f2ef9a 100644
--- a/engines/tinsel/tinsel.h
+++ b/engines/tinsel/tinsel.h
@@ -126,6 +126,7 @@ class TinselEngine : public Engine {
 	static const char *const _sampleIndices[][3];
 	static const char *const _sampleFiles[][3];
 	static const char *const _textFiles[][3];
+	static const char *const _sceneFiles[];
 
 protected:
 
@@ -161,6 +162,8 @@ public:
 	const char *getSampleIndex(LANGUAGE lang);
 	const char *getSampleFile(LANGUAGE lang);
 	const char *getTextFile(LANGUAGE lang);
+	// Noir
+	const char *getSceneFile(LANGUAGE lang);
 
 	MidiDriver *_driver;
 	SoundManager *_sound;


Commit: 5d50b5861fe57cab943f0188443ba1046bba2906
    https://github.com/scummvm/scummvm/commit/5d50b5861fe57cab943f0188443ba1046bba2906
Author: Jakob Wagner (wobakj at web.de)
Date: 2022-04-27T00:33:15+03:00

Commit Message:
TINSEL: Remap special PID values for v3

V3 discerns between the root scene process and other scene processes.
It also lets global processes be destroyed between scenes and remaps
PID_PROCESS.

Changed paths:
    engines/tinsel/pid.h
    engines/tinsel/scene.cpp


diff --git a/engines/tinsel/pid.h b/engines/tinsel/pid.h
index 6b674ba35c4..8e213bc1c9f 100644
--- a/engines/tinsel/pid.h
+++ b/engines/tinsel/pid.h
@@ -54,10 +54,12 @@ namespace Tinsel {
 
 #define PID_BTN_CLICK 0x110				// process to handle mouse button clicks
 
-#define PID_PROCESS	(0x0110 | PID_DESTROY)	// Scene process base
+#define PID_PROCESS	(((TinselVersion == 3) ? 0x0100 : 0x0110) | PID_DESTROY)	// Scene process base
 
-#define PID_GPROCESS	0x0120			// Global process base
+#define PID_GPROCESS ((TinselVersion == 3) ? ( 0x110 | PID_DESTROY) : 0x0120) // Global process base
 
+// distinction introduced by noir
+#define PID_SCENE	((TinselVersion == 3) ? (0x0001 | PID_TCODE) : PID_TCODE)	// Root scene process
 } // End of namespace Tinsel
 
 #endif	// TINSEL_PID_H
diff --git a/engines/tinsel/scene.cpp b/engines/tinsel/scene.cpp
index 7efeaaea08a..9af95d3a091 100644
--- a/engines/tinsel/scene.cpp
+++ b/engines/tinsel/scene.cpp
@@ -458,7 +458,7 @@ void DoHailScene(SCNHANDLE scene) {
 		init.event = NOEVENT;
 		init.hTinselCode = ss->hSceneScript;
 
-		CoroScheduler.createProcess(PID_TCODE, SceneTinselProcess, &init, sizeof(init));
+		CoroScheduler.createProcess(PID_SCENE, SceneTinselProcess, &init, sizeof(init));
 	}
 }
 


Commit: c44ec28e2ba66bd8cdcf670bd84cbdee6f49d772
    https://github.com/scummvm/scummvm/commit/c44ec28e2ba66bd8cdcf670bd84cbdee6f49d772
Author: Jakob Wagner (wobakj at web.de)
Date: 2022-04-27T00:33:15+03:00

Commit Message:
TINSEL: Implement SystemReel subsystem

Implementation of one special path in SetSystemReel is missing.

Changed paths:
  A engines/tinsel/noir/sysreel.cpp
  A engines/tinsel/noir/sysreel.h
    engines/tinsel/module.mk
    engines/tinsel/tinlib.cpp
    engines/tinsel/tinsel.cpp
    engines/tinsel/tinsel.h


diff --git a/engines/tinsel/module.mk b/engines/tinsel/module.mk
index 9c4729f2953..cfbe50200d9 100644
--- a/engines/tinsel/module.mk
+++ b/engines/tinsel/module.mk
@@ -48,6 +48,7 @@ MODULE_OBJS := \
 	tinsel.o \
 	token.o \
 	noir/notebook.o \
+	noir/sysreel.o \
 
 # This module can be built as a plugin
 ifeq ($(ENABLE_TINSEL), DYNAMIC_PLUGIN)
diff --git a/engines/tinsel/noir/sysreel.cpp b/engines/tinsel/noir/sysreel.cpp
new file mode 100644
index 00000000000..78db14202d3
--- /dev/null
+++ b/engines/tinsel/noir/sysreel.cpp
@@ -0,0 +1,67 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "tinsel/noir/sysreel.h"
+
+#include "common/scummsys.h"
+
+#include "tinsel/cursor.h"
+#include "tinsel/pid.h"
+#include "tinsel/tinsel.h"
+
+namespace Tinsel {
+
+/**
+ * Returns the handle to the sysreel at the given index.
+ *
+ * @param index reel to get the handle to
+ */
+SCNHANDLE SystemReel::Get(int32 index) {
+	assert(index >= 0 && index < MAX_SYSREELS);
+
+	return _reels[index];
+}
+
+/**
+ * Stores a reel at an index and if the index is a cursor
+ *
+ * @param index where to store the reel
+ * @param reel handle to the reel
+ */
+void SystemReel::Set(int32 index, SCNHANDLE reel) {
+	assert(index >= 0 && index < MAX_SYSREELS);
+
+	if (index == SYSREEL_LOADSCREEN) {
+		if (CoroScheduler.getCurrentPID() != PID_SCENE) {
+			return;
+		}
+	}
+
+	_reels[index] = reel;
+
+	// Noir actually calls a function specifically for doing DwInitCursor on
+	// system reel 11.
+	if (index == SYSREEL_CURSOR && reel != 0) {
+		_vm->_cursor->DwInitCursor(reel);
+	}
+}
+
+} // End of namespace Tinsel
diff --git a/engines/tinsel/noir/sysreel.h b/engines/tinsel/noir/sysreel.h
new file mode 100644
index 00000000000..8bf7ed21821
--- /dev/null
+++ b/engines/tinsel/noir/sysreel.h
@@ -0,0 +1,49 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef TINSEL_SYSREEL_H // prevent multiple includes
+#define TINSEL_SYSREEL_H
+
+#include "tinsel/dw.h"
+
+namespace Tinsel {
+
+class SystemReel {
+public:
+	SystemReel() = default;
+
+	SCNHANDLE Get(int32 index);
+	void Set(int32 index, SCNHANDLE reel);
+
+private:
+	const static int32 MAX_SYSREELS = 0x28;
+
+	enum {
+		SYSREEL_CURSOR = 11,
+		SYSREEL_LOADSCREEN = 0x1f
+	};
+
+	SCNHANDLE _reels[MAX_SYSREELS];
+};
+
+} // End of namespace Tinsel
+
+#endif
diff --git a/engines/tinsel/tinlib.cpp b/engines/tinsel/tinlib.cpp
index 99f62338e9c..95bf52442c2 100644
--- a/engines/tinsel/tinlib.cpp
+++ b/engines/tinsel/tinlib.cpp
@@ -66,6 +66,7 @@
 #include "tinsel/tinsel.h"
 #include "tinsel/token.h"
 #include "tinsel/noir/notebook.h"
+#include "tinsel/noir/sysreel.h"
 
 #include "common/textconsole.h"
 
@@ -2776,14 +2777,7 @@ static void SetPalette(SCNHANDLE hPal, bool escOn, int myEscape) {
  * Set system reel
  */
 static void SetSystemReel(int index, SCNHANDLE reel) {
-	switch (index) {
-		case 11:
-			DecCursor(reel);
-			break;
-		default:
-			warning("SetSystemReel(%d, %08X), STUBBED", index, reel);
-			break;
-	}
+	_vm->_systemReel->Set(index, reel);
 }
 
 /**
diff --git a/engines/tinsel/tinsel.cpp b/engines/tinsel/tinsel.cpp
index 5998eec4560..501d8531ddc 100644
--- a/engines/tinsel/tinsel.cpp
+++ b/engines/tinsel/tinsel.cpp
@@ -60,6 +60,7 @@
 #include "tinsel/timers.h"
 #include "tinsel/tinsel.h"
 #include "tinsel/noir/notebook.h"
+#include "tinsel/noir/sysreel.h"
 
 namespace Tinsel {
 
@@ -1026,6 +1027,7 @@ Common::Error TinselEngine::run() {
 
 	if (TinselVersion == 3) {
 		_notebook = new Notebook();
+		_systemReel = new SystemReel();
 	}
 
 	// Initialize backend
diff --git a/engines/tinsel/tinsel.h b/engines/tinsel/tinsel.h
index acee3f2ef9a..ec45737707a 100644
--- a/engines/tinsel/tinsel.h
+++ b/engines/tinsel/tinsel.h
@@ -65,6 +65,7 @@ class Handle;
 class Scroll;
 class Dialogs;
 class Notebook;
+class SystemReel;
 
 typedef Common::List<Common::Rect> RectList;
 
@@ -180,6 +181,7 @@ public:
 	Scroll *_scroll;
 	Dialogs *_dialogs;
 	Notebook *_notebook = nullptr;
+	SystemReel *_systemReel = nullptr;
 
 	KEYFPTR _keyHandler;
 


Commit: b71545857bd18c8f28dbb8cd9838d52ef9d904e4
    https://github.com/scummvm/scummvm/commit/b71545857bd18c8f28dbb8cd9838d52ef9d904e4
Author: Jakob Wagner (wobakj at web.de)
Date: 2022-04-27T00:33:15+03:00

Commit Message:
TINSEL: Remap special inv indexes for v3

V3 requires discerning between NOOBJECT and INV_NOICON as the values
associated to these special indexes now differ.

Changed paths:
    engines/tinsel/dialogs.cpp
    engines/tinsel/dialogs.h
    engines/tinsel/dw.h
    engines/tinsel/tinlib.cpp


diff --git a/engines/tinsel/dialogs.cpp b/engines/tinsel/dialogs.cpp
index 5cd5ba3c81a..66f57c65ffa 100644
--- a/engines/tinsel/dialogs.cpp
+++ b/engines/tinsel/dialogs.cpp
@@ -1605,7 +1605,7 @@ void Dialogs::HoldItem(int item, bool bKeepFilm) {
 	INV_OBJECT *invObj;
 
 	if (_heldItem != item) {
-		if ((TinselVersion >= 2) && (_heldItem != NOOBJECT)) {
+		if ((TinselVersion >= 2) && (_heldItem != INV_NOICON)) {
 			// No longer holding previous item
 			_vm->_cursor->DelAuxCursor(); // no longer aux cursor
 
@@ -3130,18 +3130,18 @@ void Dialogs::ConvAction(int index) {
 	MOVER *pMover = (TinselVersion >= 2) ? GetMover(_vm->_actor->GetLeadId()) : NULL;
 
 	switch (index) {
-	case INV_NOICON:
+	case NOOBJECT:
 		return;
 
 	case INV_CLOSEICON:
-		_thisIcon = -1; // Postamble
+		_thisIcon = NOOBJECT; // Postamble
 		break;
 
 	case INV_OPENICON:
 		// Store the direction the lead character is facing in when the conversation starts
 		if (TinselVersion >= 2)
 			_initialDirection = GetMoverDirection(pMover);
-		_thisIcon = -2; // Preamble
+		_thisIcon = INV_CLOSEICON; // Preamble
 		break;
 
 	default:
diff --git a/engines/tinsel/dialogs.h b/engines/tinsel/dialogs.h
index af334ca41c4..eefcddca828 100644
--- a/engines/tinsel/dialogs.h
+++ b/engines/tinsel/dialogs.h
@@ -57,12 +57,19 @@ enum {
 
 enum {
 	NOOBJECT = -1,
-	INV_NOICON = -1,
+	INV_NOICON_V0 = -1,
 	INV_CLOSEICON = -2,
 	INV_OPENICON = -3,
-	INV_HELDNOTIN = -4
+	INV_HELDNOTIN_V0 = -4,
+	// Noir discerns between NOOBJECT and INV_NOICON
+	INV_NOICON_V3 = 0,
+	INV_HELDNOTIN_V3 = 1,
+	INV_HELDIN = 2,
 };
 
+#define INV_NOICON ((TinselVersion == 3) ? INV_NOICON_V3 : INV_NOICON_V0)
+#define INV_HELDNOTIN ((TinselVersion == 3) ? INV_HELDNOTIN_V3 : INV_HELDNOTIN_V0)
+
 enum CONV_PARAM {
 	CONV_DEF,
 	CONV_BOTTOM,
@@ -90,6 +97,7 @@ enum InvCursorFN { IC_AREA,
 #define V3ATTR_X200 0x200
 #define V3ATTR_X400 0x400
 #define NOTEBOOK_TITLE 0x800 // is a notebook title
+#define V3ATTR_X1000 0x1000
 #define V3ATTR_X2000 0x2000
 
 #define sliderRange (_sliderYmax - _sliderYmin)
diff --git a/engines/tinsel/dw.h b/engines/tinsel/dw.h
index fbe5fdf404b..34f6130a0aa 100644
--- a/engines/tinsel/dw.h
+++ b/engines/tinsel/dw.h
@@ -85,6 +85,7 @@ typedef int HPOLYGON;
 #define Z_TOPW_TEXT	Z_TAG_TEXT
 
 // Started a collection of assorted maximum numbers here:
+// TODO: Noir only has two movers - deal with that
 #define MAX_MOVERS	6	// Moving actors using path system
 #define MAX_SAVED_ACTORS 32	// Saved 'Normal' actors
 #define MAX_SAVED_ALIVES 512	// Saves actors'lives
diff --git a/engines/tinsel/tinlib.cpp b/engines/tinsel/tinlib.cpp
index 95bf52442c2..844076ee0e1 100644
--- a/engines/tinsel/tinlib.cpp
+++ b/engines/tinsel/tinlib.cpp
@@ -1095,7 +1095,7 @@ static void Drop(int object) {
  * Delete all objects from inventory 1 and 2.
  */
 static void DropEverything() {
-	_vm->_dialogs->HoldItem(NOOBJECT, false);
+	_vm->_dialogs->HoldItem(INV_NOICON, false);
 
 	_vm->_dialogs->ClearInventory(INV_1);
 	_vm->_dialogs->ClearInventory(INV_2);
@@ -1217,7 +1217,7 @@ static bool HasRestarted() {
  * See if an object is in the inventory.
  */
 int Have(int object) {
-	return (_vm->_dialogs->InventoryPos(object) != NOOBJECT);
+	return (_vm->_dialogs->InventoryPos(object) != INV_NOICON);
 }
 
 /**


Commit: 99c1ea5ea03f73d6b153389c246cf79537fe2adf
    https://github.com/scummvm/scummvm/commit/99c1ea5ea03f73d6b153389c246cf79537fe2adf
Author: Jakob Wagner (wobakj at web.de)
Date: 2022-04-27T00:33:15+03:00

Commit Message:
TINSEL: Implement DECINVMAIN libcall

DECINVMAIN does not hail the loadingscreen scene yet because playing
it produces an incorrect corotine stack.

Changed paths:
    engines/tinsel/cursor.cpp
    engines/tinsel/dialogs.cpp
    engines/tinsel/dialogs.h
    engines/tinsel/handle.cpp
    engines/tinsel/heapmem.cpp
    engines/tinsel/tinlib.cpp


diff --git a/engines/tinsel/cursor.cpp b/engines/tinsel/cursor.cpp
index e7d71759a90..b4637c51ba2 100644
--- a/engines/tinsel/cursor.cpp
+++ b/engines/tinsel/cursor.cpp
@@ -321,15 +321,19 @@ void Cursor::SetAuxCursor(SCNHANDLE hFilm) {
 
 	DelAuxCursor();		// Get rid of previous
 
-	// WORKAROUND: There's no palette when loading a DW1 savegame with a held item, so exit if so
-	if (!_vm->_bg->BgPal())
-		return;
+	// Noir does not use palettes
+	if (TinselVersion < 3) {
+		// WORKAROUND: There's no palette when loading a DW1 savegame with a held item, so exit if so
+		if (!_vm->_bg->BgPal())
+			return;
+
+		assert(_vm->_bg->BgPal()); // no background palette
+		PokeInPalette(pmi);
+	}
 
 	GetCursorXY(&x, &y, false);	// Note: also waits for cursor to appear
 
 	pim = _vm->_handle->GetImage(READ_32(pFrame)); // Get pointer to auxillary cursor's image
-	assert(_vm->_bg->BgPal()); // no background palette
-	PokeInPalette(pmi);
 
 	_auxCursorOffsetX = (short)(pim->imgWidth / 2 - ((int16) pim->anioffX));
 	_auxCursorOffsetY = (short)((pim->imgHeight & ~C16_FLAG_MASK) / 2 -
diff --git a/engines/tinsel/dialogs.cpp b/engines/tinsel/dialogs.cpp
index 66f57c65ffa..00539445083 100644
--- a/engines/tinsel/dialogs.cpp
+++ b/engines/tinsel/dialogs.cpp
@@ -57,6 +57,7 @@
 #include "tinsel/tinlib.h"
 #include "tinsel/tinsel.h" // For engine access
 #include "tinsel/token.h"
+#include "tinsel/noir/sysreel.h"
 
 #include "common/textconsole.h"
 
@@ -1161,7 +1162,18 @@ void Dialogs::InventoryIconCursor(bool bNewItem) {
 		if (TinselVersion >= 2) {
 			if (bNewItem) {
 				int objIndex = GetObjectIndex(_heldItem);
-				_heldFilm = _invFilms[objIndex];
+
+				if (TinselVersion == 3) {
+					INV_OBJECT *invObj = GetInvObject(_heldItem);
+
+					if (invObj->attribute & V3ATTR_X200) {
+						_heldFilm = _vm->_systemReel->Get(objIndex);
+					} else {
+						_heldFilm = _invFilms[objIndex];
+					}
+				} else {
+					_heldFilm = _invFilms[objIndex];
+				}
 			}
 			_vm->_cursor->SetAuxCursor(_heldFilm);
 		} else {
@@ -5214,6 +5226,28 @@ void Dialogs::idec_inv2(SCNHANDLE text, int MaxContents,
 	         100, 100, true);
 }
 
+/**
+ * Called from Glitter functions: dec_invMain
+ * - Declare inventories 1,3 and 4 and hail the loadingscreen(?) scene.
+ */
+void Dialogs::idec_invMain(SCNHANDLE text, int MaxContents) {
+	idec_inv(INV_1, text, MaxContents,3, 2, 3, 2, 3, 2, 39,
+			72, false);
+	idec_inv(INV_MENU, 0, 3, 2, 2, 2, 1, 3, 1, 100, 100,
+			false);
+	idec_inv(INV_4, text, MaxContents,3, 2, 3, 2, 3, 2, 39,
+			72, false);
+
+	warning("TODO: idec_invMain: implement language scene playback");
+	// This is not yet actived because playing the loadsceen scene
+	// currently produces an invalid corountine stack.
+#if 0
+	const char *fileName = _vm->getSceneFile(TextLanguage());
+	SCNHANDLE sceneHandle = _vm->_handle->FindLanguageSceneHandle(fileName);
+	DoHailScene(sceneHandle);
+#endif
+}
+
 /**
  * Called from Glitter function 'GetInvLimit()'
  */
diff --git a/engines/tinsel/dialogs.h b/engines/tinsel/dialogs.h
index eefcddca828..5b727796971 100644
--- a/engines/tinsel/dialogs.h
+++ b/engines/tinsel/dialogs.h
@@ -42,19 +42,30 @@ struct FILM;
 struct CONFINIT;
 
 enum {
-	INV_OPEN	= -1,	// DW1 only
-	INV_CONV	= 0,
-	INV_1		= 1,
-	INV_2		= 2,
-	INV_CONF	= 3,
-	INV_MENU	= 3,	// DW2 constant
-	NUM_INV		= 4,
+	INV_OPEN 		= -1, // DW1 only
+	INV_CONV 		= 0,
+	INV_1 			= 1,
+	INV_2 			= 2,
+	INV_CONF 		= 3,
+	INV_MENU 		= 3, // DW2 constant
+	NUM_INV_V0 		= 4,
 
 	// Discworld 2 constants
-	DW2_INV_OPEN = 5,
-	INV_DEFAULT = 6
+	DW2_INV_OPEN	= 5,
+	INV_DEFAULT  	= 6,
+
+	// Noir constants
+	INV_4 		 	= 4,
+	NUM_INV_V3 	 	= 5,
+	INV_7NOINV 	 	= 7,
+	INV_8NOINV 	 	= 8,
+	INV_NOTEBOOK 	= 9,
+
+	MAX_NUM_INV 	= NUM_INV_V3 // For determination of _invD array size
 };
 
+#define NUM_INV ((TinselVersion == 3) ? NUM_INV_V3 : NUM_INV_V0)
+
 enum {
 	NOOBJECT = -1,
 	INV_NOICON_V0 = -1,
@@ -302,6 +313,9 @@ public:
 	void idec_inv2(SCNHANDLE text, int MaxContents, int MinWidth, int MinHeight,
 	               int StartWidth, int StartHeight, int MaxWidth, int MaxHeight);
 
+	// Noir
+	void idec_invMain(SCNHANDLE text, int MaxContents);
+
 	bool InventoryActive();
 
 	void PermaConvIcon(int icon, bool bEnd = false);
@@ -448,7 +462,7 @@ private:
 	SCNHANDLE _flagFilm;  // Window members and cursors' graphic data
 	SCNHANDLE _configStrings[20];
 
-	INV_DEF _invD[NUM_INV];        // Conversation + 2 inventories + ...
+	INV_DEF _invD[MAX_NUM_INV];        // Conversation + 2 inventories + ...
 	int _activeInv;                      // Which inventory is currently active
 	INV_OBJECT *_invObjects; // Inventory objects' data
 	int _numObjects;               // Number of inventory objects
diff --git a/engines/tinsel/handle.cpp b/engines/tinsel/handle.cpp
index 5388cf21fdc..c00daa26860 100644
--- a/engines/tinsel/handle.cpp
+++ b/engines/tinsel/handle.cpp
@@ -59,7 +59,8 @@ enum {
 	fSound		= 0x04000000L,	///< sound data
 	fGraphic	= 0x08000000L,	///< graphic data
 	fCompressed	= 0x10000000L,	///< compressed data
-	fLoaded		= 0x20000000L	///< set when file data has been loaded
+	fLoaded		= 0x20000000L,	///< set when file data has been loaded
+	fUnknown	= 0x40000000L	///< v3 specific
 };
 #define FSIZE_MASK	((TinselVersion == 3) ? 0xFFFFFFFFL : 0x00FFFFFFL)	//!< mask to isolate the filesize
 #define MEMFLAGS(x) ((TinselVersion == 3) ? x->flags2 : x->filesize)
diff --git a/engines/tinsel/heapmem.cpp b/engines/tinsel/heapmem.cpp
index 046aa2078d0..521c538eca6 100644
--- a/engines/tinsel/heapmem.cpp
+++ b/engines/tinsel/heapmem.cpp
@@ -33,9 +33,11 @@ namespace Tinsel {
 // internal allocation flags
 #define	DWM_USED		0x0001	///< the objects memory block is in use
 #define	DWM_DISCARDED	0x0002	///< the objects memory block has been discarded
-#define	DWM_LOCKED		0x0004	///< the objects memory block is locked
+#define	DWM_LOCKED		((TinselVersion == 3) ? 0x0200 : 0x0004)	///< the objects memory block is locked
 #define	DWM_SENTINEL	0x0008	///< the objects memory block is a sentinel
-
+// Noir
+#define	DWM_V3X20		0x0020	///< unknown
+#define	DWM_V3X4		0x0004	///< unknown
 
 struct MEM_NODE {
 	MEM_NODE *pNext;	// link to the next node in the list
diff --git a/engines/tinsel/tinlib.cpp b/engines/tinsel/tinlib.cpp
index 844076ee0e1..ed416cb20b2 100644
--- a/engines/tinsel/tinlib.cpp
+++ b/engines/tinsel/tinlib.cpp
@@ -979,6 +979,18 @@ static void DecInv2(SCNHANDLE text, int MaxContents,
 			StartWidth, StartHeight, MaxWidth, MaxHeight);
 }
 
+/**
+ * Declare parameters of inventories 1, 3 and 4.
+ * Display loadingscreen (?).
+ * Takes 8 parameter, but uses only 2.
+ */
+static void DecInvMain(SCNHANDLE text, int MaxContents,
+		int MinWidth, int MinHeight,
+		int StartWidth, int StartHeight,
+		int MaxWidth, int MaxHeight) {
+	_vm->_dialogs->idec_invMain(text, MaxContents);
+}
+
 /**
  * Declare the bits that the inventory windows are constructed from.
  */
@@ -4662,8 +4674,11 @@ NoirMapping translateNoirLibCode(int libCode, int32 *pp) {
 		pp -= mapping.numArgs - 1;
 		debug(7, "%s(%d)", mapping.name, pp[0]);
 		break;
-	case 90: // play anim based on item
-		error("Unsupported libCode %d", libCode);
+	case 90: // 2 parameters, play anim based on item
+		mapping = NoirMapping{"INVPLAY", ZZZZZZ, 2};
+		pp -= mapping.numArgs - 1;
+		debug(7, "%s(%d, %d)", mapping.name, pp[0], pp[1]);
+		break;
 	case 91:
 		mapping = NoirMapping{"INWHICHINV", INWHICHINV, 0};
 		debug(7, "%s()", mapping.name);
@@ -5630,7 +5645,9 @@ int CallLibraryRoutine(CORO_PARAM, int operand, int32 *pp, const INT_CONTEXT *pi
 		return -8;
 
 	case DECINVMAIN:
-		warning("TODO: Implement DECINVMAIN");
+		pp -= 7;			// 8 parameters
+		DecInvMain(pp[0], pp[1], pp[2], pp[3],
+			 pp[4], pp[5], pp[6], pp[7]);
 		return -8;
 
 	case DECINVW:


Commit: 8d813f5dcac80565efb59fd7baee12d401904b54
    https://github.com/scummvm/scummvm/commit/8d813f5dcac80565efb59fd7baee12d401904b54
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2022-04-27T00:33:15+03:00

Commit Message:
TINSEL: Fix comment formatting

Changed paths:
    engines/tinsel/noir/notebook.h


diff --git a/engines/tinsel/noir/notebook.h b/engines/tinsel/noir/notebook.h
index 229e9aae6ec..10a57441690 100644
--- a/engines/tinsel/noir/notebook.h
+++ b/engines/tinsel/noir/notebook.h
@@ -54,7 +54,7 @@ class Notebook {
 public:
 	Notebook() = default;
 
-	// can be a title or clue
+	// Can be a title or clue
 	void AddEntry(int32 entryIdx, int32 page1, int32 page2);
 	// Adds a connection between a clue/title
 	void AddHyperlink(int32 id1, int32 id2);




More information about the Scummvm-git-logs mailing list