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"
24 Bitmap *pix[NUM_BITMAPS];
26 Bitmap *bitmap_db_field, *bitmap_db_door;
28 Pixmap tile_clipmask[NUM_TILES];
30 DrawBuffer *fieldbuffer;
31 DrawBuffer *drawto_field;
34 boolean level_editor_test_game = FALSE;
35 boolean network_playing = FALSE;
37 int key_joystick_mapping = 0;
39 boolean redraw[MAX_BUF_XSIZE][MAX_BUF_YSIZE];
40 int redraw_x1 = 0, redraw_y1 = 0;
42 short Feld[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
43 short Ur[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
44 short MovPos[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
45 short MovDir[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
46 short MovDelay[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
47 short ChangeDelay[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
48 short Store[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
49 short Store2[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
50 short StorePlayer[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
51 short Back[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
52 boolean Stop[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
53 short JustStopped[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
54 short AmoebaNr[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
55 short AmoebaCnt[MAX_NUM_AMOEBA];
56 short AmoebaCnt2[MAX_NUM_AMOEBA];
57 short ExplodePhase[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
58 short ExplodeField[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
60 unsigned long Properties[MAX_NUM_ELEMENTS][NUM_EP_BITFIELDS];
62 int GfxFrame[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
63 int GfxAction[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
64 int GfxRandom[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
65 int GfxElement[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
67 int lev_fieldx, lev_fieldy;
68 int scroll_x, scroll_y;
72 int ScreenMovDir = MV_NO_MOVING, ScreenMovPos = 0;
74 int BorderElement = EL_STEELWALL;
75 int GameFrameDelay = GAME_FRAME_DELAY;
76 int FfwdFrameDelay = FFWD_FRAME_DELAY;
78 int BX2 = SCR_FIELDX - 1, BY2 = SCR_FIELDY - 1;
79 int SBX_Left, SBX_Right;
80 int SBY_Upper, SBY_Lower;
85 int TimeFrames, TimePlayed, TimeLeft;
87 boolean network_player_action_received = FALSE;
89 struct LevelInfo level;
90 struct PlayerInfo stored_player[MAX_PLAYERS], *local_player = NULL;
91 struct HiScore highscore[MAX_SCORE_ENTRIES];
93 struct SetupInfo setup;
95 struct GlobalInfo global;
98 struct GraphicInfo *graphic_info = NULL;
99 struct SoundInfo *sound_info = NULL;
102 /* ------------------------------------------------------------------------- */
103 /* element definitions */
104 /* ------------------------------------------------------------------------- */
106 struct ElementInfo element_info[MAX_NUM_ELEMENTS + 1] =
108 /* keyword to start parser: "ELEMENT_INFO_START" <-- do not change! */
110 /* ----------------------------------------------------------------------- */
111 /* "real" level file elements */
112 /* ----------------------------------------------------------------------- */
202 "quicksand with rock"
247 "Conway's wall of life"
270 "robot_wheel_active",
272 "magic wheel (running)"
317 "gray door (opened by red key)"
322 "gray door (opened by yellow key)"},
326 "gray door (opened by green key)"},
330 "gray door (opened by blue key)"},
344 "invisible normal wall"
369 "amoeba with content"
404 "wall with BD style diamond"
407 "wall_emerald_yellow",
409 "wall with yellow emerald"
419 "magic wall (BD style)"
422 "invisible_steelwall",
424 "invisible steel wall"
432 "dynabomb_increase_number",
434 "increases number of bombs"
437 "dynabomb_increase_size",
439 "increases explosion size"
442 "dynabomb_increase_power",
444 "increases power of explosion"
452 "sokoban_field_empty",
454 "sokoban empty field"
457 "sokoban_field_full",
459 "sokoban field with object"
462 "bd_butterfly_right",
464 "butterfly (starts moving right)"},
468 "butterfly (starts moving up)"
473 "butterfly (starts moving left)"},
477 "butterfly (starts moving down)"},
481 "firefly (starts moving right)"
486 "firefly (starts moving up)"
491 "firefly (starts moving left)"
496 "firefly (starts moving down)"
531 "bug (starts moving right)"
536 "bug (starts moving up)"
541 "bug (starts moving left)"
546 "bug (starts moving down)"
551 "spaceship (starts moving right)"},
555 "spaceship (starts moving up)"
560 "spaceship (starts moving left)"},
564 "spaceship (starts moving down)"},
568 "pac man (starts moving right)"
573 "pac man (starts moving up)"
578 "pac man (starts moving left)"
583 "pac man (starts moving down)"
598 "wall with red emerald"
601 "wall_emerald_purple",
603 "wall with purple emerald"
608 "acid pool (top left)"
611 "acid_pool_topright",
613 "acid pool (top right)"
616 "acid_pool_bottomleft",
618 "acid pool (bottom left)"
626 "acid_pool_bottomright",
628 "acid pool (bottom right)"
633 "normal wall (BD style)"
698 "fire breathing dragon"
1011 "char_bracketright",
1106 "expandable_wall_horizontal",
1108 "growing wall (horizontal)"
1111 "expandable_wall_vertical",
1113 "growing wall (vertical)"
1116 "expandable_wall_any",
1118 "growing wall (any direction)"
1123 "red door (EM style)"
1128 "yellow door (EM style)"
1133 "green door (EM style)"
1138 "blue door (EM style)"
1143 "yellow key (EM style)"
1148 "green key (EM style)"
1153 "blue key (EM style)"
1203 "port (leading right)"
1208 "port (leading down)"
1213 "port (leading left)"
1221 "sp_gravity_port_right",
1223 "port (leading right)"
1226 "sp_gravity_port_down",
1228 "port (leading down)"
1231 "sp_gravity_port_left",
1233 "port (leading left)"
1236 "sp_gravity_port_up",
1266 "sp_port_horizontal",
1273 "port (any direction)"
1296 "sp_hardware_base_1",
1301 "sp_hardware_green",
1316 "sp_hardware_yellow",
1321 "sp_hardware_base_2",
1326 "sp_hardware_base_3",
1331 "sp_hardware_base_4",
1336 "sp_hardware_base_5",
1341 "sp_hardware_base_6",
1358 "gray door (EM style, red key)"
1363 "gray door (EM style, yellow key)"
1368 "gray door (EM style, green key)"
1373 "gray door (EM style, blue key)"
1413 "gray door (opened by white key)"
1433 "switch gate (open)"
1436 "switchgate_closed",
1438 "switch gate (closed)"
1441 "switchgate_switch_up",
1442 "switchgate_switch",
1443 "switch for switch gate"
1446 "switchgate_switch_down",
1447 "switchgate_switch",
1448 "switch for switch gate"
1461 "conveyor_belt_1_left",
1463 "red conveyor belt (left)"
1466 "conveyor_belt_1_middle",
1468 "red conveyor belt (middle)"
1471 "conveyor_belt_1_right",
1473 "red conveyor belt (right)"
1476 "conveyor_belt_1_switch_left",
1477 "conveyor_belt_switch",
1478 "switch for red conveyor belt (left)"
1481 "conveyor_belt_1_switch_middle",
1482 "conveyor_belt_switch",
1483 "switch for red conveyor belt (middle)"
1486 "conveyor_belt_1_switch_right",
1487 "conveyor_belt_switch",
1488 "switch for red conveyor belt (right)"
1491 "conveyor_belt_2_left",
1493 "yellow conveyor belt (left)"
1496 "conveyor_belt_2_middle",
1498 "yellow conveyor belt (middle)"
1501 "conveyor_belt_2_right",
1503 "yellow conveyor belt (right)"
1506 "conveyor_belt_2_switch_left",
1507 "conveyor_belt_switch",
1508 "switch for yellow conveyor belt (left)"
1511 "conveyor_belt_2_switch_middle",
1512 "conveyor_belt_switch",
1513 "switch for yellow conveyor belt (middle)"
1516 "conveyor_belt_2_switch_right",
1517 "conveyor_belt_switch",
1518 "switch for yellow conveyor belt (right)"
1521 "conveyor_belt_3_left",
1523 "green conveyor belt (left)"
1526 "conveyor_belt_3_middle",
1528 "green conveyor belt (middle)"
1531 "conveyor_belt_3_right",
1533 "green conveyor belt (right)"
1536 "conveyor_belt_3_switch_left",
1537 "conveyor_belt_switch",
1538 "switch for green conveyor belt (left)"
1541 "conveyor_belt_3_switch_middle",
1542 "conveyor_belt_switch",
1543 "switch for green conveyor belt (middle)"
1546 "conveyor_belt_3_switch_right",
1547 "conveyor_belt_switch",
1548 "switch for green conveyor belt (right)"
1551 "conveyor_belt_4_left",
1553 "blue conveyor belt (left)"
1556 "conveyor_belt_4_middle",
1558 "blue conveyor belt (middle)"
1561 "conveyor_belt_4_right",
1563 "blue conveyor belt (right)"
1566 "conveyor_belt_4_switch_left",
1567 "conveyor_belt_switch",
1568 "switch for blue conveyor belt (left)"
1571 "conveyor_belt_4_switch_middle",
1572 "conveyor_belt_switch",
1573 "switch for blue conveyor belt (middle)"
1576 "conveyor_belt_4_switch_right",
1577 "conveyor_belt_switch",
1578 "switch for blue conveyor belt (right)"
1593 "light switch (off)"
1596 "light_switch_active",
1603 "sign (exclamation)"
1606 "sign_radioactivity",
1608 "sign (radio activity)"
1618 "sign (wheel chair)"
1663 "mole (starts moving left)"
1668 "mole (starts moving right)"
1673 "mole (starts moving up)"
1678 "mole (starts moving down)"
1681 "steelwall_slanted",
1683 "steel wall (slanted)"
1693 "dx unknown element 15"
1698 "dx unknown element 42"
1713 "shield (deadly, kills enemies)"
1723 "time gate (closed)"
1726 "timegate_switch_active",
1728 "switch for time gate"
1733 "switch for time gate"
1741 "balloon_switch_left",
1743 "send balloon to the left"
1746 "balloon_switch_right",
1748 "send balloon to the right"
1751 "balloon_switch_up",
1756 "balloon_switch_down",
1761 "balloon_switch_any",
1763 "send balloon in any direction"
1828 "tube (any direction)"
1841 "tube_vertical_left",
1843 "tube (vertical & left)"
1846 "tube_vertical_right",
1848 "tube (vertical & right)"
1851 "tube_horizontal_up",
1853 "tube (horizontal & up)"
1856 "tube_horizontal_down",
1858 "tube (horizontal & down)"
1868 "tube (left & down)"
1878 "tube (right & down)"
1893 "stable bomb (DX style)"
2403 "custom element 100"
2408 "custom element 101"
2413 "custom element 102"
2418 "custom element 103"
2423 "custom element 104"
2428 "custom element 105"
2433 "custom element 106"
2438 "custom element 107"
2443 "custom element 108"
2448 "custom element 109"
2453 "custom element 110"
2458 "custom element 111"
2463 "custom element 112"
2468 "custom element 113"
2473 "custom element 114"
2478 "custom element 115"
2483 "custom element 116"
2488 "custom element 117"
2493 "custom element 118"
2498 "custom element 119"
2503 "custom element 120"
2508 "custom element 121"
2513 "custom element 122"
2518 "custom element 123"
2523 "custom element 124"
2528 "custom element 125"
2533 "custom element 126"
2538 "custom element 127"
2543 "custom element 128"
2546 /* ----------------------------------------------------------------------- */
2547 /* "real" (and therefore drawable) runtime elements */
2548 /* ----------------------------------------------------------------------- */
2571 "dynabomb_player_1_active",
2576 "dynabomb_player_2_active",
2581 "dynabomb_player_3_active",
2586 "dynabomb_player_4_active",
2591 "sp_disk_red_active",
2596 "switchgate_opening",
2601 "switchgate_closing",
2626 "invisible_steelwall_active",
2631 "invisible_wall_active",
2636 "invisible_sand_active",
2641 "conveyor_belt_1_left_active",
2646 "conveyor_belt_1_middle_active",
2651 "conveyor_belt_1_right_active",
2656 "conveyor_belt_2_left_active",
2661 "conveyor_belt_2_middle_active",
2666 "conveyor_belt_2_right_active",
2671 "conveyor_belt_3_left_active",
2676 "conveyor_belt_3_middle_active",
2681 "conveyor_belt_3_right_active",
2686 "conveyor_belt_4_left_active",
2691 "conveyor_belt_4_middle_active",
2696 "conveyor_belt_4_right_active",
2711 "sp_terminal_active",
2716 "sp_buggy_base_activating",
2721 "sp_buggy_base_active",
2736 "quicksand_emptying",
2741 "magic_wall_active",
2746 "bd_magic_wall_active",
2756 "bd_magic_wall_full",
2761 "magic_wall_emptying",
2766 "bd_magic_wall_emptying",
2776 "bd_magic_wall_dead",
2781 /* ----------------------------------------------------------------------- */
2782 /* "unreal" (and therefore not drawable) runtime elements */
2783 /* ----------------------------------------------------------------------- */
2811 "acid_splash_right",
2826 "expandable_wall_growing",
2836 "player_is_leaving",
2841 "quicksand_filling",
2846 "magic_wall_filling",
2851 "bd_magic_wall_filling",
2856 /* ----------------------------------------------------------------------- */
2857 /* dummy elements (never used as game elements, only used as graphics) */
2858 /* ----------------------------------------------------------------------- */
2861 "steelwall_topleft",
2866 "steelwall_topright",
2871 "steelwall_bottomleft",
2876 "steelwall_bottomright",
2881 "steelwall_horizontal",
2886 "steelwall_vertical",
2891 "invisible_steelwall_topleft",
2896 "invisible_steelwall_topright",
2901 "invisible_steelwall_bottomleft",
2906 "invisible_steelwall_bottomright",
2911 "invisible_steelwall_horizontal",
2916 "invisible_steelwall_vertical",
2931 "shield_normal_active",
2936 "shield_deadly_active",
2941 /* keyword to stop parser: "ELEMENT_INFO_END" <-- do not change! */
2951 /* ------------------------------------------------------------------------- */
2952 /* element action and direction definitions */
2953 /* ------------------------------------------------------------------------- */
2955 struct ElementActionInfo element_action_info[NUM_ACTIONS + 1] =
2957 { ".[DEFAULT]", ACTION_DEFAULT, TRUE },
2958 { ".waiting", ACTION_WAITING, TRUE },
2959 { ".falling", ACTION_FALLING, TRUE },
2960 { ".moving", ACTION_MOVING, TRUE },
2961 { ".digging", ACTION_DIGGING, FALSE },
2962 { ".snapping", ACTION_SNAPPING, FALSE },
2963 { ".collecting", ACTION_COLLECTING, FALSE },
2964 { ".dropping", ACTION_DROPPING, FALSE },
2965 { ".pushing", ACTION_PUSHING, FALSE },
2966 { ".passing", ACTION_PASSING, FALSE },
2967 { ".impact", ACTION_IMPACT, FALSE },
2968 { ".breaking", ACTION_BREAKING, FALSE },
2969 { ".activating", ACTION_ACTIVATING, FALSE },
2970 { ".deactivating", ACTION_DEACTIVATING, FALSE },
2971 { ".opening", ACTION_OPENING, FALSE },
2972 { ".closing", ACTION_CLOSING, FALSE },
2973 { ".attacking", ACTION_ATTACKING, TRUE },
2974 { ".growing", ACTION_GROWING, TRUE },
2975 { ".shrinking", ACTION_SHRINKING, FALSE },
2976 { ".active", ACTION_ACTIVE, TRUE },
2977 { ".filling", ACTION_FILLING, FALSE },
2978 { ".emptying", ACTION_EMPTYING, FALSE },
2979 { ".changing", ACTION_CHANGING, FALSE },
2980 { ".exploding", ACTION_EXPLODING, FALSE },
2981 { ".dying", ACTION_DYING, FALSE },
2982 { ".other", ACTION_OTHER, FALSE },
2987 struct ElementDirectionInfo element_direction_info[NUM_DIRECTIONS + 1] =
2989 { ".left", MV_BIT_LEFT },
2990 { ".right", MV_BIT_RIGHT },
2991 { ".up", MV_BIT_UP },
2992 { ".down", MV_BIT_DOWN },
2997 struct SpecialSuffixInfo special_suffix_info[NUM_SPECIAL_GFX_ARGS + 1] =
2999 { ".MAIN", GAME_MODE_MAIN, },
3000 { ".LEVELS", GAME_MODE_LEVELS },
3001 { ".SCORES", GAME_MODE_SCORES, },
3002 { ".EDITOR", GAME_MODE_EDITOR, },
3003 { ".INFO", GAME_MODE_INFO, },
3004 { ".SETUP", GAME_MODE_SETUP, },
3005 { ".DOOR", GAME_MODE_PSEUDO_DOOR, },
3006 { ".PREVIEW", GAME_MODE_PSEUDO_PREVIEW, },
3011 struct TokenIntPtrInfo image_config_vars[] =
3013 { "global.num_toons", &global.num_toons },
3014 { "menu.draw_xoffset", &menu.draw_xoffset_default },
3015 { "menu.draw_yoffset", &menu.draw_yoffset_default },
3016 { "menu.draw_xoffset.MAIN", &menu.draw_xoffset[GFX_SPECIAL_ARG_MAIN] },
3017 { "menu.draw_yoffset.MAIN", &menu.draw_yoffset[GFX_SPECIAL_ARG_MAIN] },
3018 { "menu.draw_xoffset.LEVELS", &menu.draw_xoffset[GFX_SPECIAL_ARG_LEVELS] },
3019 { "menu.draw_yoffset.LEVELS", &menu.draw_yoffset[GFX_SPECIAL_ARG_LEVELS] },
3020 { "menu.draw_xoffset.SCORES", &menu.draw_xoffset[GFX_SPECIAL_ARG_SCORES] },
3021 { "menu.draw_yoffset.SCORES", &menu.draw_yoffset[GFX_SPECIAL_ARG_SCORES] },
3022 { "menu.draw_xoffset.EDITOR", &menu.draw_xoffset[GFX_SPECIAL_ARG_EDITOR] },
3023 { "menu.draw_yoffset.EDITOR", &menu.draw_yoffset[GFX_SPECIAL_ARG_EDITOR] },
3024 { "menu.draw_xoffset.INFO", &menu.draw_xoffset[GFX_SPECIAL_ARG_INFO] },
3025 { "menu.draw_yoffset.INFO", &menu.draw_yoffset[GFX_SPECIAL_ARG_INFO] },
3026 { "menu.draw_xoffset.SETUP", &menu.draw_xoffset[GFX_SPECIAL_ARG_SETUP] },
3027 { "menu.draw_yoffset.SETUP", &menu.draw_yoffset[GFX_SPECIAL_ARG_SETUP] },
3028 { "door.step_offset", &door.step_offset },
3029 { "door.step_delay", &door.step_delay },
3035 /* ------------------------------------------------------------------------- */
3036 /* font definitions */
3037 /* ------------------------------------------------------------------------- */
3039 /* Important: When one entry is a prefix of another entry, the longer entry
3040 must come first, because the dynamic configuration does prefix matching! */
3042 struct FontInfo font_info[NUM_FONTS + 1] =
3044 { "font.initial_1" },
3045 { "font.initial_2" },
3046 { "font.initial_3" },
3047 { "font.initial_4" },
3052 { "font.text_1.active" },
3053 { "font.text_2.active" },
3054 { "font.text_3.active" },
3055 { "font.text_4.active" },
3060 { "font.input_1.active" },
3061 { "font.input_2.active" },
3064 { "font.option_off" },
3065 { "font.option_on" },
3068 { "font.value_old" },
3069 { "font.level_number" },
3070 { "font.tape_recorder" },
3071 { "font.game_info" },
3075 /* ========================================================================= */
3077 /* ========================================================================= */
3079 int main(int argc, char *argv[])
3081 InitProgramInfo(argv[0], USERDATA_DIRECTORY,
3082 PROGRAM_TITLE_STRING, getWindowTitleString(),
3083 ICON_TITLE_STRING, X11_ICON_FILENAME, X11_ICONMASK_FILENAME,
3084 MSDOS_POINTER_FILENAME,
3085 COOKIE_PREFIX, FILENAME_PREFIX, GAME_VERSION_ACTUAL);
3087 InitExitFunction(CloseAllAndExit);
3088 InitPlatformDependantStuff();
3096 return 0; /* to keep compilers happy */