Request("No Level without Gregor Mc Duffin please !", REQ_CONFIRM);
else
{
+ if (LevelChanged())
+ level.game_version = GAME_VERSION_ACTUAL;
+
for(x=0; x<lev_fieldx; x++)
for(y=0; y<lev_fieldy; y++)
FieldBackup[x][y] = Ur[x][y];
#define LEVEL_CHUNK_CNT2_SIZE 160 /* size of level CNT2 chunk */
#define LEVEL_CHUNK_CNT2_UNUSED 11 /* unused CNT2 chunk bytes */
#define TAPE_HEADER_SIZE 20 /* size of tape file header */
-#define TAPE_HEADER_UNUSED 7 /* unused tape header bytes */
+#define TAPE_HEADER_UNUSED 3 /* unused tape header bytes */
/* file identifier strings */
#define LEVEL_COOKIE_TMPL "ROCKSNDIAMONDS_LEVEL_FILE_VERSION_x.x"
static int LoadLevel_VERS(FILE *file, int chunk_size, struct LevelInfo *level)
{
- ReadChunk_VERS(file, &(level->file_version), &(level->game_version));
+ level->file_version = getFileVersion(file);
+ level->game_version = getFileVersion(file);
return chunk_size;
}
SetBorderElement();
}
+static void SaveLevel_VERS(FILE *file, struct LevelInfo *level)
+{
+ putFileVersion(file, level->file_version);
+ putFileVersion(file, level->game_version);
+}
+
static void SaveLevel_HEAD(FILE *file, struct LevelInfo *level)
{
int i, x, y;
return;
}
+ level.file_version = FILE_VERSION_ACTUAL;
+ level.game_version = GAME_VERSION_ACTUAL;
/* check level field for 16-bit elements */
level.encoding_16bit_field = FALSE;
putFileChunkBE(file, "CAVE", CHUNK_SIZE_NONE);
putFileChunkBE(file, "VERS", FILE_VERS_CHUNK_SIZE);
- WriteChunk_VERS(file, FILE_VERSION_ACTUAL, GAME_VERSION_ACTUAL);
+ SaveLevel_VERS(file, &level);
putFileChunkBE(file, "HEAD", LEVEL_HEADER_SIZE);
SaveLevel_HEAD(file, &level);
static int LoadTape_VERS(FILE *file, int chunk_size, struct TapeInfo *tape)
{
- ReadChunk_VERS(file, &(tape->file_version), &(tape->game_version));
+ tape->file_version = getFileVersion(file);
+ tape->game_version = getFileVersion(file);
return chunk_size;
}
tape->num_participating_players++;
}
}
+
+ ReadUnusedBytesFromFile(file, 4);
}
return chunk_size;
tape.length_seconds = GetTapeLength();
}
+static void SaveTape_VERS(FILE *file, struct TapeInfo *tape)
+{
+ putFileVersion(file, tape->file_version);
+ putFileVersion(file, tape->game_version);
+}
+
static void SaveTape_HEAD(FILE *file, struct TapeInfo *tape)
{
int i;
fputc(store_participating_players, file);
WriteUnusedBytesToFile(file, TAPE_HEADER_UNUSED);
+
+ WriteUnusedBytesToFile(file, 4);
}
static void SaveTape_BODY(FILE *file, struct TapeInfo *tape)
return;
}
+ tape.file_version = FILE_VERSION_ACTUAL;
+ tape.game_version = GAME_VERSION_ACTUAL;
+
/* count number of participating players */
for(i=0; i<MAX_PLAYERS; i++)
if (tape.player_participates[i])
putFileChunkBE(file, "TAPE", CHUNK_SIZE_NONE);
putFileChunkBE(file, "VERS", FILE_VERS_CHUNK_SIZE);
- WriteChunk_VERS(file, FILE_VERSION_ACTUAL, GAME_VERSION_ACTUAL);
+ SaveTape_VERS(file, &tape);
putFileChunkBE(file, "HEAD", TAPE_HEADER_SIZE);
SaveTape_HEAD(file, &tape);
#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
int2str(TimeLeft, 3), FS_SMALL, FC_YELLOW);
}
-void InitGameEngine()
+
+/*
+ =============================================================================
+ InitGameSound()
+ -----------------------------------------------------------------------------
+ initialize sound effect lookup table for element actions
+ =============================================================================
+*/
+
+void InitGameSound()
{
- static int sound_effect_properties[NUM_SOUND_EFFECTS];
+ int sound_effect_properties[NUM_SOUND_EFFECTS];
int i, j;
#if 0
#endif
}
-void InitGame()
+
+/*
+ =============================================================================
+ InitGameEngine()
+ -----------------------------------------------------------------------------
+ initialize game engine due to level / tape version number
+ =============================================================================
+*/
+
+static void InitGameEngine()
{
- int i, j, x, y;
boolean emulate_bd = TRUE; /* unless non-BOULDERDASH elements found */
boolean emulate_sb = TRUE; /* unless non-SOKOBAN elements found */
boolean emulate_sp = TRUE; /* unless non-SUPAPLEX elements found */
+ int i, x, y;
+
+ for(y=0; y<lev_fieldy; y++)
+ {
+ for(x=0; x<lev_fieldx; x++)
+ {
+ if (emulate_bd && !IS_BD_ELEMENT(Feld[x][y]))
+ emulate_bd = FALSE;
+ if (emulate_sb && !IS_SB_ELEMENT(Feld[x][y]))
+ emulate_sb = FALSE;
+ if (emulate_sp && !IS_SP_ELEMENT(Feld[x][y]))
+ emulate_sp = FALSE;
+ }
+ }
+
+ game.engine_version = (tape.playing ? tape.engine_version :
+ level.game_version);
+ game.emulation = (emulate_bd ? EMU_BOULDERDASH :
+ emulate_sb ? EMU_SOKOBAN :
+ emulate_sp ? EMU_SUPAPLEX : EMU_NONE);
+
+#if 0
+ printf("level %d: level version == %06d\n", level_nr, level.game_version);
+ printf(" tape version == %06d [%s]\n",
+ tape.engine_version, (tape.playing ? "PLAYING" : "RECORDING"));
+ printf(" => game.engine_version == %06d\n", game.engine_version);
+#endif
+
+ /* dynamically adjust player properties according to game engine version */
+ game.initial_move_delay =
+ (game.engine_version <= VERSION_IDENT(2,0,1) ? INITIAL_MOVE_DELAY_ON :
+ INITIAL_MOVE_DELAY_OFF);
+
+ /* dynamically adjust player properties according to level information */
+ game.initial_move_delay_value =
+ (level.double_speed ? MOVE_DELAY_HIGH_SPEED : MOVE_DELAY_NORMAL_SPEED);
+
+ /* dynamically adjust element properties according to game engine version */
+ {
+ static int ep_em_slippery_wall[] =
+ {
+ EL_BETON,
+ EL_MAUERWERK,
+ EL_MAUER_LEBT,
+ EL_MAUER_X,
+ EL_MAUER_Y,
+ EL_MAUER_XY
+ };
+ static int ep_em_slippery_wall_num = SIZEOF_ARRAY_INT(ep_em_slippery_wall);
+
+ for (i=0; i<ep_em_slippery_wall_num; i++)
+ {
+ if (level.em_slippery_gems) /* special EM style gems behaviour */
+ Elementeigenschaften2[ep_em_slippery_wall[i]] |=
+ EP_BIT_EM_SLIPPERY_WALL;
+ else
+ Elementeigenschaften2[ep_em_slippery_wall[i]] &=
+ ~EP_BIT_EM_SLIPPERY_WALL;
+ }
+
+ /* "EL_MAUERND" was not slippery for EM gems in version 2.0.1 */
+ if (level.em_slippery_gems && game.engine_version > VERSION_IDENT(2,0,1))
+ Elementeigenschaften2[EL_MAUERND] |= EP_BIT_EM_SLIPPERY_WALL;
+ else
+ Elementeigenschaften2[EL_MAUERND] &= ~EP_BIT_EM_SLIPPERY_WALL;
+ }
+}
+
+
+/*
+ =============================================================================
+ InitGame()
+ -----------------------------------------------------------------------------
+ initialize and start new game
+ =============================================================================
+*/
+
+void InitGame()
+{
+ int i, j, x, y;
+
+ InitGameEngine();
#if DEBUG
#if USE_NEW_AMOEBA_CODE
player->last_move_dir = MV_NO_MOVING;
player->is_moving = FALSE;
- player->move_delay = -1; /* no initial move delay */
- player->move_delay_value =
- (level.double_speed ? MOVE_DELAY_HIGH_SPEED : MOVE_DELAY_NORMAL_SPEED);
+ player->move_delay = game.initial_move_delay;
+ player->move_delay_value = game.initial_move_delay_value;
player->push_delay = 0;
player->push_delay_value = 5;
}
for(y=0; y<lev_fieldy; y++)
- {
for(x=0; x<lev_fieldx; x++)
- {
- if (emulate_bd && !IS_BD_ELEMENT(Feld[x][y]))
- emulate_bd = FALSE;
- if (emulate_sb && !IS_SB_ELEMENT(Feld[x][y]))
- emulate_sb = FALSE;
- if (emulate_sp && !IS_SP_ELEMENT(Feld[x][y]))
- emulate_sp = FALSE;
-
InitField(x, y, TRUE);
- }
- }
/* correct non-moving belts to start moving left */
for (i=0; i<4; i++)
}
}
- game.version = (tape.playing ? tape.game_version : level.game_version);
- game.emulation = (emulate_bd ? EMU_BOULDERDASH :
- emulate_sb ? EMU_SOKOBAN :
- emulate_sp ? EMU_SUPAPLEX : EMU_NONE);
-
- /* dynamically adjust element properties according to game engine version */
- {
- static int ep_em_slippery_wall[] =
- {
- EL_BETON, /* dummy entry; may be overwritten with EL_MAUERND */
- EL_BETON,
- EL_MAUERWERK,
- EL_MAUER_LEBT,
- EL_MAUER_X,
- EL_MAUER_Y,
- EL_MAUER_XY
- };
-#if 1
- static int ep_em_slippery_wall_num = SIZEOF_ARRAY_INT(ep_em_slippery_wall);
-#else
- static int ep_em_slippery_wall_num =
- sizeof(ep_em_slippery_wall) / sizeof(int);
-#endif
-
-#if 1
- printf("level %d: level version == %06d\n", level_nr, level.game_version);
- printf(" tape version == %06d\n", tape.game_version);
- printf(" => game.version == %06d\n", game.version);
-
- /*
- printf("level %d: game.version == %06d\n", level_nr, level.game_version);
- printf(" file_version == %06d\n", level.file_version);
- */
-#endif
-
- if (game.version > VERSION_IDENT(2,0,1))
- ep_em_slippery_wall[0] = EL_MAUERND;
- else
- ep_em_slippery_wall[0] = EL_BETON; /* dummy entry */
-
- Elementeigenschaften2[EL_MAUERND] &= ~EP_BIT_EM_SLIPPERY_WALL;
-
- for (i=0; i<ep_em_slippery_wall_num; i++)
- {
-#if 1
- if (level.em_slippery_gems) /* special EM style gems behaviour */
-#else
- if (game.version >= GAME_VERSION_2_0)
-#endif
- Elementeigenschaften2[ep_em_slippery_wall[i]] |=
- EP_BIT_EM_SLIPPERY_WALL;
- else
- Elementeigenschaften2[ep_em_slippery_wall[i]] &=
- ~EP_BIT_EM_SLIPPERY_WALL;
- }
-
- if (IS_EM_SLIPPERY_WALL(EL_MAUERND))
- printf("IS_EM_SLIPPERY_WALL(EL_MAUERND)\n");
- else
- printf("! IS_EM_SLIPPERY_WALL(EL_MAUERND)\n");
- }
-
if (BorderElement == EL_LEERRAUM)
{
SBX_Left = 0;
DrawGraphic(SCREENX(ax-1), SCREENY(ay), GFX_MAUER_LEFT);
new_wall = TRUE;
}
+
if (rechts_frei)
{
Feld[ax+1][ay] = EL_MAUERND;
void GetPlayerConfig(void);
void DrawGameDoorValues(void);
-void InitGameEngine();
+void InitGameSound();
void InitGame(void);
void InitMovDir(int, int);
void InitAmoebaNr(int, int);
InitGfxBackground();
InitToons();
- InitGameEngine();
-
DrawMainMenu();
InitNetworkServer();
static void InitSound()
{
+ /* load custom sounds and music */
InitReloadSounds(artwork.snd_current->name);
InitReloadMusic(artwork.mus_current->name);
+
+ /* initialize sound effect lookup table for element actions */
+ InitGameSound();
}
static void InitTileClipmasks()
}
}
+int getFileVersion(FILE *file)
+{
+ int version_major, version_minor, version_patch;
+
+ version_major = fgetc(file);
+ version_minor = fgetc(file);
+ version_patch = fgetc(file);
+ fgetc(file); /* not used */
+
+ return VERSION_IDENT(version_major, version_minor, version_patch);
+}
+
+void putFileVersion(FILE *file, int version)
+{
+ int version_major = VERSION_MAJOR(version);
+ int version_minor = VERSION_MINOR(version);
+ int version_patch = VERSION_PATCH(version);
+
+ fputc(version_major, file);
+ fputc(version_minor, file);
+ fputc(version_patch, file);
+ fputc(0, file); /* not used */
+}
+
void ReadUnusedBytesFromFile(FILE *file, unsigned long bytes)
{
while (bytes-- && !feof(file))
fputc(0, file);
}
+
+/* ------------------------------------------------------------------------- */
+/* functions to translate key identifiers between different format */
+/* ------------------------------------------------------------------------- */
+
#define TRANSLATE_KEYSYM_TO_KEYNAME 0
#define TRANSLATE_KEYSYM_TO_X11KEYNAME 1
#define TRANSLATE_KEYNAME_TO_KEYSYM 2
sprintf(name_buffer, "%c", '0' + (char)(key - KSYM_0));
else if (key >= KSYM_KP_0 && key <= KSYM_KP_9)
sprintf(name_buffer, "keypad %c", '0' + (char)(key - KSYM_KP_0));
- else if (key >= KSYM_F1 && key <= KSYM_F24)
- sprintf(name_buffer, "function F%d", (int)(key - KSYM_F1 + 1));
+ else if (key >= KSYM_FKEY_FIRST && key <= KSYM_FKEY_LAST)
+ sprintf(name_buffer, "function F%d", (int)(key - KSYM_FKEY_FIRST + 1));
else if (key == KSYM_UNDEFINED)
strcpy(name_buffer, "(undefined)");
else
sprintf(name_buffer, "XK_%c", '0' + (char)(key - KSYM_0));
else if (key >= KSYM_KP_0 && key <= KSYM_KP_9)
sprintf(name_buffer, "XK_KP_%c", '0' + (char)(key - KSYM_KP_0));
- else if (key >= KSYM_F1 && key <= KSYM_F24)
- sprintf(name_buffer, "XK_F%d", (int)(key - KSYM_F1 + 1));
+ else if (key >= KSYM_FKEY_FIRST && key <= KSYM_FKEY_LAST)
+ sprintf(name_buffer, "XK_F%d", (int)(key - KSYM_FKEY_FIRST + 1));
else if (key == KSYM_UNDEFINED)
strcpy(name_buffer, "[undefined]");
else
((c2 >= '0' && c1 <= '9') || c2 == '\0'))
d = atoi(&name_ptr[4]);
- if (d >=1 && d <= 24)
+ if (d >= 1 && d <= KSYM_NUM_FKEYS)
key = KSYM_F1 + (Key)(d - 1);
}
else if (strncmp(name_ptr, "XK_", 3) == 0)
void putFile32BitInteger(FILE *, int, int);
boolean getFileChunk(FILE *, char *, int *, int);
void putFileChunk(FILE *, char *, int, int);
+int getFileVersion(FILE *);
+void putFileVersion(FILE *, int);
void ReadUnusedBytesFromFile(FILE *, unsigned long);
void WriteUnusedBytesToFile(FILE *, unsigned long);
#define KSYM_F23 KSYM_UNDEFINED
#define KSYM_F24 KSYM_UNDEFINED
+#define KSYM_FKEY_FIRST KSYM_F1
+#define KSYM_FKEY_LAST KSYM_F15
+#define KSYM_NUM_FKEYS (KSYM_FKEY_LAST - KSYM_FKEY_FIRST + 1)
+
/* SDL function definitions */
createDirectory(getLevelSetupDir(level_subdir), "level setup",PERMS_PRIVATE);
}
-void ReadChunk_VERS(FILE *file, int *file_version, int *game_version)
-{
- int file_version_major, file_version_minor, file_version_patch;
- int game_version_major, game_version_minor, game_version_patch;
-
- file_version_major = fgetc(file);
- file_version_minor = fgetc(file);
- file_version_patch = fgetc(file);
- fgetc(file); /* not used */
-
- game_version_major = fgetc(file);
- game_version_minor = fgetc(file);
- game_version_patch = fgetc(file);
- fgetc(file); /* not used */
-
- *file_version = VERSION_IDENT(file_version_major,
- file_version_minor,
- file_version_patch);
-
- *game_version = VERSION_IDENT(game_version_major,
- game_version_minor,
- game_version_patch);
-}
-
-void WriteChunk_VERS(FILE *file, int file_version, int game_version)
-{
- int file_version_major = VERSION_MAJOR(file_version);
- int file_version_minor = VERSION_MINOR(file_version);
- int file_version_patch = VERSION_PATCH(file_version);
- int game_version_major = VERSION_MAJOR(game_version);
- int game_version_minor = VERSION_MINOR(game_version);
- int game_version_patch = VERSION_PATCH(game_version);
-
- fputc(file_version_major, file);
- fputc(file_version_minor, file);
- fputc(file_version_patch, file);
- fputc(0, file); /* not used */
-
- fputc(game_version_major, file);
- fputc(game_version_minor, file);
- fputc(game_version_patch, file);
- fputc(0, file); /* not used */
-}
-
/* ------------------------------------------------------------------------- */
/* some functions to handle lists of level directories */
sortTreeInfo(&artwork.snd_first, compareTreeInfoEntries);
sortTreeInfo(&artwork.mus_first, compareTreeInfoEntries);
-#if 1
+#if 0
dumpTreeInfo(artwork.gfx_first, 0);
dumpTreeInfo(artwork.snd_first, 0);
dumpTreeInfo(artwork.mus_first, 0);
void InitUserLevelDirectory(char *);
void InitLevelSetupDirectory(char *);
-void ReadChunk_VERS(FILE *, int *, int *);
-void WriteChunk_VERS(FILE *, int, int);
-
TreeInfo *newTreeInfo();
void pushTreeInfo(TreeInfo **, TreeInfo *);
int numTreeInfo(TreeInfo *);
#define KSYM_F23 XK_F23
#define KSYM_F24 XK_F24
+#define KSYM_FKEY_FIRST KSYM_F1
+#define KSYM_FKEY_LAST KSYM_F24
+#define KSYM_NUM_FKEYS (KSYM_FKEY_LAST - KSYM_FKEY_FIRST + 1)
+
/* X11 function definitions */
struct LevelInfo
{
int file_version; /* file format version the level is stored with */
- int game_version; /* game engine version the level was created with */
+ int game_version; /* game release version the level was created with */
+
boolean encoding_16bit_field; /* level contains 16-bit elements */
boolean encoding_16bit_yamyam; /* yamyam contains 16-bit elements */
boolean encoding_16bit_amoeba; /* amoeba contains 16-bit elements */
struct TapeInfo
{
- int file_version; /* file format version the tape is stored with */
- int game_version; /* game engine version the tape was created with */
- int version;
+ int file_version; /* file format version the tape is stored with */
+ int game_version; /* game release version the tape was created with */
+ int engine_version; /* game engine version the tape was recorded with */
+
int level_nr;
unsigned long random_seed;
unsigned long date;
struct GameInfo
{
- int version;
+ /* constant within running game */
+ int engine_version;
int emulation;
+ int initial_move_delay;
+ int initial_move_delay_value;
+
+ /* variable within running game */
int yam_content_nr;
boolean magic_wall_active;
int magic_wall_time_left;
tape.level_nr = level_nr;
tape.pos[tape.counter].delay = 0;
tape.changed = TRUE;
+
tape.date = 10000*(time->tm_year % 100) + 100*time->tm_mon + time->tm_mday;
- tape.game_version = GAME_VERSION_ACTUAL;
tape.random_seed = InitRND(NEW_RANDOMIZE);
+ tape.file_version = FILE_VERSION_ACTUAL;
+ tape.game_version = GAME_VERSION_ACTUAL;
+ tape.engine_version = level.game_version;
+
for(i=0; i<MAX_PLAYERS; i++)
tape.player_participates[i] = FALSE;
}
if (!tape.playing || !tape.pausing)
return;
- if (tape.game_version != GAME_VERSION_ACTUAL &&
- !Request("This may break old version tape ! Append anyway ?",
- REQ_ASK))
- return;
-
tape.pos[tape.counter].delay = tape.delay_played;
tape.playing = FALSE;
tape.recording = TRUE;
tape.changed = TRUE;
- tape.game_version = GAME_VERSION_ACTUAL;
DrawVideoDisplay(VIDEO_STATE_PLAY_OFF | VIDEO_STATE_REC_ON,0);
}
-#define COMPILE_DATE_STRING "[2002-06-07 21:01]"
+#define COMPILE_DATE_STRING "[2002-06-09 22:29]"