diff options
Diffstat (limited to 'engines/director/lingo/lingo-bytecode.cpp')
-rw-r--r-- | engines/director/lingo/lingo-bytecode.cpp | 180 |
1 files changed, 88 insertions, 92 deletions
diff --git a/engines/director/lingo/lingo-bytecode.cpp b/engines/director/lingo/lingo-bytecode.cpp index fcc2236a67..9302c46626 100644 --- a/engines/director/lingo/lingo-bytecode.cpp +++ b/engines/director/lingo/lingo-bytecode.cpp @@ -29,6 +29,7 @@ static struct LingoV4Bytecode { const inst func; const char *proto; } lingoV4[] = { + { 0x01, STOP, "" }, { 0x03, Lingo::c_voidpush, "" }, { 0x04, Lingo::c_mul, "" }, { 0x05, Lingo::c_add, "" }, @@ -56,7 +57,6 @@ static struct LingoV4Bytecode { { 0x1b, Lingo::c_field, "" }, { 0x1c, Lingo::c_tell, "" }, { 0x1d, Lingo::c_telldone, "" }, - { 0x41, Lingo::c_intpush, "b" }, { 0, 0, 0 } }; @@ -68,9 +68,7 @@ void Lingo::initBytecode() { } - - -void Lingo::addCodeV4(Common::SeekableSubReadStreamEndian &stream, ScriptType type, uint16 id) { +void Lingo::addCodeV4(Common::SeekableSubReadStreamEndian &stream, ScriptType type, uint16 id) { debugC(1, kDebugLingoCompile, "Add V4 bytecode for type %s with id %d", scriptType2str(type), id); if (_scriptContexts[type].contains(id)) { @@ -90,116 +88,118 @@ void Lingo::addCodeV4(Common::SeekableSubReadStreamEndian &stream, ScriptType ty for (uint32 i = 0; i < 0x10; i++) { stream.readByte(); } - uint16 code_store_offset = stream.readUint16(); + uint16 codeStoreOffset = stream.readUint16(); // unk2 for (uint32 i = 0; i < 0x2e; i++) { stream.readByte(); } - uint16 globals_offset = stream.readUint16(); - uint16 globals_count = stream.readUint16(); + uint16 globalsOffset = stream.readUint16(); + uint16 globalsCount = stream.readUint16(); // unk3 for (uint32 i = 0; i < 0x4; i++) { stream.readByte(); } - uint16 functions_count = stream.readUint16(); + uint16 functionsCount = stream.readUint16(); stream.readUint16(); - uint16 functions_offset = stream.readUint16(); - uint16 consts_count = stream.readUint16(); + uint16 functionsOffset = stream.readUint16(); + uint16 constsCount = stream.readUint16(); stream.readUint16(); - uint16 consts_offset = stream.readUint16(); + uint16 constsOffset = stream.readUint16(); stream.readUint16(); stream.readUint16(); stream.readUint16(); - uint16 consts_base = stream.readUint16(); + uint16 constsBase = stream.readUint16(); // preload all the constants! // these are stored as a reference table of 6 byte entries, followed by a storage area. // copy the storage area first. - uint32 consts_store_offset = consts_offset+6*consts_count; - uint32 consts_store_size = stream.size()-consts_store_offset; - stream.seek(consts_store_offset); - byte *const_store = (byte *)malloc(consts_store_size); - stream.read(const_store, consts_store_size); + uint32 constsStoreOffset = constsOffset + 6 * constsCount; + uint32 constsStoreSize = stream.size() - constsStoreOffset; + stream.seek(constsStoreOffset); + byte *constsStore = (byte *)malloc(constsStoreSize); + stream.read(constsStore, constsStoreSize); - Common::Array<Datum> const_data; + Common::Array<Datum> constsData; // read each entry in the reference table. - stream.seek(consts_offset); - for (uint16 i=0; i<consts_count; i++) { + stream.seek(constsOffset); + for (uint16 i=0; i < constsCount; i++) { Datum constant; - uint16 const_type = stream.readUint16(); + uint16 constType = stream.readUint16(); uint32 value = stream.readUint32(); - switch (const_type) { - case 1: { // String type - constant.type = STRING; - constant.u.s = new Common::String(); - uint32 pointer = value; - while (pointer < consts_store_size) { - if (const_store[pointer] == '\r') { - constant.u.s += '\n'; - } else if (const_store[pointer] == '\0') { + switch (constType) { + case 1: // String type + { + constant.type = STRING; + constant.u.s = new Common::String(); + uint32 pointer = value; + while (pointer < constsStoreSize) { + if (constsStore[pointer] == '\r') { + constant.u.s += '\n'; + } else if (constsStore[pointer] == '\0') { + break; + } else { + constant.u.s += constsStore[pointer]; + } + pointer += 1; + } + if (pointer >= constsStoreSize) { + warning("Constant string has no null terminator"); break; - } else { - constant.u.s += const_store[pointer]; } - pointer += 1; - } - if (pointer >= consts_store_size) { - warning("Constant string has no null terminator"); - break; } - } - break; + break; case 4: // Integer type constant.type = INT; constant.u.i = (int)value; break; - case 9: { // Float type - constant.type = FLOAT; - if (value < consts_store_offset) { - warning("Constant float start offset is out of bounds"); - break; - } else if (value+4 > consts_store_size) { - warning("Constant float end offset is out of bounds"); - break; + case 9: // Float type + { + constant.type = FLOAT; + if (value < constsStoreOffset) { + warning("Constant float start offset is out of bounds"); + break; + } else if (value + 4 > constsStoreSize) { + warning("Constant float end offset is out of bounds"); + break; + } + constant.u.f = *(float *)(constsStore + value); } - constant.u.f = *(float *)(const_store+value); - } - break; + break; default: warning("Unknown constant type %d", type); break; } - const_data.push_back(constant); + constsData.push_back(constant); } - free(const_store); + free(constsStore); // parse each function! // these are stored as a code storage area, followed by a reference table of 42 byte entries. // copy the storage area first. - uint32 code_store_size = functions_offset - code_store_offset; - stream.seek(code_store_offset); - byte *code_store = (byte *)malloc(code_store_size); - stream.read(code_store, code_store_size); + uint32 codeStoreSize = functionsOffset - codeStoreOffset; + stream.seek(codeStoreOffset); + byte *codeStore = (byte *)malloc(codeStoreSize); + stream.read(codeStore, codeStoreSize); // read each entry in the function table. - stream.seek(functions_offset); - for (uint16 i=0; i<functions_count; i++) { + stream.seek(functionsOffset); + for (uint16 i=0; i<functionsCount; i++) { _currentScriptFunction = i; _currentScriptContext->functions.push_back(new ScriptData); _currentScript = _currentScriptContext->functions[_currentScriptFunction]; - uint16 name_index = stream.readUint16(); + uint16 nameIndex = stream.readUint16(); stream.readUint16(); uint32 length = stream.readUint32(); - uint32 start_offset = stream.readUint32(); - uint16 arg_count = stream.readUint16(); - uint32 arg_offset = stream.readUint32(); - uint16 var_count = stream.readUint16(); - uint32 var_names_offset = stream.readUint32(); + uint32 startOffset = stream.readUint32(); + uint16 argCount = stream.readUint16(); + uint32 argOffset = stream.readUint32(); + uint16 varCount = stream.readUint16(); + uint32 varNamesOffset = stream.readUint32(); stream.readUint16(); stream.readUint16(); stream.readUint16(); @@ -210,35 +210,35 @@ void Lingo::addCodeV4(Common::SeekableSubReadStreamEndian &stream, ScriptType ty stream.readUint16(); stream.readUint16(); - if (start_offset < code_store_offset) { + if (startOffset < codeStoreOffset) { warning("Function %d start offset is out of bounds!", i); continue; - } else if (start_offset + length >= code_store_offset + code_store_size) { + } else if (startOffset + length >= codeStoreOffset + codeStoreSize) { warning("Function %d end offset is out of bounds", i); continue; } - uint16 pointer = start_offset-code_store_offset; - Common::Array<uint32> offset_list; - while (pointer < start_offset+length-code_store_offset) { - uint8 opcode = code_store[pointer]; + uint16 pointer = startOffset - codeStoreOffset; + Common::Array<uint32> offsetList; + while (pointer < startOffset + length - codeStoreOffset) { + uint8 opcode = codeStore[pointer]; pointer += 1; if (_lingoV4.contains(opcode)) { - offset_list.push_back(_currentScript->size()); + offsetList.push_back(_currentScript->size()); g_lingo->code1(_lingoV4[opcode]->func); size_t argc = strlen(_lingoV4[opcode]->proto); - for (uint c=0; c<argc; c++) { + for (uint c=0; c < argc; c++) { switch (_lingoV4[opcode]->proto[c]) { case 'b': - offset_list.push_back(_currentScript->size()); - g_lingo->codeInt((int8)code_store[pointer]); + offsetList.push_back(_currentScript->size()); + g_lingo->codeInt((int8)codeStore[pointer]); pointer += 1; break; case 'w': - offset_list.push_back(_currentScript->size()); - offset_list.push_back(_currentScript->size()); - g_lingo->codeInt((int16)READ_UINT16(&code_store[pointer])); + offsetList.push_back(_currentScript->size()); + offsetList.push_back(_currentScript->size()); + g_lingo->codeInt((int16)READ_UINT16(&codeStore[pointer])); pointer += 2; break; default: @@ -247,37 +247,33 @@ void Lingo::addCodeV4(Common::SeekableSubReadStreamEndian &stream, ScriptType ty } } else { - // exit condition - if (opcode == 0x01) { - offset_list.push_back(_currentScript->size()); - g_lingo->code1(STOP); // unimplemented instruction - } else if (opcode < 0x40) { // 1 byte instruction - offset_list.push_back(_currentScript->size()); + if (opcode < 0x40) { // 1 byte instruction + offsetList.push_back(_currentScript->size()); g_lingo->code1(Lingo::c_unk); g_lingo->codeInt(opcode); } else if (opcode < 0x80) { // 2 byte instruction - offset_list.push_back(_currentScript->size()); + offsetList.push_back(_currentScript->size()); g_lingo->code1(Lingo::c_unk1); g_lingo->codeInt(opcode); - offset_list.push_back(_currentScript->size()); - g_lingo->codeInt((uint)code_store[pointer]); + offsetList.push_back(_currentScript->size()); + g_lingo->codeInt((uint)codeStore[pointer]); pointer += 1; } else { // 3 byte instruction - offset_list.push_back(_currentScript->size()); + offsetList.push_back(_currentScript->size()); g_lingo->code1(Lingo::c_unk2); g_lingo->codeInt(opcode); - offset_list.push_back(_currentScript->size()); - g_lingo->codeInt((uint)code_store[pointer]); - offset_list.push_back(_currentScript->size()); - g_lingo->codeInt((uint)code_store[pointer+1]); + offsetList.push_back(_currentScript->size()); + g_lingo->codeInt((uint)codeStore[pointer]); + offsetList.push_back(_currentScript->size()); + g_lingo->codeInt((uint)codeStore[pointer+1]); pointer += 2; } } } } - free(code_store); + free(codeStore); } |