rnd-20060314-1-src
authorHolger Schemel <info@artsoft.org>
Tue, 14 Mar 2006 00:42:11 +0000 (01:42 +0100)
committerHolger Schemel <info@artsoft.org>
Sat, 30 Aug 2014 08:51:10 +0000 (10:51 +0200)
* added player focus switching to level tape recording and re-playing

17 files changed:
ChangeLog
src/conftime.h
src/engines.h
src/events.c
src/game.c
src/game.h
src/game_em/display.h
src/game_em/graphics.c
src/game_em/synchro_1.c
src/libgame/system.h
src/main.c
src/main.h
src/screens.c
src/tape.c
src/tape.h
src/tools.c
src/tools.h

index 51d4a414609274c5be8fa83e4cc9413e47006033..817ca24ac44e0e43e8409853247159c6394e5db8 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,6 @@
+2006-03-14
+       * added player focus switching to level tape recording and re-playing
+
 2006-03-13
        * fixed some bugs in player focus switching in EMC and RND game engine
 
index f69b18c9a904e704b4e01175ab8e58ba6cf98568..46e25f2b3bfcb53bc26945d05d8502f92f781de2 100644 (file)
@@ -1 +1 @@
-#define COMPILE_DATE_STRING "[2006-03-13 02:03]"
+#define COMPILE_DATE_STRING "[2006-03-14 01:37]"
index 55352e0fcc2988edf9b4b2639e9a57185b8c28fe..e64f0f224436101d3b845f6c488a170ab0c7d3d8 100644 (file)
 /* functions and definitions exported from main program to game_em           */
 /* ========================================================================= */
 
+#include "game.h"
+
 extern void SetBitmaps_EM(Bitmap **);
 extern void UpdateEngineValues(int, int);
 extern void DrawAllGameValues(int, int, int, int, int);
 
+#if 0
 extern void setCenteredPlayerNr_EM(int);
 extern int getCenteredPlayerNr_EM();
 extern void setSetCenteredPlayer_EM(boolean);
 extern boolean getSetCenteredPlayer_EM();
+#endif
+
 extern int getNumActivePlayers_EM();
 extern int getGameFrameDelay_EM(int);
 
index e8f205564eb968a174789767ac649db42ebe0b0e..49d3b1a0eca85bf8f8ba41602d0d06cfdcb99f65 100644 (file)
@@ -544,10 +544,7 @@ static void HandleKeysSpecial(Key key)
   {
 #ifdef DEBUG
     if (is_string_suffix(cheat_input, ".q"))
-      for (i = 0; i < MAX_INVENTORY_SIZE; i++)
-       if (local_player->inventory_size < MAX_INVENTORY_SIZE)
-         local_player->inventory_element[local_player->inventory_size++] =
-           EL_DYNAMITE;
+      DEBUG_SetMaximumDynamite();
 #endif
   }
   else if (game_status == GAME_MODE_EDITOR)
@@ -713,6 +710,12 @@ void HandleKey(Key key, int key_status)
     {
       game.centered_player_nr_next = centered_player_nr_next;
       game.set_centered_player = TRUE;
+
+      if (tape.recording)
+      {
+       tape.centered_player_nr_next = game.centered_player_nr_next;
+       tape.set_centered_player = TRUE;
+      }
     }
   }
 
index 1843274873a34c4b8778dcd982ea540681b63016..f23555b3e7c5c00a96646b29037896f82ba986ba 100644 (file)
@@ -333,6 +333,32 @@ static void PlayLevelMusic();
 static void MapGameButtons();
 static void HandleGameButtons(struct GadgetInfo *);
 
+int AmoebeNachbarNr(int, int);
+void AmoebeUmwandeln(int, int);
+void ContinueMoving(int, int);
+void Bang(int, int);
+void InitMovDir(int, int);
+void InitAmoebaNr(int, int);
+int NewHiScore(void);
+
+void TestIfGoodThingHitsBadThing(int, int, int);
+void TestIfBadThingHitsGoodThing(int, int, int);
+void TestIfPlayerTouchesBadThing(int, int);
+void TestIfPlayerRunsIntoBadThing(int, int, int);
+void TestIfBadThingTouchesPlayer(int, int);
+void TestIfBadThingRunsIntoPlayer(int, int, int);
+void TestIfFriendTouchesBadThing(int, int);
+void TestIfBadThingTouchesFriend(int, int);
+void TestIfBadThingTouchesOtherBadThing(int, int);
+
+void KillPlayer(struct PlayerInfo *);
+void BuryPlayer(struct PlayerInfo *);
+void RemovePlayer(struct PlayerInfo *);
+
+boolean SnapField(struct PlayerInfo *, int, int);
+boolean DropElement(struct PlayerInfo *);
+
+
 static struct GadgetInfo *game_gadget[NUM_GAME_BUTTONS];
 
 
@@ -690,6 +716,18 @@ static int playfield_scan_delta_y = 1;
                                     (x) >= 0 && (x) <= lev_fieldx - 1; \
                                     (x) += playfield_scan_delta_x)     \
 
