+ static struct
+ {
+ int *elements;
+ int property;
+ } element_properties[] =
+ {
+ { ep_amoebalive, EP_AMOEBALIVE },
+ { ep_amoeboid, EP_AMOEBOID },
+ { ep_can_be_crumbled, EP_CAN_BE_CRUMBLED },
+ { ep_pforte, EP_PFORTE },
+ { ep_solid, EP_SOLID },
+ { ep_indestructible, EP_INDESTRUCTIBLE },
+ { ep_slippery, EP_SLIPPERY },
+ { ep_enemy, EP_ENEMY },
+ { ep_mauer, EP_MAUER },
+ { ep_can_fall, EP_CAN_FALL },
+ { ep_can_smash, EP_CAN_SMASH },
+ { ep_can_change, EP_CAN_CHANGE },
+ { ep_can_move, EP_CAN_MOVE },
+ { ep_could_move, EP_COULD_MOVE },
+ { ep_dont_touch, EP_DONT_TOUCH },
+ { ep_dont_go_to, EP_DONT_GO_TO },
+ { ep_food_dark_yamyam, EP_FOOD_DARK_YAMYAM },
+ { ep_bd_element, EP_BD_ELEMENT },
+ { ep_sb_element, EP_SB_ELEMENT },
+ { ep_gem, EP_GEM },
+ { ep_inactive, EP_INACTIVE },
+ { ep_explosive, EP_EXPLOSIVE },
+ { ep_food_penguin, EP_FOOD_PENGUIN },
+ { ep_pushable, EP_PUSHABLE },
+ { ep_player, EP_PLAYER },
+ { ep_walkable_over, EP_WALKABLE_OVER },
+ { ep_walkable_inside, EP_WALKABLE_INSIDE },
+ { ep_walkable_under, EP_WALKABLE_UNDER },
+ { ep_passable_over, EP_PASSABLE_OVER },
+ { ep_passable_inside, EP_PASSABLE_INSIDE },
+ { ep_passable_under, EP_PASSABLE_UNDER },
+
+ { ep_diggable, EP_DIGGABLE },
+ { ep_collectible, EP_COLLECTIBLE },
+ { ep_active_bomb, EP_ACTIVE_BOMB },
+ { ep_belt, EP_BELT },
+ { ep_belt_active, EP_BELT_ACTIVE },
+ { ep_belt_switch, EP_BELT_SWITCH },
+ { ep_sp_element, EP_SP_ELEMENT },
+ { ep_has_content, EP_HAS_CONTENT },
+ { ep_tube, EP_TUBE },
+ { NULL, -1 }
+ };
+
+#if 0
+ static int active_properties[] =
+ {
+ EP_AMOEBALIVE,
+ EP_AMOEBOID,
+ EP_PFORTE,
+ EP_SOLID,
+ EP_ENEMY,
+ EP_MAUER,
+ EP_CAN_FALL,
+ EP_CAN_SMASH,
+ EP_CAN_CHANGE,
+ EP_CAN_MOVE,
+ EP_COULD_MOVE,
+ EP_DONT_TOUCH,
+ EP_DONT_GO_TO,
+ EP_GEM,
+ EP_EXPLOSIVE,
+ EP_PUSHABLE,
+ EP_PLAYER,
+ EP_HAS_CONTENT,
+ EP_DIGGABLE,
+ EP_PASSABLE_INSIDE,
+ EP_OVER_PLAYER,
+ EP_ACTIVE_BOMB,
+
+ EP_BELT,
+ EP_BELT_ACTIVE,
+ EP_BELT_SWITCH,
+ EP_WALKABLE_UNDER,
+ EP_EM_SLIPPERY_WALL,
+ EP_CAN_BE_CRUMBLED,
+ };
+#endif
+
+ /* always start with reliable default values (no properties) */
+ for (i=0; i<MAX_NUM_ELEMENTS; i++)
+ for (j=0; j<NUM_EP_BITFIELDS; j++)
+ Properties[i][j] = EP_BITMASK_DEFAULT;
+
+ /* set all predefined element properties from above arrays */
+ for (i=0; element_properties[i].elements != NULL; i++)
+ for (j=0; (element_properties[i].elements)[j] != -1; j++)
+ SET_PROPERTY((element_properties[i].elements)[j],
+ element_properties[i].property, TRUE);
+
+ /* set properties of character elements */
+ for (i=EL_CHAR_START; i<=EL_CHAR_END; i++)
+ SET_PROPERTY(i, EP_INACTIVE, TRUE);
+
+ /* set properties derived from other properties */
+ for (i=0; i<MAX_NUM_ELEMENTS; i++)
+ {
+ if (IS_WALKABLE_OVER(i) || IS_WALKABLE_INSIDE(i) || IS_WALKABLE_UNDER(i))
+ SET_PROPERTY(i, EP_WALKABLE, TRUE);
+
+ if (IS_PASSABLE_OVER(i) || IS_PASSABLE_INSIDE(i) || IS_PASSABLE_UNDER(i))
+ SET_PROPERTY(i, EP_PASSABLE, TRUE);
+
+ if (IS_WALKABLE_OVER(i) || IS_PASSABLE_OVER(i))
+ SET_PROPERTY(i, EP_ACCESSIBLE_OVER, TRUE);
+
+ if (IS_WALKABLE_INSIDE(i) || IS_PASSABLE_INSIDE(i))
+ SET_PROPERTY(i, EP_ACCESSIBLE_INSIDE, TRUE);
+
+ if (IS_WALKABLE_UNDER(i) || IS_PASSABLE_UNDER(i))
+ SET_PROPERTY(i, EP_ACCESSIBLE_UNDER, TRUE);
+
+ if (IS_WALKABLE(i) || IS_PASSABLE(i))
+ SET_PROPERTY(i, EP_ACCESSIBLE, TRUE);
+ }
+
+#if 0
+ /* determine inactive elements (used for engine main loop optimization) */
+ for (i=0; i < MAX_NUM_ELEMENTS; i++)
+ {
+ boolean active = FALSE;
+
+ for (j=0; i < NUM_ELEMENT_PROPERTIES; j++)
+ {
+ if (HAS_PROPERTY(i, j))
+ active = TRUE;
+ }
+
+#if 0
+ if (!active)
+ SET_PROPERTY(i, EP_INACTIVE, TRUE);
+#endif
+ }
+#endif
+
+#if 0
+ for (i=0; i < MAX_NUM_ELEMENTS; i++)
+ {
+ boolean element_is_solid = TRUE;
+
+ if (IS_DIGGABLE(i) ||
+ IS_COLLECTIBLE(i) ||
+ CAN_FALL(i) ||
+ CAN_MOVE(i) ||
+ IS_PUSHABLE(i))
+ element_is_solid = FALSE;
+
+ if (IS_INDESTRUCTIBLE(i))
+ element_is_solid = TRUE;
+
+ if (element_is_solid != HAS_PROPERTY(i, EP_SOLID))
+ printf("::: '%s' should %s solid\n", element_info[i].token_name,
+ (HAS_PROPERTY(i, EP_SOLID) ? "NOT be" : "be"));
+ }
+#endif
+}
+
+static void InitGlobal()
+{
+ global.autoplay_leveldir = NULL;
+
+ global.frames_per_second = 0;
+ global.fps_slowdown = FALSE;
+ global.fps_slowdown_factor = 1;
+}
+
+void Execute_Command(char *command)
+{
+ if (strcmp(command, "print graphicsinfo.conf") == 0)
+ {
+ int i;
+
+ printf("# You can configure additional/alternative image files here.\n");
+ printf("# (The images below are default and therefore commented out.)\n");
+ printf("\n");
+ printf("%s\n", getFormattedSetupEntry("name", "Classic Graphics"));
+ printf("\n");
+ printf("%s\n", getFormattedSetupEntry("sort_priority", "100"));
+ printf("\n");
+
+ for (i=0; image_config[i].token != NULL; i++)
+ printf("# %s\n",
+ getFormattedSetupEntry(image_config[i].token,
+ image_config[i].value));
+
+ exit(0);
+ }
+ else if (strcmp(command, "print soundsinfo.conf") == 0)
+ {
+ int i;
+
+ printf("# You can configure additional/alternative sound files here.\n");
+ printf("# (The sounds below are default and therefore commented out.)\n");
+ printf("\n");
+ printf("%s\n", getFormattedSetupEntry("name", "Classic Sounds"));
+ printf("\n");
+ printf("%s\n", getFormattedSetupEntry("sort_priority", "100"));
+ printf("\n");
+
+ for (i=0; sound_config[i].token != NULL; i++)
+ printf("# %s\n",
+ getFormattedSetupEntry(sound_config[i].token,
+ sound_config[i].value));
+
+ exit(0);
+ }
+ else if (strcmp(command, "print musicinfo.conf") == 0)
+ {
+ printf("# (Currently only \"name\" and \"sort_priority\" recognized.)\n");
+ printf("\n");
+ printf("%s\n", getFormattedSetupEntry("name", "Classic Music"));
+ printf("\n");
+ printf("%s\n", getFormattedSetupEntry("sort_priority", "100"));
+
+ exit(0);
+ }
+ else if (strncmp(command, "dump level ", 11) == 0)
+ {
+ char *filename = &command[11];
+
+ if (access(filename, F_OK) != 0)
+ Error(ERR_EXIT, "cannot open file '%s'", filename);
+
+ LoadLevelFromFilename(filename);
+ DumpLevel(&level);
+
+ exit(0);
+ }
+ else if (strncmp(command, "dump tape ", 10) == 0)
+ {
+ char *filename = &command[10];
+
+ if (access(filename, F_OK) != 0)
+ Error(ERR_EXIT, "cannot open file '%s'", filename);
+
+ LoadTapeFromFilename(filename);
+ DumpTape(&tape);
+
+ exit(0);
+ }
+ else if (strncmp(command, "autoplay ", 9) == 0)
+ {
+ char *str_copy = getStringCopy(&command[9]);
+ char *str_ptr = strchr(str_copy, ' ');
+
+ global.autoplay_leveldir = str_copy;
+ global.autoplay_level_nr = -1;
+
+ if (str_ptr != NULL)
+ {
+ *str_ptr++ = '\0'; /* terminate leveldir string */
+ global.autoplay_level_nr = atoi(str_ptr); /* get level_nr value */
+ }
+ }
+ else