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