+#ifdef DEBUG
+void DEBUG_SetMaximumDynamite()
+{
+  int i;
+
+  for (i = 0; i < MAX_INVENTORY_SIZE; i++)
+    if (local_player->inventory_size < MAX_INVENTORY_SIZE)
+      local_player->inventory_element[local_player->inventory_size++] =
+       EL_DYNAMITE;
+}
+#endif
+
 static void InitPlayfieldScanModeVars()
 {
   if (game.use_reverse_scan_direction)
@@ -8847,10 +8885,12 @@ static void SetPlayerWaiting(struct PlayerInfo *player, boolean is_waiting)
       /* special case for sleeping Murphy when leaning against non-free tile */
 
       if (!IN_LEV_FIELD(player->jx - 1, player->jy) ||
-         Feld[player->jx - 1][player->jy] != EL_EMPTY)
+         (Feld[player->jx - 1][player->jy] != EL_EMPTY &&
+          !IS_MOVING(player->jx - 1, player->jy)))
        move_dir = MV_LEFT;
       else if (!IN_LEV_FIELD(player->jx + 1, player->jy) ||
-              Feld[player->jx + 1][player->jy] != EL_EMPTY)
+              (Feld[player->jx + 1][player->jy] != EL_EMPTY &&
+               !IS_MOVING(player->jx + 1, player->jy)))
        move_dir = MV_RIGHT;
       else
        player->is_sleeping = FALSE;
@@ -9087,6 +9127,7 @@ void GameActions()
 
   InitPlayfieldScanModeVars();
 
+#if 0
   if (game.set_centered_player)
   {
     boolean all_players_fit_to_screen = checkIfAllPlayersFitToScreen_RND();
@@ -9151,6 +9192,7 @@ void GameActions()
 
     game.set_centered_player = FALSE;
   }
+#endif
 
 #if USE_ONE_MORE_CHANGE_PER_FRAME
   if (game.engine_version >= VERSION_IDENT(3,2,0,7))
@@ -9185,6 +9227,79 @@ void GameActions()
 
   recorded_player_action = (tape.playing ? TapePlayAction() : NULL);
 
+#if 1
+  if (tape.set_centered_player)
+  {
+    game.centered_player_nr_next = tape.centered_player_nr_next;
+    game.set_centered_player = TRUE;
+  }
+
+  if (game.set_centered_player)
+  {
+    boolean all_players_fit_to_screen = checkIfAllPlayersFitToScreen_RND();
+
+    /* switching to "all players" only possible if all players fit to screen */
+    if (game.centered_player_nr_next == -1 && !all_players_fit_to_screen)
+    {
+      game.centered_player_nr_next = game.centered_player_nr;
+      game.set_centered_player = FALSE;
+    }
+
+    /* do not switch focus to non-existing (or non-active) player */
+    if (game.centered_player_nr_next >= 0 &&
+       !stored_player[game.centered_player_nr_next].active)
+    {
+      game.centered_player_nr_next = game.centered_player_nr;
+      game.set_centered_player = FALSE;
+    }
+  }
+
+  if (game.set_centered_player &&
+      ScreenMovPos == 0)       /* screen currently aligned at tile position */
+  {
+#if 0
+    struct PlayerInfo *player;
+    int player_nr = game.centered_player_nr_next;
+#endif
+    int sx, sy;
+
+    if (game.centered_player_nr_next == -1)
+    {
+      setScreenCenteredToAllPlayers(&sx, &sy);
+    }
+    else
+    {
+      sx = stored_player[game.centered_player_nr_next].jx;
+      sy = stored_player[game.centered_player_nr_next].jy;
+    }
+
+#if 0
+    player = &stored_player[player_nr];
+
+    if (!player->active)
+      game.centered_player_nr_next = game.centered_player_nr;
+
+    sx = player->jx;
+    sy = player->jy;
+#endif
+
+#if 0
+    if (game.centered_player_nr != game.centered_player_nr_next)
+#endif
+    {
+#if 1
+      DrawRelocateScreen(sx, sy, MV_NONE, TRUE, setup.quick_switch);
+#else
+      DrawRelocatePlayer(player, setup.quick_switch);
+#endif
+
+      game.centered_player_nr = game.centered_player_nr_next;
+    }
+
+    game.set_centered_player = FALSE;
+  }
+#endif
+
 #if 1
   /* !!! CHECK THIS (tape.pausing is always FALSE here!) !!! */
   if (recorded_player_action == NULL && tape.pausing)
index 9d73679232a97fb54eff280e902b4cabc933f260..927dade7f9365ca0316091e9fedcc68e2ca04427 100644 (file)
 #ifndef GAME_H
 #define GAME_H
 
