void ResourceContext_RES::processPatches(Resource *resource, const GamePatchDescription *patchFiles) { uint16 subjectResourceType; ResourceContext *subjectContext; uint32 subjectResourceId; uint32 patchResourceId; ResourceData *subjectResourceData; ResourceData *resourceData; // Process internal patch files if (_fileType & GAME_PATCHFILE) { subjectResourceType = ~GAME_PATCHFILE & _fileType; subjectContext = resource->getContext((GameFileTypes)subjectResourceType); if (subjectContext == NULL) { error("ResourceContext::load() Subject context not found"); } ByteArray tableBuffer; resource->loadResource(this, _table.size() - 1, tableBuffer); ByteArrayReadStreamEndian readS2(tableBuffer, _isBigEndian); for (uint32 i = 0; i < tableBuffer.size() / 8; i++) { subjectResourceId = readS2.readUint32(); patchResourceId = readS2.readUint32(); subjectResourceData = subjectContext->getResourceData(subjectResourceId); resourceData = getResourceData(patchResourceId); subjectResourceData->patchData = new PatchData(&_file, _fileName); subjectResourceData->offset = resourceData->offset; subjectResourceData->size = resourceData->size; } } }
void Sprite::loadList(int resourceId, SpriteList &spriteList) { SpriteInfo *spriteInfo; byte *spriteListData = 0; size_t spriteListLength = 0; uint16 oldSpriteCount; uint16 newSpriteCount; uint16 spriteCount; int i; int outputLength, inputLength; uint32 offset; const byte *spritePointer; const byte *spriteDataPointer; _vm->_resource->loadResource(_spriteContext, resourceId, spriteListData, spriteListLength); if (spriteListLength == 0) { return; } MemoryReadStreamEndian readS(spriteListData, spriteListLength, _spriteContext->isBigEndian); spriteCount = readS.readUint16(); debug(9, "Sprites: %d", spriteCount); oldSpriteCount = spriteList.spriteCount; newSpriteCount = spriteList.spriteCount + spriteCount; spriteList.infoList = (SpriteInfo *)realloc(spriteList.infoList, newSpriteCount * sizeof(*spriteList.infoList)); if (spriteList.infoList == NULL) { memoryError("Sprite::loadList"); } spriteList.spriteCount = newSpriteCount; bool bigHeader = _vm->getGameId() == GID_IHNM || _vm->isMacResources(); for (i = oldSpriteCount; i < spriteList.spriteCount; i++) { spriteInfo = &spriteList.infoList[i]; if (bigHeader) offset = readS.readUint32(); else offset = readS.readUint16(); if (offset >= spriteListLength) { // ITE Mac demos throw this warning warning("Sprite::loadList offset exceeded"); spriteList.spriteCount = i; return; } spritePointer = spriteListData; spritePointer += offset; if (bigHeader) { MemoryReadStreamEndian readS2(spritePointer, 8, _spriteContext->isBigEndian); spriteInfo->xAlign = readS2.readSint16(); spriteInfo->yAlign = readS2.readSint16(); spriteInfo->width = readS2.readUint16(); spriteInfo->height = readS2.readUint16(); spriteDataPointer = spritePointer + readS2.pos(); } else { MemoryReadStreamEndian readS2(spritePointer, 4); spriteInfo->xAlign = readS2.readSByte(); spriteInfo->yAlign = readS2.readSByte(); spriteInfo->width = readS2.readByte(); spriteInfo->height = readS2.readByte(); spriteDataPointer = spritePointer + readS2.pos(); } outputLength = spriteInfo->width * spriteInfo->height; inputLength = spriteListLength - (spriteDataPointer - spriteListData); decodeRLEBuffer(spriteDataPointer, inputLength, outputLength); spriteInfo->decodedBuffer = (byte *) malloc(outputLength); if (spriteInfo->decodedBuffer == NULL) { memoryError("Sprite::loadList"); } #ifdef ENABLE_IHNM // IHNM sprites are upside-down, for reasons which i can only // assume are perverse. To simplify things, flip them now. Not // at drawing time. if (_vm->getGameId() == GID_IHNM) { byte *src = _decodeBuf + spriteInfo->width * (spriteInfo->height - 1); byte *dst = spriteInfo->decodedBuffer; for (int j = 0; j < spriteInfo->height; j++) { memcpy(dst, src, spriteInfo->width); src -= spriteInfo->width; dst += spriteInfo->width; } } else #endif memcpy(spriteInfo->decodedBuffer, _decodeBuf, outputLength); } free(spriteListData); }
void Sprite::loadList(int resourceId, SpriteList &spriteList) { SpriteInfo *spriteInfo; ByteArray spriteListData; uint16 oldSpriteCount; uint16 newSpriteCount; uint16 spriteCount; uint i; int outputLength, inputLength; uint32 offset; const byte *spritePointer; const byte *spriteDataPointer; _vm->_resource->loadResource(_spriteContext, resourceId, spriteListData); if (spriteListData.empty()) { return; } ByteArrayReadStreamEndian readS(spriteListData, _spriteContext->isBigEndian()); spriteCount = readS.readUint16(); debug(9, "Sprites: %d", spriteCount); oldSpriteCount = spriteList.size(); newSpriteCount = oldSpriteCount + spriteCount; spriteList.resize(newSpriteCount); bool bigHeader = _vm->getGameId() == GID_IHNM || _vm->isMacResources(); for (i = oldSpriteCount; i < spriteList.size(); i++) { spriteInfo = &spriteList[i]; if (bigHeader) offset = readS.readUint32(); else offset = readS.readUint16(); if (offset >= spriteListData.size()) { // ITE Mac demos throw this warning warning("Sprite::loadList offset exceeded"); spriteList.resize(i); return; } spritePointer = spriteListData.getBuffer(); spritePointer += offset; if (bigHeader) { Common::MemoryReadStreamEndian readS2(spritePointer, 8, _spriteContext->isBigEndian()); spriteInfo->xAlign = readS2.readSint16(); spriteInfo->yAlign = readS2.readSint16(); spriteInfo->width = readS2.readUint16(); spriteInfo->height = readS2.readUint16(); spriteDataPointer = spritePointer + readS2.pos(); } else { Common::MemoryReadStreamEndian readS2(spritePointer, 4, false); spriteInfo->xAlign = readS2.readSByte(); spriteInfo->yAlign = readS2.readSByte(); spriteInfo->width = readS2.readByte(); spriteInfo->height = readS2.readByte(); spriteDataPointer = spritePointer + readS2.pos(); } outputLength = spriteInfo->width * spriteInfo->height; inputLength = spriteListData.size() - (spriteDataPointer - spriteListData.getBuffer()); spriteInfo->decodedBuffer.resize(outputLength); if (outputLength > 0) { decodeRLEBuffer(spriteDataPointer, inputLength, outputLength); byte *dst = &spriteInfo->decodedBuffer.front(); #ifdef ENABLE_IHNM // IHNM sprites are upside-down, for reasons which i can only // assume are perverse. To simplify things, flip them now. Not // at drawing time. if (_vm->getGameId() == GID_IHNM) { byte *src = &_decodeBuf[spriteInfo->width * (spriteInfo->height - 1)]; for (int j = 0; j < spriteInfo->height; j++) { memcpy(dst, src, spriteInfo->width); src -= spriteInfo->width; dst += spriteInfo->width; } } else #endif memcpy(dst, &_decodeBuf.front(), outputLength); } } }