[Scummvm-cvs-logs] CVS: tools descumm-common.cpp,1.10,1.11 descumm-tool.cpp,1.8,1.9 descumm6.cpp,1.180,1.181 descumm.h,1.13,1.14
Max Horn
fingolfin at users.sourceforge.net
Fri Oct 1 11:17:00 CEST 2004
Update of /cvsroot/scummvm/tools
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv32293
Modified Files:
descumm-common.cpp descumm-tool.cpp descumm6.cpp descumm.h
Log Message:
Patch #1037397 (Descumm misdecompilation fix)
Index: descumm-common.cpp
===================================================================
RCS file: /cvsroot/scummvm/tools/descumm-common.cpp,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- descumm-common.cpp 21 Sep 2004 15:17:34 -0000 1.10
+++ descumm-common.cpp 1 Oct 2004 18:16:41 -0000 1.11
@@ -39,6 +39,7 @@
bool dontOutputElse = false;
bool dontOutputElseif = false;
bool dontOutputWhile = false;
+bool dontOutputBreaks = false;
bool dontShowOpcode = false;
bool dontShowOffsets = false;
bool haltOnError;
@@ -203,6 +204,7 @@
// Returns 0 or 1 depending if it's ok to add an else
bool maybeAddElse(uint cur, uint to)
{
+ int i;
BlockStack *p;
if (((to | cur) >> 16) || (to <= cur))
@@ -215,6 +217,13 @@
if (cur != p->to)
return false; /* We have no prevoius if that is exiting right at the end of this goto */
+ /* Don't jump out of previous blocks. This test is stronger than the one in
+ maybeAddIf. ( >= vs > ) */
+ for (i = 0, p = block_stack; i < num_block_stack - 1; i++, p++) {
+ if (to >= p->to)
+ return false;
+ }
+
num_block_stack--;
if (maybeAddIf(cur, to))
return true; /* We can add an else */
@@ -246,23 +255,48 @@
if (k >= size_of_code)
return false; /* Invalid jump */
- if (org_pos[k] != g_jump_opcode)
- return false; /* Invalid jump */
-
- if (scriptVersion == 8)
- k = to + TO_LE_32(*(int32*)(org_pos + k + 1));
- else
- k = to + TO_LE_16(*(int16*)(org_pos + k + 1));
-
- if (k != elseto)
- return false; /* Not an ifelse */
-
+ if (elseto != to) {
+ if (org_pos[k] != g_jump_opcode)
+ return false; /* Invalid jump */
+
+ if (scriptVersion == 8)
+ k = to + TO_LE_32(*(int32*)(org_pos + k + 1));
+ else
+ k = to + TO_LE_16(*(int16*)(org_pos + k + 1));
+
+ if (k != elseto)
+ return false; /* Not an ifelse */
+ }
p->from = cur;
p->to = to;
return true;
}
+bool maybeAddBreak(uint cur, uint to)
+{
+ BlockStack *p;
+
+ if (((to | cur) >> 16) || (to <= cur))
+ return false; /* Invalid jump */
+
+ if (!num_block_stack)
+ return false; /* There are no previous blocks, so a break is not ok */
+
+ /* Find the first parent block that is a while and if we're jumping to the end of that, we use a break */
+ for (int i = num_block_stack - 1; i >= 0; i--) {
+ p = &block_stack[i];
+ if (p->isWhile) {
+ if (to == p->to)
+ return true;
+ else
+ return false;
+ }
+ }
+
+ return false;
+}
+
void writePendingElse()
{
if (pendingElse) {
Index: descumm-tool.cpp
===================================================================
RCS file: /cvsroot/scummvm/tools/descumm-tool.cpp,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- descumm-tool.cpp 28 Sep 2004 19:09:16 -0000 1.8
+++ descumm-tool.cpp 1 Oct 2004 18:16:41 -0000 1.9
@@ -46,6 +46,7 @@
"\t-e\tDon't output else\n"
"\t-f\tDon't output else-if\n"
"\t-w\tDon't output while\n"
+ "\t-b\tDon't output breaks\n"
"\t-c\tDon't show opcode\n"
"\t-x\tDon't show offsets\n"
"\t-h\tHalt on error\n");
@@ -220,6 +221,9 @@
case 'w':
dontOutputWhile = true;
break;
+ case 'b':
+ dontOutputBreaks = true;
+ break;
case 'c':
dontShowOpcode = true;
break;
@@ -385,7 +389,8 @@
offs_of_line = get_curoffs();
}
while (indentBlock(get_curoffs())) {
- outputLine("}", -1, -1, -1);
+ outputLine("}", offs_of_line, -1, -1);
+ offs_of_line = get_curoffs();
}
fflush(stdout);
}
Index: descumm6.cpp
===================================================================
RCS file: /cvsroot/scummvm/tools/descumm6.cpp,v
retrieving revision 1.180
retrieving revision 1.181
diff -u -d -r1.180 -r1.181
--- descumm6.cpp 28 Sep 2004 19:09:16 -0000 1.180
+++ descumm6.cpp 1 Oct 2004 18:16:42 -0000 1.181
@@ -57,51 +57,6 @@
*/
-/*
- FIXME: The current "while" and "else" detection code interfer. There simply are case
- which they can't decode correctly, leading to completely wrong output. An example
- can be seen by looking at script 52 of Sam&Max. It gets descummed to this:
-
- [002E] (43) localvar1 = 6
- [0037] (5D) while (localvar1 <= 80) {
- [0041] (5D) if (array-178[localvar1] == 0) {
- [004E] (47) array-178[localvar0] = localvar1
- [0057] (4F) var179 += 1
- [005A] (73) } else {
- [005D] (4F) localvar1 += 1
- [0060] (73) jump 37
- [0063] (**) }
- [0063] (**) }
- [0063] (**) }
- [0063] (66) stopObjectCodeB()
-
- Using "-e" we get the correct result:
- [002E] (43) localvar1 = 6
- [0037] (5D) while (localvar1 <= 80) {
- [0041] (5D) if (array-178[localvar1] == 0) {
- [004E] (47) array-178[localvar0] = localvar1
- [0057] (4F) var179 += 1
- [005A] (73) jump 63
- [005D] (**) }
- [005D] (4F) localvar1 += 1
- [0063] (**) }
- [0063] (**) }
- [0060] (66) stopObjectCodeB()
-(but note the wrong offset in the last line!)
-
-When doing raw output, we get this:
- [0031] (43) localvar1 = 6
- [0037] (5D) unless ((localvar1 <= 80)) jump 63
- [0041] (5D) unless ((array-178[localvar1] == 0)) jump 5d
- [004E] (47) array-178[localvar0] = localvar1
- [0057] (4F) var179 += 1
- [005A] (73) jump 63
- [005D] (4F) localvar1 += 1
- [0060] (73) jump 37
- [0063] (66) stopObjectCodeB()
-
-*/
-
struct StackEnt {
byte type;
@@ -954,13 +909,13 @@
break;
case seArray:
if (se->left) {
- where += sprintf(where, "array-%ld[", se->data);
+ where += sprintf(where, "array%ld[", se->data);
where = se_astext(se->left, where);
where = strecpy(where, "][");
where = se_astext(se->right, where);
where = strecpy(where, "]");
} else {
- where += sprintf(where, "array-%ld[", se->data);
+ where += sprintf(where, "array%ld[", se->data);
where = se_astext(se->right, where);
where = strecpy(where, "]");
}
@@ -1042,7 +997,14 @@
void doAdd(char *output, StackEnt * se, int val)
{
char *e = se_astext(se, output);
- sprintf(e, " += %d", val);
+ if (val == 1) {
+ sprintf(e, "++");
+ } else if (val == -1) {
+ sprintf(e, "--");
+ } else {
+ /* SCUMM doesn't support this */
+ sprintf(e, " += %d", val);
+ }
}
StackEnt *dup(char *output, StackEnt * se)
@@ -1319,6 +1281,10 @@
BlockStack *p = &block_stack[num_block_stack - 1];
if (p->isWhile && cur == p->to)
return; // A 'while' ends here.
+ if (!dontOutputBreaks && maybeAddBreak(cur, to)) {
+ sprintf(output, "break");
+ return;
+ }
}
sprintf(output, "jump %x", to);
}
@@ -1336,8 +1302,6 @@
pendingElse = false;
haveElse = true;
e = strecpy(e, "} else if (");
- if (negate)
- se = se_neg(se);
e = se_astext(se, e, false);
sprintf(e, alwaysShowOffs ? ") /*%.4X*/ {" : ") {", to);
return;
@@ -1345,12 +1309,10 @@
}
if (!dontOutputIfs && maybeAddIf(cur, to)) {
- if (!dontOutputWhile && block_stack[num_block_stack - 1].isWhile) {
- e = strecpy(e, "while (");
- } else
- e = strecpy(e, "if (");
- if (negate)
- se = se_neg(se);
+ if (!dontOutputWhile && block_stack[num_block_stack - 1].isWhile)
+ e = strecpy(e, negate ? "until (" : "while (");
+ else
+ e = strecpy(e, negate ? "unless (" : "if (");
e = se_astext(se, e, false);
sprintf(e, alwaysShowOffs ? ") /*%.4X*/ {" : ") {", to);
return;
@@ -1523,7 +1485,7 @@
"\xD6p|makeCursorColorTransparent");
break;
case 0x6C:
- ext(output, "|break");
+ ext(output, "|breakHere");
break;
case 0x6D:
ext(output, "rlp|ifClassOfIs");
@@ -2915,7 +2877,7 @@
"\xD6p|makeCursorColorTransparent");
break;
case 0x6C:
- ext(output, "|break");
+ ext(output, "|breakHere");
break;
case 0x6D:
ext(output, "rlp|ifClassOfIs");
Index: descumm.h
===================================================================
RCS file: /cvsroot/scummvm/tools/descumm.h,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- descumm.h 28 Sep 2004 19:09:16 -0000 1.13
+++ descumm.h 1 Oct 2004 18:16:42 -0000 1.14
@@ -62,6 +62,7 @@
extern bool dontOutputElse;
extern bool dontOutputElseif;
extern bool dontOutputWhile;
+extern bool dontOutputBreaks;
extern bool dontShowOpcode;
extern bool dontShowOffsets;
extern bool haltOnError;
@@ -98,6 +99,7 @@
extern bool maybeAddIf(uint cur, uint to);
extern bool maybeAddElse(uint cur, uint to);
extern bool maybeAddElseIf(uint cur, uint elseto, uint to);
+extern bool maybeAddBreak(uint cur, uint to);
extern void writePendingElse();
//
More information about the Scummvm-git-logs
mailing list