-#include "main.h"
+
+#define MAX_INVENTORY_SIZE     1000
+#define STD_NUM_KEYS           4
+#define MAX_NUM_KEYS           8
+
+
+struct GameInfo
+{
+  /* values for engine initialization */
+  int default_push_delay_fixed;
+  int default_push_delay_random;
+
+  /* constant within running game */
+  int engine_version;
+  int emulation;
+  int initial_move_delay;
+  int initial_move_delay_value;
+  int initial_push_delay_value;
+
+  /* flags to handle bugs in and changes between different engine versions */
+  /* (for the latest engine version, these flags should always be "FALSE") */
+  boolean use_change_when_pushing_bug;
+  boolean use_block_last_field_bug;
+  boolean max_num_changes_per_frame;
+  boolean use_reverse_scan_direction;
+
+  /* variable within running game */
+  int yamyam_content_nr;
+  boolean magic_wall_active;
+  int magic_wall_time_left;
+  int light_time_left;
+  int timegate_time_left;
+  int belt_dir[4];
+  int belt_dir_nr[4];
+  int switchgate_pos;
+  int wind_direction;
+  boolean gravity;
+  boolean explosions_delayed;
+  boolean envelope_active;
+
+#if 1
+  /* values for the new EMC elements */
+  int lenses_time_left;
+  int magnify_time_left;
+  boolean ball_state;
+  int ball_content_nr;
+#endif
+
+  /* values for player idle animation (no effect on engine) */
+  int player_boring_delay_fixed;
+  int player_boring_delay_random;
+  int player_sleeping_delay_fixed;
+  int player_sleeping_delay_random;
+
+  /* values for special game initialization control */
+  boolean restart_level;
+
+  /* values for special game control */
+  int centered_player_nr;
+  int centered_player_nr_next;
+  boolean set_centered_player;
+};
+
+struct PlayerInfo
+{
+  boolean present;             /* player present in level playfield */
+  boolean connected;           /* player connected (locally or via network) */
+  boolean active;              /* player present and connected */
+
+  int index_nr;                        /* player number (0 to 3) */
+  int index_bit;               /* player number bit (1 << 0 to 1 << 3) */
+  int element_nr;              /* element (EL_PLAYER_1 to EL_PLAYER_4) */
+  int client_nr;               /* network client identifier */
+
+  byte action;                 /* action from local input device */
+  byte effective_action;       /* action acknowledged from network server
+                                  or summarized over all configured input
+                                  devices when in single player mode */
+  byte programmed_action;      /* action forced by game itself (like moving
+                                  through doors); overrides other actions */
+
+  int jx, jy, last_jx, last_jy;
+  int MovDir, MovPos, GfxDir, GfxPos;
+  int Frame, StepFrame;
+
+  int GfxAction;
+
+  boolean use_murphy;
+  int artwork_element;
+
+  boolean block_last_field;
+  int block_delay_adjustment;  /* needed for different engine versions */
+
+  boolean can_fall_into_acid;
+
+  boolean LevelSolved, GameOver;
+
+  int last_move_dir;
+
+  boolean is_waiting;
+  boolean is_moving;
+  boolean is_auto_moving;
+  boolean is_digging;
+  boolean is_snapping;
+  boolean is_collecting;
+  boolean is_pushing;
+  boolean is_switching;
+  boolean is_dropping;
+  boolean is_dropping_pressed;
+
+  boolean is_bored;
+  boolean is_sleeping;
+
+  boolean cannot_move;
+
+  int frame_counter_bored;
+  int frame_counter_sleeping;
+
+  int anim_delay_counter;
+  int post_delay_counter;
+
+  int dir_waiting;
+  int action_waiting, last_action_waiting;
+  int special_action_bored;
+  int special_action_sleeping;
+
+  int num_special_action_bored;
+  int num_special_action_sleeping;
+
+  int switch_x, switch_y;
+  int drop_x, drop_y;
+
+  int show_envelope;
+
+  int move_delay;
+  int move_delay_value;
+  int move_delay_value_next;
+  int move_delay_reset_counter;
+
+  int push_delay;
+  int push_delay_value;
+
+  unsigned long actual_frame_counter;
+
+  int drop_delay;
+  int drop_pressed_delay;
+
+  int step_counter;
+
+  int score;
+  int gems_still_needed;
+  int sokobanfields_still_needed;
+  int lights_still_needed;
+  int friends_still_needed;
+  int key[MAX_NUM_KEYS];
+  int dynabomb_count, dynabomb_size, dynabombs_left, dynabomb_xl;
+  int shield_normal_time_left;
+  int shield_deadly_time_left;
+
+  int inventory_element[MAX_INVENTORY_SIZE];
+  int inventory_infinite_element;
+  int inventory_size;
+};
+
+
+extern struct GameInfo         game;
+extern struct PlayerInfo       stored_player[], *local_player;
+
+
+#ifdef DEBUG
+void DEBUG_SetMaximumDynamite();
+#endif
 
 void GetPlayerConfig(void);
 
@@ -25,62 +196,16 @@ void InitGameSound();
 void InitGame(void);
 
 void UpdateEngineValues(int, int);
-
-void InitMovDir(int, int);
-void InitAmoebaNr(int, int);
 void GameWon(void);
