diff options
author | Vincent Hamm | 2007-04-27 12:58:35 +0000 |
---|---|---|
committer | Vincent Hamm | 2007-04-27 12:58:35 +0000 |
commit | c01aa37caaadb2e65667b1156a907e92e859fee8 (patch) | |
tree | 5c55328c78f6f1664f4f46baadee583fcff977ef /engines/cruise/dataLoader.cpp | |
parent | edd9b31a483c07066537663a01c265d99d69ada7 (diff) | |
download | scummvm-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.cpp | 532 |
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 |