TextEntryList *Text::getDialog(uint dialogNum, uint entryNum) { if (dialogNum >= kADSTextMax) error("getDialog(): Invalid entry number requested, %d (max %d)", dialogNum, kADSTextMax - 1); TextEntryList *l = new TextEntryList(); byte *data = getChunkData(dialogNum); byte *ptr = data; ptr += 2; // entry number ptr += 2; // number of persons ptr += 2; // automove count ptr += 2; // cursor number ptr += 13; // misc data for (uint i = 0; i <= entryNum; i++) { do { TextEntry curDialog; ptr++; // current entry ptr += 2; curDialog.speechId = READ_LE_UINT16(ptr) - VOICE_OFFSET; ptr += 2; do { curDialog.text += *ptr++; if (*ptr == 0 && *(ptr + 1) != kEndText) { // TODO: Split lines *ptr = ' '; } } while (*ptr != kEndText); if (i == entryNum) l->push_back(curDialog); } while (*(ptr + 1) != kEndEntry); ptr += 2; // kEndText, kEndEntry if (*ptr == kEndBlock) // not found break; } delete[] data; return l; }
void Script::load(ResourceManager *resMan) { Resource *script = resMan->findResource(ResourceId(kResourceTypeScript, _nr), 0); assert(script != 0); _buf = (byte *)malloc(_bufSize); assert(_buf); assert(_bufSize >= script->size); memcpy(_buf, script->data, script->size); // Check scripts for matching signatures and patch those, if found matchSignatureAndPatch(_nr, _buf, script->size); if (getSciVersion() >= SCI_VERSION_1_1 && getSciVersion() <= SCI_VERSION_2_1) { Resource *heap = resMan->findResource(ResourceId(kResourceTypeHeap, _nr), 0); assert(heap != 0); _heapStart = _buf + _scriptSize; assert(_bufSize - _scriptSize <= heap->size); memcpy(_heapStart, heap->data, heap->size); } _exportTable = 0; _numExports = 0; _synonyms = 0; _numSynonyms = 0; if (getSciVersion() <= SCI_VERSION_1_LATE) { _exportTable = (const uint16 *)findBlockSCI0(SCI_OBJ_EXPORTS); if (_exportTable) { _numExports = READ_SCI11ENDIAN_UINT16(_exportTable + 1); _exportTable += 3; // skip header plus 2 bytes (_exportTable is a uint16 pointer) } _synonyms = findBlockSCI0(SCI_OBJ_SYNONYMS); if (_synonyms) { _numSynonyms = READ_SCI11ENDIAN_UINT16(_synonyms + 2) / 4; _synonyms += 4; // skip header } const byte* localsBlock = findBlockSCI0(SCI_OBJ_LOCALVARS); if (localsBlock) { _localsOffset = localsBlock - _buf + 4; _localsCount = (READ_LE_UINT16(_buf + _localsOffset - 2) - 4) >> 1; // half block size } } else if (getSciVersion() >= SCI_VERSION_1_1 && getSciVersion() <= SCI_VERSION_2_1) {
void RlfAnimation::decodeMaskedRunLengthEncoding(int8 *source, int8 *dest, uint32 sourceSize, uint32 destSize) const { uint32 sourceOffset = 0; uint32 destOffset = 0; while (sourceOffset < sourceSize) { int8 numberOfSamples = source[sourceOffset]; sourceOffset++; // If numberOfSamples is negative, the next abs(numberOfSamples) samples should // be copied directly from source to dest if (numberOfSamples < 0) { numberOfSamples = ABS(numberOfSamples); while (numberOfSamples > 0) { if (sourceOffset + 1 >= sourceSize) { return; } else if (destOffset + 1 >= destSize) { debug(2, "Frame decoding overflow\n\tsourceOffset=%u\tsourceSize=%u\n\tdestOffset=%u\tdestSize=%u", sourceOffset, sourceSize, destOffset, destSize); return; } byte r, g, b; Graphics::colorToRGB<Graphics::ColorMasks<555> >(READ_LE_UINT16(source + sourceOffset), r, g, b); uint16 destColor = Graphics::RGBToColor<Graphics::ColorMasks<565> >(r, g, b); WRITE_UINT16(dest + destOffset, destColor); sourceOffset += 2; destOffset += 2; numberOfSamples--; } // If numberOfSamples is >= 0, move destOffset forward ((numberOfSamples * 2) + 2) // This function assumes the dest buffer has been memset with 0's. } else { if (sourceOffset + 1 >= sourceSize) { return; } else if (destOffset + 1 >= destSize) { debug(2, "Frame decoding overflow\n\tsourceOffset=%u\tsourceSize=%u\n\tdestOffset=%u\tdestSize=%u", sourceOffset, sourceSize, destOffset, destSize); return; } destOffset += (numberOfSamples * 2) + 2; } } }
void TeenAgentEngine::init() { _mark_delay = 80; _game_delay = 110; Resources * res = Resources::instance(); use_hotspots.resize(42); byte *scene_hotspots = res->dseg.ptr(0xbb87); for (byte i = 0; i < 42; ++i) { Common::Array<UseHotspot> & hotspots = use_hotspots[i]; byte * hotspots_ptr = res->dseg.ptr(READ_LE_UINT16(scene_hotspots + i * 2)); while (*hotspots_ptr) { UseHotspot h; h.load(hotspots_ptr); hotspots_ptr += 9; hotspots.push_back(h); } } }
Common::Error LureEngine::init() { int_engine = this; _initialised = false; _saveLoadAllowed = false; initGraphics(FULL_SCREEN_WIDTH, FULL_SCREEN_HEIGHT, false); // Check the version of the lure.dat file Common::File f; VersionStructure version; if (!f.open(SUPPORT_FILENAME)) { GUIError("Could not locate Lure support file"); return Common::kUnknownError; } f.seek(0xbf * 8); f.read(&version, sizeof(VersionStructure)); f.close(); if (READ_LE_UINT16(&version.id) != 0xffff) { GUIError("Error validating %s - file is invalid or out of date", SUPPORT_FILENAME); return Common::kUnknownError; } else if ((version.vMajor != LURE_DAT_MAJOR) || (version.vMinor != LURE_DAT_MINOR)) { GUIError("Incorrect version of %s file - expected %d.%d but got %d.%d", SUPPORT_FILENAME, LURE_DAT_MAJOR, LURE_DAT_MINOR, version.vMajor, version.vMinor); return Common::kUnknownError; } _disk = new Disk(); _resources = new Resources(); _strings = new StringData(); _screen = new Screen(*_system); _mouse = new Mouse(); _events = new Events(); _menu = new Menu(); Surface::initialise(); _room = new Room(); _fights = new FightsManager(); _gameToLoad = -1; _initialised = true; return Common::kNoError; }
bool Intro::floppyScrollFlirt(void) { uint8 *scrollScreen = (uint8*)malloc(FRAME_SIZE * 2); memset(scrollScreen, 0, FRAME_SIZE); memcpy(scrollScreen + FRAME_SIZE, _skyScreen->giveCurrent(), FRAME_SIZE); uint8 *scrollPos = scrollScreen + FRAME_SIZE; uint8 *vgaData = _skyDisk->loadFile(60100); uint8 *diffData = _skyDisk->loadFile(60101); uint16 frameNum = READ_LE_UINT16(diffData); uint8 *diffPtr = diffData + 2; uint8 *vgaPtr = vgaData; bool doContinue = true; for (uint16 frameCnt = 1; (frameCnt < frameNum) && doContinue; frameCnt++) { uint8 scrollVal = *diffPtr++; if (scrollVal) scrollPos -= scrollVal * GAME_SCREEN_WIDTH; uint16 scrPos = 0; while (scrPos < FRAME_SIZE) { uint8 nrToDo, nrToSkip; do { nrToSkip = *diffPtr++; scrPos += nrToSkip; } while (nrToSkip == 255); do { nrToDo = *diffPtr++; memcpy(scrollPos + scrPos, vgaPtr, nrToDo); scrPos += nrToDo; vgaPtr += nrToDo; } while (nrToDo == 255); } _system->copyRectToScreen(scrollPos, GAME_SCREEN_WIDTH, 0, 0, GAME_SCREEN_WIDTH, GAME_SCREEN_HEIGHT); _system->updateScreen(); if (!escDelay(60)) doContinue = false; } memcpy(_skyScreen->giveCurrent(), scrollPos, FRAME_SIZE); free(diffData); free(vgaData); free(scrollScreen); return doContinue; }
int TextDisplayer::getCharLength(const char *str, int len) { int charsCount = 0; if (*str) { _screen->_charWidth = -2; int i = 0; while (i <= len && *str) { uint c = *str++; c &= 0xFF; if (c >= 0x7F && _vm->gameFlags().lang == Common::JA_JPN) { c = READ_LE_UINT16(str - 1); ++str; } i += _screen->getCharWidth(c); ++charsCount; } _screen->_charWidth = 0; } return charsCount; }
Font::Font(const char *filename, const char *data, int len) : Object() { _fname = filename; _filename = filename; _numChars = READ_LE_UINT32(data); _dataSize = READ_LE_UINT32(data + 4); _height = READ_LE_UINT32(data + 8); _baseOffsetY = READ_LE_UINT32(data + 12); _firstChar = READ_LE_UINT32(data + 24); _lastChar = READ_LE_UINT32(data + 28); data += 32; // Read character indexes - are the key/value reversed? _charIndex = new uint16[_numChars]; if (!_charIndex) error("Could not load font %s. Out of memory", filename); for (uint i = 0; i < _numChars; ++i) { _charIndex[i] = READ_LE_UINT16(data + 2 * i); } data += _numChars * 2; // Read character headers _charHeaders = new CharHeader[_numChars]; if (!_charHeaders) error("Could not load font %s. Out of memory", filename); for (uint i = 0; i < _numChars; ++i) { _charHeaders[i].offset = READ_LE_UINT32(data); _charHeaders[i].width = *(int8 *)(data + 4); _charHeaders[i].startingCol = *(int8 *)(data + 5); _charHeaders[i].startingLine = *(int8 *)(data + 6); _charHeaders[i].dataWidth = READ_LE_UINT32(data + 8); _charHeaders[i].dataHeight = READ_LE_UINT32(data + 12); data += 16; } // Read font data _fontData = new byte[_dataSize]; if (!_fontData) error("Could not load font %s. Out of memory", filename); memcpy(_fontData, data, _dataSize); }
void MoviePlayer::openTextObject(uint32 index) { MovieText *text = &_movieTexts[index]; // Pull out the text line to get the official text number (for WAV id) uint32 res = text->_textNumber / SIZE; uint32 localText = text->_textNumber & 0xffff; // Open text resource and get the line byte *textData = _vm->fetchTextLine(_vm->_resman->openResource(res), localText); text->_speechId = READ_LE_UINT16(textData); // Is it speech or subtitles, or both? // If we want subtitles, or there was no sound if (_vm->getSubtitles() || !text->_speechId) { text->_textMem = _vm->_fontRenderer->makeTextSprite(textData + 2, 600, 255, _vm->_speechFontId, 1); } _vm->_resman->closeResource(res); if (text->_textMem) { FrameHeader frame; frame.read(text->_textMem); text->_textSprite.x = 320 - frame.width / 2; text->_textSprite.y = 440 - frame.height; text->_textSprite.w = frame.width; text->_textSprite.h = frame.height; text->_textSprite.type = RDSPR_DISPLAYALIGN | RDSPR_NOCOMPRESSION; text->_textSprite.data = text->_textMem + FrameHeader::size(); text->_textSprite.isText = true; _vm->_screen->createSurface(&text->_textSprite, &_textSurface); _textX = 320 - text->_textSprite.w / 2; _textY = 420 - text->_textSprite.h; } }
void Player_Towns_v1::startSound(int sound) { uint8 *ptr = _vm->getResourceAddress(rtSound, sound); if (_vm->_game.version != 3) ptr += 2; int type = ptr[13]; if (type == 0) { uint8 velocity = 0; uint8 note = 0; if (_vm->_game.version == 3) { velocity = (_soundOverride[sound].vLeft + _soundOverride[sound].vRight); note = _soundOverride[sound].note; } velocity = velocity ? velocity >> 2 : ptr[14] >> 1; playPcmTrack(sound, ptr + 6, velocity, 64, note ? note : ptr[50], READ_LE_UINT16(ptr + 10)); } else if (type == 1) {
void unpackSpriteRle(const byte *source, int width, int height, byte *dest, int destPitch, bool flipX, bool flipY, byte oldColor, byte newColor) { const bool replaceColors = oldColor != newColor; int16 rows, chunks; int16 skip, copy; if (flipY) { dest += destPitch * (height - 1); destPitch = -destPitch; } rows = READ_LE_UINT16(source); chunks = READ_LE_UINT16(source + 2); source += 4; do { if (chunks == 0) { dest += rows * destPitch; } else { while (rows-- > 0) { uint16 rowChunks = chunks; while (rowChunks-- > 0) { skip = READ_LE_UINT16(source); copy = READ_LE_UINT16(source + 2); source += 4; if (!flipX) { memcpy(dest + skip, source, copy); } else { byte *flipDest = dest + width - skip - 1; for (int xc = 0; xc < copy; xc++) { *flipDest-- = source[xc]; } } source += copy; } if (replaceColors) for (int xc = 0; xc < width; xc++) if (dest[xc] == oldColor) dest[xc] = newColor; dest += destPitch; } } rows = READ_LE_UINT16(source); chunks = READ_LE_UINT16(source + 2); source += 4; } while (rows > 0); }
/** * Fetches up to 4 bytes from the code script */ static int32 GetBytes(const byte *scriptCode, const WorkaroundEntry* &wkEntry, int &ip, uint numBytes) { assert(numBytes <= 4 && numBytes != 3); const byte *code = scriptCode; if (wkEntry != NULL) { if (ip >= wkEntry->numBytes) { // Finished the workaround ip = wkEntry->ip; wkEntry = NULL; } else { code = wkEntry->script; } } uint32 tmp; switch (numBytes) { case 0: // Instruction byte tmp = code[ip++ * (TinselV0 ? 4 : 1)]; break; case 1: // Fetch and sign extend a 8 bit value to 32 bits. tmp = (int8)code[ip++]; break; case 2: // Fetch and sign extend a 16 bit value to 32 bits. tmp = (int16)READ_LE_UINT16(code + ip); ip += 2; break; default: if (TinselV0) tmp = (int32)READ_LE_UINT32(code + ip++ * 4); else { tmp = (int32)READ_LE_UINT32(code + ip); ip += 4; } break; } return tmp; }
/** * Search Animation */ void AnimationManager::searchAnim(const byte *data, int animIndex, int bufSize) { for (int dataIdx = 0; dataIdx <= bufSize; dataIdx++) { if (READ_BE_UINT32(&data[dataIdx]) == MKTAG('A', 'N', 'I', 'M')) { int entryIndex = data[dataIdx + 4]; if (animIndex == entryIndex) { int curBufferPos = dataIdx + 5; int count = 0; bool innerLoopCond = false; do { if (READ_BE_UINT32(&data[curBufferPos]) == MKTAG('A', 'N', 'I', 'M') || READ_BE_UINT24(&data[curBufferPos]) == MKTAG24('F', 'I', 'N')) innerLoopCond = true; if (bufSize < curBufferPos) { _animBqe[animIndex]._enabledFl = false; _animBqe[animIndex]._data = NULL; return; } ++curBufferPos; ++count; } while (!innerLoopCond); _animBqe[animIndex]._data = _vm->_globals->allocMemory(count + 50); _animBqe[animIndex]._enabledFl = true; memcpy(_animBqe[animIndex]._data, data + dataIdx + 5, 20); byte *dataP = _animBqe[animIndex]._data; int curDestDataIndx = 20; int curSrcDataIndx = dataIdx + 25; for (int i = 0; i <= 4999; i++) { memcpy(dataP + curDestDataIndx, data + curSrcDataIndx, 10); if (!READ_LE_UINT16(data + curSrcDataIndx + 4)) break; curDestDataIndx += 10; curSrcDataIndx += 10; } break; } } if (READ_BE_UINT24(&data[dataIdx]) == MKTAG24('F', 'I', 'N')) break; } }
void DreamGenContext::deallocatemem() { uint16 id = (uint16)es; debug(1, "deallocating segment %04x", id); deallocateSegment(id); //fixing invalid entries in the sprite table es = data; uint tsize = 16 * 32; uint16 bseg = data.word(kBuffers); if (!bseg) return; SegmentRef buffers(this); buffers = bseg; uint8 *ptr = buffers.ptr(kSpritetable, tsize); for(uint i = 0; i < tsize; i += 32) { uint16 seg = READ_LE_UINT16(ptr + i + 6); //debug(1, "sprite segment = %04x", seg); if (seg == id) memset(ptr + i, 0xff, 32); } }
uint32 CdfArchive::BlockDecode(uint8 *dst, uint32 a_dst_size, const uint8 *a_src, uint32 a_src_size) const { uint32 dst_size = 0; uint16 data_type = READ_LE_UINT16(a_src); const uint8 *src = a_src + sizeof(uint16); uint32 src_size = a_src_size - sizeof(uint16); // data uncompressed, just copy contents if(data_type == 0) { memcpy(dst, src, src_size); dst_size = src_size; } // deflate compression used else if(data_type == 8) dst_size = inflateZlibHeaderless((byte *)dst, a_dst_size, src, src_size); return dst_size; }
void CharsetRendererCommon::setCurID(int32 id) { if (id == -1) return; assertRange(0, id, _vm->_numCharsets - 1, "charset"); _curId = id; _fontPtr = _vm->getResourceAddress(rtCharset, id); if (_fontPtr == 0) error("CharsetRendererCommon::setCurID: charset %d not found", id); if (_vm->_game.version == 4) _fontPtr += 17; else _fontPtr += 29; _bytesPerPixel = _fontPtr[0]; _fontHeight = _fontPtr[1]; _numChars = READ_LE_UINT16(_fontPtr + 2); }
void KyraRpgEngine::restoreBlockTempData(int levelIndex) { int l = levelIndex - 1; const uint8 *p = getBlockFileData(levelIndex); uint16 len = READ_LE_UINT16(p + 4); p += 6; memset(_levelBlockProperties, 0, 1024 * sizeof(LevelBlockProperty)); uint8 *t = _lvlTempData[l]->wallsXorData; uint16 *t2 = _lvlTempData[l]->flags; for (int i = 0; i < 1024; i++) { for (int ii = 0; ii < 4; ii++) _levelBlockProperties[i].walls[ii] = p[i * len + ii] ^ *t++; _levelBlockProperties[i].flags = *t2++; } restoreMonsterTempData(_lvlTempData[l]); restoreFlyingObjectTempData(_lvlTempData[l]); restoreWallOfForceTempData(_lvlTempData[l]); }
Surface *Animation::currentFrame(int dt) { if (paused) return firstFrame(); if (frames == NULL || frames_count == 0) return NULL; Surface *r; if (data != NULL) { uint32 frame = 3 * index; //debug(0, "%u/%u", index, data_size / 3); index += dt; if (!loop && index >= data_size / 3) { return NULL; } if (data[frame] - 1 >= frames_count) { warning("invalid frame %u(0x%x) (max %u) index %u, mod %u", frame, frame, frames_count, index - 1, data_size / 3); return NULL; } r = frames + data[frame] - 1; uint16 pos = READ_LE_UINT16(data + frame + 1); index %= (data_size / 3); if (pos != 0) { x = r->x = pos % 320; y = r->y = pos / 320; } } else { //debug(0, "index %u", index); r = frames + index; index += dt; index %= frames_count; } return r; }
uint8_t *decode_bitmap(const uint8_t *src, bool alpha, int colorKey, int *w, int *h) { if (memcmp(src, "BM", 2) != 0) { return 0; } const uint32_t imageOffset = READ_LE_UINT32(src + 0xA); const int width = READ_LE_UINT32(src + 0x12); const int height = READ_LE_UINT32(src + 0x16); const int depth = READ_LE_UINT16(src + 0x1C); const int compression = READ_LE_UINT32(src + 0x1E); if ((depth != 8 && depth != 32) || compression != 0) { warning("Unhandled bitmap depth %d compression %d", depth, compression); return 0; } const int bpp = (!alpha && colorKey < 0) ? 3 : 4; uint8_t *dst = (uint8_t *)malloc(width * height * bpp); if (!dst) { warning("Failed to allocate bitmap buffer, width %d height %d bpp %d", width, height, bpp); return 0; } if (depth == 8) { const uint8_t *palette = src + 14 /* BITMAPFILEHEADER */ + 40 /* BITMAPINFOHEADER */; const bool flipY = true; clut(src + imageOffset, palette, (width + 3) & ~3, width, height, bpp, flipY, colorKey, dst); } else { assert(depth == 32 && bpp == 3); const uint8_t *p = src + imageOffset; for (int y = height - 1; y >= 0; --y) { uint8_t *q = dst + y * width * bpp; for (int x = 0; x < width; ++x) { const uint32_t color = READ_LE_UINT32(p); p += 4; *q++ = (color >> 16) & 255; *q++ = (color >> 8) & 255; *q++ = color & 255; } } } *w = width; *h = height; return dst; }
void SoundTowns_Darkmoon::loadSoundFile(Common::String name) { Common::SeekableReadStream *s = _vm->resource()->createReadStream(Common::String::format("%s.SDT", name.c_str())); if (!s) error("Failed to load sound file '%s.SDT'", name.c_str()); for (int i = 0; i < 120; i++) { _soundTable[i].type = s->readSByte(); _soundTable[i].para1 = s->readSint32LE(); _soundTable[i].para2 = s->readSint16LE(); } delete s; uint32 bytesLeft; uint8 *pmb = _vm->resource()->fileData(Common::String::format("%s.PMB", name.c_str()).c_str(), &bytesLeft); _vm->delay(300); if (pmb) { uint8 *src = pmb + 8; for (int i = 0; i < 32; i++) _intf->callback(5, 0x40, i, &src[i << 7]); _intf->callback(35, -1); src += 0x1000; bytesLeft -= 0x1008; while (bytesLeft) { _intf->callback(34, src); uint32 len = READ_LE_UINT16(&src[12]) + 32; src = src + len; bytesLeft -= len; } delete[] pmb; } else { warning("Sound file '%s.PMB' not found.", name.c_str()); // TODO } }
void DSP_Play(const uint8 *data) { uint32 len; uint32 freq; uint32 sampleLen; /* skip Create Voice File header */ data += READ_LE_UINT16(data + 20); /* first byte is Block Type : * 0x00: Terminator * 0x01: Sound data * 0x02: Sound data continuation * 0x03: Silence * 0x04: Marker * 0x05: Text * 0x06: Repeat start * 0x07: Repeat end * 0x08: Extra info * 0x09: Sound data (New format) */ if (*data != 1) return; /* next 3 bytes are block size (not including the 1 block type and * size 4 bytes) */ len = data[1] | (data[2] << 8) | (data[3] << 16); len -= 2; data += 4; /* byte 0 frequency divisor * byte 1 codec id : 0 is "8bits unsigned PCM" * bytes 2..n audio data */ freq = 1000000 / (256 - data[0]); if (data[1] != 0) Warning("Unsupported VOC codec 0x%02x\n", (int)data[1]); sampleLen = DSP_ConvertAudio(freq, data + 2, len); if(sampleLen > 0) { set_dma_sound(s_stRamBuffer, sampleLen); } }
int16 *CompressSword1::uncompressSpeech(Common::File &clu, uint32 idx, uint32 cSize, uint32 *returnSize) { uint32 resSize, srcPos; int16 *srcData, *dstData, *dstPos; uint32 headerPos = 0; int16 length, cnt; uint8 *fBuf = (uint8 *)malloc(cSize); clu.seek(idx, SEEK_SET); clu.read_throwsOnError(fBuf, cSize); while ((READ_BE_UINT32(fBuf + headerPos) != 'data') && (headerPos < 100)) headerPos++; if (headerPos < 100) { resSize = READ_LE_UINT32(fBuf + headerPos + 4) >> 1; srcData = (int16 *)(fBuf + headerPos + 8); dstData = (int16 *)malloc(resSize * 2); srcPos = 0; dstPos = dstData; cSize = (cSize - (headerPos + 8)) / 2; while (srcPos < cSize) { length = (int16)READ_LE_UINT16(srcData + srcPos); srcPos++; if (length < 0) { length = -length; for (cnt = 0; cnt < (uint16)length; cnt++) *dstPos++ = srcData[srcPos]; srcPos++; } else { memcpy(dstPos, srcData + srcPos, length * 2); dstPos += length; srcPos += length; } } free(fBuf); *returnSize = resSize * 2; if (_speechEndianness == UnknownEndian) guessEndianness(dstData, length); return dstData; } else {
void MoviePlayer::copyFrameToBuffer(byte *dst, int dstType, uint x, uint y, uint pitch) { uint h = getHeight(); uint w = getWidth(); const Graphics::Surface *surface = decodeNextFrame(); byte *src = (byte *)surface->pixels; if (hasDirtyPalette()) _vm->setPaletteFromPtr(getPalette(), 256); if (_vm->_game.features & GF_16BIT_COLOR) { dst += y * pitch + x * 2; do { for (uint i = 0; i < w; i++) { uint16 color = READ_LE_UINT16(_vm->_hePalettes + _vm->_hePaletteSlot + 768 + src[i] * 2); switch (dstType) { case kDstScreen: WRITE_UINT16(dst + i * 2, color); break; case kDstResource: WRITE_LE_UINT16(dst + i * 2, color); break; default: error("copyFrameToBuffer: Unknown dstType %d", dstType); } } dst += pitch; src += w; } while (--h); } else { dst += y * pitch + x; do { memcpy(dst, src, w); dst += pitch; src += w; } while (--h); } }
byte *TLib::getSubResource(int resNum, int rlbNum, int index, uint *size, bool suppressErrors) { // Get the specified image set byte *dataIn = getResource(RES_VISAGE, resNum, rlbNum); if (!dataIn) { if (suppressErrors) return NULL; error("Unknown sub resource %d/%d index %d", resNum, rlbNum, index); } int numEntries = READ_LE_UINT16(dataIn); uint32 entryOffset = READ_LE_UINT32(dataIn + 2 + (index - 1) * 4); uint32 nextOffset = (index == numEntries) ? _memoryManager.getSize(dataIn) : READ_LE_UINT32(dataIn + 2 + index * 4); *size = nextOffset - entryOffset; assert(*size < (1024 * 1024)); byte *entry = _memoryManager.allocate2(*size); Common::copy(&dataIn[entryOffset], &dataIn[nextOffset], entry); _memoryManager.deallocate(dataIn); return entry; }
static uint32 readFakeChar(SeekableReadStream &stream, Encoding encoding) { byte data[2]; switch (encoding) { case kEncodingASCII: case kEncodingLatin9: case kEncodingUTF8: case kEncodingCP1250: case kEncodingCP1251: case kEncodingCP1252: case kEncodingCP932: case kEncodingCP936: case kEncodingCP949: case kEncodingCP950: if (stream.read(data, 1) != 1) return 0; return data[0]; case kEncodingUTF16LE: if (stream.read(data, 2) != 2) return 0; return READ_LE_UINT16(data); case kEncodingUTF16BE: if (stream.read(data, 2) != 2) return 0; return READ_BE_UINT16(data); default: break; } return 0; }
void CLUInputStream::refill() { byte *in = _inbuf; int16 *out = _outbuf; _file->seek(_file_pos, SEEK_SET); uint len_left = _file->read(in, MIN((uint32)BUFFER_SIZE, _end_pos - _file->pos())); _file_pos = _file->pos(); while (len_left > 0) { uint16 sample; if (_firstTime) { _firstTime = false; _prev = READ_LE_UINT16(in); sample = _prev; len_left -= 2; in += 2; } else { uint16 delta = GetCompressedAmplitude(*in) << GetCompressedShift(*in); if (GetCompressedSign(*in)) sample = _prev - delta; else sample = _prev + delta; _prev = sample; len_left--; in++; } *out++ = (int16)sample; } _pos = _outbuf; _bufferEnd = out; }
static void decompress_codec3(const char *compressed, char *result) { int bitstr_value = READ_LE_UINT16(compressed); int bitstr_len = 16; compressed += 2; bool bit; for (;;) { GET_BIT; if (bit == 1) *result++ = *compressed++; else { GET_BIT; int copy_len, copy_offset; if (bit == 0) { GET_BIT; copy_len = 2 * bit; GET_BIT; copy_len += bit + 3; copy_offset = *(uint8 *)(compressed++) - 0x100; } else { copy_offset = (*(uint8 *)(compressed) | (*(uint8 *)(compressed + 1) & 0xf0) << 4) - 0x1000; copy_len = (*(uint8 *)(compressed + 1) & 0xf) + 3; compressed += 2; if (copy_len == 3) { copy_len = *(uint8 *)(compressed++) + 1; if (copy_len == 1) return; } } while (copy_len > 0) { *result = result[copy_offset]; result++; copy_len--; } } } }
void KyraRpgEngine::generateTempData() { int l = _currentLevel - 1; if (_lvlTempData[l]) { delete[] _lvlTempData[l]->wallsXorData; delete[] _lvlTempData[l]->flags; releaseMonsterTempData(_lvlTempData[l]); releaseFlyingObjectTempData(_lvlTempData[l]); releaseWallOfForceTempData(_lvlTempData[l]); delete _lvlTempData[l]; } _lvlTempData[l] = new LevelTempData; _lvlTempData[l]->wallsXorData = new uint8[4096]; _lvlTempData[l]->flags = new uint16[1024]; const uint8 *p = getBlockFileData(_currentLevel); uint16 len = READ_LE_UINT16(p + 4); p += 6; memset(_lvlTempData[l]->wallsXorData, 0, 4096); memset(_lvlTempData[l]->flags, 0, 1024 * sizeof(uint16)); uint8 *d = _lvlTempData[l]->wallsXorData; uint16 *df = _lvlTempData[l]->flags; for (int i = 0; i < 1024; i++) { for (int ii = 0; ii < 4; ii++) *d++ = p[i * len + ii] ^ _levelBlockProperties[i].walls[ii]; *df++ = _levelBlockProperties[i].flags; } _lvlTempData[l]->monsters = generateMonsterTempData(_lvlTempData[l]); _lvlTempData[l]->flyingObjects = generateFlyingObjectTempData(_lvlTempData[l]); _lvlTempData[l]->wallsOfForce = generateWallOfForceTempData(_lvlTempData[l]); _hasTempDataFlags |= (1 << l); }
void ToltecsEngine::talk(int16 slotIndex, int16 slotOffset) { byte *scanData = _script->getSlotData(slotIndex) + slotOffset; // If there's another talk text at the requested slot and it's still // active, don't overwrite it. Fixes bug #3600166. if (_screen->isTalkTextActive(slotIndex)) return; while (*scanData < 0xF0) { if (*scanData == 0x19) { scanData++; } else if (*scanData == 0x14) { scanData++; } else if (*scanData == 0x0A) { scanData += 4; } else if (*scanData < 0x0A) { scanData++; } scanData++; } if (*scanData == 0xFE) { if (_doSpeech) { int16 resIndex = READ_LE_UINT16(scanData + 1); debug(0, "ToltecsEngine::talk() playSound(resIndex: %d)", resIndex); _sound->playSpeech(resIndex); } if (_doText) { _screen->updateTalkText(slotIndex, slotOffset, false); } else { _screen->keepTalkTextItemsAlive(); } } else { _screen->updateTalkText(slotIndex, slotOffset, true); } }
void Player_AD::startMusic() { memset(_instrumentOffset, 0, sizeof(_instrumentOffset)); bool hasRhythmData = false; uint instruments = _musicData[10]; for (uint i = 0; i < instruments; ++i) { const int instrIndex = _musicData[11 + i] - 1; if (0 <= instrIndex && instrIndex < 16) { _instrumentOffset[instrIndex] = i * 16 + 16 + 3; hasRhythmData |= (_musicData[_instrumentOffset[instrIndex] + 13] != 0); } } if (hasRhythmData) { _mdvdrState = 0x20; limitHWChannels(6); } else { _mdvdrState = 0; limitHWChannels(9); } _curOffset = 0x93; // TODO: is this the same for Loom? _nextEventTimer = 40; _engineMusicTimer = 0; _internalMusicTimer = 0; _musicTimer = 0; writeReg(0xBD, _mdvdrState); const bool isLoom = (_vm->_game.id == GID_LOOM); _timerLimit = isLoom ? 473 : 256; _musicTicks = _musicData[3] * (isLoom ? 2 : 1); _loopFlag = (_musicData[4] == 0); _musicLoopStart = _curOffset + READ_LE_UINT16(_musicData + 5); }