-int NewHiScore(void);
 
 void InitPlayerGfxAnimation(struct PlayerInfo *, int, int);
-void InitMovingField(int, int, int);
 void Moving2Blocked(int, int, int *, int *);
 void Blocked2Moving(int, int, int *, int *);
-int MovingOrBlocked2Element(int, int);
-void RemoveMovingField(int, int);
 void DrawDynamite(int, int);
-void CheckDynamite(int, int);
-void Explode(int, int, int, int);
-void DynaExplode(int, int);
-void Bang(int, int);
-void Blurb(int, int);
-void Impact(int, int);
-void StartMoving(int, int);
-void ContinueMoving(int, int);
-int AmoebeNachbarNr(int, int);
-void AmoebeUmwandeln(int, int);
-void AmoebeUmwandelnBD(int, int, int);
-void AmoebeWaechst(int, int);
-void AmoebeAbleger(int, int);
-void Life(int, int);
-void Ablenk(int, int);
-void Blubber(int, int);
-void NussKnacken(int, int);
-void SiebAktivieren(int, int, int);
-void AusgangstuerPruefen(int, int);
-void AusgangstuerOeffnen(int, int);
-void AusgangstuerBlinken(int, int);
-void EdelsteinFunkeln(int, int);
-void MauerWaechst(int, int);
-void MauerAbleger(int, int);
 
 void GameActions(void);
 void ScrollLevel(int, int);
 
-void TestIfGoodThingHitsBadThing(int, int, int);
-void TestIfBadThingHitsGoodThing(int, int, int);
-void TestIfPlayerTouchesBadThing(int, int);
-void TestIfPlayerRunsIntoBadThing(int, int, int);
-void TestIfBadThingTouchesPlayer(int, int);
-void TestIfBadThingRunsIntoPlayer(int, int, int);
-void TestIfFriendTouchesBadThing(int, int);
-void TestIfBadThingTouchesFriend(int, int);
-void TestIfBadThingTouchesOtherBadThing(int, int);
-void KillPlayer(struct PlayerInfo *);
-void BuryPlayer(struct PlayerInfo *);
-void RemovePlayer(struct PlayerInfo *);
-boolean SnapField(struct PlayerInfo *, int, int);
-boolean DropElement(struct PlayerInfo *);
-
 void InitPlayLevelSound();
 void PlayLevelSound_EM(int, int, int, int);
 
index f6a82af453c8a13991d8dd0b85a5331b8fa2cb8f..9079feea90744c0f418b8d040885de46c6d3b79a 100644 (file)
 #define SYSIZE                 (SCR_FIELDY * TILEY)
 
 #if 1
+
+#if 0
 #define FRAMES_PER_SECOND      50
+#endif
 
 #define ROUNDED_DIVIDE(x, y)   (((x) + (y) - 1) / (y))
 
index 331491cfb25c7c0209bbae411d2d54e7a009645a..3b18584c1b02312000e0f4220491cc887e7d4a5c 100644 (file)
@@ -40,11 +40,13 @@ static int crumbled_state[MAX_BUF_YSIZE][MAX_BUF_XSIZE];
 
 static boolean redraw[MAX_BUF_XSIZE][MAX_BUF_YSIZE];
 
+#if 0
 #if 1
 int centered_player_nr;
 #else
 static int centered_player_nr;
 #endif
+#endif
 
 /* copy the entire screen to the window at the scroll position */
 
@@ -458,9 +460,11 @@ void game_initscreen(void)
 
   frame = 6;
 
-  centered_player_nr = getCenteredPlayerNr_EM();
+#if 0
+  game.centered_player_nr = getCenteredPlayerNr_EM();
+#endif
 
-  player_nr = (centered_player_nr != -1 ? centered_player_nr : 0);
+  player_nr = (game.centered_player_nr != -1 ? game.centered_player_nr : 0);
 
   screen_x = VALID_SCREEN_X(PLAYER_SCREEN_X(player_nr));
   screen_y = VALID_SCREEN_Y(PLAYER_SCREEN_Y(player_nr));
@@ -655,8 +659,10 @@ void RedrawPlayfield_EM(boolean force_redraw)
 #if 0
   boolean scrolling = (screen_x % TILEX != 0 || screen_y % TILEY != 0);
 #endif
-  boolean set_centered_player = getSetCenteredPlayer_EM();
-  int centered_player_nr_next = getCenteredPlayerNr_EM();
+#if 0
+  boolean game.set_centered_player = getSetCenteredPlayer_EM();
+  int game.centered_player_nr_next = getCenteredPlayerNr_EM();
+#endif
   int offset = (setup.scroll_delay ? 3 : 0) * TILEX;
   int offset_x = offset;
   int offset_y = offset;
@@ -665,28 +671,23 @@ void RedrawPlayfield_EM(boolean force_redraw)
   int x, y, sx, sy;
   int i;
 
