+#include "network.h"
+
+/* this switch controls how rocks move horizontally */
+#define OLD_GAME_BEHAVIOUR FALSE
+
+/* EXPERIMENTAL STUFF */
+#define USE_NEW_AMOEBA_CODE FALSE
+
+/* for DigField() */
+#define DF_NO_PUSH 0
+#define DF_DIG 1
+#define DF_SNAP 2
+
+/* for MoveFigure() */
+#define MF_NO_ACTION 0
+#define MF_MOVING 1
+#define MF_ACTION 2
+
+/* for ScrollFigure() */
+#define SCROLL_INIT 0
+#define SCROLL_GO_ON 1
+
+/* for Explode() */
+#define EX_PHASE_START 0
+#define EX_NO_EXPLOSION 0
+#define EX_NORMAL 1
+#define EX_CENTER 2
+#define EX_BORDER 3
+
+/* special positions in the game control window (relative to control window) */
+#define XX_LEVEL 37
+#define YY_LEVEL 20
+#define XX_EMERALDS 29
+#define YY_EMERALDS 54
+#define XX_DYNAMITE 29
+#define YY_DYNAMITE 89
+#define XX_KEYS 18
+#define YY_KEYS 123
+#define XX_SCORE 15
+#define YY_SCORE 159
+#define XX_TIME 29
+#define YY_TIME 194
+
+/* special positions in the game control window (relative to main window) */
+#define DX_LEVEL (DX + XX_LEVEL)
+#define DY_LEVEL (DY + YY_LEVEL)
+#define DX_EMERALDS (DX + XX_EMERALDS)
+#define DY_EMERALDS (DY + YY_EMERALDS)
+#define DX_DYNAMITE (DX + XX_DYNAMITE)
+#define DY_DYNAMITE (DY + YY_DYNAMITE)
+#define DX_KEYS (DX + XX_KEYS)
+#define DY_KEYS (DY + YY_KEYS)
+#define DX_SCORE (DX + XX_SCORE)
+#define DY_SCORE (DY + YY_SCORE)
+#define DX_TIME (DX + XX_TIME)
+#define DY_TIME (DY + YY_TIME)
+
+/* values for initial player move delay (initial delay counter value) */
+#define INITIAL_MOVE_DELAY_OFF -1
+#define INITIAL_MOVE_DELAY_ON 0
+
+/* values for player movement speed (which is in fact a delay value) */
+#define MOVE_DELAY_NORMAL_SPEED 8
+#define MOVE_DELAY_HIGH_SPEED 4
+
+#define DOUBLE_MOVE_DELAY(x) (x = (x <= MOVE_DELAY_HIGH_SPEED ? x * 2 : x))
+#define HALVE_MOVE_DELAY(x) (x = (x >= MOVE_DELAY_HIGH_SPEED ? x / 2 : x))
+#define DOUBLE_PLAYER_SPEED(p) (HALVE_MOVE_DELAY((p)->move_delay_value))
+#define HALVE_PLAYER_SPEED(p) (DOUBLE_MOVE_DELAY((p)->move_delay_value))
+
+/* game button identifiers */
+#define GAME_CTRL_ID_STOP 0
+#define GAME_CTRL_ID_PAUSE 1
+#define GAME_CTRL_ID_PLAY 2
+#define SOUND_CTRL_ID_MUSIC 3
+#define SOUND_CTRL_ID_LOOPS 4
+#define SOUND_CTRL_ID_SIMPLE 5
+
+#define NUM_GAME_BUTTONS 6
+
+/* forward declaration for internal use */
+static void CloseAllOpenTimegates(void);
+static void CheckGravityMovement(struct PlayerInfo *);
+static void KillHeroUnlessProtected(int, int);
+
+void PlaySoundLevel(int, int, int);
+void PlaySoundLevelAction(int, int, int);
+void PlaySoundLevelElementAction(int, int, int, int);
+
+static void MapGameButtons();
+static void HandleGameButtons(struct GadgetInfo *);
+
+static struct GadgetInfo *game_gadget[NUM_GAME_BUTTONS];
+
+#define SND_ACTION_UNKNOWN 0
+#define SND_ACTION_WAITING 1
+#define SND_ACTION_MOVING 2
+#define SND_ACTION_DIGGING 3
+#define SND_ACTION_COLLECTING 4
+#define SND_ACTION_PASSING 5
+#define SND_ACTION_IMPACT 6
+#define SND_ACTION_PUSHING 7
+#define SND_ACTION_ACTIVATING 8
+#define SND_ACTION_BURNING 9
+
+#define NUM_SND_ACTIONS 10
+
+static struct
+{
+ char *text;
+ int value;
+ boolean is_loop;
+} sound_action_properties[] =
+{
+ /* insert _all_ loop sound actions here */
+ { ".waiting", SND_ACTION_WAITING, TRUE },
+ { ".moving", SND_ACTION_MOVING, TRUE }, /* continuos moving */
+ { ".running", SND_ACTION_UNKNOWN, TRUE },
+ { ".burning", SND_ACTION_BURNING, TRUE },
+ { ".growing", SND_ACTION_UNKNOWN, TRUE },
+ { ".attacking", SND_ACTION_UNKNOWN, TRUE },
+ { ".activated", SND_ACTION_UNKNOWN, TRUE },
+
+ /* other (non-loop) sound actions are optional */
+ { ".stepping", SND_ACTION_MOVING, FALSE }, /* discrete moving */
+ { ".digging", SND_ACTION_DIGGING, FALSE },
+ { ".collecting", SND_ACTION_COLLECTING, FALSE },
+ { ".passing", SND_ACTION_PASSING, FALSE },
+ { ".impact", SND_ACTION_IMPACT, FALSE },
+ { ".pushing", SND_ACTION_PUSHING, FALSE },
+ { ".activating", SND_ACTION_ACTIVATING, FALSE },
+ { NULL, 0, 0 },
+};
+static int element_action_sound[NUM_LEVEL_ELEMENTS][NUM_SND_ACTIONS];
+static boolean is_loop_sound[NUM_SOUND_FILES];
+
+#define IS_LOOP_SOUND(x) (is_loop_sound[x])
+
+
+#ifdef DEBUG
+#if 0
+static unsigned int getStateCheckSum(int counter)
+{
+ int x, y;
+ unsigned int mult = 1;
+ unsigned int checksum = 0;
+ /*
+ static short lastFeld[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
+ */
+ static boolean first_game = TRUE;
+
+ for (y=0; y<lev_fieldy; y++) for(x=0; x<lev_fieldx; x++)
+ {
+ /*
+ if (counter == 3)
+ {
+ if (first_game)
+ lastFeld[x][y] = Feld[x][y];
+ else if (lastFeld[x][y] != Feld[x][y])
+ printf("DIFF: [%d][%d]: lastFeld == %d != %d == Feld\n",
+ x, y, lastFeld[x][y], Feld[x][y]);
+ }
+ */
+
+ checksum += mult++ * Ur[x][y];
+ checksum += mult++ * Feld[x][y];
+
+ /*
+ checksum += mult++ * MovPos[x][y];
+ checksum += mult++ * MovDir[x][y];
+ checksum += mult++ * MovDelay[x][y];
+ checksum += mult++ * Store[x][y];
+ checksum += mult++ * Store2[x][y];
+ checksum += mult++ * StorePlayer[x][y];
+ checksum += mult++ * Frame[x][y];
+ checksum += mult++ * AmoebaNr[x][y];
+ checksum += mult++ * JustStopped[x][y];
+ checksum += mult++ * Stop[x][y];
+ */
+ }
+
+ if (counter == 3 && first_game)
+ first_game = FALSE;
+
+ return checksum;
+}
+#endif
+#endif
+
+
+