aboutsummaryrefslogtreecommitdiff
path: root/engines/cruise/dataLoader.cpp
diff options
context:
space:
mode:
authorVincent Hamm2007-04-27 12:58:35 +0000
committerVincent Hamm2007-04-27 12:58:35 +0000
commitc01aa37caaadb2e65667b1156a907e92e859fee8 (patch)
tree5c55328c78f6f1664f4f46baadee583fcff977ef /engines/cruise/dataLoader.cpp
parentedd9b31a483c07066537663a01c265d99d69ada7 (diff)
downloadscummvm-rg350-c01aa37caaadb2e65667b1156a907e92e859fee8.tar.gz
scummvm-rg350-c01aa37caaadb2e65667b1156a907e92e859fee8.tar.bz2
scummvm-rg350-c01aa37caaadb2e65667b1156a907e92e859fee8.zip
Add cruise source code for scummvm
svn-id: r26605
Diffstat (limited to 'engines/cruise/dataLoader.cpp')
-rw-r--r--engines/cruise/dataLoader.cpp532
1 files changed, 532 insertions, 0 deletions
diff --git a/engines/cruise/dataLoader.cpp b/engines/cruise/dataLoader.cpp
new file mode 100644
index 0000000000..dcc1e8cca6
--- /dev/null
+++ b/engines/cruise/dataLoader.cpp
@@ -0,0 +1,532 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * 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 2
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "cruise/cruise_main.h"
+
+namespace Cruise {
+
+void loadSetEntry(uint8* name, uint8* ptr, int currentEntryIdx, int currentDestEntry);
+void loadFNTSub(uint8* ptr, int destIdx);
+
+enum fileTypeEnum
+{
+ type_UNK,
+ type_SPL,
+ type_SET,
+ type_FNT,
+};
+
+typedef enum fileTypeEnum fileTypeEnum;
+
+int loadSingleFile;
+
+// TODO: Unify decodeGfxFormat1, decodeGfxFormat4 and decodeGfxFormat5
+
+void decodeGfxFormat1(dataFileEntry* pCurrentFileEntry)
+{
+ uint8* buffer;
+ uint8* dataPtr = pCurrentFileEntry->subData.ptr;
+
+ int spriteSize = pCurrentFileEntry->height * pCurrentFileEntry->widthInColumn * 8;
+ int x = 0;
+
+ buffer = (uint8*)malloc(spriteSize);
+
+ while (x < spriteSize)
+ {
+ uint8 c;
+ uint16 p0;
+
+ p0 = (dataPtr[0] << 8) | dataPtr[1];
+
+ /* decode planes */
+ for (c = 0; c < 16; c++)
+ {
+ buffer[x+c] = ((p0 >> 15) & 1);
+
+ p0 <<= 1;
+ }
+
+ x+=16;
+
+ dataPtr+=2;
+ }
+
+ pCurrentFileEntry->subData.ptr = buffer;
+}
+
+
+void decodeGfxFormat4(dataFileEntry* pCurrentFileEntry)
+{
+ uint8* buffer;
+ uint8* dataPtr = pCurrentFileEntry->subData.ptr;
+
+ int spriteSize = pCurrentFileEntry->height * pCurrentFileEntry->widthInColumn * 2;
+ int x = 0;
+
+ buffer = (uint8*)malloc(spriteSize);
+
+ while (x < spriteSize)
+ {
+ uint8 c;
+ uint16 p0;
+ uint16 p1;
+ uint16 p2;
+ uint16 p3;
+
+ p0 = (dataPtr[0] << 8) | dataPtr[1];
+ p1 = (dataPtr[2] << 8) | dataPtr[3];
+ p2 = (dataPtr[4] << 8) | dataPtr[5];
+ p3 = (dataPtr[6] << 8) | dataPtr[7];
+
+ /* decode planes */
+ for (c = 0; c < 16; c++)
+ {
+ buffer[x+c] = ((p0 >> 15) & 1) | ((p1 >> 14) & 2) | ((p2 >> 13) & 4) | ((p3 >> 12) & 8);
+
+ p0 <<= 1;
+ p1 <<= 1;
+ p2 <<= 1;
+ p3 <<= 1;
+ }
+
+ x+=16;
+
+ dataPtr+=8;
+ }
+
+ pCurrentFileEntry->subData.ptr = buffer;
+}
+
+void decodeGfxFormat5(dataFileEntry* pCurrentFileEntry)
+{
+ uint8* buffer;
+ uint8* dataPtr = pCurrentFileEntry->subData.ptr;
+
+ int spriteSize = pCurrentFileEntry->height * pCurrentFileEntry->widthInColumn;
+ int x = 0;
+ int range = pCurrentFileEntry->height * pCurrentFileEntry->width;
+
+ buffer = (uint8*)malloc(spriteSize);
+
+ while (x < spriteSize)
+ {
+ uint8 c;
+ uint16 p0;
+ uint16 p1;
+ uint16 p2;
+ uint16 p3;
+ uint16 p4;
+
+ p0 = (dataPtr[0 + range * 0] << 8) | dataPtr[1 + range * 0];
+ p1 = (dataPtr[0 + range * 1] << 8) | dataPtr[1 + range * 1];
+ p2 = (dataPtr[0 + range * 2] << 8) | dataPtr[1 + range * 2];
+ p3 = (dataPtr[0 + range * 3] << 8) | dataPtr[1 + range * 3];
+ p4 = (dataPtr[0 + range * 4] << 8) | dataPtr[1 + range * 4];
+
+ /* decode planes */
+ for (c = 0; c < 16; c++)
+ {
+ buffer[x+c] = ((p0 >> 15) & 1) | ((p1 >> 14) & 2) | ((p2 >> 13) & 4) | ((p3 >> 12) & 8) | ((p4 >> 11) & 16);
+
+ p0 <<= 1;
+ p1 <<= 1;
+ p2 <<= 1;
+ p3 <<= 1;
+ p4 <<= 1;
+ }
+
+ x+=16;
+
+ dataPtr+=2;
+ }
+
+ pCurrentFileEntry->subData.ptr = buffer;
+}
+
+int updateResFileEntry(int height, int width, int entryNumber, int resType)
+{
+ int div = 0;
+ int size;
+
+ resetFileEntry(entryNumber);
+
+ filesDatabase[entryNumber].subData.field_1C = 0;
+
+ size = height * width; // for sprites: width * height
+
+ if(resType == 4)
+ {
+ div = size / 4;
+ }
+ else if (resType == 5)
+ {
+ width = (width * 8) / 5;
+ }
+
+ filesDatabase[entryNumber].subData.ptr = (uint8*)mallocAndZero(size + div);
+
+ if(!filesDatabase[entryNumber].subData.ptr)
+ return(-2);
+
+ filesDatabase[entryNumber].widthInColumn = width;
+ filesDatabase[entryNumber].subData.ptr2 = filesDatabase[entryNumber].subData.ptr+size;
+ filesDatabase[entryNumber].width = width / 8;
+ filesDatabase[entryNumber].resType = resType;
+ filesDatabase[entryNumber].height = height;
+ filesDatabase[entryNumber].subData.index = -1;
+
+ return entryNumber;
+}
+
+
+int createResFileEntry(int width, int height, int resType)
+{
+ int i;
+ int entryNumber;
+ int div = 0;
+ int size;
+
+ printf("Executing untested createResFileEntry!\n");
+ exit(1);
+
+ for(i = 0; i < 257; i++)
+ {
+ if(!filesDatabase[i].subData.ptr)
+ break;
+ }
+
+ if(i >= 257)
+ {
+ return(-19);
+ }
+
+ entryNumber = i;
+
+ filesDatabase[entryNumber].subData.field_1C = 0;
+
+ size = width * height; // for sprites: width * height
+
+ if(resType == 4)
+ {
+ div = size / 4;
+ }
+ else if (resType == 5)
+ {
+ width = (width * 8) / 5;
+ }
+
+ filesDatabase[entryNumber].subData.ptr = (uint8*)mallocAndZero(size + div);
+
+ if(filesDatabase[entryNumber].subData.ptr)
+ {
+ return(-2);
+ }
+
+ filesDatabase[entryNumber].widthInColumn = width;
+ filesDatabase[entryNumber].subData.ptr2 = filesDatabase[entryNumber].subData.ptr + size;
+ filesDatabase[entryNumber].width = width / 8;
+ filesDatabase[entryNumber].resType = resType;
+ filesDatabase[entryNumber].height = height;
+ filesDatabase[entryNumber].subData.index = -1;
+
+ return entryNumber;
+}
+
+fileTypeEnum getFileType(uint8* name)
+{
+ char extentionBuffer[16];
+
+ fileTypeEnum newFileType = type_UNK;
+
+ getFileExtention((char*)name,extentionBuffer);
+
+ if(!strcmp(extentionBuffer,".SPL"))
+ {
+ newFileType = type_SPL;
+ }
+ else
+ if(!strcmp(extentionBuffer,".SET"))
+ {
+ newFileType = type_SET;
+ }
+ else
+ if(!strcmp(extentionBuffer,".FNT"))
+ {
+ newFileType = type_FNT;
+ }
+
+ ASSERT(newFileType != type_UNK);
+
+ return newFileType;
+}
+
+int getNumMaxEntiresInSet(uint8* ptr)
+{
+ uint16 numEntries = *(uint16*)(ptr + 4);
+ flipShort(&numEntries);
+
+ return numEntries;
+}
+
+int loadFileMode2(uint8* name, int startIdx, int currentEntryIdx, int numIdx)
+{
+ uint8* ptr = NULL;
+ fileTypeEnum fileType;
+
+ fileType = getFileType(name);
+
+ loadFileSub1(&ptr, name, NULL);
+
+ switch(fileType)
+ {
+ case type_SET:
+ {
+ int i;
+ int numMaxEntriesInSet = getNumMaxEntiresInSet(ptr);
+
+ for(i = 0; i < numIdx; i++)
+ {
+ if ((currentEntryIdx + i) > numMaxEntriesInSet)
+ {
+ return 0; // exit if limit is reached
+ }
+ loadSetEntry(name, ptr, currentEntryIdx + i, startIdx + i);
+ }
+
+ break;
+ }
+ case type_FNT:
+ {
+ loadFNTSub(ptr, startIdx);
+ break;
+ }
+ }
+ return 0;
+}
+
+int loadFullBundle(uint8* name, int startIdx)
+{
+ uint8* ptr = NULL;
+ fileTypeEnum fileType;
+
+ fileType = getFileType(name);
+
+ loadFileSub1(&ptr,name,NULL);
+
+ switch(fileType)
+ {
+ case type_SET:
+ {
+ int i;
+ int numMaxEntriesInSet;
+
+ numMaxEntriesInSet = getNumMaxEntiresInSet(ptr); // get maximum number of sprites/animations in SET file
+
+ for(i = 0; i < numMaxEntriesInSet; i++)
+ {
+ loadSetEntry(name, ptr, i, startIdx+i);
+ }
+
+ break;
+ }
+ case type_FNT:
+ {
+ loadFNTSub(ptr, startIdx);
+ break;
+ }
+ }
+
+ return 0;
+}
+
+void loadFNTSub(uint8* ptr, int destIdx)
+{
+ uint8* ptr2 = ptr;
+ uint8* destPtr;
+ int fileIndex;
+ uint32 fontSize;
+
+ ptr2 += 4;
+ memcpy(&loadFileVar1, ptr2, 4);
+
+ flipLong(&loadFileVar1);
+
+ if(destIdx == -1)
+ {
+ fileIndex = createResFileEntry(loadFileVar1, 1 ,1);
+ }
+ else
+ {
+ fileIndex = updateResFileEntry(loadFileVar1, 1, destIdx, 1);
+ }
+
+ destPtr = filesDatabase[fileIndex].subData.ptr;
+
+ memcpy(destPtr, ptr2, loadFileVar1);
+
+ memcpy(&fontSize,ptr2,4);
+ flipLong(&fontSize);
+
+ if(destPtr!=NULL)
+ {
+ int32 i;
+ uint8* currentPtr;
+
+ destPtr = filesDatabase[fileIndex].subData.ptr;
+
+ flipLong((int32*) destPtr);
+ flipLong((int32*) (destPtr + 4));
+ flipGen(destPtr + 8, 6);
+
+ currentPtr = destPtr + 14;
+
+ for(i = 0; i < *(int16*) (destPtr + 8); i++)
+ {
+ flipLong((int32*) currentPtr);
+ currentPtr += 4;
+
+ flipGen(currentPtr, 8);
+ currentPtr += 8;
+ }
+ }
+}
+
+void loadSetEntry(uint8* name, uint8* ptr, int currentEntryIdx, int currentDestEntry)
+{
+ uint8* ptr2;
+ uint8* ptr3;
+ int offset;
+ int sec = 0;
+ uint16 numIdx;
+
+ if (!strcmpuint8(ptr,"SEC"))
+ {
+ sec = 1;
+ }
+
+ ptr2 = ptr + 4;
+
+ memcpy(&numIdx,ptr2,2);
+ flipShort(&numIdx);
+
+ ptr3 = ptr + 6;
+
+ offset = currentEntryIdx*16;
+
+ {
+ uint8* ptr4;
+ int resourceSize;
+ int fileIndex;
+ setHeaderEntry localBuffer;
+ uint8* ptr5;
+
+ ptr4 = ptr + offset + 6;
+
+ memcpy(&localBuffer, ptr4, sizeof(setHeaderEntry));
+
+ flipLong((int32*) &localBuffer.field_0);
+ flipGen(&localBuffer.width, 12);
+
+ if ((sec == 1) || (localBuffer.type == 5))
+ {
+ localBuffer.width = localBuffer.width - (localBuffer.type * 2); // Type 1: Width - (1*2) , Type 5: Width - (5*2)
+ }
+
+ resourceSize = localBuffer.width * localBuffer.height;
+
+ if(currentDestEntry == -1)
+ {
+ fileIndex = createResFileEntry(localBuffer.width,localBuffer.height,localBuffer.type);
+ }
+ else
+ {
+ fileIndex = updateResFileEntry(localBuffer.height, localBuffer.width, currentDestEntry, localBuffer.type);
+ }
+
+ if(fileIndex < 0)
+ {
+ return; // TODO: buffer is not freed
+ }
+
+ ptr5 = ptr3 + localBuffer.field_0 + numIdx * 16;
+
+ memcpy(filesDatabase[fileIndex].subData.ptr,ptr5, resourceSize);
+ ptr5 += resourceSize;
+
+ switch(localBuffer.type)
+ {
+ case 0:
+ {
+ filesDatabase[fileIndex].subData.resourceType = 8;
+ break;
+ }
+ case 1:
+ {
+ filesDatabase[fileIndex].subData.resourceType = 2;
+ decodeGfxFormat1(&filesDatabase[fileIndex]);
+ break;
+ }
+ case 4:
+ {
+ filesDatabase[fileIndex].width *= 2;
+ filesDatabase[fileIndex].subData.resourceType = 4;
+ decodeGfxFormat4(&filesDatabase[fileIndex]);
+ break;
+ }
+ case 5:
+ {
+ if (sec == 0)
+ {
+ // TODO sec type 5 needs special conversion. cut out 2 bytes at every width/5 position.
+ return;
+ }
+ filesDatabase[fileIndex].subData.resourceType = 4;
+ decodeGfxFormat5(&filesDatabase[fileIndex]);
+ break;
+ }
+ case 8:
+ {
+ filesDatabase[fileIndex].subData.resourceType = 4; // dummy !
+ break;
+ }
+ default:
+ {
+ printf("Unsuported gfx loading type: %d\n", localBuffer.type);
+ break;
+ }
+ }
+
+ filesDatabase[fileIndex].subData.index = currentDestEntry;
+ filesDatabase[fileIndex].subData.transparency = localBuffer.transparency; /*% 0x10*/;
+
+ strcpyuint8(filesDatabase[fileIndex].subData.name,name);
+ }
+
+ // TODO: free
+
+ return;
+}
+
+} // End of namespace Cruise