-  if (set_centered_player)
+  if (game.set_centered_player)
   {
     boolean all_players_fit_to_screen = checkIfAllPlayersFitToScreen();
 
     /* switching to "all players" only possible if all players fit to screen */
-    if (centered_player_nr_next == -1 && !all_players_fit_to_screen)
+    if (game.centered_player_nr_next == -1 && !all_players_fit_to_screen)
     {
-      centered_player_nr_next = centered_player_nr;
-      setCenteredPlayerNr_EM(centered_player_nr);
-
-      set_centered_player = FALSE;
-      setSetCenteredPlayer_EM(FALSE);
+      game.centered_player_nr_next = game.centered_player_nr;
+      game.set_centered_player = FALSE;
     }
 
     /* do not switch focus to non-existing (or non-active) player */
-    if (centered_player_nr_next >= 0 && !ply[centered_player_nr_next].alive)
+    if (game.centered_player_nr_next >= 0 &&
+       !ply[game.centered_player_nr_next].alive)
     {
-      centered_player_nr_next = centered_player_nr;
-      setCenteredPlayerNr_EM(centered_player_nr);
-
-      set_centered_player = FALSE;
-      setSetCenteredPlayer_EM(FALSE);
+      game.centered_player_nr_next = game.centered_player_nr;
+      game.set_centered_player = FALSE;
     }
   }
 
@@ -697,21 +698,21 @@ void RedrawPlayfield_EM(boolean force_redraw)
 #endif
   {
 #if 1
-    if (set_centered_player)
+    if (game.set_centered_player)
 #else
-    if (centered_player_nr != centered_player_nr_next)
+    if (game.centered_player_nr != game.centered_player_nr_next)
 #endif
     {
-      centered_player_nr = centered_player_nr_next;
+      game.centered_player_nr = game.centered_player_nr_next;
 
       draw_new_player_location = TRUE;
       force_redraw = TRUE;
 
-      setSetCenteredPlayer_EM(FALSE);
+      game.set_centered_player = FALSE;
     }
   }
 
-  if (centered_player_nr == -1)
+  if (game.centered_player_nr == -1)
   {
     if (draw_new_player_location)
     {
@@ -725,8 +726,8 @@ void RedrawPlayfield_EM(boolean force_redraw)
   }
   else
   {
-    sx = PLAYER_SCREEN_X(centered_player_nr);
-    sy = PLAYER_SCREEN_Y(centered_player_nr);
+    sx = PLAYER_SCREEN_X(game.centered_player_nr);
+    sy = PLAYER_SCREEN_Y(game.centered_player_nr);
   }
 
   if (draw_new_player_location && quick_relocation)
@@ -881,7 +882,7 @@ void RedrawPlayfield_EM(boolean force_redraw)
   }
 
   /* prevent scrolling away from the other players when focus on all players */
