diff options
-rw-r--r-- | engines/tinsel/dialogs.cpp | 15 | ||||
-rw-r--r-- | engines/tinsel/handle.cpp | 137 |
2 files changed, 136 insertions, 16 deletions
diff --git a/engines/tinsel/dialogs.cpp b/engines/tinsel/dialogs.cpp index 11990660d5..8006bc137f 100644 --- a/engines/tinsel/dialogs.cpp +++ b/engines/tinsel/dialogs.cpp @@ -5619,21 +5619,6 @@ extern void RegisterIcons(void *cptr, int num) { memmove(destP, srcP, 12); destP->attribute = 0; } - } else if (TinselV1Mac) { - // Macintosh version has BE encoded resources, so the values need to be byte swapped - MEM_NODE *node = MemoryAllocFixed(g_numObjects * sizeof(INV_OBJECT)); - assert(node); - g_invObjects = (INV_OBJECT *)MemoryDeref(node); - assert(g_invObjects); - INV_OBJECT *srcP = (INV_OBJECT *)cptr; - INV_OBJECT *destP = (INV_OBJECT *)g_invObjects; - - for (int i = 0; i < num; ++i, ++destP, ++srcP) { - destP->id = FROM_BE_32(srcP->id); - destP->hIconFilm = FROM_BE_32(srcP->hIconFilm); - destP->hScript = FROM_BE_32(srcP->hScript); - destP->attribute = FROM_BE_32(srcP->attribute); - } } else if (TinselV2) { if (g_invFilms == NULL) { // First time - allocate memory diff --git a/engines/tinsel/handle.cpp b/engines/tinsel/handle.cpp index 14d588dcec..4f38f005f0 100644 --- a/engines/tinsel/handle.cpp +++ b/engines/tinsel/handle.cpp @@ -30,6 +30,7 @@ #include "tinsel/dw.h" #include "tinsel/handle.h" #include "tinsel/heapmem.h" // heap memory manager +#include "tinsel/scn.h" // for the DW1 Mac resource handler #include "tinsel/timers.h" // for DwGetCurrentTime() #include "tinsel/tinsel.h" #include "tinsel/scene.h" @@ -84,7 +85,7 @@ static char g_szCdPlayFile[100]; //----------------- FORWARD REFERENCES -------------------- static void LoadFile(MEMHANDLE *pH); // load a memory block as a file - +static void convertFileToLE(MEMHANDLE *pH); /** * Loads the graphics handle table index file and preloads all the @@ -301,6 +302,9 @@ void LoadFile(MEMHANDLE *pH) { // discardable - unlock the memory MemoryUnlock(pH->_node); + if (TinselV1Mac) + convertFileToLE(pH); + // set the loaded flag pH->filesize |= fLoaded; @@ -322,6 +326,7 @@ void LoadFile(MEMHANDLE *pH) { */ byte *LockMem(SCNHANDLE offset) { uint32 handle = offset >> SCNHANDLE_SHIFT; // calc memory handle to use + //debug("Locking offset of type %d (%x), offset %d, handle %d", (offset & HANDLEMASK) >> SCNHANDLE_SHIFT, (offset & HANDLEMASK) >> SCNHANDLE_SHIFT, offset & OFFSETMASK, handle); MEMHANDLE *pH; // points to table entry // range check the memory handle @@ -375,6 +380,136 @@ byte *LockMem(SCNHANDLE offset) { return MemoryDeref(pH->_node) + (offset & OFFSETMASK); } +void convertFileToLE(MEMHANDLE *pH) { + assert(TinselV1Mac); + + char szFilename[sizeof(pH->szName) + 1]; + // extract and zero terminate the filename + memcpy(szFilename, pH->szName, sizeof(pH->szName)); + szFilename[sizeof(pH->szName)] = 0; + + debug("Converting file: %s", szFilename); + + byte *data = MemoryDeref(pH->_node); + byte *ptr = data; + + // Process each chunk + + while (true) { + uint32 pos = ptr - data; + + uint32 chunkId = READ_BE_UINT32(ptr); + WRITE_LE_UINT32(ptr, chunkId); ptr += 4; + + uint32 nextChunkOffset = READ_BE_UINT32(ptr); + WRITE_LE_UINT32(ptr, nextChunkOffset); ptr += 4; + + uint32 chunkSize = (nextChunkOffset > 0 ? nextChunkOffset : pH->filesize & FSIZE_MASK) - pos; + uint32 chunkDataSize = chunkSize - 4 - 4; // chunk ID, chunk length + uint32 tmp = 0; // for temp data + + debug("Chunk ID: %x, size %d, next chunk: %d", chunkId, chunkSize, nextChunkOffset); + + switch (chunkId) { + case CHUNK_SCENE - 1: + assert(chunkDataSize == 8 * 4); + for (uint32 i = 0; i < 8; i++) { + // numEntrance, numPoly, numTaggedActor, defRefer, hSceneScript, + // hEntrance, hPoly, hTaggedActor + WRITE_LE_UINT32(ptr, READ_BE_UINT32(ptr)); ptr += 4; + } + break; + case CHUNK_TOTAL_ACTORS - 1: + case CHUNK_TOTAL_GLOBALS - 1: + case CHUNK_TOTAL_OBJECTS - 1: + case CHUNK_TOTAL_POLY - 1: + assert(chunkDataSize == 4); + WRITE_LE_UINT32(ptr, READ_BE_UINT32(ptr)); ptr += 4; + break; + case CHUNK_OBJECTS - 1: + // INV_OBJECT structure + assert(chunkDataSize % 16 == 0); + for (uint32 i = 0; i < chunkDataSize / 16; i++) { + WRITE_LE_UINT32(ptr, READ_BE_UINT32(ptr)); ptr += 4; // id + WRITE_LE_UINT32(ptr, READ_BE_UINT32(ptr)); ptr += 4; // hIconFilm + WRITE_LE_UINT32(ptr, READ_BE_UINT32(ptr)); ptr += 4; // hScript + WRITE_LE_UINT32(ptr, READ_BE_UINT32(ptr)); ptr += 4; // attribute + } + break; + case CHUNK_FONT: + assert(chunkDataSize == 4 * 11 + 4 * 300 + 4 * 223); + // FONT structure: xSpacing, ySpacing, xShadow, yShadow, spaceSize + // OBJ_INIT: hObjImg, objFlags, objID, objX, objY, objZ + for (uint32 i = 0; i < 11; i++) { + WRITE_LE_UINT32(ptr, READ_BE_UINT32(ptr)); ptr += 4; + } + // SCNHANDLE fontDef[300] + for (uint32 i = 0; i < 300; i++) { + WRITE_LE_UINT32(ptr, READ_BE_UINT32(ptr)); ptr += 4; + } + // TODO: the font chunk in dw.scn is 2136 bytes, we've only processed the + // first 44 + 300 * 4 = 1244 ones, so we're left with 892 more... + // Since all resources are BE in the Mac version, I assume that these are + // 32-bit integers that should be byte swapped as well. + for (uint32 i = 0; i < 223; i++) { + WRITE_LE_UINT32(ptr, READ_BE_UINT32(ptr)); ptr += 4; + } + break; + case CHUNK_BITMAP: + // TODO + break; + case CHUNK_PALETTE: + // Palette entries: 32-bit integers, each one with [R, G, B, unused] bytes + assert(chunkDataSize % 256 == 0); + for (uint32 i = 0; i < 256; i++) { + WRITE_LE_UINT32(ptr, READ_BE_UINT32(ptr)); ptr += 4; + } + break; + case CHUNK_IMAGE: + assert(chunkDataSize % 16 == 0); + for (uint32 i = 0; i < chunkDataSize / 16; i++) { + WRITE_LE_UINT16(ptr, READ_BE_UINT16(ptr)); ptr += 2; // width + WRITE_LE_UINT16(ptr, READ_BE_UINT16(ptr)); ptr += 2; // height + WRITE_LE_UINT32(ptr, READ_BE_UINT32(ptr)); ptr += 4; + WRITE_LE_UINT32(ptr, READ_BE_UINT32(ptr)); ptr += 4; + WRITE_LE_UINT32(ptr, READ_BE_UINT32(ptr)); ptr += 4; + } + break; + case CHUNK_ANI_FRAME: + assert(chunkDataSize % 8 == 0); + for (uint32 i = 0; i < chunkDataSize / 8; i++) { + WRITE_LE_UINT32(ptr, READ_BE_UINT32(ptr)); ptr += 4; // SCNHANDLE + WRITE_LE_UINT32(ptr, READ_BE_UINT32(ptr)); ptr += 4; + } + break; + case CHUNK_FILM: + // Filled with 32-bit integers + assert(chunkDataSize % 4 == 0); + for (uint32 i = 0; i < chunkDataSize / 4; i++) { + WRITE_LE_UINT32(ptr, READ_BE_UINT32(ptr)); ptr += 4; + } + break; + case CHUNK_PCODE: + // Too complicated to handle here - handled by the script parser + break; + case CHUNK_ENTRANCE: + // Entrance structure (ENTRANCE_STRUC) + assert(chunkDataSize == 8); + WRITE_LE_UINT32(ptr, READ_BE_UINT32(ptr)); ptr += 4; // eNumber - entrance number + WRITE_LE_UINT32(ptr, READ_BE_UINT32(ptr)); ptr += 4; // hScript - handle to entrance script + break; + default: + error("Unknown chunk ID: %x", chunkId); + } + + // Jump to the next chunk + if (!nextChunkOffset) + break; + + ptr = data + nextChunkOffset; + } +} + /** * Called to lock the current scene and make it non-discardable. * @param offset Handle and offset to data |