1 /***********************************************************
2 * Rocks'n'Diamonds -- McDuffin Strikes Back! *
3 *----------------------------------------------------------*
4 * (c) 1995-2002 Artsoft Entertainment *
6 * Detmolder Strasse 189 *
9 * e-mail: info@artsoft.org *
10 *----------------------------------------------------------*
12 ***********************************************************/
14 #include "libgame/libgame.h"
22 Bitmap *pix[NUM_BITMAPS];
23 Pixmap tile_clipmask[NUM_TILES];
24 DrawBuffer *fieldbuffer;
25 DrawBuffer *drawto_field;
27 int game_status = MAINMENU;
28 boolean level_editor_test_game = FALSE;
29 boolean network_playing = FALSE;
31 int key_joystick_mapping = 0;
33 boolean redraw[MAX_BUF_XSIZE][MAX_BUF_YSIZE];
34 int redraw_x1 = 0, redraw_y1 = 0;
36 short Feld[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
37 short Ur[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
38 short MovPos[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
39 short MovDir[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
40 short MovDelay[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
41 short Store[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
42 short Store2[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
43 short StorePlayer[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
44 short Frame[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
45 short GfxAction[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
46 boolean Stop[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
47 short JustStopped[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
48 short AmoebaNr[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
49 short AmoebaCnt[MAX_NUM_AMOEBA], AmoebaCnt2[MAX_NUM_AMOEBA];
50 short ExplodeField[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
51 unsigned long Elementeigenschaften1[MAX_ELEMENTS];
52 unsigned long Elementeigenschaften2[MAX_ELEMENTS];
54 int lev_fieldx,lev_fieldy, scroll_x,scroll_y;
56 int FX = SX, FY = SY, ScrollStepSize;
57 int ScreenMovDir = MV_NO_MOVING, ScreenMovPos = 0;
59 int BorderElement = EL_STEELWALL;
60 int GameFrameDelay = GAME_FRAME_DELAY;
61 int FfwdFrameDelay = FFWD_FRAME_DELAY;
62 int BX1 = 0, BY1 = 0, BX2 = SCR_FIELDX-1, BY2 = SCR_FIELDY-1;
63 int SBX_Left, SBX_Right;
64 int SBY_Upper, SBY_Lower;
65 int ZX,ZY, ExitX,ExitY;
68 int TimeFrames, TimePlayed, TimeLeft;
70 boolean network_player_action_received = FALSE;
72 struct LevelInfo level;
73 struct PlayerInfo stored_player[MAX_PLAYERS], *local_player = NULL;
74 struct HiScore highscore[MAX_SCORE_ENTRIES];
76 struct SetupInfo setup;
78 struct GlobalInfo global;
80 /* filenames of sound effects */
81 char *sound_name[NUM_SOUNDS] =
140 /* this is used to reduce memory usage of the different animation types */
141 int graphics_action_mapping[] =
143 0, /* GFX_ACTION_DEFAULT (0) */
144 0, /* GFX_ACTION_WAITING (1) */
146 1, /* GFX_ACTION_FALLING (2) */
147 2, /* GFX_ACTION_MOVING (3) */
148 3, /* GFX_ACTION_DIGGING (4) */
149 4, /* GFX_ACTION_SNAPPING (5) */
150 5, /* GFX_ACTION_COLLECTING (6) */
151 6, /* GFX_ACTION_PUSHING (7) */
153 7, /* GFX_ACTION_PASSING (8) */
154 7, /* GFX_ACTION_IMPACT (9) */
155 7, /* GFX_ACTION_CRACKING (10) */
156 7, /* GFX_ACTION_BREAKING (11) */
157 7, /* GFX_ACTION_ACTIVATING (12) */
158 7, /* GFX_ACTION_OPENING (13) */
159 7, /* GFX_ACTION_CLOSING (14) */
160 7, /* GFX_ACTION_EATING (15) */
161 7, /* GFX_ACTION_ATTACKING (16) */
162 7, /* GFX_ACTION_GROWING (17) */
163 7, /* GFX_ACTION_SHRINKING (18) */
164 7 /* GFX_ACTION_OTHER (19) */
167 struct FileInfo *image_files;
168 struct FileInfo *sound_files;
170 struct ElementInfo element_info[MAX_ELEMENTS] =
172 { "empty_space", "empty space" }, /* 0 */
174 { "wall", "normal wall" },
175 { "wall", "round wall" },
178 { "emerald", "emerald" },
179 { "exit", "closed exit" },
180 { "player", "player" },
182 { "spaceship", "spaceship" }, /* 10 */
183 { "yamyam", "yam yam" },
184 { "robot", "robot" },
185 { "wall", "steel wall" },
186 { "diamond", "diamond" },
187 { "amoeba", "dead amoeba" },
188 { "quicksand", "empty quicksand" },
189 { "quicksand", "quicksand with rock" },
190 { "amoeba", "amoeba drop" },
192 { "magic_wall", "magic wall" }, /* 20 */
193 { "speed_pill", "speed pill" },
194 { "acid", "acid pool" },
195 { "amoeba", "dropping amoeba" },
196 { "amoeba", "normal amoeba" },
197 { "nut", "nut with emerald" },
198 { "gameoflife", "Conway's wall of life" },
199 { "biomaze", "biomaze" },
200 { "dynamite", "burning dynamite" },
202 { "robot_wheel", "magic wheel" }, /* 30 */
203 { "robot_wheel", "magic wheel (running)" },
204 { "key", "red key" },
205 { "key", "yellow key" },
206 { "key", "green key" },
207 { "key", "blue key" },
208 { "gate", "red door" },
209 { "gate", "yellow door" },
210 { "gate", "green door" },
211 { "gate", "blue door" },
212 { "gate", "gray door (opened by red key)" }, /* 40 */
213 { "gate", "gray door (opened by yellow key)"},
214 { "gate", "gray door (opened by green key)"},
215 { "gate", "gray door (opened by blue key)"},
216 { "dynamite", "dynamite" },
217 { "pacman", "pac man" },
218 { "wall", "invisible normal wall" },
219 { "lamp", "lamp (off)" },
220 { "lamp", "lamp (on)" },
221 { "wall", "wall with emerald" },
222 { "wall", "wall with diamond" }, /* 50 */
223 { "amoeba", "amoeba with content" },
224 { "bd_amoeba", "amoeba (BD style)" },
225 { "time_orb_full", "time orb (full)" },
226 { "time_orb_empty", "time orb (empty)" },
227 { "wall", "growing wall" },
228 { "bd_diamond", "diamond (BD style)" },
229 { "emerald", "yellow emerald" },
230 { "wall", "wall with BD style diamond" },
231 { "wall", "wall with yellow emerald" },
232 { "dark_yamyam", "dark yam yam" }, /* 60 */
233 { "bd_magic_wall", "magic wall (BD style)" },
234 { "wall", "invisible steel wall" },
236 { "dynabomb_nr", "increases number of bombs" },
237 { "dynabomb_sz", "increases explosion size" },
238 { "dynabomb_xl", "increases power of explosion" },
239 { "sokoban_object", "sokoban object" },
240 { "sokoban_field", "sokoban empty field" },
241 { "sokoban_field", "sokoban field with object" },
242 { "bd_butterfly", "butterfly (starts moving right)"}, /* 70 */
243 { "bd_butterfly", "butterfly (starts moving up)" },
244 { "bd_butterfly", "butterfly (starts moving left)"},
245 { "bd_butterfly", "butterfly (starts moving down)"},
246 { "bd_firefly", "firefly (starts moving right)" },
247 { "bd_firefly", "firefly (starts moving up)" },
248 { "bd_firefly", "firefly (starts moving left)" },
249 { "bd_firefly", "firefly (starts moving down)" },
250 { "bd_butterfly", "butterfly" },
251 { "bd_firefly", "firefly" },
252 { "player", "yellow player" }, /* 80 */
253 { "player", "red player" },
254 { "player", "green player" },
255 { "player", "blue player" },
256 { "bug", "bug (starts moving right)" },
257 { "bug", "bug (starts moving up)" },
258 { "bug", "bug (starts moving left)" },
259 { "bug", "bug (starts moving down)" },
260 { "spaceship", "spaceship (starts moving right)"},
261 { "spaceship", "spaceship (starts moving up)" },
262 { "spaceship", "spaceship (starts moving left)"}, /* 90 */
263 { "spaceship", "spaceship (starts moving down)"},
264 { "pacman", "pac man (starts moving right)" },
265 { "pacman", "pac man (starts moving up)" },
266 { "pacman", "pac man (starts moving left)" },
267 { "pacman", "pac man (starts moving down)" },
268 { "emerald", "red emerald" },
269 { "emerald", "purple emerald" },
270 { "wall", "wall with red emerald" },
271 { "wall", "wall with purple emerald" },
272 { NULL, "unknown" }, /* 100 */
277 { NULL, "normal wall (BD style)" },
278 { "bd_rock", "rock (BD style)" },
279 { "exit", "open exit" },
280 { NULL, "black orb bomb" },
281 { "amoeba", "amoeba" },
282 { "mole", "mole" }, /* 110 */
283 { "penguin", "penguin" },
284 { "satellite", "satellite" },
285 { NULL, "arrow left" },
286 { NULL, "arrow right" },
287 { NULL, "arrow up" },
288 { NULL, "arrow down" },
290 { "dragon", "fire breathing dragon" },
291 { "key", "red key (EM style)" },
292 { NULL, "letter ' '" }, /* 120 */
293 { NULL, "letter '!'" },
294 { NULL, "letter '\"'" },
295 { NULL, "letter '#'" },
296 { NULL, "letter '$'" },
297 { NULL, "letter '%'" },
298 { NULL, "letter '&'" },
299 { NULL, "letter '''" },
300 { NULL, "letter '('" },
301 { NULL, "letter ')'" },
302 { NULL, "letter '*'" }, /* 130 */
303 { NULL, "letter '+'" },
304 { NULL, "letter ','" },
305 { NULL, "letter '-'" },
306 { NULL, "letter '.'" },
307 { NULL, "letter '/'" },
308 { NULL, "letter '0'" },
309 { NULL, "letter '1'" },
310 { NULL, "letter '2'" },
311 { NULL, "letter '3'" },
312 { NULL, "letter '4'" }, /* 140 */
313 { NULL, "letter '5'" },
314 { NULL, "letter '6'" },
315 { NULL, "letter '7'" },
316 { NULL, "letter '8'" },
317 { NULL, "letter '9'" },
318 { NULL, "letter ':'" },
319 { NULL, "letter ';'" },
320 { NULL, "letter '<'" },
321 { NULL, "letter '='" },
322 { NULL, "letter '>'" }, /* 150 */
323 { NULL, "letter '?'" },
324 { NULL, "letter '@'" },
325 { NULL, "letter 'A'" },
326 { NULL, "letter 'B'" },
327 { NULL, "letter 'C'" },
328 { NULL, "letter 'D'" },
329 { NULL, "letter 'E'" },
330 { NULL, "letter 'F'" },
331 { NULL, "letter 'G'" },
332 { NULL, "letter 'H'" }, /* 160 */
333 { NULL, "letter 'I'" },
334 { NULL, "letter 'J'" },
335 { NULL, "letter 'K'" },
336 { NULL, "letter 'L'" },
337 { NULL, "letter 'M'" },
338 { NULL, "letter 'N'" },
339 { NULL, "letter 'O'" },
340 { NULL, "letter 'P'" },
341 { NULL, "letter 'Q'" },
342 { NULL, "letter 'R'" }, /* 170 */
343 { NULL, "letter 'S'" },
344 { NULL, "letter 'T'" },
345 { NULL, "letter 'U'" },
346 { NULL, "letter 'V'" },
347 { NULL, "letter 'W'" },
348 { NULL, "letter 'X'" },
349 { NULL, "letter 'Y'" },
350 { NULL, "letter 'Z'" },
351 { NULL, "letter 'Ä'" },
352 { NULL, "letter 'Ö'" }, /* 180 */
353 { NULL, "letter 'Ü'" },
354 { NULL, "letter '^'" },
355 { NULL, "letter ''" },
356 { NULL, "letter ''" },
357 { NULL, "letter ''" },
358 { NULL, "letter ''" },
359 { NULL, "letter ''" },
360 { NULL, "letter ''" },
361 { NULL, "letter ''" },
362 { NULL, "letter ''" }, /* 190 */
363 { NULL, "letter ''" },
364 { NULL, "letter ''" },
365 { NULL, "letter ''" },
366 { NULL, "letter ''" },
367 { NULL, "letter ''" },
368 { NULL, "letter ''" },
369 { NULL, "letter ''" },
370 { NULL, "letter ''" },
371 { NULL, "letter ''" },
372 { "wall", "growing wall (horizontal)" }, /* 200 */
373 { "wall", "growing wall (vertical)" },
374 { "wall", "growing wall (all directions)" },
375 { "gate", "red door (EM style)" },
376 { "gate", "yellow door (EM style)" },
377 { "gate", "green door (EM style)" },
378 { "gate", "blue door (EM style)" },
379 { "key", "yellow key (EM style)" },
380 { "key", "green key (EM style)" },
381 { "key", "blue key (EM style)" },
382 { "empty_space", "empty space" }, /* 210 */
383 { "sp_zonk", "zonk" },
384 { "sp_base", "base" },
385 { "player", "murphy" },
386 { "sp_infotron", "infotron" },
387 { "wall", "chip (single)" },
388 { "wall", "hardware" },
389 { "sp_exit", "exit" },
390 { "sp_disk_orange", "orange disk" },
391 { "sp_port", "port (leading right)" },
392 { "sp_port", "port (leading down)" }, /* 220 */
393 { "sp_port", "port (leading left)" },
394 { "sp_port", "port (leading up)" },
395 { "sp_port", "port (leading right)" },
396 { "sp_port", "port (leading down)" },
397 { "sp_port", "port (leading left)" },
398 { "sp_port", "port (leading up)" },
399 { "sp_sniksnak", "snik snak" },
400 { "sp_disk_yellow", "yellow disk" },
401 { "sp_terminal", "terminal" },
402 { "sp_disk_red", "red disk" }, /* 230 */
403 { "sp_port", "port (vertical)" },
404 { "sp_port", "port (horizontal)" },
405 { "sp_port", "port (all directions)" },
406 { "sp_electron", "electron" },
407 { "sp_buggy_base", "buggy base" },
408 { "wall", "chip (left half)" },
409 { "wall", "chip (right half)" },
410 { "wall", "hardware" },
411 { "wall", "hardware" },
412 { "wall", "hardware" }, /* 240 */
413 { "wall", "hardware" },
414 { "wall", "hardware" },
415 { "wall", "hardware" },
416 { "wall", "hardware" },
417 { "wall", "hardware" },
418 { "wall", "hardware" },
419 { "wall", "hardware" },
420 { "wall", "chip (upper half)" },
421 { "wall", "chip (lower half)" },
422 { "gate", "gray door (EM style, red key)" }, /* 250 */
423 { "gate", "gray door (EM style, yellow key)"},
424 { "gate", "gray door (EM style, green key)"},
425 { "gate", "gray door (EM style, blue key)"},
431 { "pearl", "pearl" }, /* (256) */
432 { "crystal", "crystal" },
433 { "wall", "wall with pearl" },
434 { "wall", "wall with crystal" },
435 { "gate", "white door" }, /* 260 */
436 { "gate", "gray door (opened by white key)"},
437 { "key", "white key" },
438 { "shield_normal", "shield (normal)" },
439 { "extra_time", "extra time" },
440 { "switchgate", "switch gate (open)" },
441 { "switchgate", "switch gate (closed)" },
442 { "switchgate_switch", "switch for switch gate" },
443 { "switchgate_switch", "switch for switch gate" },
445 { NULL, "-" }, /* 270 */
446 { "conveyor_belt", "red conveyor belt (left)" },
447 { "conveyor_belt", "red conveyor belt (middle)" },
448 { "conveyor_belt", "red conveyor belt (right)" },
449 { "conveyor_belt_switch", "switch for red conveyor belt (left)"},
450 { "conveyor_belt_switch", "switch for red conveyor belt (middle)"},
451 { "conveyor_belt_switch", "switch for red conveyor belt (right)"},
452 { "conveyor_belt", "yellow conveyor belt (left)" },
453 { "conveyor_belt", "yellow conveyor belt (middle)" },
454 { "conveyor_belt", "yellow conveyor belt (right)" },
455 { "conveyor_belt_switch", "switch for yellow conveyor belt (left)"},
456 { "conveyor_belt_switch", "switch for yellow conveyor belt (middle)"},
457 { "conveyor_belt_switch", "switch for yellow conveyor belt (right)"},
458 { "conveyor_belt", "green conveyor belt (left)" },
459 { "conveyor_belt", "green conveyor belt (middle)" },
460 { "conveyor_belt", "green conveyor belt (right)" },
461 { "conveyor_belt_switch", "switch for green conveyor belt (left)"},
462 { "conveyor_belt_switch", "switch for green conveyor belt (middle)"},
463 { "conveyor_belt_switch", "switch for green conveyor belt (right)"},
464 { "conveyor_belt", "blue conveyor belt (left)" },
465 { "conveyor_belt", "blue conveyor belt (middle)" },
466 { "conveyor_belt", "blue conveyor belt (right)" },
467 { "conveyor_belt_switch", "switch for blue conveyor belt (left)"},
468 { "conveyor_belt_switch", "switch for blue conveyor belt (middle)"},
469 { "conveyor_belt_switch", "switch for blue conveyor belt (right)"},
470 { "sand", "land mine" },
471 { "envelope", "mail envelope" },
472 { "light_switch", "light switch (off)" },
473 { "light_switch", "light switch (on)" },
474 { "wall", "sign (exclamation)" },
475 { "wall", "sign (radio activity)" }, /* 300 */
476 { "wall", "sign (stop)" },
477 { "wall", "sign (wheel chair)" },
478 { "wall", "sign (parking)" },
479 { "wall", "sign (one way)" },
480 { "wall", "sign (heart)" },
481 { "wall", "sign (triangle)" },
482 { "wall", "sign (round)" },
483 { "wall", "sign (exit)" },
484 { "wall", "sign (yin yang)" },
485 { "wall", "sign (other)" }, /* 310 */
486 { "mole", "mole (starts moving left)" },
487 { "mole", "mole (starts moving right)" },
488 { "mole", "mole (starts moving up)" },
489 { "mole", "mole (starts moving down)" },
490 { "wall", "steel wall (slanted)" },
491 { "sand", "invisible sand" },
492 { NULL, "dx unknown 15" },
493 { NULL, "dx unknown 42" },
495 { NULL, "-" }, /* 320 */
496 { "shield_deadly", "shield (deadly, kills enemies)"},
497 { "timegate", "time gate (open)" },
498 { "timegate", "time gate (closed)" },
499 { "timegate_switch", "switch for time gate" },
500 { "timegate_switch", "switch for time gate" },
501 { "balloon", "balloon" },
502 { "balloon_switch", "send balloon to the left" },
503 { "balloon_switch", "send balloon to the right" },
504 { "balloon_switch", "send balloon up" },
505 { "balloon_switch", "send balloon down" }, /* 330 */
506 { "balloon_switch", "send balloon in any direction" },
507 { "wall", "steel wall" },
508 { "wall", "steel wall" },
509 { "wall", "steel wall" },
510 { "wall", "steel wall" },
511 { "wall", "normal wall" },
512 { "wall", "normal wall" },
513 { "wall", "normal wall" },
514 { "wall", "normal wall" },
515 { "wall", "normal wall" }, /* 340 */
516 { "wall", "normal wall" },
517 { "wall", "normal wall" },
518 { "wall", "normal wall" },
519 { "tube", "tube (all directions)" },
520 { "tube", "tube (vertical)" },
521 { "tube", "tube (horizontal)" },
522 { "tube", "tube (vertical & left)" },
523 { "tube", "tube (vertical & right)" },
524 { "tube", "tube (horizontal & up)" },
525 { "tube", "tube (horizontal & down)" }, /* 350 */
526 { "tube", "tube (left & up)" },
527 { "tube", "tube (left & down)" },
528 { "tube", "tube (right & up)" },
529 { "tube", "tube (right & down)" },
530 { "spring", "spring" },
532 { "dx_bomb", "stable bomb (DX style)" },
536 "-------------------------------",
540 struct GraphicInfo graphic_info[MAX_GRAPHICS];
541 struct NewGraphicInfo new_graphic_info[NUM_IMAGE_FILES];
544 /* ========================================================================= */
546 /* ========================================================================= */
548 int main(int argc, char *argv[])
550 InitCommandName(argv[0]);
551 InitExitFunction(CloseAllAndExit);
552 InitPlatformDependantStuff();
560 return 0; /* to keep compilers happy */