-  if (centered_player_nr == -1)
+  if (game.centered_player_nr == -1)
   {
 #if 1
     /* check if all players are still visible with new scrolling position */
index 1fe8faf0a99382bd7180381da190f358ffe2025f..c6f0067428dc59360b0189fab5b8d8acc594568d 100644 (file)
 #include "display.h"
 
 
+#if 0
 extern int centered_player_nr;
+#endif
+
 extern boolean checkIfAllPlayersFitToScreen();
 
 static void check_player(struct PLAYER *);
@@ -551,7 +554,8 @@ static void check_player(struct PLAYER *ply)
     ply->x = x;
     ply->y = y;
 
-    can_move = (centered_player_nr != -1 || checkIfAllPlayersFitToScreen());
+    can_move = (game.centered_player_nr != -1 ||
+               checkIfAllPlayersFitToScreen());
 
     ply->x = oldx;
     ply->y = oldy;
index 84f128770d8aeb10a5ca7bab31279d8b212d4163..128726a610b96312960353c8baac1594b04e4fcf 100644 (file)
 #define BUTTON_1                       4
 #define BUTTON_2                       5
 
+/* values for special "focus player" bitmasks */
+#define BIT_SET_FOCUS                  6
+
 /* values for move directions and special "button" key bitmasks */
 #define MV_NONE                        0
 #define MV_LEFT                        (1 << MV_BIT_LEFT)
 #define KEY_BUTTON             (KEY_BUTTON_1 | KEY_BUTTON_2)
 #define KEY_ACTION             (KEY_MOTION | KEY_BUTTON)
 
+#define SET_FOCUS              (1 << BIT_SET_FOCUS)
+
 #define MV_DIR_FROM_BIT(x)     ((x) < NUM_DIRECTIONS ? 1 << (x) :        \
                                 (x) == MV_BIT_UPLEFT    ? MV_UPLEFT    : \
                                 (x) == MV_BIT_UPRIGHT   ? MV_UPRIGHT   : \
 #define CURSOR_DEFAULT         0
 #define CURSOR_PLAYFIELD       1
 
+/* fundamental game speed values */
+#define ONE_SECOND_DELAY       1000    /* delay value for one second */
+#define GAME_FRAME_DELAY       20      /* frame delay in milliseconds */
+#define FFWD_FRAME_DELAY       10      /* 200% speed for fast forward */
+#define FRAMES_PER_SECOND      (ONE_SECOND_DELAY / GAME_FRAME_DELAY)
 
 /* maximum playfield size supported by libgame functions */
 #define MAX_PLAYFIELD_WIDTH    128
index 2daf291a8d5ad2a82820005b44d6b75f2a0c4f41..ec2ec514fa2609fc3edeb27d340e7b28d250ffac 100644 (file)
@@ -16,6 +16,7 @@
 #include "main.h"
 #include "init.h"
 #include "game.h"
+#include "tape.h"
 #include "events.h"
 #include "config.h"
 
index bb7d8766f9146d446bc7d0b3be113c8293074556..b2a69ad38a745709d4696a1b926322075a625e1a 100644 (file)
 #define EL_NAME(e)             ((e) >= 0 ? element_info[e].token_name : "(?)")
 
 /* fundamental game speed values */
-#define ONE_SECOND_DELAY       1000    /* delay value for one second */
-#define GAME_FRAME_DELAY       20      /* frame delay in milliseconds */
-#define FFWD_FRAME_DELAY       10      /* 200% speed for fast forward */
-#define FRAMES_PER_SECOND      (ONE_SECOND_DELAY / GAME_FRAME_DELAY)
 #define MICROLEVEL_SCROLL_DELAY        50      /* delay for scrolling micro level */
 #define MICROLEVEL_LABEL_DELAY 250     /* delay for micro level label */
 
 #define MAX_LEVEL_NAME_LEN     32
 #define MAX_LEVEL_AUTHOR_LEN   32
 #define MAX_ELEMENT_NAME_LEN   32
-#define MAX_TAPE_LEN           (1000 * FRAMES_PER_SECOND) /* max.time x fps */
 #define MAX_TAPES_PER_SET      1024
 #define MAX_SCORE_ENTRIES      100
 #define MAX_NUM_AMOEBA         100
+#if 0  /* game.h */
 #define MAX_INVENTORY_SIZE     1000
 #define STD_NUM_KEYS           4
 #define MAX_NUM_KEYS           8
+#endif
 #define NUM_BELTS              4
 #define NUM_BELT_PARTS         3
 #define MIN_ENVELOPE_XSIZE     1
@@ -1785,107 +1782,6 @@ struct Content
   int e[3][3];
 };
 
-struct PlayerInfo
-{
-  boolean present;             /* player present in level playfield */
-  boolean connected;           /* player connected (locally or via network) */
-  boolean active;              /* player present and connected */
-
-  int index_nr;                        /* player number (0 to 3) */
-  int index_bit;               /* player number bit (1 << 0 to 1 << 3) */
-  int element_nr;              /* element (EL_PLAYER_1 to EL_PLAYER_4) */
-  int client_nr;               /* network client identifier */
-
-  byte action;                 /* action from local input device */
-  byte effective_action;       /* action acknowledged from network server
-                                  or summarized over all configured input
-                                  devices when in single player mode */
-  byte programmed_action;      /* action forced by game itself (like moving
-                                  through doors); overrides other actions */
-
-  int jx, jy, last_jx, last_jy;
-  int MovDir, MovPos, GfxDir, GfxPos;
-  int Frame, StepFrame;
-
-  int GfxAction;
-
-  boolean use_murphy;
-  int artwork_element;
-
-  boolean block_last_field;
-  int block_delay_adjustment;  /* needed for different engine versions */
-
-  boolean can_fall_into_acid;
-
-  boolean LevelSolved, GameOver;
-
-  int last_move_dir;
-
-  boolean is_waiting;
-  boolean is_moving;
-  boolean is_auto_moving;
-  boolean is_digging;
-  boolean is_snapping;
-  boolean is_collecting;
-  boolean is_pushing;
-  boolean is_switching;
-  boolean is_dropping;
-  boolean is_dropping_pressed;
-
-  boolean is_bored;
-  boolean is_sleeping;
-
-  boolean cannot_move;
-
-  int frame_counter_bored;
-  int frame_counter_sleeping;
-
-  int anim_delay_counter;
-  int post_delay_counter;
-
-  int dir_waiting;
-  int action_waiting, last_action_waiting;
-  int special_action_bored;
-  int special_action_sleeping;
-
-  int num_special_action_bored;
-  int num_special_action_sleeping;
-
-  int switch_x, switch_y;
-  int drop_x, drop_y;
-
-  int show_envelope;
-
-  int move_delay;
-  int move_delay_value;
-  int move_delay_value_next;
-  int move_delay_reset_counter;
-
-  int push_delay;
-  int push_delay_value;
-
-  unsigned long actual_frame_counter;
-
-  int drop_delay;
-  int drop_pressed_delay;
-
-  int step_counter;
-
-  int score;
-  int gems_still_needed;
-  int sokobanfields_still_needed;
-  int lights_still_needed;
-  int friends_still_needed;
-  int key[MAX_NUM_KEYS];
-  int dynabomb_count, dynabomb_size, dynabombs_left, dynabomb_xl;
-  int shield_normal_time_left;
-  int shield_deadly_time_left;
-
-  int inventory_element[MAX_INVENTORY_SIZE];
-  int inventory_infinite_element;
-  int inventory_size;
-};
-
 struct LevelSetInfo
 {
   int music[MAX_LEVELS];
@@ -2014,99 +1910,6 @@ struct LevelInfo
   boolean changed;             /* set when level was changed in the editor */
 };
 
