fixed single-step mode for wrap-around levels in EM engine
[rocksndiamonds.git] / src / game_em / game.c
1 /* 2007-11-06 03:39:32
2  *
3  * handle interaction between screen and cave
4  */
5
6 #include "main_em.h"
7
8
9 struct CAVE cav;
10 struct LOGIC lev;
11 struct PLAYER ply[MAX_PLAYERS];
12
13 struct EngineSnapshotInfo_EM engine_snapshot_em;
14
15 /* handle input actions for players */
16
17 static void readjoy(byte action, struct PLAYER *ply)
18 {
19   boolean north = FALSE;
20   boolean east  = FALSE;
21   boolean south = FALSE;
22   boolean west  = FALSE;
23   boolean snap  = FALSE;
24   boolean drop  = FALSE;
25
26   if (game_em.use_single_button && action & (JOY_BUTTON_1 | JOY_BUTTON_2))
27     action |= JOY_BUTTON_1 | JOY_BUTTON_2;
28
29   if (action & JOY_LEFT)
30     west = TRUE;
31
32   if (action & JOY_RIGHT)
33     east = TRUE;
34
35   if (action & JOY_UP)
36     north = TRUE;
37
38   if (action & JOY_DOWN)
39     south = TRUE;
40
41   if (action & JOY_BUTTON_1)
42     snap = TRUE;
43
44   if (action & JOY_BUTTON_2)
45     drop = TRUE;
46
47   /* always update drop action */
48   ply->joy_drop = drop;
49
50   if (ply->joy_stick || (north | east | south | west))  /* (no "| snap"!) */
51   {
52     ply->joy_n = north;
53     ply->joy_e = east;
54     ply->joy_s = south;
55     ply->joy_w = west;
56
57     /* when storing last action, only update snap action with direction */
58     /* (prevents clearing direction if snapping stopped before frame 7) */
59     ply->joy_snap = snap;
60   }
61
62   /* if no direction was stored before, allow setting snap to current state */
63   if (!ply->joy_n &&
64       !ply->joy_e &&
65       !ply->joy_s &&
66       !ply->joy_w)
67     ply->joy_snap = snap;
68
69   /* use bug with snap key (mainly TAS keys) sometimes moving the player */
70   if (game_em.use_snap_key_bug)
71     ply->joy_snap = snap;
72 }
73
74 void InitGameEngine_EM(void)
75 {
76   prepare_em_level();
77
78   logic_init();
79
80   game_initscreen();
81
82   RedrawPlayfield_EM(FALSE);
83 }
84
85 void GameActions_EM(byte action[MAX_PLAYERS], boolean warp_mode)
86 {
87   int i;
88   boolean any_player_dropping = FALSE;
89
90   game_em.random = game_em.random * 129 + 1;
91
92   frame = (frame + 1) % 8;
93
94   for (i = 0; i < MAX_PLAYERS; i++)
95     readjoy(action[i], &ply[i]);
96
97   UpdateEngineValues(CAVE_POS_X(screen_x / TILEX),
98                      CAVE_POS_Y(screen_y / TILEY),
99                      CAVE_POS_X(ply[0].x),
100                      CAVE_POS_Y(ply[0].y));
101
102   logic();
103
104   for (i = 0; i < MAX_PLAYERS; i++)
105     if (ply[i].joy_drop &&
106         ply[i].dynamite &&
107         ply[i].dynamite_cnt > 0 &&
108         ply[i].dynamite_cnt < 5)
109       any_player_dropping = TRUE;
110
111   boolean single_step_mode_paused =
112     CheckSingleStepMode_EM(action, frame, game_em.any_player_moving,
113                            game_em.any_player_snapping, any_player_dropping);
114
115   // draw wrapping around before going to single step pause mode
116   if (single_step_mode_paused && logic_check_wrap())
117     logic_move();
118
119   RedrawPlayfield_EM(FALSE);
120 }
121
122 void SaveEngineSnapshotValues_EM(void)
123 {
124   int i;
125
126   engine_snapshot_em.game_em = game_em;
127   engine_snapshot_em.lev = lev;
128
129   engine_snapshot_em.frame = frame;
130   engine_snapshot_em.screen_x = screen_x;
131   engine_snapshot_em.screen_y = screen_y;
132
133   for (i = 0; i < 4; i++)
134     engine_snapshot_em.ply[i] = ply[i];
135 }
136
137 void LoadEngineSnapshotValues_EM(void)
138 {
139   int i;
140
141   game_em = engine_snapshot_em.game_em;
142   lev = engine_snapshot_em.lev;
143
144   frame = engine_snapshot_em.frame;
145   screen_x = engine_snapshot_em.screen_x;
146   screen_y = engine_snapshot_em.screen_y;
147
148   for (i = 0; i < 4; i++)
149     ply[i] = engine_snapshot_em.ply[i];
150 }