/** * Allocates enough RAM to hold the global Glitter variables. */ void RegisterGlobals(int num) { if (pGlobals == NULL) { numGlobals = num; hMasterScript = !TinselV2 ? 0 : READ_LE_UINT32(FindChunk(MASTER_SCNHANDLE, CHUNK_MASTER_SCRIPT)); // Allocate RAM for pGlobals and make sure it's allocated pGlobals = (int32 *)calloc(numGlobals, sizeof(int32)); if (pGlobals == NULL) { error("Cannot allocate memory for global data"); } // Allocate RAM for interpret contexts and make sure it's allocated icList = (INT_CONTEXT *)calloc(NUM_INTERPRET, sizeof(INT_CONTEXT)); if (icList == NULL) { error("Cannot allocate memory for interpret contexts"); } g_scheduler->setResourceCallback(FreeInterpretContextPr); } else { // Check size is still the same assert(numGlobals == num); memset(pGlobals, 0, numGlobals * sizeof(int32)); memset(icList, 0, NUM_INTERPRET * sizeof(INT_CONTEXT)); } if (TinselV2) { // read initial values CdCD(nullContext); Common::File f; if (!f.open(GLOBALS_FILENAME)) error(CANNOT_FIND_FILE, GLOBALS_FILENAME); int32 length = f.readSint32LE(); if (length != num) error(FILE_IS_CORRUPT, GLOBALS_FILENAME); for (int i = 0; i < length; ++i) pGlobals[i] = f.readSint32LE(); if (f.eos() || f.err()) error(FILE_IS_CORRUPT, GLOBALS_FILENAME); f.close(); } }
ChunkBlock GhostRoom::readChunkBlock(Common::File &file) { ChunkBlock cb; cb._flavour = (Flavour)file.readByte(); cb._x = file.readSint16LE(); cb._y = file.readSint16LE(); cb._width = file.readSint16LE(); cb._height = file.readSint16LE(); cb._size = file.readSint32LE(); return cb; }
void Background::loadSprites(byte number) { Common::File f; _filename = _filename.format("chunk%d.avd", number); if (!f.open(_filename)) return; // We skip because some rooms don't have sprites in the background. f.seek(44); _spriteNum = f.readByte(); for (int i = 0; i < _spriteNum; i++) _offsets[i] = f.readSint32LE(); for (int i = 0; i < _spriteNum; i++) { f.seek(_offsets[i]); SpriteType sprite; sprite._type = (PictureType)(f.readByte()); sprite._x = f.readSint16LE(); sprite._y = f.readSint16LE(); sprite._width = f.readSint16LE(); sprite._height = f.readSint16LE(); sprite._size = f.readSint32LE(); bool natural = f.readByte(); bool memorize = f.readByte(); if (memorize) { _sprites[i]._x = sprite._x; _sprites[i]._width = sprite._width; _sprites[i]._y = sprite._y; _sprites[i]._height = sprite._height; _sprites[i]._type = sprite._type; if (natural) _vm->_graphics->getNaturalPicture(_sprites[i]); else { _sprites[i]._size = sprite._size; _sprites[i]._picture = _vm->_graphics->loadPictureRaw(f, _sprites[i]._width * 8, _sprites[i]._height + 1); } } else _sprites[i]._x = kOnDisk; } f.close(); }
/** * Draw background animation * @remarks Originally called 'show_one' */ void Background::draw(int16 destX, int16 destY, byte sprId) { assert(sprId < 40); if (_sprites[sprId]._x > kOnDisk) { if (destX < 0) { destX = _sprites[sprId]._x * 8; destY = _sprites[sprId]._y; } drawSprite(destX, destY, _sprites[sprId]); } else { Common::File f; if (!f.open(_filename)) // Filename was set in loadBackgroundSprites(). return; // We skip because some rooms don't have sprites in the background. f.seek(_offsets[sprId]); SpriteType sprite; sprite._type = (PictureType)(f.readByte()); sprite._x = f.readSint16LE(); sprite._y = f.readSint16LE(); sprite._width = f.readSint16LE(); sprite._height = f.readSint16LE(); sprite._size = f.readSint32LE(); f.skip(2); // Natural and Memorize are used in Load() sprite._picture = _vm->_graphics->loadPictureRaw(f, sprite._width * 8, sprite._height + 1); if (destX < 0) { destX = sprite._x * 8; destY = sprite._y; } drawSprite(destX, destY, sprite); sprite._picture.free(); f.close(); } }
void RenderManager::readImageToSurface(const Common::String &fileName, Graphics::Surface &destination, bool transposed) { Common::File file; if (!_engine->getSearchManager()->openFile(file, fileName)) { warning("Could not open file %s", fileName.c_str()); return; } // Read the magic number // Some files are true TGA, while others are TGZ uint32 fileType = file.readUint32BE(); uint32 imageWidth; uint32 imageHeight; Image::TGADecoder tga; uint16 *buffer; // All ZVision images are in RGB 555 destination.format = _engine->_resourcePixelFormat; bool isTGZ; // Check for TGZ files if (fileType == MKTAG('T', 'G', 'Z', '\0')) { isTGZ = true; // TGZ files have a header and then Bitmap data that is compressed with LZSS uint32 decompressedSize = file.readSint32LE() / 2; imageWidth = file.readSint32LE(); imageHeight = file.readSint32LE(); LzssReadStream lzssStream(&file); buffer = (uint16 *)(new uint16[decompressedSize]); lzssStream.read(buffer, 2 * decompressedSize); #ifndef SCUMM_LITTLE_ENDIAN for (uint32 i = 0; i < decompressedSize; ++i) buffer[i] = FROM_LE_16(buffer[i]); #endif } else { isTGZ = false; // Reset the cursor file.seek(0); // Decode if (!tga.loadStream(file)) { warning("Error while reading TGA image"); return; } Graphics::Surface tgaSurface = *(tga.getSurface()); imageWidth = tgaSurface.w; imageHeight = tgaSurface.h; buffer = (uint16 *)tgaSurface.getPixels(); } // Flip the width and height if transposed if (transposed) { uint16 temp = imageHeight; imageHeight = imageWidth; imageWidth = temp; } // If the destination internal buffer is the same size as what we're copying into it, // there is no need to free() and re-create if (imageWidth != destination.w || imageHeight != destination.h) { destination.create(imageWidth, imageHeight, _engine->_resourcePixelFormat); } // If transposed, 'un-transpose' the data while copying it to the destination // Otherwise, just do a simple copy if (transposed) { uint16 *dest = (uint16 *)destination.getPixels(); for (uint32 y = 0; y < imageHeight; ++y) { uint32 columnIndex = y * imageWidth; for (uint32 x = 0; x < imageWidth; ++x) { dest[columnIndex + x] = buffer[x * imageHeight + y]; } } } else { memcpy(destination.getPixels(), buffer, imageWidth * imageHeight * destination.format.bytesPerPixel); } // Cleanup if (isTGZ) { delete[] buffer; } else { tga.destroy(); } }
void RenderManager::readImageToSurface(const Common::String &fileName, Graphics::Surface &destination) { Common::File file; if (!file.open(fileName)) { warning("Could not open file %s", fileName.c_str()); return; } // Read the magic number // Some files are true TGA, while others are TGZ uint32 fileType = file.readUint32BE(); uint32 imageWidth; uint32 imageHeight; Graphics::TGADecoder tga; uint16 *buffer; bool isTransposed = _renderTable.getRenderState() == RenderTable::PANORAMA; // All ZVision images are in RGB 555 Graphics::PixelFormat pixelFormat555 = Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0); destination.format = pixelFormat555; bool isTGZ; // Check for TGZ files if (fileType == MKTAG('T', 'G', 'Z', '\0')) { isTGZ = true; // TGZ files have a header and then Bitmap data that is compressed with LZSS uint32 decompressedSize = file.readSint32LE(); imageWidth = file.readSint32LE(); imageHeight = file.readSint32LE(); LzssReadStream lzssStream(&file); buffer = (uint16 *)(new uint16[decompressedSize]); lzssStream.read(buffer, decompressedSize); } else { isTGZ = false; // Reset the cursor file.seek(0); // Decode if (!tga.loadStream(file)) { warning("Error while reading TGA image"); return; } Graphics::Surface tgaSurface = *(tga.getSurface()); imageWidth = tgaSurface.w; imageHeight = tgaSurface.h; buffer = (uint16 *)tgaSurface.getPixels(); } // Flip the width and height if transposed if (isTransposed) { uint16 temp = imageHeight; imageHeight = imageWidth; imageWidth = temp; } // If the destination internal buffer is the same size as what we're copying into it, // there is no need to free() and re-create if (imageWidth != destination.w || imageHeight != destination.h) { destination.create(imageWidth, imageHeight, pixelFormat555); } // If transposed, 'un-transpose' the data while copying it to the destination // Otherwise, just do a simple copy if (isTransposed) { uint16 *dest = (uint16 *)destination.getPixels(); for (uint32 y = 0; y < imageHeight; ++y) { uint32 columnIndex = y * imageWidth; for (uint32 x = 0; x < imageWidth; ++x) { dest[columnIndex + x] = buffer[x * imageHeight + y]; } } } else { memcpy(destination.getPixels(), buffer, imageWidth * imageHeight * _pixelFormat.bytesPerPixel); } // Cleanup if (isTGZ) { delete[] buffer; } else { tga.destroy(); } // Convert in place to RGB 565 from RGB 555 destination.convertToInPlace(_pixelFormat); }