[Scummvm-git-logs] scummvm master -> 217312dedfe6f2a33c2ef6ef721716c59c4b43ed
dreammaster
noreply at scummvm.org
Sun Feb 18 02:46:12 UTC 2024
This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
217312dedf M4: Endian proofing ws loading
Commit: 217312dedfe6f2a33c2ef6ef721716c59c4b43ed
https://github.com/scummvm/scummvm/commit/217312dedfe6f2a33c2ef6ef721716c59c4b43ed
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2024-02-17T18:46:05-08:00
Commit Message:
M4: Endian proofing ws loading
Changed paths:
engines/m4/wscript/ws_load.cpp
diff --git a/engines/m4/wscript/ws_load.cpp b/engines/m4/wscript/ws_load.cpp
index e51941a8c52..3e93af3419e 100644
--- a/engines/m4/wscript/ws_load.cpp
+++ b/engines/m4/wscript/ws_load.cpp
@@ -53,12 +53,39 @@ namespace M4 {
#define MAX_ASSET_HASH 255
+/**
+ * This tries to encapsulate an uint32 * that also does endian conversion automatically.
+ * GetNextInt32 can't just return values directly, because in the case of some chunk
+ * types, the underlying data being pointed to gets byte swapped.
+ */
+class IntPointer {
+private:
+ int32 *_ptr = nullptr;
+
+public:
+ void set(int32 *ptr) { _ptr = ptr; }
+ void swap() { *_ptr = SWAP_INT32(*_ptr); }
+ int32 *ptr() const { return _ptr; }
+ int32 operator*() const { return READ_LE_INT32(_ptr); }
+};
-static bool GetNextint32(char **assetPtr, char *endOfAssetBlock, uint32 **returnVal);
static int32 ProcessCELS(const char * /*assetName*/, char **parseAssetPtr, char * /*mainAssetPtr*/, char *endOfAssetBlock,
int32 **dataOffset, int32 **palDataOffset, RGB8 *myPalette);
static void RestoreSSPaletteInfo(RGB8 *myPalette, int32 *palPtr);
+static bool GetNextint32(char **assetPtr, char *endOfAssetBlock, IntPointer &returnVal) {
+ // Check to see if we still have an int32 available
+ if ((endOfAssetBlock - *assetPtr) < 4) {
+ return false;
+ }
+
+ // Get the next int32
+ returnVal.set((int32 *)*assetPtr);
+ *assetPtr += 4;
+
+ return true;
+}
+
bool InitWSAssets() {
int32 i;
@@ -249,10 +276,10 @@ bool LoadWSAssets(const char *wsAssetName, RGB8 *myPalette) {
MemHandle workHandle;
char *mainAssetPtr, *parseAssetPtr, *endOfAssetBlock;
uint32 *tempPtr;
- uint32 *chunkType, *chunkSize, *chunkHash;
+ IntPointer chunkType, chunkSize, chunkHash;
bool finished, chunkSwap;
int32 *celsPtr, *palPtr;
- uint32 i;
+ int32 i;
int32 assetSize;
// Check that the loader has been initialized
@@ -277,17 +304,17 @@ bool LoadWSAssets(const char *wsAssetName, RGB8 *myPalette) {
finished = false;
// Get the first chunkType
- if (!GetNextint32(&parseAssetPtr, endOfAssetBlock, &chunkType)) {
+ if (!GetNextint32(&parseAssetPtr, endOfAssetBlock, chunkType)) {
finished = true;
}
// Process each chunk according to type
while (!finished) {
// Read in the chunk size and hash number
- if (!GetNextint32(&parseAssetPtr, endOfAssetBlock, &chunkSize)) {
+ if (!GetNextint32(&parseAssetPtr, endOfAssetBlock, chunkSize)) {
error_show(FL, 'WSLE', "Asset Name: %s", wsAssetName);
}
- if (!GetNextint32(&parseAssetPtr, endOfAssetBlock, &chunkHash)) {
+ if (!GetNextint32(&parseAssetPtr, endOfAssetBlock, chunkHash)) {
error_show(FL, 'WSLE', "Asset Name: %s", wsAssetName);
}
@@ -297,9 +324,9 @@ bool LoadWSAssets(const char *wsAssetName, RGB8 *myPalette) {
// Chunk is a machine chunk
case CHUNK_HCAM:
// Byte swap the type, size and hash and continue through case CHUNK_MACH.
- *chunkType = SWAP_INT32(*chunkType);
- *chunkSize = SWAP_INT32(*chunkSize);
- *chunkHash = SWAP_INT32(*chunkHash);
+ chunkType.swap();
+ chunkSize.swap();
+ chunkHash.swap();
chunkSwap = true;
// Fall through
@@ -336,9 +363,9 @@ bool LoadWSAssets(const char *wsAssetName, RGB8 *myPalette) {
case CHUNK_UQES:
// Chunk is a machine chunk
// Byte swap the type, size and hash and continue through case CHUNK_SEQU.
- *chunkType = SWAP_INT32(*chunkType);
- *chunkSize = SWAP_INT32(*chunkSize);
- *chunkHash = SWAP_INT32(*chunkHash);
+ chunkType.swap();
+ chunkSize.swap();
+ chunkHash.swap();
chunkSwap = true;
// Fall through
@@ -375,9 +402,9 @@ bool LoadWSAssets(const char *wsAssetName, RGB8 *myPalette) {
case CHUNK_ATAD:
// Chunk is a data chunk
// Byte swap the type, size and hash and continue through case CHUNK_DATA.
- *chunkType = SWAP_INT32(*chunkType);
- *chunkSize = SWAP_INT32(*chunkSize);
- *chunkHash = SWAP_INT32(*chunkHash);
+ chunkType.swap();
+ chunkSize.swap();
+ chunkHash.swap();
chunkSwap = true;
// Fall through
@@ -413,9 +440,9 @@ bool LoadWSAssets(const char *wsAssetName, RGB8 *myPalette) {
case CHUNK_SLEC:
// Byte swap the type, size and hash and continue through case CHUNK_CELS.
- *chunkType = SWAP_INT32(*chunkType);
- *chunkSize = SWAP_INT32(*chunkSize);
- *chunkHash = SWAP_INT32(*chunkHash);
+ chunkType.swap();
+ chunkSize.swap();
+ chunkHash.swap();
chunkSwap = true;
// Fall through
@@ -465,7 +492,7 @@ bool LoadWSAssets(const char *wsAssetName, RGB8 *myPalette) {
}
// Read the next chunkType, or signal we are finished
- if (!GetNextint32(&parseAssetPtr, endOfAssetBlock, &chunkType)) {
+ if (!GetNextint32(&parseAssetPtr, endOfAssetBlock, chunkType)) {
finished = true;
}
}
@@ -774,24 +801,12 @@ int32 AddWSAssetCELS(const char *wsAssetName, int32 hash, RGB8 *myPalette) {
return -1;
}
-static bool GetNextint32(char **assetPtr, char *endOfAssetBlock, uint32 **returnVal) {
- // Check to see if we still have an int32 available
- if ((endOfAssetBlock - *assetPtr) < 4) {
- return false;
- }
-
- // Get the next int32
- *returnVal = (uint32 *)*assetPtr;
- *assetPtr += 4;
-
- return true;
-}
-
static int32 ProcessCELS(const char * /*assetName*/, char **parseAssetPtr, char * /*mainAssetPtr*/, char *endOfAssetBlock,
- int32 **dataOffset, int32 **palDataOffset, RGB8 *myPalette) {
- uint32 *celsType, *numColors, *palData;
- uint32 *tempPtr, *celsSize, *data, *dataPtr, *offsetPtr, i, j, *header, *format;
- bool byteSwap;
+ int32 **dataOffset, int32 **palDataOffset, RGB8 *myPalette) {
+ IntPointer celsType, numColors, celsSize;
+ int32 *tempPtr, *data, *dataPtr, *offsetPtr, *palData, i, j;
+ IntPointer header, format;
+ bool byteSwap;
if (!_GWS(wsloaderInitialized))
return -1;
@@ -800,19 +815,19 @@ static int32 ProcessCELS(const char * /*assetName*/, char **parseAssetPtr, char
*palDataOffset = nullptr;
// Get the header and the format
- if (!GetNextint32(parseAssetPtr, endOfAssetBlock, &header)) {
+ if (!GetNextint32(parseAssetPtr, endOfAssetBlock, header)) {
ws_LogErrorMsg(FL, "Unable to get the SS header");
return -1;
}
- if (!GetNextint32(parseAssetPtr, endOfAssetBlock, &format)) {
+ if (!GetNextint32(parseAssetPtr, endOfAssetBlock, format)) {
ws_LogErrorMsg(FL, "Unable to get the SS format");
return -1;
}
// Make sure the file is tagged "M4SS" (or "SS4M")
if (*header == HEAD_SS4M) {
- *header = SWAP_INT32(*header);
- *format = SWAP_INT32(*format);
+ header.swap();
+ format.swap();
} else if (*header != HEAD_M4SS) {
ws_LogErrorMsg(FL, "SS chunk is not a valid M4SS chunk.");
return -1;
@@ -825,7 +840,7 @@ static int32 ProcessCELS(const char * /*assetName*/, char **parseAssetPtr, char
}
// Get the CELS chunk type - either PAL information, or the actual SS info
- if (!GetNextint32(parseAssetPtr, endOfAssetBlock, &celsType)) {
+ if (!GetNextint32(parseAssetPtr, endOfAssetBlock, celsType)) {
ws_LogErrorMsg(FL, "Unable to read the SS chunk type.");
return -1;
}
@@ -835,19 +850,19 @@ static int32 ProcessCELS(const char * /*assetName*/, char **parseAssetPtr, char
if ((*celsType == CELS__PAL) || (*celsType == CELS_LAP_)) {
// Read the chunk size, and the number of palette colors, and byte-swap if necessary
- if (!GetNextint32(parseAssetPtr, endOfAssetBlock, &celsSize)) {
+ if (!GetNextint32(parseAssetPtr, endOfAssetBlock, celsSize)) {
ws_LogErrorMsg(FL, "Unable to read the SS PAL chunk size.");
return -1;
}
- if (!GetNextint32(parseAssetPtr, endOfAssetBlock, &numColors)) {
+ if (!GetNextint32(parseAssetPtr, endOfAssetBlock, numColors)) {
ws_LogErrorMsg(FL, "Unable to read the SS PAL number of colors.");
return -1;
}
if (*celsType == CELS_LAP_) {
- *celsType = SWAP_INT32(*celsType);
- *celsSize = SWAP_INT32(*celsSize);
- *numColors = SWAP_INT32(*numColors);
+ celsType.swap();
+ celsSize.swap();
+ numColors.swap();
byteSwap = true;
}
@@ -858,8 +873,8 @@ static int32 ProcessCELS(const char * /*assetName*/, char **parseAssetPtr, char
}
// The asset block offset for palData should begin with the number of colors
- *palDataOffset = (int32 *)numColors;
- palData = (uint32 *)numColors;
+ *palDataOffset = numColors.ptr();
+ palData = numColors.ptr();
if (((intptr)endOfAssetBlock - (intptr)(*parseAssetPtr)) < ((int32)(*celsSize) - 8)) {
ws_LogErrorMsg(FL, "Pal info is larger than asset block.");
@@ -871,7 +886,7 @@ static int32 ProcessCELS(const char * /*assetName*/, char **parseAssetPtr, char
// The data is always read in low byte first, but we need it high byte first
// regardless of the endianness of the machine.
if (byteSwap) {
- tempPtr = (uint32 *)&numColors[1];
+ tempPtr = numColors.ptr() + 1;
for (i = 0; i < *numColors; i++) {
*tempPtr = SWAP_INT32(*tempPtr);
tempPtr++;
@@ -882,8 +897,8 @@ static int32 ProcessCELS(const char * /*assetName*/, char **parseAssetPtr, char
// The palette info has been processed, now it can be stored
if (myPalette) {
- tempPtr = (uint32 *)(&palData[1]);
- for (i = 0; i < (uint32)*numColors; i++) {
+ tempPtr = (int32 *)(&palData[1]);
+ for (i = 0; i < *numColors; i++) {
j = (*tempPtr & 0xff000000) >> 24;
myPalette[j].r = (*tempPtr & 0x00ff0000) >> 14;
myPalette[j].g = (*tempPtr & 0x0000ff00) >> 6;
@@ -894,7 +909,7 @@ static int32 ProcessCELS(const char * /*assetName*/, char **parseAssetPtr, char
byteSwap = false;
// Pal chunk has been processed, get the next chunk type
- if (!GetNextint32(parseAssetPtr, endOfAssetBlock, &celsType)) {
+ if (!GetNextint32(parseAssetPtr, endOfAssetBlock, celsType)) {
ws_LogErrorMsg(FL, "Unable to read the SS chunk type.");
return -1;
}
@@ -907,21 +922,21 @@ static int32 ProcessCELS(const char * /*assetName*/, char **parseAssetPtr, char
}
// Read in the chunk size
- if (!GetNextint32(parseAssetPtr, endOfAssetBlock, &celsSize)) {
+ if (!GetNextint32(parseAssetPtr, endOfAssetBlock, celsSize)) {
ws_LogErrorMsg(FL, "Unable to read the SS chunk size.");
return -1;
}
// Byteswap if necessary
if (*celsType == CELS_SS__) {
- *celsType = SWAP_INT32(*celsType);
- *celsSize = SWAP_INT32(*celsSize);
+ celsType.swap();
+ celsSize.swap();
byteSwap = true;
}
// The asset block offset for the cel should begin with the celsType
- *dataOffset = (int32 *)celsType;
- data = (uint32 *)celsType;
+ *dataOffset = (int32 *)celsType.ptr();
+ data = (int32 *)celsType.ptr();
// Verify that we actually got legitimate values
if ((int32)(*celsSize) <= 0) {
@@ -965,7 +980,7 @@ static int32 ProcessCELS(const char * /*assetName*/, char **parseAssetPtr, char
for (i = 0; i < data[CELS_COUNT]; i++) {
// The beginning of sprite i is the dataPtr + the number of bytes in the offset table
- tempPtr = (uint32 *)((intptr)dataPtr + offsetPtr[i]);
+ tempPtr = (int32 *)((intptr)dataPtr + offsetPtr[i]);
// Byteswap the individual sprite's header
for (j = 0; j < SS_INDV_HEAD; j++) {
More information about the Scummvm-git-logs
mailing list