void MacText::render(int from, int to) { reallocSurface(); from = MAX<int>(0, from); to = MIN<int>(to, _textLines.size() - 1); // Clear the screen _surface->fillRect(Common::Rect(0, _textLines[from].y, _surface->w, _textLines[to].y + getLineHeight(to)), _bgcolor); for (int i = from; i <= to; i++) { int xOffset = 0; if (_textAlignment == kTextAlignRight) xOffset = _textMaxWidth - getLineWidth(i); else if (_textAlignment == kTextAlignCenter) xOffset = (_textMaxWidth / 2) - (getLineWidth(i) / 2); // TODO: _textMaxWidth, when -1, was not rendering ANY text. for (uint j = 0; j < _textLines[i].chunks.size(); j++) { if (_textLines[i].chunks[j].text.empty()) continue; _textLines[i].chunks[j].getFont()->drawString(_surface, _textLines[i].chunks[j].text, xOffset, _textLines[i].y, _maxWidth, _fgcolor); xOffset += _textLines[i].chunks[j].getFont()->getStringWidth(_textLines[i].chunks[j].text); } } for (uint i = 0; i < _textLines.size(); i++) { debugN(4, "%2d ", i); for (uint j = 0; j < _textLines[i].chunks.size(); j++) debugN(4, "[%d (%d)] \"%s\" ", _textLines[i].chunks[j].fontId, _textLines[i].chunks[j].textSlant, _textLines[i].chunks[j].text.c_str()); debug(4, "%s", ""); } }
void ParseRuleList::print() const { const ParseRuleList *list = this; int pos = 0; while (list) { debugN("R%03d: ", pos); vocab_print_rule(list->rule); debugN("\n"); list = list->next; pos++; } debugN("%d rules total.\n", pos); }
static void kernelSignatureDebugType(const uint16 type) { bool firstPrint = true; const SignatureDebugType *list = signatureDebugTypeList; while (list->typeCheck) { if (type & list->typeCheck) { if (!firstPrint) debugN(", "); debugN("%s", list->text); firstPrint = false; } list++; } }
void RivenSwitchCommand::dump(byte tabs) { Common::String varName = _vm->getStack()->getName(kVariableNames, _variableId); printTabs(tabs); debugN("switch (%s) {\n", varName.c_str()); for (uint16 j = 0; j < _branches.size(); j++) { printTabs(tabs + 1); if (_branches[j].value == 0xFFFF) debugN("default:\n"); else debugN("case %d:\n", _branches[j].value); _branches[j].script->dumpScript(tabs + 2); printTabs(tabs + 2); debugN("break;\n"); } printTabs(tabs); debugN("}\n"); }
// edit list atom int QuickTimeParser::readELST(Atom atom) { Track *track = _tracks.back(); _fd->readByte(); // version _fd->readByte(); _fd->readByte(); _fd->readByte(); // flags track->editCount = _fd->readUint32BE(); track->editList = new EditListEntry[track->editCount]; debug(2, "Track %d edit list count: %d", _tracks.size() - 1, track->editCount); uint32 offset = 0; for (uint32 i = 0; i < track->editCount; i++){ track->editList[i].trackDuration = _fd->readUint32BE(); track->editList[i].mediaTime = _fd->readSint32BE(); track->editList[i].mediaRate = Rational(_fd->readUint32BE(), 0x10000); track->editList[i].timeOffset = offset; debugN(3, "\tDuration = %d (Offset = %d), Media Time = %d, ", track->editList[i].trackDuration, offset, track->editList[i].mediaTime); track->editList[i].mediaRate.debugPrint(3, "Media Rate ="); offset += track->editList[i].trackDuration; } return 0; }
Vga::~Vga() { _mono = 0; Common::String buffer = ""; /* clear(0); setMode(_oldMode); setColors(); restoreScreen(_oldScreen); sunrise(_oldColors); */ free(_oldColors); free(_newColors); if (_msg) buffer = Common::String(_msg); if (_name) buffer = buffer + " [" + _name + "]"; debugN("%s", buffer.c_str()); delete _showQ; delete _spareQ; delete[] _sysPal; for (int idx = 0; idx < 4; idx++) { _page[idx]->free(); delete _page[idx]; } }
Vga::Vga() : _frmCnt(0), _msg(NULL), _name(NULL), _setPal(false), _mono(0) { _oldColors = NULL; _newColors = NULL; _showQ = new Queue(true); _spareQ = new Queue(false); _sysPal = new Dac[kPalCount]; for (int idx = 0; idx < 4; idx++) { _page[idx] = new Graphics::Surface(); _page[idx]->create(320, 200, Graphics::PixelFormat::createFormatCLUT8()); } #if 0 // This part was used to display credits at the beginning of the game for (int i = 10; i < 20; i++) { char *text = _text->getText(i); if (text) { debugN(1, "%s\n", text); } } #endif _oldColors = (Dac *)malloc(sizeof(Dac) * kPalCount); _newColors = (Dac *)malloc(sizeof(Dac) * kPalCount); getColors(_oldColors); sunset(); setColors(); clear(0); }
static int _vbpt_write_subexpression(ParseTreeNode *nodes, int *pos, ParseRule *rule, uint rulepos, int writepos) { uint token; while ((token = ((rulepos < rule->_data.size()) ? rule->_data[rulepos++] : TOKEN_CPAREN)) != TOKEN_CPAREN) { uint nexttoken = (rulepos < rule->_data.size()) ? rule->_data[rulepos] : TOKEN_CPAREN; if (token == TOKEN_OPAREN) { int writepos2 = _vbpt_pareno(nodes, pos, writepos); rulepos = _vbpt_write_subexpression(nodes, pos, rule, rulepos, writepos2); nexttoken = (rulepos < rule->_data.size()) ? rule->_data[rulepos] : TOKEN_CPAREN; if (nexttoken != TOKEN_CPAREN) writepos = _vbpt_parenc(nodes, pos, writepos); } else if (token & TOKEN_STUFFING_LEAF) { if (nexttoken == TOKEN_CPAREN) writepos = _vbpt_terminate(nodes, pos, writepos, token & 0xffff); else writepos = _vbpt_append(nodes, pos, writepos, token & 0xffff); } else if (token & TOKEN_STUFFING_WORD) { if (nexttoken == TOKEN_CPAREN) writepos = _vbpt_terminate_word(nodes, pos, writepos, token & 0xffff); else writepos = _vbpt_append_word(nodes, pos, writepos, token & 0xffff); } else { warning("\nError in parser (grammar.cpp, _vbpt_write_subexpression()): Rule data broken in rule "); vocab_print_rule(rule); debugN(", at token position %d\n", *pos); return rulepos; } } return rulepos; }
int PrintDebug(void* theEnv, char* logicalName, char* str) { //this is the bottom so we don't pass the information on //prevent exploits by using format strings debugN("%s",str); return 1; }
// edit list atom int QuickTimeDecoder::readELST(MOVatom atom) { MOVStreamContext *st = _streams[_numStreams - 1]; _fd->readByte(); // version _fd->readByte(); _fd->readByte(); _fd->readByte(); // flags st->editCount = _fd->readUint32BE(); st->editList = new EditListEntry[st->editCount]; debug(2, "Track %d edit list count: %d", _numStreams - 1, st->editCount); for (uint32 i = 0; i < st->editCount; i++) { st->editList[i].trackDuration = _fd->readUint32BE(); st->editList[i].mediaTime = _fd->readSint32BE(); st->editList[i].mediaRate = Common::Rational(_fd->readUint32BE(), 0x10000); debugN(3, "\tDuration = %d, Media Time = %d, ", st->editList[i].trackDuration, st->editList[i].mediaTime); st->editList[i].mediaRate.debugPrint(3, "Media Rate ="); } if (st->editCount != 1) warning("Multiple edit list entries. Things may go awry"); return 0; }
reg_t kSaid(EngineState *s, int argc, reg_t *argv) { reg_t heap_said_block = argv[0]; byte *said_block; int new_lastmatch; Vocabulary *voc = g_sci->getVocabulary(); #ifdef DEBUG_PARSER const int debug_parser = 1; #else const int debug_parser = 0; #endif if (!heap_said_block.getSegment()) return NULL_REG; said_block = (byte *)s->_segMan->derefBulkPtr(heap_said_block, 0); if (!said_block) { warning("Said on non-string, pointer %04x:%04x", PRINT_REG(heap_said_block)); return NULL_REG; } #ifdef DEBUG_PARSER debugN("Said block: "); g_sci->getVocabulary()->debugDecipherSaidBlock(said_block); #endif if (voc->parser_event.isNull() || (readSelectorValue(s->_segMan, voc->parser_event, SELECTOR(claimed)))) { return NULL_REG; } new_lastmatch = said(said_block, debug_parser); if (new_lastmatch != SAID_NO_MATCH) { /* Build and possibly display a parse tree */ #ifdef DEBUG_PARSER debugN("kSaid: Match.\n"); #endif s->r_acc = make_reg(0, 1); if (new_lastmatch != SAID_PARTIAL_MATCH) writeSelectorValue(s->_segMan, voc->parser_event, SELECTOR(claimed), 1); } else { return NULL_REG; } return s->r_acc; }
void Expression::printVarIndex() { byte *arrDesc; int16 dim; int16 dimCount; int16 operation; int16 temp; int32 pos = _vm->_game->_script->pos(); operation = _vm->_game->_script->readByte(); switch (operation) { case OP_LOAD_VAR_INT32: case OP_LOAD_VAR_STR: temp = _vm->_game->_script->readUint16() * 4; debugN(5, "&var_%d", temp); if ((operation == OP_LOAD_VAR_STR) && (_vm->_game->_script->peekByte() == 13)) { _vm->_game->_script->skip(1); debugN(5, "+"); printExpr(OP_END_MARKER); } break; case OP_ARRAY_INT32: case OP_ARRAY_STR: debugN(5, "&var_%d[", _vm->_game->_script->readUint16()); dimCount = _vm->_game->_script->readByte(); arrDesc = _vm->_game->_script->getData() + _vm->_game->_script->pos(); _vm->_game->_script->skip(dimCount); for (dim = 0; dim < dimCount; dim++) { printExpr(OP_END_MARKER); debugN(5, " of %d", (int16) arrDesc[dim]); if (dim != dimCount - 1) debugN(5, ","); } debugN(5, "]"); if ((operation == OP_ARRAY_STR) && (_vm->_game->_script->peekByte() == 13)) { _vm->_game->_script->skip(1); debugN(5, "+"); printExpr(OP_END_MARKER); } break; default: debugN(5, "var_0"); break; } debugN(5, "\n"); _vm->_game->_script->seek(pos); return; }
void Parse::printVarIndex() { char *arrDesc; int16 dim; int16 dimCount; int16 operation; int16 temp; char *pos = _vm->_global->_inter_execPtr; operation = *_vm->_global->_inter_execPtr++; switch (operation) { case 23: case 25: temp = _vm->_inter->load16() * 4; debugN(5, "&var_%d", temp); if (operation == 25 && *_vm->_global->_inter_execPtr == 13) { _vm->_global->_inter_execPtr++; debugN(5, "+"); printExpr(12); } break; case 26: case 28: debugN(5, "&var_%d[", _vm->_inter->load16()); dimCount = *_vm->_global->_inter_execPtr++; arrDesc = _vm->_global->_inter_execPtr; _vm->_global->_inter_execPtr += dimCount; for (dim = 0; dim < dimCount; dim++) { printExpr(12); debugN(5, " of %d", (int16)arrDesc[dim]); if (dim != dimCount - 1) debugN(5, ","); } debugN(5, "]"); if (operation == 28 && *_vm->_global->_inter_execPtr == 13) { _vm->_global->_inter_execPtr++; debugN(5, "+"); printExpr(12); } break; default: debugN(5, "var_0"); break; } debugN(5, "\n"); _vm->_global->_inter_execPtr = pos; return; }
/** * List any currently active objects */ void Saver::listObjects() { Common::List<SavedObject *>::iterator i; int count = 1; for (i = _objList.begin(); i != _objList.end(); ++i, ++count) debug("%d - %s", count, (*i)->getClassName().c_str()); debugN("\n"); }
CDToonsDecoder::CDToonsDecoder(uint16 width, uint16 height) { debugN(5, "CDToons: width %d, height %d\n", width, height); _surface = new Graphics::Surface(); _surface->create(width, height, Graphics::PixelFormat::createFormatCLUT8()); _currentPaletteId = 0; memset(_palette, 0, 256 * 3); _dirtyPalette = false; }
int AgiEngine::decodeObjects(uint8 *mem, uint32 flen) { unsigned int i, so, padsize, spos; padsize = _game.gameFlags & ID_AMIGA ? 4 : 3; _game.numObjects = 0; _objects = NULL; // check if first pointer exceeds file size // if so, its encrypted, else it is not if (READ_LE_UINT16(mem) > flen) { debugN(0, "Decrypting objects... "); decrypt(mem, flen); debug(0, "done."); } // alloc memory for object list // byte 3 = number of animated objects. this is ignored.. ?? if (READ_LE_UINT16(mem) / padsize > 256) { // die with no error! AGDS game needs not to die to work!! :( return errOK; } _game.numObjects = READ_LE_UINT16(mem) / padsize; debugC(5, kDebugLevelResources, "num_objects = %d (padsize = %d)", _game.numObjects, padsize); if (allocObjects(_game.numObjects) != errOK) return errNotEnoughMemory; // build the object list spos = getVersion() >= 0x2000 ? padsize : 0; for (i = 0, so = spos; i < _game.numObjects; i++, so += padsize) { int offset; _objects[i].location = *(mem + so + 2); offset = READ_LE_UINT16(mem + so) + spos; if ((uint) offset < flen) { _objects[i].name = (char *)strdup((const char *)mem + offset); } else { warning("object %i name beyond object filesize (%04x > %04x)", i, offset, flen); _objects[i].name = strdup(""); } // Don't show the invalid "?" object in ego's inventory in the fanmade // game Beyond the Titanic 2 (bug #3116541). if (!strcmp(_objects[i].name, "?") && _objects[i].location == EGO_OWNED) _objects[i].location = 0; } debug(0, "Reading objects: %d objects read.", _game.numObjects); return errOK; }
void Lingo::execute(int pc) { for(_pc = pc; (*_currentScript)[_pc] != STOP && !_returning;) { for (uint i = 0; i < _stack.size(); i++) { debugN(5, "%d ", _stack[i].u.i); } debug(5, "%s", ""); _pc++; (*((*_currentScript)[_pc - 1]))(); } }
bool GameVar::load(MfcArchive &file) { _varName = file.readPascalString(); _varType = file.readUint32LE(); debugN(6, "[%03d] ", file.getLevel()); for (int i = 0; i < file.getLevel(); i++) debugN(6, " "); debugN(6, "<%s>: ", transCyrillic((byte *)_varName)); switch (_varType) { case 0: _value.intValue = file.readUint32LE(); debug(6, "d --> %d", _value.intValue); break; case 1: _value.intValue = file.readUint32LE(); // FIXME debug(6, "f --> %f", _value.floatValue); break; case 2: _value.stringValue = file.readPascalString(); debug(6, "s --> %s", _value.stringValue); break; default: error("Unknown var type: %d (0x%x)", _varType, _varType); } file.incLevel(); _parentVarObj = (GameVar *)file.readClass(); _prevVarObj = (GameVar *)file.readClass(); _nextVarObj = (GameVar *)file.readClass(); _field_14 = (GameVar *)file.readClass(); _subVars = (GameVar *)file.readClass(); file.decLevel(); return true; }
int AgiEngine::decodeObjects(uint8 *mem, uint32 flen) { unsigned int i, so, padsize; padsize = _game.gameFlags & ID_AMIGA ? 4 : 3; _game.numObjects = 0; _objects = NULL; // check if first pointer exceeds file size // if so, its encrypted, else it is not if (READ_LE_UINT16(mem) > flen) { debugN(0, "Decrypting objects... "); decrypt(mem, flen); debug(0, "done."); } // alloc memory for object list // byte 3 = number of animated objects. this is ignored.. ?? if (READ_LE_UINT16(mem) / padsize >= 256) { // die with no error! AGDS game needs not to die to work!! :( return errOK; } _game.numObjects = READ_LE_UINT16(mem) / padsize; debugC(5, kDebugLevelResources, "num_objects = %d (padsize = %d)", _game.numObjects, padsize); if (allocObjects(_game.numObjects) != errOK) return errNotEnoughMemory; // build the object list for (i = 0, so = padsize; i < _game.numObjects; i++, so += padsize) { int offset; (_objects + i)->location = *(mem + so + 2); offset = READ_LE_UINT16(mem + so) + padsize; if ((uint) offset < flen) { (_objects + i)->name = (char *)strdup((const char *)mem + offset); } else { warning("object %i name beyond object filesize (%04x > %04x)", i, offset, flen); (_objects + i)->name = strdup(""); } } debug(0, "Reading objects: %d objects read.", _game.numObjects); return errOK; }
void MacFontManager::generateFont(MacFont &toFont, MacFont &fromFont) { debugN("Found font substitute for font '%s' ", getFontName(toFont)); debug("as '%s'", getFontName(fromFont)); MacFONTFont *font = Graphics::MacFONTFont::scaleFont(fromFont.getFont(), toFont.getSize()); if (!font) { warning("Failed to generate font '%s'", getFontName(toFont)); } toFont.setGenerated(true); toFont.setFont(font); FontMan.assignFontToName(getFontName(toFont), font); _fontRegistry.setVal(getFontName(toFont), new MacFont(toFont)); debug("Generated font '%s'", getFontName(toFont)); }
void Scene::processMessageList() { debug(7, "Scene::processMessageList() _isMessageListBusy = %d; _isKlaymenBusy = %d", _isMessageListBusy, _isKlaymenBusy); if (_isMessageListBusy || _isKlaymenBusy) return; _isMessageListBusy = true; if (!_messageList) { _messageList2 = NULL; _messageListStatus = 0; } if (_messageList && _klaymen) { #if 0 debug("MessageList: %p, %d", (void*)_messageList, _messageList->size()); for (uint i = 0; i < _messageList->size(); ++i) { if (i == _messageListIndex) debugN("**"); else debugN(" "); debug("(%08X, %08X)", (*_messageList)[i].messageNum, (*_messageList)[i].messageValue); } debug("--------------------------------"); #endif while (_messageList && _messageListIndex < _messageListCount && !_isKlaymenBusy) { uint32 messageNum = (*_messageList)[_messageListIndex].messageNum; uint32 messageParam = (*_messageList)[_messageListIndex].messageValue; ++_messageListIndex; if (_messageListIndex == _messageListCount) sendMessage(_klaymen, 0x1021, 0); if (_doConvertMessages) messageNum = convertMessageNum(messageNum); if (messageNum == 0x1009 || messageNum == 0x1024) { sendMessage(_parentModule, messageNum, messageParam); } else if (messageNum == 0x100A) { _messageValue = messageParam; sendMessage(_parentModule, messageNum, messageParam); } else if (messageNum == 0x4001) { _isKlaymenBusy = true; sendPointMessage(_klaymen, 0x4001, _mouseClickPos); } else if (messageNum == 0x100D) { if (this->hasMessageHandler() && sendMessage(this, 0x100D, messageParam) != 0) continue; } else if (messageNum == 0x101A) { _messageListStatus = 0; } else if (messageNum == 0x101B) { _messageListStatus = 2; } else if (messageNum == 0x1020) { _canAcceptInput = false; } else if (messageNum >= 0x2000 && messageNum <= 0x2FFF) { if (this->hasMessageHandler() && sendMessage(this, messageNum, messageParam) != 0) { _isMessageListBusy = false; return; } } else if (messageNum != 0x4003) { _isKlaymenBusy = true; if (_klaymen->hasMessageHandler() && sendMessage(_klaymen, messageNum, messageParam) != 0) { _isKlaymenBusy = false; } } if (_messageListIndex == _messageListCount) { _canAcceptInput = true; _messageList = NULL; } } } _isMessageListBusy = false; }
Graphics::Surface *CDToonsDecoder::decodeImage(Common::SeekableReadStream *stream) { uint16 u0 = stream->readUint16BE(); // always 9? uint16 frameId = stream->readUint16BE(); uint16 blocksValidUntil = stream->readUint16BE(); byte u6 = stream->readByte(); byte backgroundColor = stream->readByte(); debugN(5, "CDToons frame %d, size %d, unknown %04x (at 0), blocks valid until %d, unknown 6 is %02x, bkg color is %02x\n", frameId, stream->size(), u0, blocksValidUntil, u6, backgroundColor); Common::Rect clipRect = readRect(stream); debugN(9, "CDToons clipRect: (%d, %d) to (%d, %d)\n", clipRect.left, clipRect.top, clipRect.right, clipRect.bottom); Common::Rect dirtyRect = readRect(stream); debugN(9, "CDToons dirtyRect: (%d, %d) to (%d, %d)\n", dirtyRect.left, dirtyRect.top, dirtyRect.right, dirtyRect.bottom); uint32 flags = stream->readUint32BE(); if (flags & 0x80) error("CDToons: frame already processed?"); debugN(5, "CDToons flags: %08x\n", flags); uint16 blockCount = stream->readUint16BE(); uint16 blockOffset = stream->readUint16BE(); debugN(9, "CDToons: %d blocks at 0x%04x\n", blockCount, blockOffset); // max block id? uint16 u32 = stream->readUint16BE(); debugN(5, "CDToons unknown at 32: %04x\n", u32); byte actionCount = stream->readByte(); byte u35 = stream->readByte(); uint16 paletteId = stream->readUint16BE(); byte paletteSet = stream->readByte(); debugN(9, "CDToons palette id %04x, palette byte %02x\n", paletteId, paletteSet); byte u39 = stream->readByte(); uint16 u40 = stream->readUint16BE(); uint16 u42 = stream->readUint16BE(); debugN(5, "CDToons: unknown at 35 is %02x, unknowns at 39: %02x, %04x, %04x\n", u35, u39, u40, u42); Common::Array<CDToonsAction> actions; for (uint i = 0; i < actionCount; i++) { CDToonsAction action; action.blockId = stream->readUint16BE(); action.rect = readRect(stream); debugN(9, "CDToons action: render block %d at (%d, %d) to (%d, %d)\n", action.blockId, action.rect.left, action.rect.top, action.rect.right, action.rect.bottom); actions.push_back(action); } if (stream->pos() > blockOffset) error("CDToons header ended at 0x%08x, but blocks should have started at 0x%08x", stream->pos(), blockOffset); if (stream->pos() != blockOffset) error("CDToons had %d unknown bytes after header", blockOffset - stream->pos()); for (uint i = 0; i < blockCount; i++) { uint16 blockId = stream->readUint16BE(); if (blockId >= 1200) error("CDToons: block id %d was too high", blockId); if (_blocks.contains(blockId)) error("CDToons: new block %d was already seen", blockId); CDToonsBlock block; block.flags = stream->readUint16BE(); // flag 1 = palette, flag 2 = data? if (block.flags & 0x8000) error("CDToons: block already processed?"); block.size = stream->readUint32BE(); if (block.size < 14) error("CDToons: block size was %d, too small", block.size); block.size -= 14; block.startFrame = stream->readUint16BE(); block.endFrame = stream->readUint16BE(); block.unknown12 = stream->readUint16BE(); block.data = new byte[block.size]; stream->read(block.data, block.size); debugN(9, "CDToons block id 0x%04x of size 0x%08x, flags %04x, from frame %d to %d, unknown at 12 is %04x\n", blockId, block.size, block.flags, block.startFrame, block.endFrame, block.unknown12); _blocks[blockId] = block; } byte xFrmBegin = 0, xFrmCount; Common::Array<CDToonsDiff> diffs; while (true) { int32 nextPos = stream->pos(); uint32 tag = stream->readUint32BE(); uint32 size = stream->readUint32BE(); nextPos += size; switch (tag) { case MKTAG('D','i','f','f'): { debugN(5, "CDToons: Diff\n"); uint16 count = stream->readUint16BE(); Common::Rect diffClipRect = readRect(stream); debugN(9, "CDToons diffClipRect: (%d, %d) to (%d, %d)\n", diffClipRect.left, diffClipRect.top, diffClipRect.right, diffClipRect.bottom); debugN(5, "CDToons Diff: %d subentries\n", count); for (uint i = 0; i < count; i++) { CDToonsDiff diff; diff.rect = readRect(stream); diff.size = stream->readUint32BE(); if (diff.size < 20) error("CDToons: Diff block size was %d, too small", diff.size); uint16 diffWidth = stream->readUint16BE(); uint16 diffHeight = stream->readUint16BE(); uint16 unknown16 = stream->readUint16BE(); uint16 unknown18 = stream->readUint16BE(); diff.size -= 8; if (diffWidth != diff.rect.width() || diffHeight != diff.rect.height()) error("CDToons: Diff sizes didn't match"); debugN(5, "CDToons Diff: size %d, frame from (%d, %d) to (%d, %d), unknowns %04x, %04x\n", diff.size, diff.rect.left, diff.rect.top, diff.rect.right, diff.rect.bottom, unknown16, unknown18); diff.data = new byte[diff.size]; stream->read(diff.data, diff.size); diffs.push_back(diff); } } break; case MKTAG('X','F','r','m'): { debugN(5, "CDToons: XFrm\n"); if (!(flags & 0x10)) error("CDToons: useless XFrm?"); if (xFrmBegin) error("CDToons: duplicate XFrm"); xFrmBegin = stream->readByte(); xFrmCount = stream->readByte(); debugN(9, "CDToons XFrm: run %d actions from %d\n", xFrmCount, xFrmBegin - 1); // TODO: don't ignore (if xFrmCount is non-zero) Common::Rect dirtyRectXFrm = readRect(stream); debugN(9, "CDToons XFrm dirtyRect: (%d, %d) to (%d, %d)\n", dirtyRectXFrm.left, dirtyRectXFrm.top, dirtyRectXFrm.right, dirtyRectXFrm.bottom); // always zero? Common::Rect dirtyRect2XFrm = readRect(stream); debugN(9, "CDToons XFrm dirtyRect2: (%d, %d) to (%d, %d)\n", dirtyRect2XFrm.left, dirtyRect2XFrm.top, dirtyRect2XFrm.right, dirtyRect2XFrm.bottom); } break; case MKTAG('M','r','k','s'): debugN(5, "CDToons: Mrks\n"); if (!(flags & 0x2)) error("CDToons: useless Mrks?"); // TODO warning("CDToons: encountered Mrks, not implemented yet"); break; case MKTAG('S','c','a','l'): // TODO warning("CDToons: encountered Scal, not implemented yet"); break; case MKTAG('W','r','M','p'): warning("CDToons: encountered WrMp, ignoring"); break; case MKTAG('F','r','t','R'): { debugN(5, "CDToons: FrtR\n"); if (!(flags & 0x40)) error("CDToons: useless FrtR?"); uint16 count = stream->readUint16BE(); debugN(9, "CDToons FrtR: %d dirty rectangles\n", count); for (uint i = 0; i < count; i++) { Common::Rect dirtyRectFrtR = readRect(stream); debugN(9, "CDToons FrtR dirtyRect: (%d, %d) to (%d, %d)\n", dirtyRectFrtR.left, dirtyRectFrtR.top, dirtyRectFrtR.right, dirtyRectFrtR.bottom); } } break; case MKTAG('B','c','k','R'): { debugN(5, "CDToons: BckR\n"); if (!(flags & 0x20)) error("CDToons: useless BckR?"); uint16 count = stream->readUint16BE(); debugN(9, "CDToons BckR: %d subentries\n", count); for (uint i = 0; i < count; i++) { Common::Rect dirtyRectBckR = readRect(stream); debugN(9, "CDToons BckR dirtyRect: (%d, %d) to (%d, %d)\n", dirtyRectBckR.left, dirtyRectBckR.top, dirtyRectBckR.right, dirtyRectBckR.bottom); } } break; default: warning("Unknown CDToons tag '%s'", tag2str(tag)); } if (stream->pos() > nextPos) error("CDToons ran off the end of a block while reading it (at %d, next block at %d)", stream->pos(), nextPos); if (stream->pos() != nextPos) { warning("CDToons had %d unknown bytes after block", nextPos - stream->pos()); stream->seek(nextPos); } if (stream->pos() == stream->size()) break; } for (uint i = 0; i < diffs.size(); i++) { renderBlock(diffs[i].data, diffs[i].size, diffs[i].rect.left, diffs[i].rect.top, diffs[i].rect.width(), diffs[i].rect.height()); delete[] diffs[i].data; } if (!diffs.empty()) return _surface; for (uint i = 0; i < actions.size(); i++) { CDToonsAction &action = actions[i]; if (i == 0 && action.blockId == 0) memset(_surface->pixels, backgroundColor, _surface->w * _surface->h); if (!_blocks.contains(action.blockId)) continue; if (!action.rect.right) continue; if (i == 0 && !diffs.empty()) continue; CDToonsBlock &block = _blocks[action.blockId]; uint16 width = READ_BE_UINT16(block.data + 2); uint16 height = READ_BE_UINT16(block.data); renderBlock(block.data + 14, block.size - 14, action.rect.left, action.rect.top, width, height); } if (paletteId && _currentPaletteId != paletteId) { if (!_blocks.contains(paletteId)) error("CDToons: no block for palette %04x", paletteId); if (_blocks[paletteId].size != 2 * 3 * 256) error("CDToons: palette %04x is wrong size (%d)", paletteId, _blocks[paletteId].size); _currentPaletteId = paletteId; if (!paletteSet) setPalette(_blocks[paletteId].data); } return _surface; }
void CDToonsDecoder::renderBlock(byte *data, uint dataSize, int destX, int destY, uint width, uint height) { byte *currData = data; byte *dataEnd = data + dataSize; debugN(9, "CDToons renderBlock at (%d, %d), width %d, height %d\n", destX, destY, width, height); if (destX + width > _surface->w) width = _surface->w - destX; if (destY + height > _surface->h) height = _surface->h - destY; uint skip = 0; if (destX < 0) { skip = -destX; if (width <= skip) return; width -= skip; destX = 0; } for (uint y = 0; y < height; y++) { if (destY + (int)y >= _surface->h) break; if (currData + 2 > dataEnd) error("CDToons renderBlock overran whole data by %d bytes", (uint32)(currData - dataEnd)); uint16 lineSize = READ_BE_UINT16(currData); currData += 2; byte *nextLine = currData + lineSize; if (nextLine > dataEnd) error("CDToons renderBlock was going to overrun data by %d bytes (line size %d)", (uint32)(nextLine - dataEnd), (uint32)(nextLine - currData)); if (destY + (int)y < 0) { currData = nextLine; continue; } byte *pixels = (byte *)_surface->getBasePtr(destX, destY + y); int leftToSkip = skip; uint x = 0; bool done = false; while (x < width && !done) { int size = (uint)*currData; currData++; bool raw = !(size & 0x80); size = (size & 0x7f) + 1; if (leftToSkip) { if (leftToSkip >= size) { leftToSkip -= size; if (raw) currData += size; else currData++; continue; } else { size -= leftToSkip; if (raw) currData += leftToSkip; leftToSkip = 0; } } if (x + size >= width) { size = width - x; done = true; } if (destX + (int)x + size >= (int)_surface->w) { size = MIN<int>((int)_surface->w - destX - (int)x, width - x); done = true; } if (size <= 0) { size = 0; done = true; } if (raw) { memcpy(pixels + x, currData, size); currData += size; x += size; } else { byte color = *currData; currData++; if (color) { memset(pixels + x, color, size); } x += size; } if (currData > nextLine) { warning("CDToons renderBlock overran line by %d bytes", (uint32)(currData - nextLine)); return; } } currData = nextLine; } }
// // Print hexdump of the data passed in // void hexdump(const byte *data, int len, int bytesPerLine, int startOffset) { assert(1 <= bytesPerLine && bytesPerLine <= 32); int i; byte c; int offset = startOffset; while (len >= bytesPerLine) { debugN("%06x: ", offset); for (i = 0; i < bytesPerLine; i++) { debugN("%02x ", data[i]); if (i % 4 == 3) debugN(" "); } debugN(" |"); for (i = 0; i < bytesPerLine; i++) { c = data[i]; if (c < 32 || c >= 127) c = '.'; debugN("%c", c); } debugN("|\n"); data += bytesPerLine; len -= bytesPerLine; offset += bytesPerLine; } if (len <= 0) return; debugN("%06x: ", offset); for (i = 0; i < bytesPerLine; i++) { if (i < len) debugN("%02x ", data[i]); else debugN(" "); if (i % 4 == 3) debugN(" "); } debugN(" |"); for (i = 0; i < len; i++) { c = data[i]; if (c < 32 || c >= 127) c = '.'; debugN("%c", c); } for (; i < bytesPerLine; i++) debugN(" "); debugN("|\n"); }
void Parse::printExpr_internal(char stopToken) { int16 dimCount; char operation; int16 num; int16 dim; char *arrDesc; char func; num = 0; while (1) { operation = *_vm->_global->_inter_execPtr++; if (operation >= 16 && operation <= 29) { // operands switch (operation) { case 17: // uint16 variable load debugN(5, "var16_%d", _vm->_inter->load16()); break; case 18: // uint8 variable load: debugN(5, "var8_%d", _vm->_inter->load16()); break; case 19: // uint32 immediate debugN(5, "%d", READ_LE_UINT32(_vm->_global->_inter_execPtr)); _vm->_global->_inter_execPtr += 4; break; case 20: // uint16 immediate debugN(5, "%d", _vm->_inter->load16()); break; case 21: // uint8 immediate debugN(5, "%d", *_vm->_global->_inter_execPtr++); break; case 22: // string immediate debugN(5, "\42%s\42", _vm->_global->_inter_execPtr); _vm->_global->_inter_execPtr += strlen(_vm->_global->_inter_execPtr) + 1; break; case 23: // uint32 variable load case 24: // uint32 variable load as uint16 debugN(5, "var_%d", _vm->_inter->load16()); break; case 25: // string variable load debugN(5, "(&var_%d)", _vm->_inter->load16()); if (*_vm->_global->_inter_execPtr == 13) { _vm->_global->_inter_execPtr++; debugN(5, "{"); printExpr_internal(12); // this also prints the closing } } break; case 16: // uint8 array access case 26: // uint32 array access case 27: // uint16 array access case 28: // string array access debugN(5, "\n"); if (operation == 28) debugN(5, "(&"); debugN(5, "var_%d[", _vm->_inter->load16()); dimCount = *_vm->_global->_inter_execPtr++; arrDesc = _vm->_global->_inter_execPtr; _vm->_global->_inter_execPtr += dimCount; for (dim = 0; dim < dimCount; dim++) { printExpr_internal(12); debugN(5, " of %d", (int16)arrDesc[dim]); if (dim != dimCount - 1) debugN(5, ","); } debugN(5, "]"); if (operation == 28) debugN(5, ")"); if (operation == 28 && *_vm->_global->_inter_execPtr == 13) { _vm->_global->_inter_execPtr++; debugN(5, "{"); printExpr_internal(12); // this also prints the closing } } break; case 29: // function func = *_vm->_global->_inter_execPtr++; if (func == 5) debugN(5, "sqr("); else if (func == 10) debugN(5, "rand("); else if (func == 7) debugN(5, "abs("); else if (func == 0 || func == 1 || func == 6) debugN(5, "sqrt("); else debugN(5, "id("); printExpr_internal(10); break; } continue; } // if (operation >= 16 && operation <= 29) // operators switch (operation) { case 9: debugN(5, "("); break; case 11: debugN(5, "!"); break; case 10: debugN(5, ")"); break; case 1: debugN(5, "-"); break; case 2: debugN(5, "+"); break; case 3: debugN(5, "-"); break; case 4: debugN(5, "|"); break; case 5: debugN(5, "*"); break; case 6: debugN(5, "/"); break; case 7: debugN(5, "%%"); break; case 8: debugN(5, "&"); break; case 30: debugN(5, "||"); break; case 31: debugN(5, "&&"); break; case 32: debugN(5, "<"); break; case 33: debugN(5, "<="); break; case 34: debugN(5, ">"); break; case 35: debugN(5, ">="); break; case 36: debugN(5, "=="); break; case 37: debugN(5, "!="); break; case 99: debugN(5, "\n"); break; case 12: debugN(5, "}"); if (stopToken != 12) { debugN(5, "Closing paren without opening?"); } break; default: debugN(5, "<%d>", (int16)operation); error("printExpr: invalid operator in expression"); break; } if (operation == 9) { num++; continue; } if (operation == 11 || (operation >= 1 && operation <= 8)) continue; if (operation >= 30 && operation <= 37) continue; if (operation == 10) num--; if (operation == stopToken) { if (stopToken != 10 || num < 0) { return; } } } }
bool RivenConsole::Cmd_DumpScript(int argc, const char **argv) { if (argc < 4) { DebugPrintf("Usage: dumpScript <stack> <CARD or HSPT> <card>\n"); return true; } uint16 oldStack = _vm->getCurStack(); byte newStack = 0; for (byte i = 1; i <= tspit + 1; i++) if (!scumm_stricmp(argv[1], _vm->getStackName(i - 1).c_str())) { newStack = i; break; } if (!newStack) { DebugPrintf("\'%s\' is not a stack name!\n", argv[1]); return true; } newStack--; _vm->changeToStack(newStack); // Load in Variable Names Common::SeekableReadStream *nameStream = _vm->getResource(ID_NAME, VariableNames); Common::StringArray varNames; uint16 namesCount = nameStream->readUint16BE(); uint16 *stringOffsets = new uint16[namesCount]; for (uint16 i = 0; i < namesCount; i++) stringOffsets[i] = nameStream->readUint16BE(); nameStream->seek(namesCount * 2, SEEK_CUR); int32 curNamesPos = nameStream->pos(); for (uint32 i = 0; i < namesCount; i++) { nameStream->seek(curNamesPos + stringOffsets[i]); Common::String name; for (char c = nameStream->readByte(); c; c = nameStream->readByte()) name += c; varNames.push_back(name); } delete nameStream; // Load in External Command Names nameStream = _vm->getResource(ID_NAME, ExternalCommandNames); Common::StringArray xNames; namesCount = nameStream->readUint16BE(); stringOffsets = new uint16[namesCount]; for (uint16 i = 0; i < namesCount; i++) stringOffsets[i] = nameStream->readUint16BE(); nameStream->seek(namesCount * 2, SEEK_CUR); curNamesPos = nameStream->pos(); for (uint32 i = 0; i < namesCount; i++) { nameStream->seek(curNamesPos + stringOffsets[i]); Common::String name; for (char c = nameStream->readByte(); c; c = nameStream->readByte()) name += c; xNames.push_back(name); } delete nameStream; // Get CARD/HSPT data and dump their scripts if (!scumm_stricmp(argv[2], "CARD")) { // Use debugN to print these because the scripts can get very large and would // really be useless if the the text console is not used. A DumpFile could also // theoretically be used, but I (clone2727) typically use this dynamically and // don't want countless files laying around without game context. If one would // want a file of a script they could just redirect stdout to a file or use // deriven. debugN("\n\nDumping scripts for %s\'s card %d!\n", argv[1], (uint16)atoi(argv[3])); debugN("==================================\n\n"); Common::SeekableReadStream *cardStream = _vm->getResource(MKTAG('C','A','R','D'), (uint16)atoi(argv[3])); cardStream->seek(4); RivenScriptList scriptList = _vm->_scriptMan->readScripts(cardStream, false); for (uint32 i = 0; i < scriptList.size(); i++) { scriptList[i]->dumpScript(varNames, xNames, 0); delete scriptList[i]; } delete cardStream; } else if (!scumm_stricmp(argv[2], "HSPT")) { // See above for why this is printed via debugN debugN("\n\nDumping scripts for %s\'s card %d hotspots!\n", argv[1], (uint16)atoi(argv[3])); debugN("===========================================\n\n"); Common::SeekableReadStream *hsptStream = _vm->getResource(MKTAG('H','S','P','T'), (uint16)atoi(argv[3])); uint16 hotspotCount = hsptStream->readUint16BE(); for (uint16 i = 0; i < hotspotCount; i++) { debugN("Hotspot %d:\n", i); hsptStream->seek(22, SEEK_CUR); // Skip non-script related stuff RivenScriptList scriptList = _vm->_scriptMan->readScripts(hsptStream, false); for (uint32 j = 0; j < scriptList.size(); j++) { scriptList[j]->dumpScript(varNames, xNames, 1); delete scriptList[j]; } } delete hsptStream; } else { DebugPrintf("%s doesn't have any scripts!\n", argv[2]); } // See above for why this is printed via debugN debugN("\n\n"); _vm->changeToStack(oldStack); DebugPrintf("Script dump complete.\n"); return true; }
void RivenTimerCommand::dump(byte tabs) { printTabs(tabs); debugN("doTimer();\n"); }
void RivenStackChangeCommand::dump(byte tabs) { printTabs(tabs); debugN("changeStack(%d, %d);\n", _stackId, _cardId); }
bool WinFont::loadFromFNT(Common::SeekableReadStream &stream) { uint16 version = stream.readUint16LE(); // We'll accept Win1, Win2, and Win3 fonts if (version != 0x100 && version != 0x200 && version != 0x300) { warning("Bad FNT version %04x", version); return false; } /* uint32 size = */ stream.readUint32LE(); stream.skip(60); // Copyright info uint16 fontType = stream.readUint16LE(); /* uint16 points = */ stream.readUint16LE(); /* uint16 vertRes = */ stream.readUint16LE(); /* uint16 horizRes = */ stream.readUint16LE(); /* uint16 ascent = */ stream.readUint16LE(); /* uint16 internalLeading = */ stream.readUint16LE(); /* uint16 externalLeading = */ stream.readUint16LE(); /* byte italic = */ stream.readByte(); /* byte underline = */ stream.readByte(); /* byte strikeOut = */ stream.readByte(); /* uint16 weight = */ stream.readUint16LE(); /* byte charSet = */ stream.readByte(); uint16 pixWidth = stream.readUint16LE(); _pixHeight = stream.readUint16LE(); /* byte pitchAndFamily = */ stream.readByte(); /* uint16 avgWidth = */ stream.readUint16LE(); _maxWidth = stream.readUint16LE(); _firstChar = stream.readByte(); _lastChar = stream.readByte(); _defaultChar = stream.readByte(); /* byte breakChar = */ stream.readByte(); /* uint16 widthBytes = */ stream.readUint16LE(); /* uint32 device = */ stream.readUint32LE(); /* uint32 face = */ stream.readUint32LE(); /* uint32 bitsPointer = */ stream.readUint32LE(); uint32 bitsOffset = stream.readUint32LE(); /* byte reserved = */ stream.readByte(); if (version == 0x100) { // Seems Win1 has an extra byte? stream.readByte(); } else if (version == 0x300) { // For Windows 3.0, Microsoft added 6 new fields. All of which are // guaranteed to be 0. Which leads to the question: Why add these at all? /* uint32 flags = */ stream.readUint32LE(); /* uint16 aSpace = */ stream.readUint16LE(); /* uint16 bSpace = */ stream.readUint16LE(); /* uint16 cSpace = */ stream.readUint16LE(); /* uint32 colorPointer = */ stream.readUint32LE(); stream.skip(16); // Reserved } // Begin loading in the glyphs _glyphCount = (_lastChar - _firstChar) + 2; _glyphs = new GlyphEntry[_glyphCount]; for (uint16 i = 0; i < _glyphCount; i++) { _glyphs[i].charWidth = stream.readUint16LE(); // Use the default if present if (pixWidth) _glyphs[i].charWidth = pixWidth; _glyphs[i].offset = (version == 0x300) ? stream.readUint32LE() : stream.readUint16LE(); // Seems the offsets in the Win1 font format are based on bitsOffset if (version == 0x100) _glyphs[i].offset += bitsOffset; } // TODO: Currently only raster fonts are supported! if (fontType & 1) { warning("Vector FNT files not supported yet"); return false; } // Read in the bitmaps for the raster images for (uint16 i = 0; i < _glyphCount - 1; i++) { stream.seek(_glyphs[i].offset); _glyphs[i].bitmap = new byte[_pixHeight * _glyphs[i].charWidth]; // Calculate the amount of columns byte colCount = (_glyphs[i].charWidth + 7) / 8; for (uint16 j = 0; j < colCount; j++) { for (uint16 k = 0; k < _pixHeight; k++) { byte x = stream.readByte(); uint offset = j * 8 + k * _glyphs[i].charWidth; for (byte l = 0; l < 8 && j * 8 + l < _glyphs[i].charWidth; l++) _glyphs[i].bitmap[offset + l] = (x & (1 << (7 - l))) ? 1 : 0; } } #if 0 // Debug print debug("Character %02x '%c' at %08x", indexToCharacter(i), indexToCharacter(i), _glyphs[i].offset); for (uint16 j = 0; j < _pixHeight; j++) { for (uint16 k = 0; k < _glyphs[i].charWidth; k++) debugN("%c", _glyphs[i].bitmap[k + j * _glyphs[i].charWidth] ? 'X' : ' '); debugN("\n"); } #endif } return true; }
void RivenSimpleCommand::dump(byte tabs) { printTabs(tabs); debugN("%s;\n", describe().c_str()); }