mirror of
https://github.com/libretro/scummvm.git
synced 2025-02-12 22:51:11 +00:00
DIRECTOR: LINGO: Fix string constants, make constant pushing inline
This commit is contained in:
parent
d1347b0ce1
commit
e943f8c291
@ -56,7 +56,7 @@ static LingoV4Bytecode lingoV4[] = {
|
|||||||
{ 0x41, Lingo::c_intpush, "b" },
|
{ 0x41, Lingo::c_intpush, "b" },
|
||||||
{ 0x42, Lingo::c_argcpush, "b" },
|
{ 0x42, Lingo::c_argcpush, "b" },
|
||||||
{ 0x43, Lingo::c_argcnoretpush, "b" },
|
{ 0x43, Lingo::c_argcnoretpush, "b" },
|
||||||
{ 0x44, Lingo::c_constpush, "bv" },
|
// 0x44, push a constant
|
||||||
{ 0x45, Lingo::c_namepush, "b" },
|
{ 0x45, Lingo::c_namepush, "b" },
|
||||||
{ 0x53, Lingo::c_jump, "jb" },
|
{ 0x53, Lingo::c_jump, "jb" },
|
||||||
{ 0x54, Lingo::c_jump, "jbn" },
|
{ 0x54, Lingo::c_jump, "jbn" },
|
||||||
@ -69,7 +69,7 @@ static LingoV4Bytecode lingoV4[] = {
|
|||||||
{ 0x81, Lingo::c_intpush, "w" },
|
{ 0x81, Lingo::c_intpush, "w" },
|
||||||
{ 0x82, Lingo::c_argcpush, "w" },
|
{ 0x82, Lingo::c_argcpush, "w" },
|
||||||
{ 0x83, Lingo::c_argcnoretpush, "w" },
|
{ 0x83, Lingo::c_argcnoretpush, "w" },
|
||||||
{ 0x84, Lingo::c_constpush, "wv" },
|
// 0x84, push a constant
|
||||||
{ 0x93, Lingo::c_jump, "jw" },
|
{ 0x93, Lingo::c_jump, "jw" },
|
||||||
{ 0x94, Lingo::c_jump, "jwn" },
|
{ 0x94, Lingo::c_jump, "jwn" },
|
||||||
{ 0x95, Lingo::c_jumpifz, "jw" },
|
{ 0x95, Lingo::c_jumpifz, "jw" },
|
||||||
@ -449,13 +449,24 @@ void Lingo::addCodeV4(Common::SeekableSubReadStreamEndian &stream, ScriptType ty
|
|||||||
constant.type = STRING;
|
constant.type = STRING;
|
||||||
constant.u.s = new Common::String();
|
constant.u.s = new Common::String();
|
||||||
uint32 pointer = value;
|
uint32 pointer = value;
|
||||||
while (pointer < constsStoreSize) {
|
if (pointer + 4 >= constsStoreSize) {
|
||||||
|
error("Constant string is too small");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
uint32 length = READ_BE_UINT32(&constsStore[pointer]);
|
||||||
|
pointer += 4;
|
||||||
|
uint32 end = pointer + length;
|
||||||
|
if (end >= constsStoreSize) {
|
||||||
|
error("Constant string is too large");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
while (pointer < end) {
|
||||||
if (constsStore[pointer] == '\r') {
|
if (constsStore[pointer] == '\r') {
|
||||||
constant.u.s += '\n';
|
*constant.u.s += '\n';
|
||||||
} else if (constsStore[pointer] == '\0') {
|
} else if (constsStore[pointer] == '\0') {
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
constant.u.s += constsStore[pointer];
|
*constant.u.s += constsStore[pointer];
|
||||||
}
|
}
|
||||||
pointer += 1;
|
pointer += 1;
|
||||||
}
|
}
|
||||||
@ -548,9 +559,60 @@ void Lingo::addCodeV4(Common::SeekableSubReadStreamEndian &stream, ScriptType ty
|
|||||||
Common::Array<uint32> jumpList;
|
Common::Array<uint32> jumpList;
|
||||||
while (pointer < startOffset + length - codeStoreOffset) {
|
while (pointer < startOffset + length - codeStoreOffset) {
|
||||||
uint8 opcode = codeStore[pointer];
|
uint8 opcode = codeStore[pointer];
|
||||||
|
|
||||||
pointer += 1;
|
pointer += 1;
|
||||||
if (_lingoV4.contains(opcode)) {
|
|
||||||
|
if (opcode == 0x44 || opcode == 0x84) {
|
||||||
|
// push a constant
|
||||||
|
offsetList.push_back(_currentScript->size());
|
||||||
|
int arg = 0;
|
||||||
|
if (opcode == 0x84) {
|
||||||
|
arg = (uint16)READ_BE_UINT16(&codeStore[pointer]);
|
||||||
|
pointer += 2;
|
||||||
|
} else {
|
||||||
|
arg = (uint8)codeStore[pointer];
|
||||||
|
pointer += 1;
|
||||||
|
}
|
||||||
|
// remove struct size alignment
|
||||||
|
if (arg % 6) {
|
||||||
|
warning("Opcode 0x%02x arg %d not a multiple of 6!", opcode, arg);
|
||||||
|
}
|
||||||
|
arg /= 6;
|
||||||
|
Datum constant = _currentScriptContext->constants[arg];
|
||||||
|
switch (constant.type) {
|
||||||
|
case INT:
|
||||||
|
g_lingo->code1(Lingo::c_intpush);
|
||||||
|
break;
|
||||||
|
case FLOAT:
|
||||||
|
g_lingo->code1(Lingo::c_floatpush);
|
||||||
|
break;
|
||||||
|
case STRING:
|
||||||
|
g_lingo->code1(Lingo::c_stringpush);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
error("Unknown constant type %d", constant.type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (opcode == 0x84) {
|
||||||
|
offsetList.push_back(_currentScript->size());
|
||||||
|
offsetList.push_back(_currentScript->size());
|
||||||
|
} else {
|
||||||
|
offsetList.push_back(_currentScript->size());
|
||||||
|
}
|
||||||
|
switch (constant.type) {
|
||||||
|
case INT:
|
||||||
|
g_lingo->codeInt(constant.u.i);
|
||||||
|
break;
|
||||||
|
case FLOAT:
|
||||||
|
g_lingo->codeFloat(constant.u.f);
|
||||||
|
break;
|
||||||
|
case STRING:
|
||||||
|
g_lingo->codeString(constant.u.s->c_str());
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
error("Unknown constant type %d", constant.type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (_lingoV4.contains(opcode)) {
|
||||||
offsetList.push_back(_currentScript->size());
|
offsetList.push_back(_currentScript->size());
|
||||||
g_lingo->code1(_lingoV4[opcode]->func);
|
g_lingo->code1(_lingoV4[opcode]->func);
|
||||||
|
|
||||||
@ -572,13 +634,6 @@ void Lingo::addCodeV4(Common::SeekableSubReadStreamEndian &stream, ScriptType ty
|
|||||||
arg = (uint16)READ_BE_UINT16(&codeStore[pointer]);
|
arg = (uint16)READ_BE_UINT16(&codeStore[pointer]);
|
||||||
pointer += 2;
|
pointer += 2;
|
||||||
break;
|
break;
|
||||||
case 'v':
|
|
||||||
// argument refers to a variable; remove struct size alignment
|
|
||||||
if (arg % 6) {
|
|
||||||
warning("Opcode 0x%02x arg %d not a multiple of 6!", opcode, arg);
|
|
||||||
}
|
|
||||||
arg /= 6;
|
|
||||||
break;
|
|
||||||
case 'n':
|
case 'n':
|
||||||
// argument is negative
|
// argument is negative
|
||||||
arg *= -1;
|
arg *= -1;
|
||||||
|
@ -66,7 +66,6 @@ static struct FuncDescr {
|
|||||||
{ Lingo::c_floatpush, "c_floatpush", "f" },
|
{ Lingo::c_floatpush, "c_floatpush", "f" },
|
||||||
{ Lingo::c_stringpush, "c_stringpush", "s" },
|
{ Lingo::c_stringpush, "c_stringpush", "s" },
|
||||||
{ Lingo::c_symbolpush, "c_symbolpush", "s" }, // D3
|
{ Lingo::c_symbolpush, "c_symbolpush", "s" }, // D3
|
||||||
{ Lingo::c_constpush, "c_constpush", "i" },
|
|
||||||
{ Lingo::c_namepush, "c_namepush", "i" },
|
{ Lingo::c_namepush, "c_namepush", "i" },
|
||||||
{ Lingo::c_varpush, "c_varpush", "s" },
|
{ Lingo::c_varpush, "c_varpush", "s" },
|
||||||
{ Lingo::c_setImmediate,"c_setImmediate","i" },
|
{ Lingo::c_setImmediate,"c_setImmediate","i" },
|
||||||
@ -250,13 +249,6 @@ void Lingo::c_symbolpush() {
|
|||||||
g_lingo->push(Datum(new Common::String(s)));
|
g_lingo->push(Datum(new Common::String(s)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Lingo::c_constpush() {
|
|
||||||
Datum d;
|
|
||||||
int i = g_lingo->readInt();
|
|
||||||
d = g_lingo->_currentScriptContext->constants[i];
|
|
||||||
g_lingo->push(d);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Lingo::c_namepush() {
|
void Lingo::c_namepush() {
|
||||||
Datum d;
|
Datum d;
|
||||||
int i = g_lingo->readInt();
|
int i = g_lingo->readInt();
|
||||||
|
@ -295,7 +295,6 @@ public:
|
|||||||
static void c_floatpush();
|
static void c_floatpush();
|
||||||
static void c_stringpush();
|
static void c_stringpush();
|
||||||
static void c_symbolpush();
|
static void c_symbolpush();
|
||||||
static void c_constpush();
|
|
||||||
static void c_namepush();
|
static void c_namepush();
|
||||||
static void c_varpush();
|
static void c_varpush();
|
||||||
static void c_argcpush();
|
static void c_argcpush();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user