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