-struct TapeInfo
-{
-  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 */
-
-  char *level_identifier;
-  int level_nr;
-  unsigned long random_seed;
-  unsigned long date;
-  unsigned long counter;
-  unsigned long length;
-  unsigned long length_seconds;
-  unsigned int delay_played;
-  boolean pause_before_death;
-  boolean recording, playing, pausing;
-  boolean fast_forward;
-  boolean warp_forward;
-  boolean deactivate_display;
-  boolean auto_play;
-  boolean auto_play_level_solved;
-  boolean quick_resume;
-  boolean single_step;
-  boolean changed;
-  boolean player_participates[MAX_PLAYERS];
-  int num_participating_players;
-
-  struct
-  {
-    byte action[MAX_PLAYERS];
-    byte delay;
-  } pos[MAX_TAPE_LEN];
-
-  boolean no_valid_file;       /* set when tape file missing or invalid */
-};
-
-struct GameInfo
-{
-  /* values for engine initialization */
-  int default_push_delay_fixed;
-  int default_push_delay_random;
-
-  /* constant within running game */
-  int engine_version;
-  int emulation;
-  int initial_move_delay;
-  int initial_move_delay_value;
-  int initial_push_delay_value;
-
-  /* flags to handle bugs in and changes between different engine versions */
-  /* (for the latest engine version, these flags should always be "FALSE") */
-  boolean use_change_when_pushing_bug;
-  boolean use_block_last_field_bug;
-  boolean max_num_changes_per_frame;
-  boolean use_reverse_scan_direction;
-
-  /* variable within running game */
-  int yamyam_content_nr;
-  boolean magic_wall_active;
-  int magic_wall_time_left;
-  int light_time_left;
-  int timegate_time_left;
-  int belt_dir[4];
-  int belt_dir_nr[4];
-  int switchgate_pos;
-  int wind_direction;
-  boolean gravity;
-  boolean explosions_delayed;
-  boolean envelope_active;
-
-#if 1
-  /* values for the new EMC elements */
-  int lenses_time_left;
-  int magnify_time_left;
-  boolean ball_state;
-  int ball_content_nr;
-#endif
-
-  /* values for player idle animation (no effect on engine) */
-  int player_boring_delay_fixed;
-  int player_boring_delay_random;
-  int player_sleeping_delay_fixed;
-  int player_sleeping_delay_random;
-
-  /* values for special game initialization control */
-  boolean restart_level;
-
-  /* values for special game control */
-  int centered_player_nr;
-  int centered_player_nr_next;
-  boolean set_centered_player;
-};
-
 struct GlobalInfo
 {
   char *autoplay_leveldir;
@@ -2505,10 +2308,8 @@ extern int                       graphics_action_mapping[];
 
 extern struct LevelSetInfo     levelset;
 extern struct LevelInfo                level, level_template;
-extern struct PlayerInfo       stored_player[], *local_player;
 extern struct HiScore          highscore[];
 extern struct TapeInfo         tape;
-extern struct GameInfo         game;
 extern struct GlobalInfo       global;
 extern struct MenuInfo         menu;
 extern struct DoorInfo         door_1, door_2;
index 76e2444709815029e88dd31fcad6bbe6d4510ca1..fd78deb5d491bdd1122b4b9e70f2410bf15f3cdc 100644 (file)
@@ -3193,6 +3193,14 @@ void HandleGameActions()
 
     recorded_player_action = (tape.playing ? TapePlayAction() : NULL);
 
+#if 1
+    if (tape.set_centered_player)
+    {
+      game.centered_player_nr_next = tape.centered_player_nr_next;
+      game.set_centered_player = TRUE;
+    }
+#endif
+
 #if 1
     /* !!! CHECK THIS (tape.pausing is always FALSE here!) !!! */
     if (recorded_player_action == NULL && tape.pausing)
index e8fb1b7e4d86410763c02faa029bb28a912b935d..becd0ad9affd199b714e7c3c663ede2383c65331 100644 (file)
@@ -485,6 +485,9 @@ void TapeErase()
 
   for (i = 0; i < MAX_PLAYERS; i++)
     tape.player_participates[i] = FALSE;
+
+  tape.centered_player_nr_next = -1;
+  tape.set_centered_player = FALSE;
 }
 
 static void TapeRewind()
@@ -502,6 +505,9 @@ static void TapeRewind()
   tape.quick_resume = FALSE;
   tape.single_step = FALSE;
 
