Ticket #8356: diff_v1_0_1.txt

File diff_v1_0_1.txt, 11.9 KB (added by SF/madm00se, 20 years ago)

Descumm multipatch v1.0.1

Line 
1Index: tools/descumm-common.cpp
2===================================================================
3RCS file: /cvsroot/scummvm/tools/descumm-common.cpp,v
4retrieving revision 1.10
5diff -U8 -d -r1.10 descumm-common.cpp
6--- tools/descumm-common.cpp 21 Sep 2004 15:17:34 -0000 1.10
7+++ tools/descumm-common.cpp 30 Sep 2004 01:06:54 -0000
8@@ -34,16 +34,17 @@
9
10 int g_jump_opcode;
11
12 bool alwaysShowOffs = false;
13 bool dontOutputIfs = false;
14 bool dontOutputElse = false;
15 bool dontOutputElseif = false;
16 bool dontOutputWhile = false;
17+bool dontOutputBreaks = false;
18 bool dontShowOpcode = false;
19 bool dontShowOffsets = false;
20 bool haltOnError;
21
22 byte scriptVersion;
23 byte heVersion;
24
25 byte *cur_pos, *org_pos;
26@@ -198,28 +199,36 @@
27 p->from = cur;
28 p->to = to;
29 return true;
30 }
31
32 // Returns 0 or 1 depending if it's ok to add an else
33 bool maybeAddElse(uint cur, uint to)
34 {
35+ int i;
36 BlockStack *p;
37
38 if (((to | cur) >> 16) || (to <= cur))
39 return false; /* Invalid jump */
40
41 if (!num_block_stack)
42 return false; /* There are no previous blocks, so an else is not ok */
43
44 p = &block_stack[num_block_stack - 1];
45 if (cur != p->to)
46 return false; /* We have no prevoius if that is exiting right at the end of this goto */
47
48+ /* Don't jump out of previous blocks. This test is stronger than the one in
49+ maybeAddIf. ( >= vs > ) */
50+ for (i = 0, p = block_stack; i < num_block_stack - 1; i++, p++) {
51+ if (to >= p->to)
52+ return false;
53+ }
54+
55 num_block_stack--;
56 if (maybeAddIf(cur, to))
57 return true; /* We can add an else */
58 num_block_stack++;
59 return false; /* An else is not OK here :( */
60 }
61
62 bool maybeAddElseIf(uint cur, uint elseto, uint to)
63@@ -241,33 +250,58 @@
64 if (scriptVersion == 8)
65 k = to - 5;
66 else
67 k = to - 3;
68
69 if (k >= size_of_code)
70 return false; /* Invalid jump */
71
72- if (org_pos[k] != g_jump_opcode)
73- return false; /* Invalid jump */
74-
75- if (scriptVersion == 8)
76- k = to + TO_LE_32(*(int32*)(org_pos + k + 1));
77- else
78- k = to + TO_LE_16(*(int16*)(org_pos + k + 1));
79-
80- if (k != elseto)
81- return false; /* Not an ifelse */
82-
83+ if (elseto != to) {
84+ if (org_pos[k] != g_jump_opcode)
85+ return false; /* Invalid jump */
86+
87+ if (scriptVersion == 8)
88+ k = to + TO_LE_32(*(int32*)(org_pos + k + 1));
89+ else
90+ k = to + TO_LE_16(*(int16*)(org_pos + k + 1));
91+
92+ if (k != elseto)
93+ return false; /* Not an ifelse */
94+ }
95 p->from = cur;
96 p->to = to;
97
98 return true;
99 }
100
101+bool maybeAddBreak(uint cur, uint to)
102+{
103+ BlockStack *p;
104+
105+ if (((to | cur) >> 16) || (to <= cur))
106+ return false; /* Invalid jump */
107+
108+ if (!num_block_stack)
109+ return false; /* There are no previous blocks, so a break is not ok */
110+
111+ /* Find the first parent block that is a while and if we're jumping to the end of that, we use a break */
112+ for (int i = num_block_stack - 1; i >= 0; i--) {
113+ p = &block_stack[i];
114+ if (p->isWhile) {
115+ if (to == p->to)
116+ return true;
117+ else
118+ return false;
119+ }
120+ }
121+
122+ return false;
123+}
124+
125 void writePendingElse()
126 {
127 if (pendingElse) {
128 char buf[32];
129 sprintf(buf, alwaysShowOffs ? "} else /*%.4X*/ {" : "} else {", pendingElseTo);
130 outputLine(buf, offs_of_line, pendingElseOpcode, pendingElseIndent - 1);
131 offs_of_line = pendingElseOffs;
132 pendingElse = false;
133Index: tools/descumm-tool.cpp
134===================================================================
135RCS file: /cvsroot/scummvm/tools/descumm-tool.cpp,v
136retrieving revision 1.8
137diff -U8 -d -r1.8 descumm-tool.cpp
138--- tools/descumm-tool.cpp 28 Sep 2004 19:09:16 -0000 1.8
139+++ tools/descumm-tool.cpp 30 Sep 2004 01:06:54 -0000
140@@ -41,16 +41,17 @@
141 "\t-n\tUse Indy3-256 specific hacks\n"
142 "\t-z\tUse Zak256 specific hacks\n"
143 "\t-u\tScript is Unblocked/has no header\n"
144 "\t-o\tAlways Show offsets\n"
145 "\t-i\tDon't output ifs\n"
146 "\t-e\tDon't output else\n"
147 "\t-f\tDon't output else-if\n"
148 "\t-w\tDon't output while\n"
149+ "\t-b\tDon't output breaks\n"
150 "\t-c\tDon't show opcode\n"
151 "\t-x\tDon't show offsets\n"
152 "\t-h\tHalt on error\n");
153 exit(0);
154 }
155
156 int skipVerbHeader_V12(byte *p)
157 {
158@@ -215,16 +216,19 @@
159 dontOutputElse = true;
160 break;
161 case 'f':
162 dontOutputElseif = true;
163 break;
164 case 'w':
165 dontOutputWhile = true;
166 break;
167+ case 'b':
168+ dontOutputBreaks = true;
169+ break;
170 case 'c':
171 dontShowOpcode = true;
172 break;
173 case 'x':
174 dontShowOffsets = true;
175 break;
176 case 'h':
177 haltOnError = true;
178@@ -380,17 +384,18 @@
179 if (haveElse) {
180 haveElse = false;
181 j--;
182 }
183 outputLine(buf, offs_of_line, opcode, j);
184 offs_of_line = get_curoffs();
185 }
186 while (indentBlock(get_curoffs())) {
187- outputLine("}", -1, -1, -1);
188+ outputLine("}", offs_of_line, -1, -1);
189+ offs_of_line = get_curoffs();
190 }
191 fflush(stdout);
192 }
193
194 printf("END\n");
195
196 /*
197 if (scriptVersion >= 6 && num_stack != 0) {
198Index: tools/descumm.h
199===================================================================
200RCS file: /cvsroot/scummvm/tools/descumm.h,v
201retrieving revision 1.13
202diff -U8 -d -r1.13 descumm.h
203--- tools/descumm.h 28 Sep 2004 19:09:16 -0000 1.13
204+++ tools/descumm.h 30 Sep 2004 01:06:54 -0000
205@@ -57,16 +57,17 @@
206 //
207 // Command line options
208 //
209 extern bool alwaysShowOffs;
210 extern bool dontOutputIfs;
211 extern bool dontOutputElse;
212 extern bool dontOutputElseif;
213 extern bool dontOutputWhile;
214+extern bool dontOutputBreaks;
215 extern bool dontShowOpcode;
216 extern bool dontShowOffsets;
217 extern bool haltOnError;
218
219 //
220 // The SCUMM version used for the script we are descumming.
221 //
222 extern byte scriptVersion;
223@@ -93,16 +94,17 @@
224 extern char *strecpy(char *buf, const char *src);
225 extern int get_curoffs();
226 extern int get_byte();
227 extern int get_word();
228
229 extern bool maybeAddIf(uint cur, uint to);
230 extern bool maybeAddElse(uint cur, uint to);
231 extern bool maybeAddElseIf(uint cur, uint elseto, uint to);
232+extern bool maybeAddBreak(uint cur, uint to);
233 extern void writePendingElse();
234
235 //
236 // Entry points for the descumming
237 //
238 extern void next_line_V12(char *buf); // For V1 and V2
239 extern void next_line_V345(char *buf); // For V3, V4, V5
240 extern void next_line_V67(char *buf);
241Index: tools/descumm6.cpp
242===================================================================
243RCS file: /cvsroot/scummvm/tools/descumm6.cpp,v
244retrieving revision 1.180
245diff -U8 -d -r1.180 descumm6.cpp
246--- tools/descumm6.cpp 28 Sep 2004 19:09:16 -0000 1.180
247+++ tools/descumm6.cpp 30 Sep 2004 01:06:55 -0000
248@@ -52,61 +52,16 @@
249 Anyway, the fixed key pattern here seems to be for each case:
250 dup - push - eq - jumpFalse - kill
251 And of course a push before the first of these. Note that there doesn't have
252 to be a jump before each case: after all, "fall through" is possible with C(++)
253 switch/case statements, too, so it's possible they used that in Scumm, too.
254
255 */
256
257-/*
258- FIXME: The current "while" and "else" detection code interfer. There simply are case
259- which they can't decode correctly, leading to completely wrong output. An example
260- can be seen by looking at script 52 of Sam&Max. It gets descummed to this:
261-
262- [002E] (43) localvar1 = 6
263- [0037] (5D) while (localvar1 <= 80) {
264- [0041] (5D) if (array-178[localvar1] == 0) {
265- [004E] (47) array-178[localvar0] = localvar1
266- [0057] (4F) var179 += 1
267- [005A] (73) } else {
268- [005D] (4F) localvar1 += 1
269- [0060] (73) jump 37
270- [0063] (**) }
271- [0063] (**) }
272- [0063] (**) }
273- [0063] (66) stopObjectCodeB()
274-
275- Using "-e" we get the correct result:
276- [002E] (43) localvar1 = 6
277- [0037] (5D) while (localvar1 <= 80) {
278- [0041] (5D) if (array-178[localvar1] == 0) {
279- [004E] (47) array-178[localvar0] = localvar1
280- [0057] (4F) var179 += 1
281- [005A] (73) jump 63
282- [005D] (**) }
283- [005D] (4F) localvar1 += 1
284- [0063] (**) }
285- [0063] (**) }
286- [0060] (66) stopObjectCodeB()
287-(but note the wrong offset in the last line!)
288-
289-When doing raw output, we get this:
290- [0031] (43) localvar1 = 6
291- [0037] (5D) unless ((localvar1 <= 80)) jump 63
292- [0041] (5D) unless ((array-178[localvar1] == 0)) jump 5d
293- [004E] (47) array-178[localvar0] = localvar1
294- [0057] (4F) var179 += 1
295- [005A] (73) jump 63
296- [005D] (4F) localvar1 += 1
297- [0060] (73) jump 37
298- [0063] (66) stopObjectCodeB()
299-
300-*/
301-
302
303 struct StackEnt {
304 byte type;
305 long data;
306 StackEnt *left, *right;
307 char *str;
308 StackEnt **list;
309 };
310@@ -949,23 +904,23 @@
311 where += sprintf(where, "localvar%ld", se->data & 0xFFF);
312 } else {
313 where += sprintf(where, "?var?%ld", se->data);
314 }
315 }
316 break;
317 case seArray:
318 if (se->left) {
319- where += sprintf(where, "array-%ld[", se->data);
320+ where += sprintf(where, "array%ld[", se->data);
321 where = se_astext(se->left, where);
322 where = strecpy(where, "][");
323 where = se_astext(se->right, where);
324 where = strecpy(where, "]");
325 } else {
326- where += sprintf(where, "array-%ld[", se->data);
327+ where += sprintf(where, "array%ld[", se->data);
328 where = se_astext(se->right, where);
329 where = strecpy(where, "]");
330 }
331 break;
332 case seUnary:
333 where += sprintf(where, "%s", oper_list[se->data]);
334 where = se_astext(se->left, where);
335 break;
336@@ -1037,17 +992,24 @@
337 char *e = se_astext(dst, output);
338 e = strecpy(e, " = ");
339 se_astext(src, e);
340 }
341
342 void doAdd(char *output, StackEnt * se, int val)
343 {
344 char *e = se_astext(se, output);
345- sprintf(e, " += %d", val);
346+ if (val == 1) {
347+ sprintf(e, "++");
348+ } else if (val == -1) {
349+ sprintf(e, "--");
350+ } else {
351+ /* SCUMM doesn't support this */
352+ sprintf(e, " += %d", val);
353+ }
354 }
355
356 StackEnt *dup(char *output, StackEnt * se)
357 {
358 static int dupindex = 0;
359
360 if (se->type == seInt)
361 return se;
362@@ -1314,16 +1276,20 @@
363 pendingElseOffs = cur;
364 pendingElseOpcode = g_jump_opcode;
365 pendingElseIndent = num_block_stack;
366 } else {
367 if (num_block_stack && !dontOutputWhile) {
368 BlockStack *p = &block_stack[num_block_stack - 1];
369 if (p->isWhile && cur == p->to)
370 return; // A 'while' ends here.
371+ if (!dontOutputBreaks && maybeAddBreak(cur, to)) {
372+ sprintf(output, "break");
373+ return;
374+ }
375 }
376 sprintf(output, "jump %x", to);
377 }
378 }
379
380 void jumpif(char *output, StackEnt * se, bool negate)
381 {
382 int offset = get_word();
383@@ -1331,31 +1297,27 @@
384 int to = cur + offset;
385 char *e = output;
386
387 if (!dontOutputElseif && pendingElse) {
388 if (maybeAddElseIf(cur, pendingElseTo, to)) {
389 pendingElse = false;
390 haveElse = true;
391 e = strecpy(e, "} else if (");
392- if (negate)
393- se = se_neg(se);
394 e = se_astext(se, e, false);
395 sprintf(e, alwaysShowOffs ? ") /*%.4X*/ {" : ") {", to);
396 return;
397 }
398 }
399
400 if (!dontOutputIfs && maybeAddIf(cur, to)) {
401- if (!dontOutputWhile && block_stack[num_block_stack - 1].isWhile) {
402- e = strecpy(e, "while (");
403- } else
404- e = strecpy(e, "if (");
405- if (negate)
406- se = se_neg(se);
407+ if (!dontOutputWhile && block_stack[num_block_stack - 1].isWhile)
408+ e = strecpy(e, negate ? "until (" : "while (");
409+ else
410+ e = strecpy(e, negate ? "unless (" : "if (");
411 e = se_astext(se, e, false);
412 sprintf(e, alwaysShowOffs ? ") /*%.4X*/ {" : ") {", to);
413 return;
414 }
415
416 e = strecpy(e, negate ? "if (" : "unless (");
417 e = se_astext(se, e);
418 sprintf(e, ") jump %x", to);
419@@ -1518,17 +1480,17 @@
420 "\x97|softUserputOff,"
421 "\x99z|setCursorImg,"
422 "\x9App|setCursorHotspot,"
423 "\x9Cp|initCharset,"
424 "\x9Dl|charsetColors,"
425 "\xD6p|makeCursorColorTransparent");
426 break;
427 case 0x6C:
428- ext(output, "|break");
429+ ext(output, "|breakHere");
430 break;
431 case 0x6D:
432 ext(output, "rlp|ifClassOfIs");
433 break;
434 case 0x6E:
435 ext(output, "lp|setClass");
436 break;
437 case 0x6F:
438@@ -2910,17 +2872,17 @@
439 "\x97|softUserputOff,"
440 "\x99z|setCursorImg,"
441 "\x9App|setCursorHotspot,"
442 "\x9Cp|initCharset,"
443 "\x9Dl|charsetColors,"
444 "\xD6p|makeCursorColorTransparent");
445 break;
446 case 0x6C:
447- ext(output, "|break");
448+ ext(output, "|breakHere");
449 break;
450 case 0x6D:
451 ext(output, "rlp|ifClassOfIs");
452 break;
453 case 0x6E:
454 ext(output, "lp|setClass");
455 break;
456 case 0x6F: