[Scummvm-git-logs] scummvm master -> a3f7609de36939f8550d5d7dde02ffef5c75231a

bluegr noreply at scummvm.org
Sun Jan 9 20:39:03 UTC 2022


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

Summary:
e95a3b6efb TINSEL: Refactor and simplify actor data loading
a3f7609de3 TINSEL: Refactor and simplify scene hopper data


Commit: e95a3b6efbc2bbe1121ef85d3852429c461fbea7
    https://github.com/scummvm/scummvm/commit/e95a3b6efbc2bbe1121ef85d3852429c461fbea7
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2022-01-09T22:38:43+02:00

Commit Message:
TINSEL: Refactor and simplify actor data loading

- Actor data is now obtained as a copy via GetActorData(), which handles
  endianess internally
- There is now a single ACTORDATA class for all Tinsel versions
- Struct packing has been removed from the actor data class, as we no
  longer cast raw data to image pointers

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


diff --git a/engines/tinsel/actors.cpp b/engines/tinsel/actors.cpp
index e6447c768c9..b5c33dede1f 100644
--- a/engines/tinsel/actors.cpp
+++ b/engines/tinsel/actors.cpp
@@ -45,25 +45,6 @@
 
 namespace Tinsel {
 
-#include "common/pack-start.h"	// START STRUCT PACKING
-
-/** actor struct - one per actor */
-struct T1_ACTOR_STRUC {
-	int32 masking;			///< type of actor masking
-	SCNHANDLE hActorId;		///< handle actor ID string index
-	SCNHANDLE hActorCode;	///< handle to actor script
-} PACKED_STRUCT;
-
-struct T2_ACTOR_STRUC {
-	SCNHANDLE hActorId;	// handle actor ID string index
-	SCNHANDLE hTagText;	// tag
-	int32 tagPortionV;	// defines tag area
-	int32 tagPortionH;	// defines tag area
-	SCNHANDLE hActorCode;	// handle to actor script
-} PACKED_STRUCT;
-
-#include "common/pack-end.h"	// END STRUCT PACKING
-
 #define RANGE_CHECK(num)	assert(num > 0 && num <= _numActors);
 
 struct ACTORINFO {
@@ -213,8 +194,8 @@ int Actor::TaggedActorIndex(int actor) {
  * @param as			Actor structure
  * @param bRunScript	Flag for whether to run actor's script for the scene
  */
-void Actor::StartActor(const T1_ACTOR_STRUC *as, bool bRunScript) {
-	SCNHANDLE hActorId = FROM_32(as->hActorId);
+void Actor::StartActor(const ACTORDATA *ad, bool bRunScript) {
+	SCNHANDLE hActorId = ad->hActorId;
 
 	// Zero-out many things
 	_actorInfo[hActorId - 1].bHidden = false;
@@ -226,15 +207,15 @@ void Actor::StartActor(const T1_ACTOR_STRUC *as, bool bRunScript) {
 	_actorInfo[hActorId - 1].presObj = nullptr;
 
 	// Store current scene's parameters for this actor
-	_actorInfo[hActorId - 1].mtype = FROM_32(as->masking);
-	_actorInfo[hActorId - 1].actorCode = FROM_32(as->hActorCode);
+	_actorInfo[hActorId - 1].mtype = ad->masking;
+	_actorInfo[hActorId - 1].actorCode = ad->hActorCode;
 
 	// Run actor's script for this scene
 	if (bRunScript) {
 		if (_actorsOn)
 			_actorInfo[hActorId - 1].bAlive = true;
 
-		if (_actorInfo[hActorId - 1].bAlive && FROM_32(as->hActorCode))
+		if (_actorInfo[hActorId - 1].bAlive && ad->hActorCode)
 			ActorEvent(hActorId, STARTUP, PLR_NOEVENT);
 	}
 }
@@ -246,38 +227,41 @@ void Actor::StartActor(const T1_ACTOR_STRUC *as, bool bRunScript) {
  * @param bRunScript	Flag for whether to run actor scene scripts
  */
 void Actor::StartTaggedActors(SCNHANDLE ah, int numActors, bool bRunScript) {
-	int	i;
+	if (!TinselV2) {
+		// Tinsel 1 load variation
 
-	if (TinselV2) {
-		// Clear it all out for a fresh start
-		memset(_taggedActors, 0, sizeof(_taggedActors));
-		_numTaggedActors = numActors;
-	} else {
 		// Only actors with code blocks got (x, y) re-initialized, so...
-		for (i = 0; i < _numActors; i++) {
+		for (int i = 0; i < _numActors; i++) {
 			_actorInfo[i].x = _actorInfo[i].y = 0;
 			_actorInfo[i].mtype = 0;
 		}
-	}
 
-	if (!TinselV2) {
-		// Tinsel 1 load variation
-		const T1_ACTOR_STRUC *as = (const T1_ACTOR_STRUC *)_vm->_handle->LockMem(ah);
-		for (i = 0; i < numActors; i++, as++) {
-			StartActor(as, bRunScript);
+		const ACTORDATA *ad = _vm->_handle->GetActorData(ah, numActors);
+		for (int i = 0; i < numActors; i++) {
+			StartActor(&ad[i], bRunScript);
 		}
-	} else if (numActors > 0) {
+		delete[] ad;
+	} else {
 		// Tinsel 2 load variation
-		const T2_ACTOR_STRUC *as = (T2_ACTOR_STRUC *)_vm->_handle->LockMem(ah);
-		for (i = 0; i < numActors; i++, as++) {
-			assert(as->hActorCode);
+
+		// Clear it all out for a fresh start
+		memset(_taggedActors, 0, sizeof(_taggedActors));
+		_numTaggedActors = numActors;
+
+		if (numActors == 0)
+			return;
+
+		const ACTORDATA *ad = _vm->_handle->GetActorData(ah, numActors);
+
+		for (int i = 0; i < numActors; i++) {
+			assert(ad[i].hActorCode);
 
 			// Store current scene's parameters for this tagged actor
-			_taggedActors[i].id			= FROM_32(as->hActorId);
-			_taggedActors[i].hTagText	= FROM_32(as->hTagText);
-			_taggedActors[i].tagPortionV	= FROM_32(as->tagPortionV);
-			_taggedActors[i].tagPortionH	= FROM_32(as->tagPortionH);
-			_taggedActors[i].hActorCode	= FROM_32(as->hActorCode);
+			_taggedActors[i].id          = ad[i].hActorId;
+			_taggedActors[i].hTagText    = ad[i].hTagText;
+			_taggedActors[i].tagPortionV = ad[i].tagPortionV;
+			_taggedActors[i].tagPortionH = ad[i].tagPortionH;
+			_taggedActors[i].hActorCode  = ad[i].hActorCode;
 
 			// Run actor's script for this scene
 			if (bRunScript) {
@@ -286,6 +270,8 @@ void Actor::StartTaggedActors(SCNHANDLE ah, int numActors, bool bRunScript) {
 				ActorEvent(_taggedActors[i].id, STARTUP, false, 0);
 			}
 		}
+
+		delete[] ad;
 	}
 }
 
diff --git a/engines/tinsel/actors.h b/engines/tinsel/actors.h
index ecf86d2a2fd..77fdfdaa8bd 100644
--- a/engines/tinsel/actors.h
+++ b/engines/tinsel/actors.h
@@ -39,8 +39,6 @@ struct FREEL;
 struct INT_CONTEXT;
 struct MOVER;
 struct OBJECT;
-struct T1_ACTOR_STRUC;
-struct T2_ACTOR_STRUC;
 struct ACTORINFO;
 struct Z_POSITIONS;
 
@@ -82,6 +80,15 @@ struct Z_POSITIONS {
 
 typedef SAVED_ACTOR *PSAVED_ACTOR;
 
+struct ACTORDATA {
+	int32 masking;        ///< type of actor masking (Tinsel V1)
+	SCNHANDLE hActorId;   ///< handle actor ID string index
+	SCNHANDLE hActorCode; ///< handle to actor script
+	SCNHANDLE hTagText;   // tag (Tinsel V2)
+	int32 tagPortionV;    // defines tag area (Tinsel V2)
+	int32 tagPortionH;    // defines tag area (Tinsel V2)
+};
+
 /*----------------------------------------------------------------------*/
 
 class Actor {
@@ -194,7 +201,7 @@ public:
 	void syncAllActorsAlive(Common::Serializer &s);
 
 private:
-	void StartActor(const T1_ACTOR_STRUC *as, bool bRunScript);
+	void StartActor(const ACTORDATA *ad, bool bRunScript);
 	void GetActorTagPortion(int ano, unsigned *top, unsigned *bottom, unsigned *left, unsigned *right);
 
 	ACTORINFO *_actorInfo;
diff --git a/engines/tinsel/handle.cpp b/engines/tinsel/handle.cpp
index 029755f57c8..33087bf646b 100644
--- a/engines/tinsel/handle.cpp
+++ b/engines/tinsel/handle.cpp
@@ -26,6 +26,7 @@
 #include "common/memstream.h"
 #include "common/textconsole.h"
 
+#include "tinsel/actors.h"
 #include "tinsel/background.h"
 #include "tinsel/drives.h"
 #include "tinsel/dw.h"
@@ -407,6 +408,40 @@ SCNHANDLE Handle::GetFontImageHandle(SCNHANDLE offset) {
 	return handle;
 }
 
+/**
+ * Return an actor's data specified by a SCNHANDLE
+ * Handles endianess internally
+ * @param offset			Handle and offset to data
+ * @return IMAGE structure
+*/
+const ACTORDATA *Handle::GetActorData(SCNHANDLE offset, int numActors) {
+	byte *data = LockMem(offset);
+	const bool isBE = TinselV1Mac || TinselV1Saturn;
+	const uint32 size = TinselV2 ? 20 : 12; // ACTORDATA struct size
+
+	Common::MemoryReadStreamEndian *stream = new Common::MemoryReadStreamEndian(data, size * numActors, isBE);
+
+	ACTORDATA *actorData = new ACTORDATA[numActors];
+
+	for (int i = 0; i < numActors; i++) {
+		if (!TinselV2) {
+			actorData[i].masking = stream->readSint32();
+			actorData[i].hActorId = stream->readUint32();
+			actorData[i].hActorCode = stream->readUint32();
+		} else {
+			actorData[i].hActorId = stream->readUint32();
+			actorData[i].hTagText = stream->readUint32();
+			actorData[i].tagPortionV = stream->readSint32();
+			actorData[i].tagPortionH = stream->readSint32();
+			actorData[i].hActorCode = stream->readUint32();
+		}
+	}
+
+	delete stream;
+
+	return actorData;
+}
+
 /**
  * Compute and return the address specified by a SCNHANDLE.
  * @param offset			Handle and offset to data
diff --git a/engines/tinsel/handle.h b/engines/tinsel/handle.h
index 01d06544347..f8edd2f65f3 100644
--- a/engines/tinsel/handle.h
+++ b/engines/tinsel/handle.h
@@ -36,6 +36,7 @@ struct FONT;
 struct MEMHANDLE;
 struct PALETTE;
 struct IMAGE;
+struct ACTORDATA;
 
 class Handle {
 public:
@@ -52,6 +53,7 @@ public:
 	const IMAGE *GetImage(SCNHANDLE offset);
 	void SetImagePalette(SCNHANDLE offset, SCNHANDLE palHandle);
 	SCNHANDLE GetFontImageHandle(SCNHANDLE offset);
+	const ACTORDATA *GetActorData(SCNHANDLE offset, int numActors);
 	byte *LockMem(SCNHANDLE offset);
 
 	void LockScene(SCNHANDLE offset);


Commit: a3f7609de36939f8550d5d7dde02ffef5c75231a
    https://github.com/scummvm/scummvm/commit/a3f7609de36939f8550d5d7dde02ffef5c75231a
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2022-01-09T22:38:43+02:00

Commit Message:
TINSEL: Refactor and simplify scene hopper data

This also allows us to remove struct packing, since the raw data is no
longer cast to the hopper structs

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


diff --git a/engines/tinsel/dialogs.cpp b/engines/tinsel/dialogs.cpp
index b8a5cfe3594..d2dee777526 100644
--- a/engines/tinsel/dialogs.cpp
+++ b/engines/tinsel/dialogs.cpp
@@ -886,7 +886,6 @@ bool Dialogs::LanguageChange() {
  */
 void Dialogs::PrimeSceneHopper() {
 	Common::File f;
-	char *pBuffer;
 	uint32 vSize;
 
 	// Open the file (it's on the CD)
@@ -902,32 +901,49 @@ void Dialogs::PrimeSceneHopper() {
 	// allocate a buffer for it all
 	assert(_pHopper == NULL);
 	uint32 size = f.size() - 8;
+	_numScenes = vSize / sizeof(HOPPER);
 
-	// make sure memory allocated
-	pBuffer = (char *)malloc(size);
-	if (pBuffer == NULL)
-		// cannot alloc buffer for index
-		error(NO_MEM, "Scene hopper data");
+	_pHopper = new HOPPER[_numScenes];
 
-	// load data
-	if (f.read(pBuffer, size) != size)
-		// file must be corrupt if we get to here
-		error(FILE_IS_CORRUPT, HOPPER_FILENAME);
+	for (int i = 0; i < _numScenes; i++) {
+		_pHopper[i].hScene = FROM_32(f.readUint32LE());
+		_pHopper[i].hSceneDesc = FROM_32(f.readUint32LE());
+		_pHopper[i].numEntries = FROM_32(f.readUint32LE());
+		_pHopper[i].entryIndex = FROM_32(f.readUint32LE());
 
-	// Set data pointers
-	_pHopper = (PHOPPER)pBuffer;
-	_pEntries = (PHOPENTRY)(pBuffer + vSize);
-	_numScenes = vSize / sizeof(HOPPER);
+		if (f.err()) {
+			// file must be corrupt if we get to here
+			error(FILE_IS_CORRUPT, HOPPER_FILENAME);
+		}
+	}
+
+	_pEntries = new HOPENTRY[_numScenes];
+
+	for (int i = 0; i < _numScenes; i++) {
+		_pEntries[i].eNumber = FROM_32(f.readUint32LE());
+		_pEntries[i].hDesc = FROM_32(f.readUint32LE());
+		_pEntries[i].flags = FROM_32(f.readUint32LE());
+
+		if (f.err()) {
+			// file must be corrupt if we get to here
+			error(FILE_IS_CORRUPT, HOPPER_FILENAME);
+		}
+	}
 
 	// close the file
 	f.close();
 }
 
 /**
- * Free the scene hopper data file
+ * Free the scene hopper data
  */
 void Dialogs::FreeSceneHopper() {
-	free(_pHopper);
+	delete[] _pEntries;
+	_pEntries = nullptr;
+
+	_pChosenScene = nullptr;
+
+	delete[] _pHopper;
 	_pHopper = nullptr;
 }
 
@@ -951,7 +967,7 @@ void Dialogs::FirstScene(int first) {
 	// Fill in the rest
 	for (i = 0; i < NUM_RGROUP_BOXES && i + first < _numScenes; i++) {
 		cd.box[i].textMethod = TM_STRINGNUM;
-		cd.box[i].ixText = FROM_32(_pHopper[i + first].hSceneDesc);
+		cd.box[i].ixText = _pHopper[i + first].hSceneDesc;
 	}
 	// Blank out the spare ones (if any)
 	while (i < NUM_RGROUP_BOXES) {
@@ -974,10 +990,10 @@ void Dialogs::SetChosenScene() {
 void Dialogs::FirstEntry(int first) {
 	int i;
 
-	_invD[INV_MENU].hInvTitle = FROM_32(_pChosenScene->hSceneDesc);
+	_invD[INV_MENU].hInvTitle = _pChosenScene->hSceneDesc;
 
 	// get number of entrances
-	_numEntries = FROM_32(_pChosenScene->numEntries);
+	_numEntries = _pChosenScene->numEntries;
 
 	// Force first to a sensible value
 	if (first > _numEntries - NUM_RGROUP_BOXES)
@@ -987,7 +1003,7 @@ void Dialogs::FirstEntry(int first) {
 
 	for (i = 0; i < NUM_RGROUP_BOXES && i < _numEntries; i++) {
 		cd.box[i].textMethod = TM_STRINGNUM;
-		cd.box[i].ixText = FROM_32(_pEntries[FROM_32(_pChosenScene->entryIndex) + i + first].hDesc);
+		cd.box[i].ixText = _pEntries[_pChosenScene->entryIndex + i + first].hDesc;
 	}
 	// Blank out the spare ones (if any)
 	while (i < NUM_RGROUP_BOXES) {
@@ -999,16 +1015,16 @@ void Dialogs::FirstEntry(int first) {
 }
 
 void Dialogs::HopAction() {
-	PHOPENTRY pEntry = _pEntries + FROM_32(_pChosenScene->entryIndex) + cd.selBox + cd.extraBase;
+	HOPENTRY *pEntry = _pEntries + _pChosenScene->entryIndex + cd.selBox + cd.extraBase;
 
-	uint32 hScene = FROM_32(_pChosenScene->hScene);
-	uint32 eNumber = FROM_32(pEntry->eNumber);
+	uint32 hScene = _pChosenScene->hScene;
+	uint32 eNumber = pEntry->eNumber;
 	debugC(DEBUG_BASIC, kTinselDebugAnimations, "Scene hopper chose scene %xh,%d\n", hScene, eNumber);
 
-	if (FROM_32(pEntry->flags) & fCall) {
+	if (pEntry->flags & fCall) {
 		SaveScene(Common::nullContext);
 		NewScene(Common::nullContext, _pChosenScene->hScene, pEntry->eNumber, TRANS_FADE);
-	} else if (FROM_32(pEntry->flags) & fHook)
+	} else if (pEntry->flags & fHook)
 		HookScene(hScene, eNumber, TRANS_FADE);
 	else
 		NewScene(Common::nullContext, hScene, eNumber, TRANS_CUT);
diff --git a/engines/tinsel/dialogs.h b/engines/tinsel/dialogs.h
index 8a97defef0c..5da308ce680 100644
--- a/engines/tinsel/dialogs.h
+++ b/engines/tinsel/dialogs.h
@@ -156,24 +156,18 @@ struct INV_DEF {
 
 //----- Data pertinant to scene hoppers ------------------------
 
-#include "common/pack-start.h"	// START STRUCT PACKING
-
 struct HOPPER {
 	uint32		hScene;
 	SCNHANDLE	hSceneDesc;
 	uint32		numEntries;
 	uint32		entryIndex;
-} PACKED_STRUCT;
-typedef HOPPER *PHOPPER;
+};
 
 struct HOPENTRY {
 	uint32	eNumber;	// entrance number
 	SCNHANDLE hDesc;	// handle to entrance description
 	uint32	flags;
-} PACKED_STRUCT;
-typedef HOPENTRY *PHOPENTRY;
-
-#include "common/pack-end.h"	// END STRUCT PACKING
+};
 
 enum BTYPE {
 	RGROUP, ///< Radio button group - 1 is selectable at a time. Action on double click
@@ -512,13 +506,13 @@ private:
 	bool _bMoveOnUnHide; // Set before start of conversation
 	    // - causes conversation to be started in a sensible place
 
-	PHOPPER _pHopper;
-	PHOPENTRY _pEntries;
+	HOPPER *_pHopper;
+	HOPENTRY *_pEntries;
 	int _numScenes;
 
 	int _numEntries;
 
-	PHOPPER _pChosenScene;
+	HOPPER *_pChosenScene;
 
 	int _lastChosenScene;
 	bool _bRemember;




More information about the Scummvm-git-logs mailing list