+  tape.centered_player_nr_next = -1;
+  tape.set_centered_player = FALSE;
+
   InitRND(tape.random_seed);
 }
 
@@ -585,8 +591,9 @@ void TapeStopRecording()
   MapTapeEjectButton();
 }
 
-void TapeRecordAction(byte action[MAX_PLAYERS])
+void TapeRecordAction(byte action_raw[MAX_PLAYERS])
 {
+  byte action[MAX_PLAYERS];
   int i;
 
   if (!tape.recording)         /* (record action even when tape is paused) */
@@ -598,6 +605,19 @@ void TapeRecordAction(byte action[MAX_PLAYERS])
     return;
   }
 
+  for (i = 0; i < MAX_PLAYERS; i++)
+    action[i] = action_raw[i];
+
+  if (tape.set_centered_player)
+  {
+    for (i = 0; i < MAX_PLAYERS; i++)
+      if (tape.centered_player_nr_next == i ||
+         tape.centered_player_nr_next == -1)
+       action[i] |= SET_FOCUS;
+
+    tape.set_centered_player = FALSE;
+  }
+
   if (tape.pos[tape.counter].delay > 0)                /* already stored action */
   {
     boolean changed_events = FALSE;
@@ -778,6 +798,21 @@ byte *TapePlayAction()
   for (i = 0; i < MAX_PLAYERS; i++)
     action[i] = tape.pos[tape.counter].action[i];
 
+  tape.set_centered_player = FALSE;
+  tape.centered_player_nr_next = -999;
+
+  for (i = 0; i < MAX_PLAYERS; i++)
+  {
+    if (action[i] & SET_FOCUS)
+    {
+      tape.set_centered_player = TRUE;
+      tape.centered_player_nr_next =
+       (tape.centered_player_nr_next == -999 ? i : -1);
+    }
+
+    action[i] &= ~SET_FOCUS;
+  }
+
   tape.delay_played++;
   if (tape.delay_played >= tape.pos[tape.counter].delay)
   {
index 3cb2038a46e85874f851767754745a04fad98a10..18107addd01b106324effba8e4f9ba552d8d8fb0 100644 (file)
 #ifndef TAPE_H
 #define TAPE_H
 
-#include "main.h"
-
 
 /* values for TapeTogglePause() */
 #define        TAPE_TOGGLE_MANUAL      TRUE
 #define        TAPE_TOGGLE_AUTOMATIC   FALSE
 
+/* values for tape properties */
+#define MAX_TAPE_LEN           (1000 * FRAMES_PER_SECOND) /* max.time x fps */
+
 /* some positions in the video tape control window */
 #define VIDEO_DISPLAY1_XPOS    5
 #define VIDEO_DISPLAY1_YPOS    5
 #define VIDEO_DISPLAY_SYMBOL_ONLY      -2
 
 
+struct TapeInfo
+{
+  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 */
+
+  char *level_identifier;
+  int level_nr;
+  unsigned long random_seed;
+  unsigned long date;
+  unsigned long counter;
+  unsigned long length;
+  unsigned long length_seconds;
+  unsigned int delay_played;
+  boolean pause_before_death;
+  boolean recording, playing, pausing;
+  boolean fast_forward;
+  boolean warp_forward;
+  boolean deactivate_display;
+  boolean auto_play;
+  boolean auto_play_level_solved;
+  boolean quick_resume;
+  boolean single_step;
+  boolean changed;
+  boolean player_participates[MAX_PLAYERS];
+  int num_participating_players;
+  int centered_player_nr_next;
+  boolean set_centered_player;
+
+  struct
+  {
+    byte action[MAX_PLAYERS];
+    byte delay;
+  } pos[MAX_TAPE_LEN];
+
+  boolean no_valid_file;       /* set when tape file missing or invalid */
+};
+
+
 void DrawVideoDisplay(unsigned long, unsigned long);
 void DrawCompleteVideoDisplay(void);
 
index f9b4f6394e41ce11db31acc447be9493a2835f3a..74e4c8d8dbee2eab499ad784424dd6655ebb8684 100644 (file)
@@ -5125,6 +5125,7 @@ int font2baseimg(int font_nr)
   return font_info[font_nr].special_graphic[GFX_SPECIAL_ARG_DEFAULT];
 }
 
+#if 0
 void setCenteredPlayerNr_EM(int centered_player_nr)
 {
   game.centered_player_nr = game.centered_player_nr_next = centered_player_nr;
@@ -5153,6 +5154,7 @@ boolean getSetCenteredPlayer_EM()
 {
   return game.set_centered_player;
 }
+#endif
 
 int getNumActivePlayers_EM()
 {
index 0168369e982bedcbe456f949fe89a22b270f34b6..b1d0dd86d0287562067d61b86d3404d9a73461d7 100644 (file)
@@ -15,6 +15,7 @@
 #define TOOLS_H
 
 #include "main.h"
+#include "game.h"
 
 /* for SetDrawtoField */
 #define DRAW_DIRECT            0