void Script::o_strcmpnejmp() { // 0x1A uint16 varnum = readScript8or16bits(); uint8 val; uint8 result = 1; debugScript(1, false, "STRCMP-NEJMP: var[0x%04X..],", varnum); do { val = readScriptChar(true, true, true); if (_variables[varnum] != val) { result = 0; } varnum++; debugScript(1, false, " 0x%02X", val); } while (!(getCodeByte(_currentInstruction - 1) & 0x80)); uint16 address = readScript16bits(); if (!result) { debugScript(1, true, " jumping to @0x%04X", address); _currentInstruction = address; } else { debugScript(1, true, " not jumping"); } }
void Script::o_printstring() { char stringstorage[15], newchar; uint8 counter = 0; debugScript(1, true, "PRINTSTRING"); memset(stringstorage, 0, 15); do { newchar = readScriptChar(true, true, true) + 0x30; if (newchar < 0x30 || newchar > 0x39) { // If character is invalid, chuck a space in if (newchar < 0x41 || newchar > 0x7A) { newchar = 0x20; } } stringstorage[counter] = newchar; counter++; } while (!(getCodeByte(_currentInstruction - 1) & 0x80)); stringstorage[counter] = 0; // Load the font if required if (!_font) { _font = new Font(_vm->_system); } _font->printstring(stringstorage); }
void Script::o_printstring() { char stringstorage[15]; uint8 counter = 0; debugScript(1, true, "PRINTSTRING"); memset(stringstorage, 0, 15); do { char newchar = readScriptChar(true, true, true) + 0x30; if (newchar < 0x30 || newchar > 0x39) { // If character is invalid, chuck a space in if (newchar < 0x41 || newchar > 0x7A) { newchar = 0x20; } } stringstorage[counter] = newchar; counter++; } while (!(getCodeByte(_currentInstruction - 1) & 0x80)); stringstorage[counter] = 0; Common::Rect topbar(640, 80); Graphics::Surface *gamescreen = _vm->_system->lockScreen(); // Clear the top bar gamescreen->fillRect(topbar, 0); // Draw the string printString(gamescreen, stringstorage); _vm->_system->unlockScreen(); }
void Script::o_loadstring() { uint16 varnum = readScript8or16bits(); debugScript(1, false, "LOADSTRING var[0x%04X..] =", varnum); do { setVariable(varnum++, readScriptChar(true, true, true)); debugScript(1, false, " 0x%02X", _variables[varnum - 1]); } while (!(getCodeByte(_currentInstruction - 1) & 0x80)); debugScript(1, false, "\n"); }
void Script::o_strcmpnejmp_var() { // 0x21 uint16 data = readScriptVar(); if (data > 9) { data -= 7; } data = _variables[data + 0x19]; bool stringsmatch = 1; do { if (_variables[data++] != readScriptChar(true, true, true)) { stringsmatch = 0; } } while (!(getCodeByte(_currentInstruction - 1) & 0x80)); uint16 offset = readScript16bits(); if (!stringsmatch) { _currentInstruction = offset; } }
void Script::o_charlessjmp() { uint16 varnum = readScript8or16bits(); uint8 result = 0; debugScript(1, false, "CHARLESS-JMP: var[0x%04X..],", varnum); do { uint8 val = readScriptChar(true, true, true); if (val > _variables[varnum]) { result = 1; } varnum++; debugScript(1, false, " 0x%02X", val); } while (!(getCodeByte(_currentInstruction - 1) & 0x80)); uint16 address = readScript16bits(); if (result) { debugScript(1, true, " jumping to @0x%04X", address); _currentInstruction = address; } else { debugScript(1, true, " not jumping"); } }
void execStatement(void) { if(codeToken == TKN_STATEMENT_MARKER) { execLineNumber = getCodeStatementMarker(); execStatementCount++; statementStartPtr = codeSegmentPtr; if(debugger) debugger->traceStatementExecution(); getCodeToken(); } switch(codeToken) { case TKN_IDENTIFIER: { SymTableNodePtr idPtr = getCodeSymTableNodePtr(); ABL_Assert(idPtr != nullptr, 0, " oops "); if(idPtr->defn.key == DFN_FUNCTION) { bool skipOrder = false; uint8_t orderDWord = 0; uint8_t orderBitMask = 0; if((idPtr->defn.info.routine.flags & ROUTINE_FLAG_ORDER) && CurModule->getOrderCallFlags()) { orderDWord = getCodeByte(); orderBitMask = getCodeByte(); skipOrder = !CurModule->isLibrary() && CurModule->getOrderCallFlag(orderDWord, orderBitMask); } TypePtr returnType = execRoutineCall(idPtr, skipOrder); if(idPtr->defn.info.routine.flags & ROUTINE_FLAG_ORDER) { if(AutoReturnFromOrders) { //----------------------------------------------------------------- // We called an Order function, and we're in an Orders/State block, // so do we continue the flow of orders or stop here? int32_t returnVal = tos->integer; pop(); if(returnVal == 0) execOrderReturn(returnVal); else if(CurModule->getOrderCallFlags()) { CurModule->setOrderCallFlag(orderDWord, orderBitMask); } } } else if(returnType) { //------------------------------------------ // In case this routine returns a value, pop // the return value off the stack... pop(); } } else execAssignmentStatement(idPtr); } break; case TKN_CODE: { bool wasAutoReturnFromOrders = AutoReturnFromOrders; AutoReturnFromOrders = ((CurRoutineIdPtr->defn.info.routine.flags & (ROUTINE_FLAG_ORDER + ROUTINE_FLAG_STATE)) != 0); getCodeToken(); TokenCodeType endToken = TKN_END_FUNCTION; if(CurRoutineIdPtr->defn.info.routine.flags & ROUTINE_FLAG_ORDER) endToken = TKN_END_ORDER; else if(CurRoutineIdPtr->defn.info.routine.flags & ROUTINE_FLAG_STATE) endToken = TKN_END_STATE; TokenCodeType endTokenFinal = TKN_END_MODULE; if(CurLibrary) endTokenFinal = TKN_END_LIBRARY; else if(CurRoutineIdPtr->defn.info.routine.flags & ROUTINE_FLAG_FSM) endTokenFinal = TKN_END_FSM; while((codeToken != endToken) && (codeToken != endTokenFinal) && !NewStateSet) execStatement(); if(NewStateSet) return; getCodeToken(); AutoReturnFromOrders = wasAutoReturnFromOrders; } break; case TKN_FOR: execForStatement(); break; case TKN_IF: execIfStatement(); break; case TKN_REPEAT: execRepeatStatement(); break; case TKN_WHILE: execWhileStatement(); break; case TKN_SWITCH: execSwitchStatement(); break; case TKN_TRANS: execTransStatement(); break; case TKN_TRANS_BACK: execTransBackStatement(); break; case TKN_SEMICOLON: case TKN_ELSE: case TKN_UNTIL: break; default: //runtimeError(ABL_ERR_RUNTIME_UNIMPLEMENTED_FEATURE); NODEFAULT; } while(codeToken == TKN_SEMICOLON) getCodeToken(); }
uint8 Script::readScript8bits() { uint8 data = getCodeByte(_currentInstruction); _currentInstruction++; return data; }