Ticket #5893: dumpsword.2.c

File dumpsword.2.c, 9.6 KB (added by eriktorbjorn, 12 years ago)

Updated version, but the chances are just cosmetical.

Line 
1#include <stdio.h>
2#include <string.h>
3
4#define ARRAYSIZE(arr) (sizeof(arr) / sizeof(arr[0]))
5
6#define FX_START_DOS 556172
7#define FX_START_WIN 165352
8
9#define NUM_SOUNDS 280
10
11/* Using these resource names, I do get a reasonably close approximation of
12 * the FX list in staticresource.cpp for the sound effects that appear to be
13 * in the demo data files. Though the goal is to eventually create a mapping,
14 * rather than storing two copies of the entire structure.
15 */
16
17const char *resNamesDemo06[] = {
18 /* 00 */
19 "FX_CAMERA1", "FX_CAMERA2", "FX_CAMERA3", "FX_CANDO",
20 "FX_CANUP", "FX_CAW1", "FX_DUST", "FX_HORN1",
21 "FX_HORN2", "FX_HORN3", "FX_PAP1", "FX_PAP2",
22 "FX_PICK1", "FX_PICK2", "FX_PICK3", "FX_PICK4",
23 /* 10 */
24 "FX_PICK5", "FX_TRAFFIC2", "FX_TWEET1", "FX_TWEET2",
25 "FX_TWEET3", "FX_TWEET4", "FX_TWEET5", "FX_BIN1",
26 "FX_BIN2", "FX_BIN3", "FX_CAT", "FX_COVERON2",
27 "FX_CRATE", "FX_DRAIN", "FX_HOLE", "FX_BODY",
28 /* 20 */
29 "FX_BOTDN", "FX_BOTUP", "FX_GULP", "FX_LIGHT",
30 "FX_PIKUP", "FX_PAP3", "FX_PAP4", "FX_PAP5",
31 "FX_PISTOL", "FX_TBOX", "FX_KNOKKNOK", "FX_ALBCLO",
32 "FX_ALBOP", "FX_LADD1", "FX_LADD2", "FX_LADD3",
33 /* 30 */
34 "FX_RAT1", "FX_RAT2", "FX_SEWSTEP1", "FX_SEWSTEP2",
35 "FX_SWATER3", "FX_DRIP1", "FX_DRIP2", "FX_DRIP3",
36 "FX_SWATER1", "FX_SEWLADU7"
37};
38
39const char *resNamesDemo07[] = {
40 /* 00 */
41 "FX_BIRD", "FX_BIRD2", "FX_CARLTON", "FX_CARS",
42 "FX_DOORTRY", "FX_FIESTA", "FX_FLATDOOR", "FX_FONEUP",
43 "FX_FONEDN", "FX_GEOCCH", "FX_GEOCHAIR", "FX_GEOCHR9",
44 NULL, "FX_NICOPEN", "FX_NICLOSE", "FX_PHONICO1",
45 /* 10 */
46 "FX_GRAMOFON", "FX_SHOCK1", "FX_WINDUP11", "FX_FRISK",
47 "FX_TRAFFIC3", "FX_DESKBELL", "FX_PAPER6", "FX_PHONEDN2",
48 "FX_PHONEUP2", "FX_PIANO14", "FX_TRYDOR14", "FX_CABCLOSE",
49 "FX_CABOPEN", "FX_DORCLOSE", "FX_WINDOPEN", "FX_COO",
50 /* 20 */
51 "FX_COO2", "FX_LEDGE1", "FX_LEDGE2", "FX_BRIEFOFF",
52 "FX_BRIEFON", "FX_JUMPIN", "FX_WARDIN", "FX_WARDOUT",
53 "FX_CLIMBIN", "FX_CLIMBOUT"
54};
55
56const char *resNamesDemo08[] = {
57 /* 00 */
58 "FX_MUESEXT", "FX_AIRCON28", "FX_SARCO28A", "FX_SARCO28B",
59 "FX_SARCO28C", "FX_TOTEM28A", "FX_ALARM", "FX_CARABINE",
60 "FX_DOOR29", "FX_FISHFALL", "FX_GDROP29", "FX_GUI_HIT",
61 "FX_GUN1", "FX_ROPEDOWN", "FX_SARCO29", "FX_SMASHGLA",
62 /* 10 */
63 "FX_TOTEM29A", "FX_TOTEM29B", "FX_HOSPEXT", "FX_GRAVEL1",
64 "FX_GRAVEL2", "FX_HOSPNOISE", "FX_CUPBOPEN", "FX_CUPBCLOS",
65 "FX_SHINY", "FX_SHINYOFF", "FX_SHINYON", "FX_BLOODPRE",
66 "FX_GUN34", "FX_PULSE2", "FX_PULSE3"
67};
68
69const char *resNamesDemo09[] = {
70 /* 00 */
71 "FX_MANOP36", "FX_MONTAMB", "FX_OOH", "FX_PULLUP36",
72 "FX_REPLCE36", "FX_AMBIEN37", "FX_CHAIN37_AND37B","FX_DOOR37",
73 "FX_HOLE37", "FX_KNOCK37", "FX_KNOCK37B", "FX_WINCH37",
74 "FX_AIRCON41", "FX_FONEDN41", "FX_FONEUP41", "FX_PHONCALL",
75 /* 10 */
76 "FX_THERM01", "FX_DRIER1", "FX_CHURCHFX"
77};
78
79const char *resNamesDemo0A[] = {
80 /* 00 */
81 "FX_EIRBIRD3", "FX_SHOCK2", "FX_EIRBIRD1", "FX_EIRBIRD2",
82 "FX_SWITCH19", "FX_TRAPOPEN", "FX_VIOLIN19", "FX_WHISTLE",
83 "FX_BARFLAP", "FX_DORCLOSE20","FX_DRINK", "FX_FITZHIT",
84 "FX_FITZRUN", "FX_FITZUP", "FX_FUSE20", "FX_PULLPINT",
85 /* 10 */
86 "FX_WASHER", "FX_CELTAP", "FX_TAP", "FX_TAP2",
87 "FX_CLIMBHAY", "FX_FARMERGO", "FX_CASTLWAL", "FX_CLIMBFAL",
88 "FX_KEYSTEP", "FX_WIND", "FX_GEOGOAT", "FX_GOATBAA",
89 "FX_GOATCHEW", "FX_GOATDOH", "FX_PLOUGH", NULL,
90 /* 20 - FX_RAB3A, FX_RAT3B, FX_RAT3C, and RX_RAT3D all use same id */
91 NULL, "FX_SECDOR25", "FX_SLABFALL", "FX_SLABUP",
92 "FX_TRIGER25", "FX_WRING", "FX_LEVER", "FX_LEVER2",
93 "FX_RAT3ABCD",
94
95};
96
97const char *resNamesDemo0B[] = {
98 /* 00 */
99 "FX_SPNBIRD1", "FX_SPNBIRD2", "FX_AMBIEN56", "FX_DOGS56",
100 "FX_PENDULUM", "FX_CANFALL", "FX_HOSE57", "FX_HOSE57B",
101 "FX_SPAIN", "FX_CHESS", NULL, "FX_LIONFALL",
102 "FX_LIONFAL2", "FX_TOOTHPUL", "FX_SECDOR61", "FX_WELLDRIP"
103};
104
105const char *resNamesDemo0C[] = {
106 /* 00 */
107 "FX_SHOCK3", "FX_STALLBEL", "FX_AYUBDOOR", "FX_BALLPLAY",
108 "FX_CATHIT", "FX_MARIB", "FX_NEWTON", "FX_STALLCAT",
109 "FX_STATBREK", "FX_KEYS49", "FX_MANG1", "FX_MANG2",
110 "FX_MANG3", "FX_UNLOCK49", "FX_WCCHAIN", "FX_CUBDOR",
111 /* 10 */
112 "FX_BREKSTIK", "FX_CLIMBDWN", "FX_CRICKET", "FX_GEOFAL54",
113 "FX_KHANDOWN", "FX_RINGPULL", "FX_SECDOR54", "FX_SHOTKHAN",
114 "FX_SYRIWIND", "FX_THUMP1", "FX_SECDOR55"
115};
116
117const char *resNamesDemo0D[] = {
118 /* 00 */
119 "FX_SHOCK63", "FX_TRAINEXT", "FX_TRAININT", "FX_DOOR65",
120 "FX_WIND66", "FX_WINDOW66", "FX_BRAKES", "FX_DOOR69",
121 "FX_EKSHOOT", "FX_PNEUMO69", "FX_TICK69", "FX_TRNPASS"
122};
123
124const char *resNamesDemo0E[] = {
125 /* 00 */
126 "FX_WIND71", "FX_GUST71", "FX_OWL71A", "FX_OWL71B",
127 "FX_COG72A", "FX_PING", "FX_RUMMAGE1", "FX_RUMMAGE2",
128 "FX_SECDOR72", "FX_DAGGER1", "FX_GUNPOWDR", "FX_TORCH73",
129 "FX_ROSSODIE", "FX_CHOKE1", "FX_CHOKE2", "FX_FIGHT2",
130 /* 10 */
131 "FX_GUN79"
132};
133
134void dumpResNames(const char **resNames, long base, unsigned int numResources) {
135 int i;
136
137 for (i = 0; i < numResources; i++) {
138 if (resNames[i]) {
139 int len = strlen(resNames[i]);
140 printf("#define %s\t\t\t\t", resNames[i]);
141 if (strlen(resNames[i]) < 8)
142 printf("\t\t");
143 else if (strlen(resNames[i]) < 16)
144 printf("\t");
145 printf("0x%08X\n", base + i);
146 }
147 }
148
149 printf("\n");
150}
151
152const char *guessResName(unsigned long resId) {
153 unsigned long resFamily = (resId >> 24) & 0xFF;
154 unsigned long resIndex = resId & 0x00FFFFFF;
155 const char **resNames;
156 int numResources;
157
158 switch (resFamily) {
159 case 0x06:
160 resNames = resNamesDemo06;
161 numResources = ARRAYSIZE(resNamesDemo06);
162 break;
163 case 0x07:
164 resNames = resNamesDemo07;
165 numResources = ARRAYSIZE(resNamesDemo07);
166 break;
167 case 0x08:
168 resNames = resNamesDemo08;
169 numResources = ARRAYSIZE(resNamesDemo08);
170 break;
171 case 0x09:
172 resNames = resNamesDemo09;
173 numResources = ARRAYSIZE(resNamesDemo09);
174 break;
175 case 0x0A:
176 resNames = resNamesDemo0A;
177 numResources = ARRAYSIZE(resNamesDemo0A);
178 break;
179 case 0x0B:
180 resNames = resNamesDemo0B;
181 numResources = ARRAYSIZE(resNamesDemo0B);
182 break;
183 case 0x0C:
184 resNames = resNamesDemo0C;
185 numResources = ARRAYSIZE(resNamesDemo0C);
186 break;
187 case 0x0D:
188 resNames = resNamesDemo0D;
189 numResources = ARRAYSIZE(resNamesDemo0D);
190 break;
191 case 0x0E:
192 resNames = resNamesDemo0E;
193 numResources = ARRAYSIZE(resNamesDemo0E);
194 break;
195 default:
196 return "UNKNOWN";
197 }
198
199 if (resIndex < numResources && resNames[resIndex])
200 return resNames[resIndex];
201
202 return "UNKNOWN";
203}
204
205unsigned long readUint32(FILE *input) {
206 unsigned char buf[4];
207
208 fread(buf, 1, sizeof(buf), input);
209 return buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
210}
211
212void dumpFx(FILE *input, int index) {
213 unsigned long resId = readUint32(input);
214 unsigned long fxType = readUint32(input);
215 unsigned long fxParam = readUint32(input);
216 const char *resName;
217 int silent, len, i;
218
219 printf("\t// %d\n", index);
220 printf("\t{\n");
221 resName = guessResName(resId);
222 len = strlen(resName);
223 printf("\t\t%s,", resName);
224 if (len < 7)
225 printf("\t\t\t");
226 else if (len < 15)
227 printf("\t\t");
228 else
229 printf("\t");
230 printf("// sampleId (0x%08X)\n", resId);
231 printf("\t\t");
232 switch (fxType) {
233 case 1:
234 printf("FX_SPOT");
235 break;
236 case 2:
237 printf("FX_LOOP");
238 break;
239 case 3:
240 printf("FX_RANDOM");
241 break;
242 default:
243 printf("UNKNOWN");
244 break;
245 }
246 printf(",\t\t// type (%d)\n", fxType);
247 printf("\t\t%d,\t\t\t// delay (or random chance)\n", fxParam);
248
249 printf("\t\t{\t\t\t// roomVolList\n");
250
251 silent = 0;
252
253 for (i = 0; i < 7; i++) {
254 unsigned long roomNo = readUint32(input);
255 unsigned long fxLeftVol = readUint32(input);
256 unsigned long fxRightVol = readUint32(input);
257 int terminator = 0;
258
259 if (roomNo == 0 && fxLeftVol == 0 && fxRightVol == 0)
260 terminator = 1;
261
262 if (!silent) {
263 printf("\t\t\t{%d,%d,%d}", roomNo, fxLeftVol, fxRightVol);
264 if (i == 0) {
265 if (!terminator)
266 printf(",");
267 else
268 printf("\t");
269 printf("\t// {roomNo,leftVol,rightVol}");
270 } else if (i < 6 && !terminator)
271 printf(",");
272
273 if (i > 0 && terminator)
274 printf("\t\t// NULL-TERMINATOR");
275
276 printf("\n");
277 }
278
279 if (terminator)
280 silent = 1;
281 }
282
283 printf("\t\t}\n");
284 printf("\t}");
285
286 if (index < NUM_SOUNDS - 1)
287 printf(",");
288
289 printf("\n");
290}
291
292int checkFile(FILE *input, long offset) {
293 unsigned char buf[92];
294 int i;
295
296 fseek(input, offset, SEEK_SET);
297
298 if (fread(buf, 1, sizeof(buf), input) != sizeof(buf)) {
299 return 0;
300 }
301
302 /* The first entry of the data structure is all zeroes */
303 for (i = 0; i < sizeof(buf); i++) {
304 if (buf[i]) {
305 return 0;
306 }
307 }
308
309 return 1;
310}
311
312int dumpAllFx(FILE *input) {
313 int i;
314
315 printf("const FxDef Sound::_fxList[%d] = {\n", NUM_SOUNDS);
316
317 for (i = 0; i < NUM_SOUNDS; i++) {
318 dumpFx(input, i);
319 }
320
321 printf("};\n");
322
323}
324
325int main(int argc, char *argv[]) {
326 FILE *input;
327 long pos;
328
329 if (argc != 2) {
330 fprintf(stderr, "Usage: %s filename\n", argv[0]);
331 return 1;
332 }
333
334 input = fopen(argv[1], "rb");
335 if (!input) {
336 fprintf(stderr, "Could not open '%s' for reading!\n", argv[1]);
337 return 1;
338 }
339
340 if (checkFile(input, FX_START_WIN)) {
341 printf("// Data dumped from Windows EXE\n\n");
342 pos = FX_START_WIN;
343 } else if (checkFile(input, FX_START_DOS)) {
344 printf("// Data dumped from DOS EXE\n\n");
345 pos = FX_START_DOS;
346 } else {
347 fprintf(stderr, "Could not identify the EXE file!\n");
348 return 1;
349 }
350
351 fseek(input, pos, SEEK_SET);
352
353 dumpResNames(resNamesDemo06, 0x06000000, ARRAYSIZE(resNamesDemo06));
354 dumpResNames(resNamesDemo07, 0x07000000, ARRAYSIZE(resNamesDemo07));
355 dumpResNames(resNamesDemo08, 0x08000000, ARRAYSIZE(resNamesDemo08));
356 dumpResNames(resNamesDemo09, 0x09000000, ARRAYSIZE(resNamesDemo09));
357 dumpResNames(resNamesDemo0A, 0x0A000000, ARRAYSIZE(resNamesDemo0A));
358 dumpResNames(resNamesDemo0B, 0x0B000000, ARRAYSIZE(resNamesDemo0B));
359 dumpResNames(resNamesDemo0C, 0x0C000000, ARRAYSIZE(resNamesDemo0C));
360 dumpResNames(resNamesDemo0D, 0x0D000000, ARRAYSIZE(resNamesDemo0D));
361 dumpResNames(resNamesDemo0E, 0x0E000000, ARRAYSIZE(resNamesDemo0E));
362
363 dumpAllFx(input);
364
365 fclose(input);
366 return 0;
367}