MemoryBlock *Disk::getEntry(uint16 id) { // Get the index of the resource, if necessary opening the correct file uint8 index = indexOf(id); // Calculate the offset and size of the entry uint32 size = (uint32) _entries[index].size; if (_entries[index].sizeExtension) size += 0x10000; uint32 offset = (uint32) _entries[index].offset * 0x20; MemoryBlock *result = Memory::allocate(size); _fileHandle->seek(offset, SEEK_SET); _fileHandle->read(result->data(), size); return result; }
MemoryBlock *Disk::getEntry(uint16 id) { // Special room area check uint16 tempId = id & 0x3fff; if ((tempId == 0x120) || (tempId == 0x311) || (tempId == 8) || (tempId == 0x410)) { ValueTableData &fieldList = Resources::getReference().fieldList(); if (fieldList.getField(AREA_FLAG) != 0) id ^= 0x8000; } // Get the index of the resource, if necessary opening the correct file uint8 index = indexOf(id); // Calculate the offset and size of the entry uint32 size = (uint32) _entries[index].size; if (_entries[index].sizeExtension) size += 0x10000; uint32 offset = (uint32) _entries[index].offset * 0x20 + _dataOffset; MemoryBlock *result = Memory::allocate(size); _fileHandle->seek(offset, SEEK_SET); _fileHandle->read(result->data(), size); return result; }
bool Debugger::cmd_showAnim(int argc, const char **argv) { Resources &res = Resources::getReference(); if (argc < 2) { DebugPrintf("showAnim animId [[frame_width frame_height] | list]\n"); return true; } // Get the animation Id int animId = strToInt(argv[1]); HotspotAnimData *data = res.getAnimation(animId); if (data == NULL) { DebugPrintf("No such animation Id exists\n"); return true; } // Figure out the total size of the animation - this will be used for guestimating // frame sizes, or validating that a specified frame size is correct MemoryBlock *src = Disk::getReference().getEntry(data->animId); int numFrames = READ_LE_UINT16(src->data()); uint16 *headerEntry = (uint16 *) (src->data() + 2); assert((numFrames >= 1) && (numFrames < 100)); // Calculate total needed size for output and create memory block to hold it uint32 totalSize = 0; for (uint16 ctr = 0; ctr < numFrames; ++ctr, ++headerEntry) { totalSize += (READ_LE_UINT16(headerEntry) + 31) / 32; } totalSize = (totalSize + 0x81) << 4; MemoryBlock *dest = Memory::allocate(totalSize); uint32 srcStart = (numFrames + 1) * sizeof(uint16) + 6; uint32 destSize = AnimationDecoder::decode_data(src, dest, srcStart) - 0x40; // Figure out the frame size int frameSize; if ((data->flags & PIXELFLAG_HAS_TABLE) != 0) { // Table based animation, so get frame size from frame 1 offset frameSize = READ_LE_UINT16(src->data()); } else { // Get frame size from dividing uncompressed size by number of frames frameSize = destSize / numFrames; } // Free up the data delete src; delete dest; int width, height; if (argc == 4) { // Width and height specified width = strToInt(argv[2]); height = strToInt(argv[3]); if ((width * height) != (frameSize * 2)) { DebugPrintf("Warning: Total size = %d, Frame size (%d,%d) * %d frames = %d bytes\n", destSize, width, height, numFrames, width * height * numFrames / 2); } } else { // Guestimate a frame size frameSize = destSize / numFrames; // Figure out the approximate starting point of a width 3/4 the frame size width = frameSize * 3 / 4; bool descFlag = (argc == 3); if (descFlag) DebugPrintf("Target size = %d\n", frameSize * 2); while ((width > 0) && (descFlag || (((frameSize * 2) % width) != 0))) { if (((frameSize * 2) % width) == 0) DebugPrintf("Frame size (%d,%d) found\n", width, frameSize * 2 / width); --width; } if (argc == 3) { DebugPrintf("Done\n"); return true; } else if (width == 0) { DebugPrintf("Total size = %d, # frames = %d, frame Size = %d - No valid frame dimensions\n", destSize, numFrames, frameSize); return true; } height = (frameSize * 2) / width; DebugPrintf("# frames = %d, guestimated frame size = (%d,%d)\n", numFrames, width, height); } // Bottle object is used as a handy hotspot holder that doesn't have any // tick proc behavior that we need to worry about Hotspot *hotspot = res.activateHotspot(BOTTLE_HOTSPOT_ID); hotspot->setLayer(0xfe); hotspot->setSize(width, height); Hotspot *player = res.activateHotspot(PLAYER_ID); hotspot->setColorOffset(player->resource()->colorOffset); hotspot->setAnimation(animId); DebugPrintf("Done\n"); return true; }