int FWScript::o2_removeSeq() { byte a = getNextByte(); byte b = getNextByte(); debugC(5, kCineDebugScript, "Line: %d: removeSeq(%d,%d) -> TODO", _line, a, b); removeSeq(a, 0, b); return 0; }
int FWScript::o2_modifySeqListElement() { byte a = getNextByte(); byte b = getNextByte(); uint16 c = getNextWord(); uint16 d = getNextWord(); byte e = getNextByte(); debugC(5, kCineDebugScript, "Line: %d: o2_modifySeqListElement(%d,%d,%d,%d,%d)", _line, a, b, c, d, e); modifySeqListElement(a, 0, b, c, d, e); return 0; }
/** * @todo Check whether this opcode's name is backwards (i.e. should it be o2_isSeqNotRunning?) */ int FWScript::o2_isSeqRunning() { byte a = getNextByte(); byte b = getNextByte(); debugC(5, kCineDebugScript, "Line: %d: o2_isSeqRunning(%d,%d)", _line, a, b); if (isSeqRunning(a, 0, b)) { _compare = 1; } else { _compare = 0; } return 0; }
int FWScript::o2_addSeqListElement() { byte param1 = getNextByte(); byte param2 = getNextByte(); byte param3 = getNextByte(); byte param4 = getNextByte(); uint16 param5 = getNextWord(); uint16 param6 = getNextWord(); uint16 param7 = getNextWord(); debugC(5, kCineDebugScript, "Line: %d: addSeqListElement(%d,%d,%d,%d,%d,%d,%d)", _line, param1, param2, param3, param4, param5, param6, param7); addSeqListElement(param1, 0, param2, param3, param4, param5, param6, 0, param7); return 0; }
int FWScript::o2_playSample() { if (g_cine->getPlatform() == Common::kPlatformAmiga || g_cine->getPlatform() == Common::kPlatformAtariST) { // no-op in these versions getNextByte(); getNextByte(); getNextWord(); getNextByte(); getNextWord(); getNextWord(); return 0; } return o1_playSample(); }
int FWScript::o2_loadAbs() { byte param1 = getNextByte(); const char *param2 = getNextString(); debugC(5, kCineDebugScript, "Line: %d: loadABS(%d,%s)", _line, param1, param2); // Load the resource to an absolute position if (loadResource(param2, param1) == -1) { // Check if the loading failed // WORKAROUND: In the 256 color PC version of Operation Stealth when // walking out of the airport in Santa Paragua to the street the // player character should be seen as a grey silhuette while walking // behind the glass. But actually the player character is completely // invisible when walking behind the glass because the animation files // used are wrongly loaded. In AIRPORT.PRC's 6th script there are // calls loadAbs("JOHN01.ANI", 73) and loadAbs("JOHN02.ANI", 37) to // load the animations involved but no such files are found with the // game. Corresponding SET-files are found though. As it worked and // looked fine when I tried loading them instead of the missing ANI // files I'm doing so here. NOTE: At least the German Amiga version // of Operation Stealth seems to have all the files involved // (JOHN01.ANI, JOHN02.ANI, JOHN01.SET and JOHN02.SET). if (scumm_stricmp(param2, "JOHN01.ANI") == 0 && param1 == 73) { loadResource("JOHN01.SET", param1); } else if (scumm_stricmp(param2, "JOHN02.ANI") == 0 && param1 == 37) { loadResource("JOHN02.SET", param1); } } return 0; }
int FWScript::o2_unloadMask22() { byte param = getNextByte(); debugC(5, kCineDebugScript, "Line: %d: removeOverlay22(%d)", _line, param); removeOverlay(param, 22); return 0; }
int FWScript::o2_startObjectScript() { byte param = getNextByte(); debugC(5, kCineDebugScript, "Line: %d: startObjectScript(%d)", _line, param); runObjectScript(param); return 0; }
int FWScript::o2_setAdditionalBgVScroll() { byte param1 = getNextByte(); if (param1) { byte param2 = getNextByte(); debugC(5, kCineDebugScript, "Line: %d: additionalBgVScroll = var[%d]", _line, param2); renderer->setScroll(_localVars[param2]); } else { uint16 param2 = getNextWord(); debugC(5, kCineDebugScript, "Line: %d: additionalBgVScroll = %d", _line, param2); renderer->setScroll(param2); } return 0; }
int FWScript::o2_addBackground() { byte param1 = getNextByte(); const char *param2 = getNextString(); debugC(5, kCineDebugScript, "Line: %d: addBackground(%s,%d)", _line, param2, param1); addBackground(param2, param1); return 0; }
int FWScript::o2_useBgScroll() { byte param = getNextByte(); assert(param < 9); debugC(5, kCineDebugScript, "Line: %d: useBgScroll(%d)", _line, param); renderer->selectScrollBg(param); return 0; }
int FWScript::o2_removeBackground() { byte param = getNextByte(); assert(param); debugC(5, kCineDebugScript, "Line: %d: removeBackground(%d)", _line, param); renderer->removeBg(param); return 0; }
// Reverse and interleave the incoming tdi, tdoExpected arrays: // 0123456789ABCDEFGHIJ -> 9J8I7H6G5F4E3D2C1B0A // static FLStatus swapAndInterleaveBytes(XC *xc, uint32 numBytes, struct Buffer *outBuf, const char **error) { FLStatus retVal = FL_SUCCESS; uint8 *ptr; BufferStatus bStatus; uint32 i = numBytes; bStatus = bufAppendConst(outBuf, 0x00, numBytes*2, error); CHECK_STATUS(bStatus, FL_ALLOC_ERR, cleanup, "swapAndInterleaveBytes()"); ptr = outBuf->data + outBuf->length - 2; while ( i-- ) { *ptr = getNextByte(xc); ptr -= 2; } i = numBytes; ptr = outBuf->data + outBuf->length - 1; while ( i-- ) { *ptr = getNextByte(xc); ptr -= 2; } cleanup: return retVal; }
int FWScript::o2_stopObjectScript() { byte param = getNextByte(); debugC(5, kCineDebugScript, "Line: %d: stopObjectScript(%d)", _line, param); ScriptList::iterator it = g_cine->_objectScripts.begin(); for (; it != g_cine->_objectScripts.end(); ++it) { if ((*it)->_index == param) { (*it)->_index = -1; } } return 0; }
/** * @todo The assert may produce false positives and requires testing */ int FWScript::o2_gotoIfDiffNearest() { byte labelIdx = getNextByte(); if (_compare != kCmpEQ) { assert(_labels[labelIdx] != -1); debugC(5, kCineDebugScript, "Line: %d: if(!=) goto nearest %d (true)", _line, labelIdx); _pos = _script.getLabel(*_info, labelIdx, _pos); } else { debugC(5, kCineDebugScript, "Line: %d: if(!=) goto nearest %d (false)", _line, labelIdx); } return 0; }
DATA_ENCODER_RETURN_TYPE MNMSysexDecoder::get8(uint8_t *c) { uint8_t byte; totalCnt++; again: if (repeatCount > 0) { repeatCount--; *c = repeatByte; DATA_ENCODER_TRUE(); } DATA_ENCODER_CHECK(getNextByte(&byte)); if (IS_BIT_SET(byte, 7)) { repeatCount = byte & 0x7F; DATA_ENCODER_CHECK(getNextByte(&repeatByte)); goto again; } else { *c = byte; DATA_ENCODER_TRUE(); } }
// Read "numBytes" bytes from the stream and write them out in reverse order to the supplied buffer // "outBuf". If ENABLE_SWAP is undefined, no swapping is done. // static FLStatus swapBytes(XC *xc, uint32 numBytes, struct Buffer *outBuf, const char **error) { FLStatus retVal = FL_SUCCESS; uint8 *ptr; BufferStatus bStatus; #ifdef ENABLE_SWAP bStatus = bufAppendConst(outBuf, 0x00, numBytes, error); CHECK_STATUS(bStatus, FL_ALLOC_ERR, cleanup, "swapBytes()"); ptr = outBuf->data + outBuf->length - 1; while ( numBytes-- ) { *ptr-- = getNextByte(xc); } #else const uint32 initLength = outBuf->length; bStatus = bufAppendConst(outBuf, 0x00, numBytes, error); CHECK_STATUS(bStatus, FL_ALLOC_ERR, cleanup, "swapBytes()"); ptr = outBuf->data + initLength - 1; while ( numBytes-- ) { *ptr++ = getNextByte(xc); } #endif cleanup: return retVal; }
int FWScript::o2_playSampleAlt() { byte num = getNextByte(); byte channel = getNextByte(); uint16 frequency = getNextWord(); getNextByte(); getNextWord(); uint16 size = getNextWord(); if (size == 0xFFFF) { size = g_cine->_animDataTable[num]._width * g_cine->_animDataTable[num]._height; } if (g_cine->_animDataTable[num].data()) { if (g_cine->getPlatform() == Common::kPlatformDOS) { // if speaker output is available, play sound on it // if it's another device, don't play anything // TODO: implement this, it's used in the introduction for example // on each letter displayed } else { g_sound->playSound(channel, frequency, g_cine->_animDataTable[num].data(), size, 0, 0, 63, 0); } } return 0; }
// Parse the XSVF, reversing the byte-ordering of all the bytestreams. // static FLStatus xsvfSwapBytes(XC *xc, struct Buffer *outBuf, uint32 *maxBufSize, const char **error) { FLStatus fStatus, retVal = FL_SUCCESS; uint32 newXSize = 0, curXSize = 0, totOffset = 0; uint32 numBytes; BufferStatus bStatus; uint8 thisByte; uint32 dummy; bool zeroMask = false; if ( !maxBufSize ) { maxBufSize = &dummy; } *maxBufSize = 0; thisByte = getNextByte(xc); while ( thisByte != XCOMPLETE ) { switch ( thisByte ) { case XTDOMASK:{ // Swap the XTDOMASK bytes. uint32 initLength; const uint8 *p; const uint8 *end; if ( newXSize != curXSize ) { curXSize = newXSize; sendXSize(outBuf, curXSize, error); } initLength = (uint32)outBuf->length; numBytes = bitsToBytes(curXSize); bStatus = bufAppendByte(outBuf, XTDOMASK, error); CHECK_STATUS(bStatus, FL_ALLOC_ERR, cleanup, "xsvfSwapBytes()"); fStatus = swapBytes(xc, numBytes, outBuf, error); CHECK_STATUS(fStatus, fStatus, cleanup, "xsvfSwapBytes()"); p = outBuf->data + initLength + 1; end = outBuf->data + outBuf->length; while ( *p == 0 && p < end ) p++; if ( p == end ) { // All zeros so delete the command outBuf->length = initLength; zeroMask = true; } else { // Keep the command if ( numBytes > *maxBufSize ) { *maxBufSize = numBytes; } zeroMask = false; } break; } case XSDRTDO: // Swap the tdiValue and tdoExpected bytes. if ( newXSize != curXSize ) { curXSize = newXSize; sendXSize(outBuf, curXSize, error); } numBytes = bitsToBytes(curXSize); if ( zeroMask ) { // The last mask was all zeros, so replace this XSDRTDO with an XSDR and throw away // the tdoExpected bytes. bStatus = bufAppendByte(outBuf, XSDR, error); CHECK_STATUS(bStatus, FL_ALLOC_ERR, cleanup, "xsvfSwapBytes()"); fStatus = swapBytes(xc, numBytes, outBuf, error); CHECK_STATUS(fStatus, fStatus, cleanup, "xsvfSwapBytes()"); while ( numBytes-- ) { getNextByte(xc); } } else { // The last mask was not all zeros, so we must honour the XSDRTDO's tdoExpected bytes. CHECK_STATUS( numBytes > BUF_SIZE, FL_UNSUPPORTED_SIZE_ERR, cleanup, "xsvfSwapBytes(): Previous mask was nonzero, but no room to compare %d bytes", numBytes); if ( numBytes > *maxBufSize ) { *maxBufSize = numBytes; } bStatus = bufAppendByte(outBuf, XSDRTDO, error); CHECK_STATUS(bStatus, FL_ALLOC_ERR, cleanup, "xsvfSwapBytes()"); fStatus = swapAndInterleaveBytes(xc, numBytes, outBuf, error); CHECK_STATUS(fStatus, fStatus, cleanup, "xsvfSwapBytes()"); } break; case XREPEAT: // Drop XREPEAT for now. Will probably be needed for CPLDs. getNextByte(xc); break; case XRUNTEST: // Copy the XRUNTEST bytes as-is. bStatus = bufAppendByte(outBuf, XRUNTEST, error); CHECK_STATUS(bStatus, FL_ALLOC_ERR, cleanup, "xsvfSwapBytes()"); bStatus = bufAppendByte(outBuf, getNextByte(xc), error); CHECK_STATUS(bStatus, FL_ALLOC_ERR, cleanup, "xsvfSwapBytes()"); bStatus = bufAppendByte(outBuf, getNextByte(xc), error); CHECK_STATUS(bStatus, FL_ALLOC_ERR, cleanup, "xsvfSwapBytes()"); bStatus = bufAppendByte(outBuf, getNextByte(xc), error); CHECK_STATUS(bStatus, FL_ALLOC_ERR, cleanup, "xsvfSwapBytes()"); bStatus = bufAppendByte(outBuf, getNextByte(xc), error); CHECK_STATUS(bStatus, FL_ALLOC_ERR, cleanup, "xsvfSwapBytes()"); break; case XSIR: // Swap the XSIR bytes. bStatus = bufAppendByte(outBuf, XSIR, error); CHECK_STATUS(bStatus, FL_ALLOC_ERR, cleanup, "xsvfSwapBytes()"); thisByte = getNextByte(xc); bStatus = bufAppendByte(outBuf, thisByte, error); CHECK_STATUS(bStatus, FL_ALLOC_ERR, cleanup, "xsvfSwapBytes()"); fStatus = swapBytes(xc, (uint32)bitsToBytes(thisByte), outBuf, error); CHECK_STATUS(fStatus, fStatus, cleanup, "xsvfSwapBytes()"); break; case XSDRSIZE: // Just store it; if it differs from the old one it will be sent when required newXSize = getNextByte(xc); // Get MSB newXSize <<= 8; newXSize |= getNextByte(xc); newXSize <<= 8; newXSize |= getNextByte(xc); newXSize <<= 8; newXSize |= getNextByte(xc); // Get LSB break; case XSDR: // Copy over if ( newXSize != curXSize ) { curXSize = newXSize; sendXSize(outBuf, curXSize, error); } bStatus = bufAppendByte(outBuf, XSDR, error); CHECK_STATUS(bStatus, FL_ALLOC_ERR, cleanup, "xsvfSwapBytes()"); fStatus = swapBytes(xc, bitsToBytes(curXSize), outBuf, error); CHECK_STATUS(fStatus, fStatus, cleanup, "xsvfSwapBytes()"); break; case XSDRB: // Roll XSDRB, XSDRC*, XSDRE into one XSDR curXSize = newXSize; sendXSize(outBuf, curXSize, error); totOffset = (uint32)outBuf->length - 4; // each subsequent XSDRC & XSDRE updates this XSDRSIZE bStatus = bufAppendByte(outBuf, XSDR, error); CHECK_STATUS(bStatus, FL_ALLOC_ERR, cleanup, "xsvfSwapBytes()"); fStatus = swapBytes(xc, bitsToBytes(newXSize), outBuf, error); CHECK_STATUS(fStatus, fStatus, cleanup, "xsvfSwapBytes()"); break; case XSDRC: // Just add the XSDRC data to the end of the previous XSDR curXSize += newXSize; bStatus = bufWriteLongBE(outBuf, totOffset, curXSize, error); CHECK_STATUS(bStatus, FL_ALLOC_ERR, cleanup, "xsvfSwapBytes()"); fStatus = swapBytes(xc, bitsToBytes(newXSize), outBuf, error); CHECK_STATUS(fStatus, fStatus, cleanup, "xsvfSwapBytes()"); break; case XSDRE: // Just add the XSDRE data to the end of the previous XSDR curXSize += newXSize; bStatus = bufWriteLongBE(outBuf, totOffset, curXSize, error); CHECK_STATUS(bStatus, FL_ALLOC_ERR, cleanup, "xsvfSwapBytes()"); fStatus = swapBytes(xc, bitsToBytes(newXSize), outBuf, error); CHECK_STATUS(fStatus, fStatus, cleanup, "xsvfSwapBytes()"); break; case XSTATE: // There doesn't seem to be much point in these commands, since the other commands have // implied state transitions anyway. Just make sure the TAP is initialised to be at // Run-Test/Idle before playing the CSVF stream. getNextByte(xc); break; case XENDIR: // Only the default XENDIR state (TAPSTATE_RUN_TEST_IDLE) is supported. Fail fast if // there's an attempt to switch the XENDIR state to PAUSE_IR. thisByte = getNextByte(xc); CHECK_STATUS( thisByte, FL_UNSUPPORTED_DATA_ERR, cleanup, "xsvfSwapBytes(): Only XENDIR(TAPSTATE_RUN_TEST_IDLE) is supported!"); break; case XENDDR: // Only the default XENDDR state (TAPSTATE_RUN_TEST_IDLE) is supported. Fail fast if // there's an attempt to switch the XENDDR state to PAUSE_DR. thisByte = getNextByte(xc); CHECK_STATUS( thisByte, FL_UNSUPPORTED_DATA_ERR, cleanup, "xsvfSwapBytes(): Only XENDDR(TAPSTATE_RUN_TEST_IDLE) is supported!"); break; default: // All other commands are unsupported, so fail if they're encountered. CHECK_STATUS( true, FL_UNSUPPORTED_CMD_ERR, cleanup, "xsvfSwapBytes(): Unsupported command 0x%02X!", thisByte); } thisByte = getNextByte(xc); } // Add the XCOMPLETE command bStatus = bufAppendByte(outBuf, XCOMPLETE, error); CHECK_STATUS(bStatus, FL_ALLOC_ERR, cleanup, "xsvfSwapBytes()"); cleanup: return retVal; }
int main (int argc, char **argv) { int linePos = 0; int precedingNewlines = 0; unsigned char uChar[4]; fillBuf(); uChar[0] = getNextByte(); #ifdef _WIN32 // Work around newline replacement on Windows extern int fileno(FILE*); setmode(fileno(stdout), O_BINARY); #endif while (1) { for (int i = 1; i < 4; i++) { uChar[i] = 0x00; } if ((uChar[0] & 0b11100000) == 0b11100000) { uChar[1] = getNextByte(); uChar[2] = getNextByte(); if (printReplacement(uChar)) { fwrite(uChar, 3, 1, stdout); } precedingNewlines = 0; } else if (uChar[0] == '\r') { uChar[1] = getNextByte(); if (uChar[1] == '\n') { fwrite(&uChar[1], 1, 1, stdout); } precedingNewlines++; linePos = 0; } else { if (uChar[0] == '\n') { precedingNewlines++; /* Handle text wrapping */ uChar[0] = getNextByte(); if (linePos > 45 && uChar[0] != ' ' && uChar[0] != '\t' && uChar[0] != '\n') { fwrite(" ", 1, 1, stdout); } else { fwrite("\n", 1, 1, stdout); } linePos = 0; } if (uChar[0] == 0x91 || uChar[0] == 0x92) { fwrite("'", 1, 1, stdout); precedingNewlines = 0; } else if (uChar[0] == 0x93 || uChar[0] == 0x94) { fwrite("\"", 1, 1, stdout); precedingNewlines = 0; } else if ( (uChar[0] != ' ' && uChar[0] != '\t') || precedingNewlines < 2 || nextLineIndented()) { fwrite(uChar, 1, 1, stdout); if (uChar[0] != '\n') { precedingNewlines = 0; } else { precedingNewlines++; } } } linePos +=1; uChar[0] = getNextByte(); } return 0; }
unsigned char image::getNextMarker() { unsigned char nextMarker; while((nextMarker = getNextByte()) == 0xFF); // to skip any stuffed FF bytes return nextMarker; }
int FWScript::o2_wasZoneChecked() { byte param = getNextByte(); _compare = (param < NUM_MAX_ZONE && g_cine->_zoneQuery[param]) ? 1 : 0; debugC(5, kCineDebugScript, "Line: %d: o2_wasZoneChecked(%d)", _line, param); return 0; }