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 |
|
---|
17 | const 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 |
|
---|
39 | const 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_PHONIC01",
|
---|
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 |
|
---|
56 | const 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 |
|
---|
69 | const 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 |
|
---|
79 | const 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 |
|
---|
97 | const 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 |
|
---|
105 | const 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 |
|
---|
117 | const 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 |
|
---|
124 | const 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 |
|
---|
134 | void 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 |
|
---|
152 | const 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 |
|
---|
205 | unsigned 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 |
|
---|
212 | void 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 |
|
---|
258 | if (!silent) {
|
---|
259 | printf("\t\t\t{%d,%d,%d}", roomNo, fxLeftVol, fxRightVol);
|
---|
260 | if (i == 0)
|
---|
261 | printf(",\t// {roomNo,leftVol,rightVol}\n");
|
---|
262 | else if (i < 6)
|
---|
263 | printf(",\n");
|
---|
264 | else
|
---|
265 | printf("\n");
|
---|
266 | }
|
---|
267 |
|
---|
268 | if (roomNo == 0 && fxLeftVol == 0 && fxRightVol == 0)
|
---|
269 | silent = 1;
|
---|
270 | }
|
---|
271 |
|
---|
272 | printf("\t\t}\n");
|
---|
273 | printf("\t}");
|
---|
274 |
|
---|
275 | if (index < NUM_SOUNDS - 1)
|
---|
276 | printf(",");
|
---|
277 |
|
---|
278 | printf("\n");
|
---|
279 | }
|
---|
280 |
|
---|
281 | int checkFile(FILE *input, long offset) {
|
---|
282 | unsigned char buf[92];
|
---|
283 | int i;
|
---|
284 |
|
---|
285 | fseek(input, offset, SEEK_SET);
|
---|
286 |
|
---|
287 | if (fread(buf, 1, sizeof(buf), input) != sizeof(buf)) {
|
---|
288 | return 0;
|
---|
289 | }
|
---|
290 |
|
---|
291 | /* The first entry of the data structure is all zeroes */
|
---|
292 | for (i = 0; i < sizeof(buf); i++) {
|
---|
293 | if (buf[i]) {
|
---|
294 | return 0;
|
---|
295 | }
|
---|
296 | }
|
---|
297 |
|
---|
298 | return 1;
|
---|
299 | }
|
---|
300 |
|
---|
301 | int dumpAllFx(FILE *input) {
|
---|
302 | int i;
|
---|
303 |
|
---|
304 | printf("const FxDef::_fxList[%d] = {\n", NUM_SOUNDS);
|
---|
305 |
|
---|
306 | for (i = 0; i < NUM_SOUNDS; i++) {
|
---|
307 | dumpFx(input, i);
|
---|
308 | }
|
---|
309 |
|
---|
310 | printf("};\n");
|
---|
311 |
|
---|
312 | }
|
---|
313 |
|
---|
314 | int main(int argc, char *argv[]) {
|
---|
315 | FILE *input;
|
---|
316 | long pos;
|
---|
317 |
|
---|
318 | if (argc != 2) {
|
---|
319 | fprintf(stderr, "Usage: %s filename\n", argv[0]);
|
---|
320 | return 1;
|
---|
321 | }
|
---|
322 |
|
---|
323 | input = fopen(argv[1], "rb");
|
---|
324 | if (!input) {
|
---|
325 | fprintf(stderr, "Could not open '%s' for reading!\n", argv[1]);
|
---|
326 | return 1;
|
---|
327 | }
|
---|
328 |
|
---|
329 | if (checkFile(input, FX_START_WIN)) {
|
---|
330 | printf("// Data dumped from Windows EXE\n\n");
|
---|
331 | pos = FX_START_WIN;
|
---|
332 | } else if (checkFile(input, FX_START_DOS)) {
|
---|
333 | printf("// Data dumped from DOS EXE\n\n");
|
---|
334 | pos = FX_START_DOS;
|
---|
335 | } else {
|
---|
336 | fprintf(stderr, "Could not identify the EXE file!\n");
|
---|
337 | return 1;
|
---|
338 | }
|
---|
339 |
|
---|
340 | fseek(input, pos, SEEK_SET);
|
---|
341 |
|
---|
342 | dumpResNames(resNamesDemo06, 0x06000000, ARRAYSIZE(resNamesDemo06));
|
---|
343 | dumpResNames(resNamesDemo07, 0x07000000, ARRAYSIZE(resNamesDemo07));
|
---|
344 | dumpResNames(resNamesDemo08, 0x08000000, ARRAYSIZE(resNamesDemo08));
|
---|
345 | dumpResNames(resNamesDemo09, 0x09000000, ARRAYSIZE(resNamesDemo09));
|
---|
346 | dumpResNames(resNamesDemo0A, 0x0A000000, ARRAYSIZE(resNamesDemo0A));
|
---|
347 | dumpResNames(resNamesDemo0B, 0x0B000000, ARRAYSIZE(resNamesDemo0B));
|
---|
348 | dumpResNames(resNamesDemo0C, 0x0C000000, ARRAYSIZE(resNamesDemo0C));
|
---|
349 | dumpResNames(resNamesDemo0D, 0x0D000000, ARRAYSIZE(resNamesDemo0D));
|
---|
350 | dumpResNames(resNamesDemo0E, 0x0E000000, ARRAYSIZE(resNamesDemo0E));
|
---|
351 |
|
---|
352 | dumpAllFx(input);
|
---|
353 |
|
---|
354 | fclose(input);
|
---|
355 | return 0;
|
---|
356 | }
|
---|