diff options
-rw-r--r-- | engines/director/lingo/lingo-bytecode.cpp | 58 | ||||
-rw-r--r-- | engines/director/lingo/lingo-codegen.cpp | 6 | ||||
-rw-r--r-- | engines/director/lingo/lingo-gr.y | 19 |
3 files changed, 51 insertions, 32 deletions
diff --git a/engines/director/lingo/lingo-bytecode.cpp b/engines/director/lingo/lingo-bytecode.cpp index c04515ac07..41dce3dad8 100644 --- a/engines/director/lingo/lingo-bytecode.cpp +++ b/engines/director/lingo/lingo-bytecode.cpp @@ -27,7 +27,7 @@ namespace Director { static struct LingoV4Bytecode { const uint8 opcode; const inst func; - const char *args; + const char *proto; } lingoV4[] = { { 0x03, Lingo::c_voidpush, "" }, { 0x04, Lingo::c_mul, "" }, @@ -63,7 +63,7 @@ static struct LingoV4Bytecode { void Lingo::initBytecode() { for (LingoV4Bytecode *op = lingoV4; op->opcode; op++) { - _lingoV4[op->opcode] = new Opcode( op->func, op->args ); + _lingoV4[op->opcode] = new Opcode( op->func, op->proto ); } } @@ -96,13 +96,13 @@ void Lingo::addCodeV4(Common::SeekableSubReadStreamEndian &stream, ScriptType ty stream.readByte(); } uint16 functions_count = stream.readUint16(); - uint16 unk4 = stream.readUint16(); - uint16 unk5 = stream.readUint16(); + stream.readUint16(); + stream.readUint16(); uint16 consts_count = stream.readUint16(); stream.readUint16(); uint16 consts_offset = stream.readUint16(); stream.readUint16(); - uint16 unk6 = stream.readUint16(); + stream.readUint16(); stream.readUint16(); uint16 consts_base = stream.readUint16(); @@ -216,7 +216,7 @@ void Lingo::addCodeV4(Common::SeekableSubReadStreamEndian &stream, ScriptType ty continue; } - uint32 pointer = start_offset-code_store_offset; + uint16 pointer = start_offset-code_store_offset; Common::Array<uint32> offset_list; while (pointer < end_offset-code_store_offset) { uint8 opcode = code_store[pointer]; @@ -224,38 +224,48 @@ void Lingo::addCodeV4(Common::SeekableSubReadStreamEndian &stream, ScriptType ty pointer += 1; if (_lingoV4.contains(opcode)) { offset_list.push_back(_currentScript->size()); - _currentScript->push_back(_lingoV4[opcode]->func); + g_lingo->code1(_lingoV4[opcode]->func); + size_t argc = strlen(_lingoV4[opcode]->proto); + 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]); + 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])); + pointer += 2; + break; + default: + break; + } + } } else { // unimplemented instruction - inst op_value = 0; - WRITE_UINT32(&op_value, opcode); if (opcode < 0x40) { offset_list.push_back(_currentScript->size()); - _currentScript->push_back(Lingo::c_nop); - _currentScript->push_back(op_value); + g_lingo->code1(Lingo::c_nop); + g_lingo->codeInt(opcode); } else if (opcode < 0x80) { offset_list.push_back(_currentScript->size()); - _currentScript->push_back(Lingo::c_nop1); - _currentScript->push_back(op_value); - inst arg1 = 0; - WRITE_UINT32(&arg1, code_store[pointer]); + g_lingo->code1(Lingo::c_nop1); + g_lingo->codeInt(opcode); offset_list.push_back(_currentScript->size()); - _currentScript->push_back(arg1); + g_lingo->codeInt((uint)code_store[pointer]); pointer += 1; } else { offset_list.push_back(_currentScript->size()); - _currentScript->push_back(Lingo::c_nop2); - _currentScript->push_back(op_value); - inst arg1 = 0; - WRITE_UINT32(&arg1, code_store[pointer]); + g_lingo->code1(Lingo::c_nop2); + g_lingo->codeInt(opcode); offset_list.push_back(_currentScript->size()); - _currentScript->push_back(arg1); - inst arg2 = 0; - WRITE_UINT32(&arg2, code_store[pointer+1]); + g_lingo->codeInt((uint)code_store[pointer]); offset_list.push_back(_currentScript->size()); - _currentScript->push_back(arg2); + g_lingo->codeInt((uint)code_store[pointer+1]); pointer += 2; } } diff --git a/engines/director/lingo/lingo-codegen.cpp b/engines/director/lingo/lingo-codegen.cpp index 425962fafc..07f733f9ca 100644 --- a/engines/director/lingo/lingo-codegen.cpp +++ b/engines/director/lingo/lingo-codegen.cpp @@ -275,21 +275,19 @@ int Lingo::codeFloat(double f) { } int Lingo::codeInt(int val) { - int res = g_lingo->code1(g_lingo->c_intpush); inst i = 0; WRITE_UINT32(&i, val); g_lingo->code1(i); - return res; + return _currentScript->size(); } int Lingo::codeArray(int arraySize) { - int res = g_lingo->code1(g_lingo->c_arraypush); inst i = 0; WRITE_UINT32(&i, arraySize); g_lingo->code1(i); - return res; + return _currentScript->size(); } void Lingo::codeArg(Common::String *s) { diff --git a/engines/director/lingo/lingo-gr.y b/engines/director/lingo/lingo-gr.y index 4348dcdee3..71c9bbbb48 100644 --- a/engines/director/lingo/lingo-gr.y +++ b/engines/director/lingo/lingo-gr.y @@ -150,7 +150,8 @@ asgn: tPUT expr tINTO ID { $$ = $4; delete $2; } | tSET THEENTITY '=' expr { - g_lingo->codeInt(0); // Put dummy id + g_lingo->code1(g_lingo->c_intpush); + g_lingo->codeInt(0); // Put dummy id g_lingo->code1(g_lingo->c_theentityassign); inst e = 0, f = 0; WRITE_UINT32(&e, $2[0]); @@ -172,6 +173,7 @@ asgn: tPUT expr tINTO ID { $$ = $4; delete $2; } | tSET THEENTITY tTO expr { + g_lingo->code1(g_lingo->c_intpush); g_lingo->codeInt(0); // Put dummy id g_lingo->code1(g_lingo->c_theentityassign); inst e = 0, f = 0; @@ -414,7 +416,9 @@ tell: tTELL { $$ = g_lingo->code1(g_lingo->c_tellcode); g_lingo->code1(STOP); } -expr: INT { $$ = g_lingo->codeInt($1); } +expr: INT { + $$ = g_lingo->code1(g_lingo->c_intpush); + g_lingo->codeInt($1); } | FLOAT { $$ = g_lingo->code1(g_lingo->c_floatpush); g_lingo->codeFloat($1); } @@ -440,7 +444,8 @@ expr: INT { $$ = g_lingo->codeInt($1); } g_lingo->codeString($1->c_str()); delete $1; } | THEENTITY { - $$ = g_lingo->codeInt(0); // Put dummy id + $$ = g_lingo->code1(g_lingo->c_intpush); + g_lingo->codeInt(0); // Put dummy id g_lingo->code1(g_lingo->c_theentitypush); inst e = 0, f = 0; WRITE_UINT32(&e, $1[0]); @@ -473,7 +478,7 @@ expr: INT { $$ = g_lingo->codeInt($1); } | '+' expr %prec UNARY { $$ = $2; } | '-' expr %prec UNARY { $$ = $2; g_lingo->code1(g_lingo->c_negate); } | '(' expr ')' { $$ = $2; } - | '[' arglist ']' { $$ = g_lingo->codeArray($2); } + | '[' arglist ']' { $$ = g_lingo->code1(g_lingo->c_arraypush); g_lingo->codeArray($2); } | tSPRITE expr tINTERSECTS expr { g_lingo->code1(g_lingo->c_intersects); } | tSPRITE expr tWITHIN expr { g_lingo->code1(g_lingo->c_within); } | tCHAR expr tOF expr { g_lingo->code1(g_lingo->c_charOf); } @@ -545,12 +550,15 @@ gotofunc: tGO tLOOP { g_lingo->code1(g_lingo->c_gotoloop); } | tGO tNEXT { g_lingo->code1(g_lingo->c_gotonext); } | tGO tPREVIOUS { g_lingo->code1(g_lingo->c_gotoprevious); } | tGO gotoframe { + g_lingo->code1(g_lingo->c_intpush); g_lingo->codeInt(1); g_lingo->code1(g_lingo->c_goto); } | tGO gotoframe gotomovie { + g_lingo->code1(g_lingo->c_intpush); g_lingo->codeInt(3); g_lingo->code1(g_lingo->c_goto); } | tGO gotomovie { + g_lingo->code1(g_lingo->c_intpush); g_lingo->codeInt(2); g_lingo->code1(g_lingo->c_goto); } ; @@ -565,12 +573,15 @@ gotomovie: tOF tMOVIE expr playfunc: tPLAY tDONE { g_lingo->code1(g_lingo->c_playdone); } | tPLAY gotoframe { + g_lingo->code1(g_lingo->c_intpush); g_lingo->codeInt(1); g_lingo->code1(g_lingo->c_play); } | tPLAY gotoframe gotomovie { + g_lingo->code1(g_lingo->c_intpush); g_lingo->codeInt(3); g_lingo->code1(g_lingo->c_play); } | tPLAY gotomovie { + g_lingo->code1(g_lingo->c_intpush); g_lingo->codeInt(2); g_lingo->code1(g_lingo->c_play); } | tPLAYACCEL { g_lingo->codeSetImmediate(true); } arglist { |