[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