void PrinceEngine::specialPlotInside(int x, int y) { if (_coords < _coordsBufEnd) { WRITE_LE_UINT16(_coords, x); _coords += 2; WRITE_LE_UINT16(_coords, y); _coords += 2; } }
void AGOSEngine_PN::writeval(uint8 *ptr, int val) { uint8 *savpt = _workptr; int lsav = _linct, a, b, x; _workptr = ptr; _linct = 255; if ((a = readfromline()) < 247) error("writeval: Write to constant (%d)", a); switch (a) { case 249: error("writeval: Write to constant (%d)", a); break; case 250: error("writeval: Write to constant (%d)", a); break; case 251: _variableArray[varval()] = val; break; case 252: b = varval(); _dataBase[_quickptr[0] + b * _quickshort[0] + varval()] = val; break; case 254: b = varval(); _dataBase[_quickptr[3] + b * _quickshort[2] + varval()] = val; break; case 247: b = varval(); x = _quickptr[11] + b * _quickshort[4] + varval() * 2; WRITE_LE_UINT16(_dataBase + x, val); break; case 248: b = varval(); x = _quickptr[12] + b * _quickshort[5] + varval() * 2; WRITE_LE_UINT16(_dataBase + x, val); break; case 253: b = varval(); setbitf((uint32)_quickptr[1] + b * _quickshort[1], varval(), val); break; case 255: b = varval(); setbitf((uint32)_quickptr[4] + b * _quickshort[3], varval(), val); break; default: error("WRITEVAL : undefined evaluation %d", a); } _linct = lsav; _workptr = savpt; }
// will actually patch previously found signature area void Script::applyPatch(const uint16 *patch, byte *scriptData, const uint32 scriptSize, int32 signatureOffset) { byte orgData[PATCH_VALUELIMIT]; int32 offset = signatureOffset; uint16 patchWord = *patch; // Copy over original bytes from script uint32 orgDataSize = scriptSize - offset; if (orgDataSize > PATCH_VALUELIMIT) orgDataSize = PATCH_VALUELIMIT; memcpy(&orgData, &scriptData[offset], orgDataSize); while (patchWord != PATCH_END) { uint16 patchValue = patchWord & PATCH_VALUEMASK; switch (patchWord & PATCH_COMMANDMASK) { case PATCH_ADDTOOFFSET: // add value to offset offset += patchValue & ~PATCH_ADDTOOFFSET; break; case PATCH_GETORIGINALBYTE: // get original byte from script if (patchValue >= orgDataSize) error("patching: can not get requested original byte from script"); scriptData[offset] = orgData[patchValue]; offset++; break; case PATCH_ADJUSTWORD: { // Adjust word right before current position byte *adjustPtr = &scriptData[offset - 2]; uint16 adjustWord = READ_LE_UINT16(adjustPtr); adjustWord += patchValue; WRITE_LE_UINT16(adjustPtr, adjustWord); break; } case PATCH_ADJUSTWORD_NEG: { // Adjust word right before current position (negative way) byte *adjustPtr = &scriptData[offset - 2]; uint16 adjustWord = READ_LE_UINT16(adjustPtr); adjustWord -= patchValue; WRITE_LE_UINT16(adjustPtr, adjustWord); break; } default: scriptData[offset] = patchValue & 0xFF; offset++; } patch++; patchWord = *patch; } }
byte *Sword2Engine::fetchPsxBackground(uint32 location) { Common::File file; PSXScreensEntry header; uint32 screenOffset, dataOffset; uint32 totSize; // Total size of background, counting data, offset table and additional header byte *buffer; if (!file.open("screens.clu")) { GUIErrorMessage("Broken Sword 2: Cannot open screens.clu"); return NULL; } file.seek(location * 4, SEEK_SET); screenOffset = file.readUint32LE(); if (screenOffset == 0) { // We don't have screen data for this location number. file.close(); return NULL; } // Get to the beginning of PSXScreensEntry file.seek(screenOffset + ResHeader::size(), SEEK_SET); buffer = (byte *)malloc(PSXScreensEntry::size()); file.read(buffer, PSXScreensEntry::size()); // Prepare the header header.read(buffer); free(buffer); file.seek(screenOffset + header.bgOffset + 4, SEEK_SET); dataOffset = file.readUint32LE(); file.seek(screenOffset + header.bgOffset, SEEK_SET); totSize = header.bgSize + (dataOffset - header.bgOffset) + 8; buffer = (byte *)malloc(totSize); // Write some informations before background data WRITE_LE_UINT16(buffer, header.bgXres); WRITE_LE_UINT16(buffer + 2, header.bgYres); WRITE_LE_UINT32(buffer + 4, header.bgOffset); file.read(buffer + 8, totSize - 8); // Do not write on the header file.close(); return buffer; }
static void writeFakeChar(std::vector<byte> &output, uint32 c, 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: output.push_back(c); break; case kEncodingUTF16LE: WRITE_LE_UINT16(data, c); output.push_back(data[0]); output.push_back(data[1]); break; case kEncodingUTF16BE: WRITE_BE_UINT16(data, c); output.push_back(data[0]); output.push_back(data[1]); break; default: break; } }
void SoundTowns_Darkmoon::playSoundEffect(uint8 track, uint8 volume) { if (!_sfxEnabled) return; if (volume == 255) return playTrack(track); uint8 *pcm = 0; switch (_soundTable[track].type) { case 0: if (_soundTable[track].para1 == -1 || (uint32)_soundTable[track].para1 > _pcmDataSize) return; pcm = _pcmData + _soundTable[track].para1; WRITE_LE_UINT16(&pcm[24], _soundTable[track].para2 * 98 / 1000); _intf->callback(39, 0x47); _intf->callback(37, 0x47, 60, volume, pcm); break; case 3: _intf->callback(2, _lastEnvChan); _intf->callback(4, _lastEnvChan, _soundTable[track].para1); _intf->callback(1, _lastEnvChan, _soundTable[track].para2, volume); break; default: break; } if (++_lastEnvChan == 0x43) _lastEnvChan = 0x40; }
void Object::setVectorItem(int16 index, int16 value) { if (getClass() == 0x7FFF) { byte *vector = (byte *)getData(); vector[index] = value; } else if (getClass() <= 0x7FFE) { int16 *vector = (int16 *)getData(); WRITE_LE_UINT16(&vector[index], value); } }
void SaveGame::writeLEUint16(uint16 data) { if (!_saving) error("SaveGame::writeBlock called when restoring a savegame"); if (_currentSection == 0) error("Tried to write a block without starting a section"); checkAlloc(2); WRITE_LE_UINT16(&_sectionBuffer[_sectionSize], data); _sectionSize += 2; }
void DecompressorLZW::buildCelHeaders(byte **seeker, byte **writer, int celindex, int *cc_lengths, int max) { for (int c = 0; c < max; c++) { memcpy(*writer, *seeker, 6); *seeker += 6; *writer += 6; int w = *((*seeker)++); WRITE_LE_UINT16(*writer, w); /* Zero extension */ *writer += 2; *writer += cc_lengths[celindex]; celindex++; } }
// following routine creates filled rectangle // immediately as VGA video chunks, in near memory as fast as possible, // especially for text line real time display Bitmap::Bitmap(CGE2Engine *vm, uint16 w, uint16 h, uint8 fill) : _w((w + 3) & ~3), // only full uint32 allowed! _h(h), _map(0), _b(nullptr), _vm(vm) { uint16 dsiz = _w >> 2; // data size (1 plane line size) uint16 lsiz = 2 + dsiz + 2; // uint16 for line header, uint16 for gap uint16 psiz = _h * lsiz; // - last gape, but + plane trailer uint8 *v = new uint8[4 * psiz + _h * sizeof(*_b)];// the same for 4 planes // + room for wash table WRITE_LE_UINT16(v, (kBmpCPY | dsiz)); // data chunk hader memset(v + 2, fill, dsiz); // data bytes WRITE_LE_UINT16(v + lsiz - 2, (kBmpSKP | ((kScrWidth / 4) - dsiz))); // gap // Replicate lines byte *destP; for (destP = v + lsiz; destP < (v + psiz); destP += lsiz) Common::copy(v, v + lsiz, destP); WRITE_LE_UINT16(v + psiz - 2, kBmpEOI); // plane trailer uint16 // Replicate planes for (destP = v + psiz; destP < (v + 4 * psiz); destP += psiz) Common::copy(v, v + psiz, destP); HideDesc *b = (HideDesc *)(v + 4 * psiz); b->_skip = (kScrWidth - _w) >> 2; b->_hide = _w >> 2; // Replicate across the entire table for (HideDesc *hdP = b + 1; hdP < (b + _h); hdP++) *hdP = *b; b->_skip = 0; // fix the first entry _v = v; _b = b; }
void SoundDesc::convToSigned() { if ((_type != SOUND_SND) && (_type != SOUND_WAV)) return; if (!_data || !_dataPtr) return; if (_mixerFlags & Audio::FLAG_16BITS) { byte *data = _dataPtr; for (uint32 i = 0; i < _size; i++, data += 2) WRITE_LE_UINT16(data, READ_LE_UINT16(data) ^ 0x8000); } else for (uint32 i = 0; i < _size; i++) _dataPtr[i] ^= 0x80; }
void SoundTowns_Darkmoon::playTrack(uint8 track) { if (track >= 120 || !_sfxEnabled) return; uint8 *pcm = 0; switch (_soundTable[track].type) { case -1: if (track == 0) haltTrack(); else if (track == 2) beginFadeOut(); break; case 0: if (_soundTable[track].para1 == -1 || (uint32)_soundTable[track].para1 > _pcmDataSize) return; pcm = _pcmData + _soundTable[track].para1; WRITE_LE_UINT16(&pcm[24], _soundTable[track].para2 * 98 / 1000); _intf->callback(39, 0x47); _intf->callback(37, 0x47, 60, track == 11 ? 127 : _pcmVol, pcm); break; case 2: resetTrigger(); g_system->getAudioCDManager()->play(_soundTable[track].para1 - 1, 1, 0, 0); break; case 3: _lastSfxChan ^= 3; _intf->callback(39, _lastSfxChan); _intf->callback(4, _lastSfxChan, _soundTable[track].para1); _intf->callback(1, _lastSfxChan, _soundTable[track].para2, 127); break; default: break; } }
reg_t GfxText16::allocAndFillReferenceRectArray() { uint rectCount = _codeRefRects.size(); if (rectCount) { reg_t rectArray; byte *rectArrayPtr = g_sci->getEngineState()->_segMan->allocDynmem(4 * 2 * (rectCount + 1), "text code reference rects", &rectArray); GfxCoordAdjuster *coordAdjuster = g_sci->_gfxCoordAdjuster; for (uint curRect = 0; curRect < rectCount; curRect++) { coordAdjuster->kernelLocalToGlobal(_codeRefRects[curRect].left, _codeRefRects[curRect].top); coordAdjuster->kernelLocalToGlobal(_codeRefRects[curRect].right, _codeRefRects[curRect].bottom); WRITE_LE_UINT16(rectArrayPtr + 0, _codeRefRects[curRect].left); WRITE_LE_UINT16(rectArrayPtr + 2, _codeRefRects[curRect].top); WRITE_LE_UINT16(rectArrayPtr + 4, _codeRefRects[curRect].right); WRITE_LE_UINT16(rectArrayPtr + 6, _codeRefRects[curRect].bottom); rectArrayPtr += 8; } WRITE_LE_UINT16(rectArrayPtr + 0, 0x7777); WRITE_LE_UINT16(rectArrayPtr + 2, 0x7777); WRITE_LE_UINT16(rectArrayPtr + 4, 0x7777); WRITE_LE_UINT16(rectArrayPtr + 6, 0x7777); return rectArray; } return NULL_REG; }
int16 GameDatabase::setObjectProperty(int16 objectIndex, int16 propertyId, int16 value) { if (objectIndex == 0) return 0; int16 propertyFlag; //int16 *property = findObjectProperty(objectIndex, propertyId, propertyFlag); int16 *property = findObjectPropertyCached(objectIndex, propertyId, propertyFlag); if (property) { if (propertyFlag == 1) { WRITE_LE_UINT16(property, value); } else { warning("GameDatabase::setObjectProperty(%04X, %04X, %04X) Trying to set constant property", objectIndex, propertyId, value); } return value; } else { return 0; } }
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); } }
void DecompressorLZW::reorderPic(byte *src, byte *dest, int dsize) { uint16 view_size, view_start, cdata_size; int i; byte *seeker = src; byte *writer = dest; char viewdata[7]; byte *cdata, *cdata_start; *writer++ = PIC_OP_OPX; *writer++ = PIC_OPX_SET_PALETTE; for (i = 0; i < 256; i++) /* Palette translation map */ *writer++ = i; WRITE_LE_UINT32(writer, 0); /* Palette stamp */ writer += 4; view_size = READ_LE_UINT16(seeker); seeker += 2; view_start = READ_LE_UINT16(seeker); seeker += 2; cdata_size = READ_LE_UINT16(seeker); seeker += 2; memcpy(viewdata, seeker, sizeof(viewdata)); seeker += sizeof(viewdata); memcpy(writer, seeker, 4*256); /* Palette */ seeker += 4*256; writer += 4*256; if (view_start != PAL_SIZE + 2) { /* +2 for the opcode */ memcpy(writer, seeker, view_start-PAL_SIZE-2); seeker += view_start - PAL_SIZE - 2; writer += view_start - PAL_SIZE - 2; } if (dsize != view_start + EXTRA_MAGIC_SIZE + view_size) { memcpy(dest + view_size + view_start + EXTRA_MAGIC_SIZE, seeker, dsize - view_size - view_start - EXTRA_MAGIC_SIZE); seeker += dsize - view_size - view_start - EXTRA_MAGIC_SIZE; } cdata_start = cdata = (byte *)malloc(cdata_size); memcpy(cdata, seeker, cdata_size); seeker += cdata_size; writer = dest + view_start; *writer++ = PIC_OP_OPX; *writer++ = PIC_OPX_EMBEDDED_VIEW; *writer++ = 0; *writer++ = 0; *writer++ = 0; WRITE_LE_UINT16(writer, view_size + 8); writer += 2; memcpy(writer, viewdata, sizeof(viewdata)); writer += sizeof(viewdata); *writer++ = 0; decodeRLE(&seeker, &cdata, writer, view_size); free(cdata_start); }
void WRITE_SCI11ENDIAN_UINT16(void *ptr, uint16 val) { if (g_sci->getPlatform() == Common::kPlatformMacintosh && getSciVersion() >= SCI_VERSION_1_1) WRITE_BE_UINT16(ptr, val); else WRITE_LE_UINT16(ptr, val); }
void DecompressorLZW::reorderView(byte *src, byte *dest) { byte *cellengths; int loopheaders; int lh_present; int lh_mask; int pal_offset; int cel_total; int unknown; byte *seeker = src; char celcounts[100]; byte *writer = dest; byte *lh_ptr; byte *rle_ptr, *pix_ptr; int l, lb, c, celindex, lh_last = -1; int chptr; int w; int *cc_lengths; byte **cc_pos; /* Parse the main header */ cellengths = src + READ_LE_UINT16(seeker) + 2; seeker += 2; loopheaders = *seeker++; lh_present = *seeker++; lh_mask = READ_LE_UINT16(seeker); seeker += 2; unknown = READ_LE_UINT16(seeker); seeker += 2; pal_offset = READ_LE_UINT16(seeker); seeker += 2; cel_total = READ_LE_UINT16(seeker); seeker += 2; cc_pos = (byte **) malloc(sizeof(byte *) * cel_total); cc_lengths = (int *) malloc(sizeof(int) * cel_total); for (c = 0; c < cel_total; c++) cc_lengths[c] = READ_LE_UINT16(cellengths + 2 * c); *writer++ = loopheaders; *writer++ = VIEW_HEADER_COLORS_8BIT; WRITE_LE_UINT16(writer, lh_mask); writer += 2; WRITE_LE_UINT16(writer, unknown); writer += 2; WRITE_LE_UINT16(writer, pal_offset); writer += 2; lh_ptr = writer; writer += 2 * loopheaders; /* Make room for the loop offset table */ pix_ptr = writer; memcpy(celcounts, seeker, lh_present); seeker += lh_present; lb = 1; celindex = 0; rle_ptr = pix_ptr = cellengths + (2 * cel_total); w = 0; for (l = 0; l < loopheaders; l++) { if (lh_mask & lb) { /* The loop is _not_ present */ if (lh_last == -1) { warning("Error: While reordering view: Loop not present, but can't re-use last loop"); lh_last = 0; } WRITE_LE_UINT16(lh_ptr, lh_last); lh_ptr += 2; } else { lh_last = writer - dest; WRITE_LE_UINT16(lh_ptr, lh_last); lh_ptr += 2; WRITE_LE_UINT16(writer, celcounts[w]); writer += 2; WRITE_LE_UINT16(writer, 0); writer += 2; /* Now, build the cel offset table */ chptr = (writer - dest) + (2 * celcounts[w]); for (c = 0; c < celcounts[w]; c++) { WRITE_LE_UINT16(writer, chptr); writer += 2; cc_pos[celindex+c] = dest + chptr; chptr += 8 + READ_LE_UINT16(cellengths + 2 * (celindex + c)); } buildCelHeaders(&seeker, &writer, celindex, cc_lengths, celcounts[w]); celindex += celcounts[w]; w++; } lb = lb << 1; } if (celindex < cel_total) { warning("View decompression generated too few (%d / %d) headers", celindex, cel_total); return; } /* Figure out where the pixel data begins. */ for (c = 0; c < cel_total; c++) pix_ptr += getRLEsize(pix_ptr, cc_lengths[c]); rle_ptr = cellengths + (2 * cel_total); for (c = 0; c < cel_total; c++) decodeRLE(&rle_ptr, &pix_ptr, cc_pos[c] + 8, cc_lengths[c]); if (pal_offset) { *writer++ = 'P'; *writer++ = 'A'; *writer++ = 'L'; for (c = 0; c < 256; c++) *writer++ = c; seeker -= 4; /* The missing four. Don't ask why. */ memcpy(writer, seeker, 4*256 + 4); } free(cc_pos); free(cc_lengths); }
void GameDatabase::setVar(int16 index, int16 value) { WRITE_LE_UINT16(_gameState + index * 2, value); }
void ScriptInterpreter::pushInt16(int16 value) { WRITE_LE_UINT16(_stack + _regs.sp, value); _regs.sp -= 2; }
void ScriptInterpreter::localWrite16(int16 offset, int16 value) { //debug(1, "localWrite16(%d, %d)", offset, value); WRITE_LE_UINT16(&_localData[offset], value); }
reg_t GfxText32::createTextBitmap(reg_t textObject, uint16 maxWidth, uint16 maxHeight, reg_t prevHunk) { reg_t stringObject = readSelector(_segMan, textObject, SELECTOR(text)); // The object in the text selector of the item can be either a raw string // or a Str object. In the latter case, we need to access the object's data // selector to get the raw string. if (_segMan->isHeapObject(stringObject)) stringObject = readSelector(_segMan, stringObject, SELECTOR(data)); Common::String text = _segMan->getString(stringObject); // HACK: The character offsets of the up and down arrow buttons are off by one // in GK1, for some unknown reason. Fix them here. if (text.size() == 1 && (text[0] == 29 || text[0] == 30)) { text.setChar(text[0] + 1, 0); } GuiResourceId fontId = readSelectorValue(_segMan, textObject, SELECTOR(font)); GfxFont *font = _cache->getFont(fontId); bool dimmed = readSelectorValue(_segMan, textObject, SELECTOR(dimmed)); int16 alignment = readSelectorValue(_segMan, textObject, SELECTOR(mode)); uint16 foreColor = readSelectorValue(_segMan, textObject, SELECTOR(fore)); uint16 backColor = readSelectorValue(_segMan, textObject, SELECTOR(back)); Common::Rect nsRect = g_sci->_gfxCompare->getNSRect(textObject); uint16 width = nsRect.width() + 1; uint16 height = nsRect.height() + 1; // Limit rectangle dimensions, if requested if (maxWidth > 0) width = maxWidth; if (maxHeight > 0) height = maxHeight; // Upscale the coordinates/width if the fonts are already upscaled if (_screen->fontIsUpscaled()) { width = width * _screen->getDisplayWidth() / _screen->getWidth(); height = height * _screen->getDisplayHeight() / _screen->getHeight(); } int entrySize = width * height + BITMAP_HEADER_SIZE; reg_t memoryId = NULL_REG; if (prevHunk.isNull()) { memoryId = _segMan->allocateHunkEntry("TextBitmap()", entrySize); writeSelector(_segMan, textObject, SELECTOR(bitmap), memoryId); } else { memoryId = prevHunk; } byte *memoryPtr = _segMan->getHunkPointer(memoryId); if (prevHunk.isNull()) memset(memoryPtr, 0, BITMAP_HEADER_SIZE); byte *bitmap = memoryPtr + BITMAP_HEADER_SIZE; memset(bitmap, backColor, width * height); // Save totalWidth, totalHeight WRITE_LE_UINT16(memoryPtr, width); WRITE_LE_UINT16(memoryPtr + 2, height); int16 charCount = 0; uint16 curX = 0, curY = 0; const char *txt = text.c_str(); int16 textWidth, textHeight, totalHeight = 0, offsetX = 0, offsetY = 0; uint16 start = 0; // Calculate total text height while (*txt) { charCount = GetLongest(txt, width, font); if (charCount == 0) break; Width(txt, 0, (int16)strlen(txt), fontId, textWidth, textHeight, true); totalHeight += textHeight; txt += charCount; while (*txt == ' ') txt++; // skip over breaking spaces } txt = text.c_str(); // Draw text in buffer while (*txt) { charCount = GetLongest(txt, width, font); if (charCount == 0) break; Width(txt, start, charCount, fontId, textWidth, textHeight, true); switch (alignment) { case SCI_TEXT32_ALIGNMENT_RIGHT: offsetX = width - textWidth; break; case SCI_TEXT32_ALIGNMENT_CENTER: // Center text both horizontally and vertically offsetX = (width - textWidth) / 2; offsetY = (height - totalHeight) / 2; break; case SCI_TEXT32_ALIGNMENT_LEFT: offsetX = 0; break; default: warning("Invalid alignment %d used in TextBox()", alignment); } for (int i = 0; i < charCount; i++) { unsigned char curChar = txt[i]; font->drawToBuffer(curChar, curY + offsetY, curX + offsetX, foreColor, dimmed, bitmap, width, height); curX += font->getCharWidth(curChar); } curX = 0; curY += font->getHeight(); txt += charCount; while (*txt == ' ') txt++; // skip over breaking spaces } return memoryId; }
void writeUint16(FILE *file, uint16_t value) { char v[2]; WRITE_LE_UINT16(&v, value); fwrite(&v, 1, 2, file); }
// Box void FontManager::box(int idx, int messageId, const Common::String &filename, int xp, int yp) { int textPosX = xp; if (idx < 0) error("Bad number for text"); _fontFixedWidth = 11; _boxWidth = 11 * _text[idx]._length; if (_text[idx]._textLoadedFl) { int textType = _text[idx]._textType; if (textType != 6 && textType != 1 && textType != 3 && textType != 5) { int yCurrent = yp + 5; for (int lineNum = 0; lineNum < _text[idx]._lineCount; ++lineNum) { displayText(xp + 5, yCurrent, _text[idx]._lines[lineNum], _text[idx]._color); yCurrent += _fontFixedHeight + 1; } } else { int height = _text[idx]._height; int width = _text[idx]._width; _vm->_graphicsMan->restoreSurfaceRect( _vm->_graphicsMan->_frontBuffer, _text[idx]._textBlock, xp, yp, _text[idx]._width, _text[idx]._height); _vm->_graphicsMan->addDirtyRect(xp, yp, xp + width, yp + height); } } else { int lineCount = 0; for (int i = 0; i <= 19; i++) _textSortArray[i] = 0; _text[idx]._textLoadedFl = true; Common::String file = filename; if (strncmp(file.c_str(), _oldName.c_str(), strlen(file.c_str())) != 0) { // Starting to access a new file, so read in the index file for the file _oldName = file; _indexName = Common::String(file.c_str(), file.size() - 3); _indexName += "IND"; Common::File f; if (!f.open(_indexName)) error("Error opening file - %s", _indexName.c_str()); int filesize = f.size(); for (int i = 0; i < (filesize / 4); ++i) _index[i] = f.readUint32LE(); f.close(); } int bufSize; if (filename[0] != 'Z' || filename[1] != 'O') { Common::File f; if (!f.open(file)) error("Error opening file - %s", _indexName.c_str()); bufSize = 2048; f.seek(_index[messageId]); _tempText = _vm->_globals->allocMemory(2058); if (_tempText == NULL) error("Error allocating text"); Common::fill(&_tempText[0], &_tempText[2058], 0); f.read(_tempText, 2048); f.close(); } else { bufSize = 100; _tempText = _vm->_globals->allocMemory(110); Common::fill(&_tempText[0], &_tempText[110], 0); memcpy(_tempText, _zoneText + _index[messageId], 96); WRITE_LE_UINT16((uint16 *)_tempText + 48, READ_LE_INT16(_zoneText + _index[messageId] + 96)); } byte *curTempTextPtr = _tempText; for (int i = 0; i < bufSize; i++) { byte curChar = *curTempTextPtr; if ((byte)(*curTempTextPtr + 46) > 27) { if ((byte)(curChar + 80) > 27) { if ((byte)(curChar - 65) <= 25 || (byte)(curChar - 97) <= 25) curChar = 32; } else { curChar -= 79; } } else { curChar += 111; } *curTempTextPtr = curChar; curTempTextPtr++; }; int textLength; for (textLength = 0; textLength < bufSize; textLength++) { byte curChar = _tempText[textLength]; if (curChar == '\r' || curChar == '\n') { _tempText[textLength] = 0; if (!_text[idx]._length) break; } } if (bufSize && bufSize > textLength) { _text[idx]._length = textLength; _boxWidth = 0; for (int curStrIdx = 0; curStrIdx < textLength + 1; curStrIdx++) { byte curChar = _tempText[curStrIdx]; if (curChar <= 31) curChar = ' '; _boxWidth += _vm->_objectsMan->getWidth(_font, curChar - 32); } _boxWidth += 2; _text[idx]._pos.x = 320 - abs(_boxWidth / 2); textPosX = _vm->_events->_startPos.x + _text[idx]._pos.x; lineCount = 1; _text[idx]._lines[0] = Common::String((const char *)_tempText, textLength); } else { if (!_boxWidth) _boxWidth = 240; int tempTextIdx = 0; int lineSize; byte curChar; do { int curLineSize = 0; int ptrb = _boxWidth - 4; for (;;) { lineSize = curLineSize; do { curChar = _tempText[tempTextIdx + curLineSize++]; } while (curChar != ' ' && curChar != '%'); if (curLineSize >= ptrb / _fontFixedWidth) { if (curChar == '%') curChar = ' '; break; } if (curChar == '%') { lineSize = curLineSize; break; } } // WORKAROUND: Perhaps due to the usage of ScummVM strings here, recalculate what the // actual length of the line to be copied will be. Otherwise, you can see artifacts, // such as a single character beyond the end of string NULL. int actualSize = 0; while (actualSize < lineSize && _tempText[tempTextIdx + actualSize]) ++actualSize; _text[idx]._lines[lineCount] = Common::String((const char *)_tempText + tempTextIdx, actualSize); _textSortArray[lineCount++] = lineSize; tempTextIdx += lineSize; } while (curChar != '%'); for (int i = 0; i <= 19; i++) { if (_textSortArray[i] <= 0) { _textSortArray[i] = 0; } else { int ptrc = 0; for (int curIdx = 0; curIdx < _textSortArray[i] - 1; curIdx++) { Common::String &line = _text[idx]._lines[i]; byte curChar2 = (curIdx >= (int)line.size()) ? '\0' : line.c_str()[curIdx]; if (curChar2 <= 31) curChar2 = ' '; ptrc += _vm->_objectsMan->getWidth(_font, (byte)curChar2 - 32); } _textSortArray[i] = ptrc; } } for (int i = 0; i <= 19; i++) { for (int j = i + 1; j != i; j = (j + 1) % 20) { if (_textSortArray[i] < _textSortArray[j]) _textSortArray[i] = 0; } }; for (int i = 0; i <= 19; i++) { if (_textSortArray[i]) _boxWidth = _textSortArray[i]; } if ((_text[idx]._textType < 2) || (_text[idx]._textType > 3)) { int i; for (i = xp - _vm->_events->_startPos.x; _boxWidth + i > 638 && i > -2 && _text[idx]._textType; i -= 2) ; _text[idx]._pos.x = i; textPosX = _vm->_events->_startPos.x + i; } else { _text[idx]._pos.x = textPosX; } } int posX = textPosX; int posY = yp; int saveWidth = _boxWidth + 10; int saveHeight = (_fontFixedHeight + 1) * lineCount + 12; if (_text[idx]._textType == 6) { _text[idx]._pos.x = 315 - abs(saveWidth / 2); textPosX = posX = _vm->_events->_startPos.x + _text[idx]._pos.x; _text[idx]._pos.y = posY = 50; } int textType = _text[idx]._textType; if (textType == 1 || textType == 3 || textType == 5 || textType == 6) { int size = saveHeight * saveWidth; byte *ptrd = _vm->_globals->allocMemory(size); if (ptrd == NULL) error("Cutting a block for text box (%d)", size); _vm->_graphicsMan->copySurfaceRect(_vm->_graphicsMan->_frontBuffer, ptrd, posX, posY, saveWidth, saveHeight); _vm->_graphicsMan->fillSurface(ptrd, _vm->_graphicsMan->_colorTable, size); _vm->_graphicsMan->restoreSurfaceRect(_vm->_graphicsMan->_frontBuffer, ptrd, posX, posY, saveWidth, saveHeight); _vm->_globals->freeMemory(ptrd); _vm->_graphicsMan->drawHorizontalLine(_vm->_graphicsMan->_frontBuffer, posX, posY, saveWidth, (byte)-2); _vm->_graphicsMan->drawHorizontalLine(_vm->_graphicsMan->_frontBuffer, posX, saveHeight + posY, saveWidth, (byte)-2); _vm->_graphicsMan->drawVerticalLine(_vm->_graphicsMan->_frontBuffer, posX, posY, saveHeight, (byte)-2); _vm->_graphicsMan->drawVerticalLine(_vm->_graphicsMan->_frontBuffer, saveWidth + posX, posY, saveHeight, (byte)-2); } _text[idx]._lineCount = lineCount; int textPosY = posY + 5; for (int lineNum = 0; lineNum < lineCount; ++lineNum) { displayText(textPosX + 5, textPosY, _text[idx]._lines[lineNum], _text[idx]._color); textPosY += _fontFixedHeight + 1; } int blockWidth = saveWidth + 1; int blockHeight = saveHeight + 1; _text[idx]._width = blockWidth; _text[idx]._height = blockHeight; textType = _text[idx]._textType; if (textType == 6 || textType == 1 || textType == 3 || textType == 5) { _text[idx]._textBlock = _vm->_globals->freeMemory(_text[idx]._textBlock); int blockSize = blockHeight * blockWidth; byte *ptre = _vm->_globals->allocMemory(blockSize + 20); if (ptre == NULL) error("Cutting a block for text box (%d)", blockSize); _text[idx]._textBlock = ptre; _text[idx]._width = blockWidth; _text[idx]._height = blockHeight; _vm->_graphicsMan->copySurfaceRect(_vm->_graphicsMan->_frontBuffer, _text[idx]._textBlock, posX, posY, _text[idx]._width, blockHeight); } _tempText = _vm->_globals->freeMemory(_tempText); } }
void Memory::writeUint16(int seg, uint16_t offset, uint16_t value) { uint8_t *p = (uint8_t *)getPtr(seg, offset); if (_debug) fprintf(stdout, "Memory::writeUint16 %X\n", value); WRITE_LE_UINT16(p, value); }
byte *Sword2Engine::fetchPsxParallax(uint32 location, uint8 level) { Common::File file; PSXScreensEntry header; uint32 screenOffset; uint16 horTiles; // Number of horizontal tiles in the parallax grid uint16 verTiles; // Number of vertical tiles in parallax grid uint32 totSize; // Total size of parallax, counting data, grid, and additional header byte *buffer; uint16 plxXres; uint16 plxYres; uint32 plxOffset; uint32 plxSize; if (level > 1) return NULL; if (!file.open("screens.clu")) { GUIErrorMessage("Broken Sword 2: Cannot open screens.clu"); return NULL; } file.seek(location * 4, SEEK_SET); screenOffset = file.readUint32LE(); if (screenOffset == 0) // There is no screen here return NULL; // Get to the beginning of PSXScreensEntry file.seek(screenOffset + ResHeader::size(), SEEK_SET); buffer = (byte *)malloc(PSXScreensEntry::size()); file.read(buffer, PSXScreensEntry::size()); // Initialize the header header.read(buffer); free(buffer); // We are fetching... if (level == 0) { // a background parallax plxXres = header.bgPlxXres; plxYres = header.bgPlxYres; plxOffset = header.bgPlxOffset; plxSize = header.bgPlxSize; } else { // a foreground parallax plxXres = header.fgPlxXres; plxYres = header.fgPlxYres; plxOffset = header.fgPlxOffset; plxSize = header.fgPlxSize; } if (plxXres == 0 || plxYres == 0 || plxSize == 0) // This screen has no parallax data. return NULL; debug(2, "fetchPsxParallax() -> %s parallax, xRes: %u, yRes: %u", (level == 0) ? "Background" : "Foreground", plxXres, plxYres); // Calculate the number of tiles which compose the parallax grid. horTiles = plxXres % 64 ? (plxXres / 64) + 1 : plxXres / 64; verTiles = plxYres % 16 ? (plxYres / 16) + 1 : plxYres / 16; totSize = plxSize + horTiles * verTiles * 4 + 8; file.seek(screenOffset + plxOffset, SEEK_SET); buffer = (byte *)malloc(totSize); // Insert parallax resolution information in the buffer, // preceding parallax data. WRITE_LE_UINT16(buffer, plxXres); WRITE_LE_UINT16(buffer + 2, plxYres); WRITE_LE_UINT16(buffer + 4, horTiles); WRITE_LE_UINT16(buffer + 6, verTiles); // Read parallax data from file and store it inside the buffer, // skipping the generated header. file.read(buffer + 8, totSize - 8); file.close(); return buffer; }
void rec_bytecode(TProtoFunc* func, int* inst) { int n_op = num_opcodes(func); int i, newsize; Opcode *opcode_list = luaM_newvector(n_op, Opcode); Byte* p = func->code; //Change const index i = 0; newsize = 0; while (1) { p += INFO(func, p, &opcode_list[i]); Opcode &op = opcode_list[i]; //Change const index, if needed if (op.op_class == PUSHCONSTANT || op.op_class == GETGLOBAL || op.op_class == SETGLOBAL || op.op_class == GETDOTTED || op.op_class == PUSHSELF) if (op.arg != inst[op.arg]) { op.arg = inst[op.arg]; fix_op(&op); } newsize += op.size; ++i; if (op.op == ENDCODE) break; } luaM_free(func->code); Byte *code = (Byte*)luaM_malloc(newsize); func->code = code; //Compile bytecode Byte out[4]; //Out stacksize and arguments number code[0] = (byte)opcode_list[0].arg; if (opcode_list[1].op == VARARGS) code[1] = (byte)opcode_list[1].arg + ZEROVARARG; else code[1] = (byte)opcode_list[1].arg; code += 2; for (i = 2; i < n_op; ++i) { Opcode &op = opcode_list[i]; //Out opcode out[0] = (byte)op.op; //Out args if (op.op == SETLIST || op.op == CLOSURE || op.op == CALLFUNC) { out[1] = (byte)op.arg; out[2] = (byte)op.arg2; } else if (op.size == 2) out[1] = (byte)op.arg; else if (op.size >= 3) WRITE_LE_UINT16(out + 1, op.arg); if (op.op == SETLISTW) out[3] = (byte)op.arg2; memcpy(code, out, op.size); code += op.size; } luaM_free(opcode_list); }
void ToltecsEngine::walk(byte *walkData) { int16 xdelta, ydelta, v8, v10, v11; int16 xstep, ystep; ScriptWalk walkInfo; walkInfo.y = READ_LE_UINT16(walkData + 0); walkInfo.x = READ_LE_UINT16(walkData + 2); walkInfo.y1 = READ_LE_UINT16(walkData + 4); walkInfo.x1 = READ_LE_UINT16(walkData + 6); walkInfo.y2 = READ_LE_UINT16(walkData + 8); walkInfo.x2 = READ_LE_UINT16(walkData + 10); walkInfo.yerror = READ_LE_UINT16(walkData + 12); walkInfo.xerror = READ_LE_UINT16(walkData + 14); walkInfo.mulValue = READ_LE_UINT16(walkData + 16); walkInfo.scaling = READ_LE_UINT16(walkData + 18); walkInfo.scaling = -_segmap->getScalingAtPoint(walkInfo.x, walkInfo.y); if (walkInfo.y1 < walkInfo.y2) ystep = -1; else ystep = 1; ydelta = ABS(walkInfo.y1 - walkInfo.y2) * _walkSpeedY; if (walkInfo.x1 < walkInfo.x2) xstep = -1; else xstep = 1; xdelta = ABS(walkInfo.x1 - walkInfo.x2) * _walkSpeedX; debug(0, "ToltecsEngine::walk() xdelta = %d; ydelta = %d", xdelta, ydelta); if (xdelta > ydelta) SWAP(xdelta, ydelta); v8 = 100 * xdelta; if (v8 != 0) { if (walkInfo.scaling > 0) v8 -= v8 * ABS(walkInfo.scaling) / 100; else v8 += v8 * ABS(walkInfo.scaling) / 100; if (ydelta != 0) v8 /= ydelta; } if (ydelta > ABS(walkInfo.x1 - walkInfo.x2) * _walkSpeedX) { v10 = 100 - walkInfo.scaling; v11 = v8; } else { v10 = v8; v11 = 100 - walkInfo.scaling; } walkInfo.yerror += walkInfo.mulValue * v10; while (walkInfo.yerror >= 100 * _walkSpeedY) { walkInfo.yerror -= 100 * _walkSpeedY; if (walkInfo.y == walkInfo.y1) { walkInfo.x = walkInfo.x1; break; } walkInfo.y += ystep; } walkInfo.xerror += walkInfo.mulValue * v11; while (walkInfo.xerror >= 100 * _walkSpeedX) { walkInfo.xerror -= 100 * _walkSpeedX; if (walkInfo.x == walkInfo.x1) { walkInfo.y = walkInfo.y1; break; } walkInfo.x += xstep; } WRITE_LE_UINT16(walkData + 0, walkInfo.y); WRITE_LE_UINT16(walkData + 2, walkInfo.x); WRITE_LE_UINT16(walkData + 4, walkInfo.y1); WRITE_LE_UINT16(walkData + 6, walkInfo.x1); WRITE_LE_UINT16(walkData + 8, walkInfo.y2); WRITE_LE_UINT16(walkData + 10, walkInfo.x2); WRITE_LE_UINT16(walkData + 12, walkInfo.yerror); WRITE_LE_UINT16(walkData + 14, walkInfo.xerror); WRITE_LE_UINT16(walkData + 16, walkInfo.mulValue); WRITE_LE_UINT16(walkData + 18, walkInfo.scaling); }
void WRITE_SCIENDIAN_UINT16(void *ptr, uint16 val) { if (g_sci->isBE()) WRITE_BE_UINT16(ptr, val); else WRITE_LE_UINT16(ptr, val); }
BitmapPtr Bitmap::code(uint8 *map) { if (!map) return nullptr; uint16 cnt; if (_v) { // old X-map exists, so remove it delete[] _v; _v = nullptr; } while (true) { // at most 2 times: for (V == NULL) & for allocated block; uint8 *im = _v + 2; uint16 *cp = (uint16 *) _v; if (_v) { // 2nd pass - fill the hide table for (uint i = 0; i < _h; i++) { _b[i]._skip = 0xFFFF; _b[i]._hide = 0x0000; } } for (int bpl = 0; bpl < 4; bpl++) { // once per each bitplane uint8 *bm = map; bool skip = (bm[bpl] == kPixelTransp); uint16 j; cnt = 0; for (uint i = 0; i < _h; i++) { // once per each line uint8 pix; for (j = bpl; j < _w; j += 4) { pix = bm[j]; if (_v && (pix != kPixelTransp)) { if (j < _b[i]._skip) _b[i]._skip = j; if (j >= _b[i]._hide) _b[i]._hide = j + 1; } if (((pix == kPixelTransp) != skip) || (cnt >= 0x3FF0)) { // end of block cnt |= (skip) ? kBmpSKP : kBmpCPY; if (_v) WRITE_LE_UINT16(cp, cnt); // store block description uint16 cp = (uint16 *) im; im += 2; skip = (pix == kPixelTransp); cnt = 0; } if (!skip) { if (_v) *im = pix; im++; } cnt++; } bm += _w; if (_w < kScrWidth) { if (skip) cnt += (kScrWidth - j + 3) / 4; else { cnt |= kBmpCPY; if (_v) WRITE_LE_UINT16(cp, cnt); cp = (uint16 *) im; im += 2; skip = true; cnt = (kScrWidth - j + 3) / 4; } } } if (cnt && ! skip) { cnt |= kBmpCPY; if (_v) WRITE_LE_UINT16(cp, cnt); cp = (uint16 *) im; im += 2; } if (_v) WRITE_LE_UINT16(cp, kBmpEOI); cp = (uint16 *) im; im += 2; } if (_v) break; uint16 sizV = (uint16)(im - 2 - _v); _v = new uint8[sizV + _h * sizeof(*_b)]; _b = (HideDesc *)(_v + sizV); } cnt = 0; for (uint i = 0; i < _h; i++) { if (_b[i]._skip == 0xFFFF) { // whole line is skipped _b[i]._skip = (cnt + kScrWidth) >> 2; cnt = 0; } else {