+2010-06-09
+ * improved single step mode in R'n'D, EM and SP engines
+
+2010-06-08
+ * version number set to 3.3.0.2
+
2010-06-08
* version 3.3.0.1 released
CONFIG_GAME = $(CONFIG_GAME_DIR) $(CONFIG_SCORE_ENTRIES) $(CONFIG_SPECIAL)
CONFIG = $(CONFIG_GAME) $(JOYSTICK)
-# DEBUG = -DDEBUG -g
+DEBUG = -DDEBUG -g
# PROFILING = $(PROFILING_FLAGS)
# OPTIONS = $(DEBUG) -Wall # only for debugging purposes
-#define COMPILE_DATE_STRING "2010-06-08 22:20"
+#define COMPILE_DATE_STRING "2010-06-09 23:36"
extern void PlayLevelSound_EM(int, int, int, int);
extern void InitGraphicInfo_EM(void);
-extern void CheckSingleStepMode_EM(byte action[], int, boolean);
+extern void CheckSingleStepMode_EM(byte action[], int, boolean, boolean);
void SetGfxAnimation_EM(struct GraphicInfo_EM *, int, int, int, int);
void getGraphicSourceObjectExt_EM(struct GraphicInfo_EM *, int, int, int, int);
extern void SetBitmaps_SP(Bitmap **);
#endif
-void CheckSingleStepMode_SP(boolean);
+void CheckSingleStepMode_SP(boolean, boolean);
void getGraphicSource_SP(struct GraphicInfo_SP *, int, int, int, int);
int getGraphicInfo_Delay(int);
if (game_status == GAME_MODE_PLAYING)
{
/* only needed for single-step tape recording mode */
- static boolean clear_button_2[MAX_PLAYERS] = { FALSE,FALSE,FALSE,FALSE };
+ static boolean clear_snap_button[MAX_PLAYERS] = { FALSE,FALSE,FALSE,FALSE };
+ static boolean clear_drop_button[MAX_PLAYERS] = { FALSE,FALSE,FALSE,FALSE };
+ static boolean element_snapped[MAX_PLAYERS] = { FALSE,FALSE,FALSE,FALSE };
static boolean element_dropped[MAX_PLAYERS] = { FALSE,FALSE,FALSE,FALSE };
int pnr;
- ssi = setup.shortcut;
-
for (pnr = 0; pnr < MAX_PLAYERS; pnr++)
{
byte key_action = 0;
if (key == *key_info[i].key_custom)
key_action |= key_info[i].action;
- for (i = 0; i < NUM_DIRECTIONS; i++)
- if (key == *key_info[i].key_snap)
- key_action |= key_info[i].action | JOY_BUTTON_SNAP;
+ /* use combined snap+direction keys for the first player only */
+ if (pnr == 0)
+ {
+ ssi = setup.shortcut;
+
+ for (i = 0; i < NUM_DIRECTIONS; i++)
+ if (key == *key_info[i].key_snap)
+ key_action |= key_info[i].action | JOY_BUTTON_SNAP;
+ }
- if (tape.single_step && clear_button_2[pnr])
+ /* clear delayed snap and drop actions in single step mode (see below) */
+ if (tape.single_step)
{
- stored_player[pnr].action &= ~KEY_BUTTON_2;
- clear_button_2[pnr] = FALSE;
+ if (clear_snap_button[pnr])
+ {
+ stored_player[pnr].action &= ~KEY_BUTTON_SNAP;
+ clear_snap_button[pnr] = FALSE;
+ }
+
+ if (clear_drop_button[pnr])
+ {
+ stored_player[pnr].action &= ~KEY_BUTTON_DROP;
+ clear_drop_button[pnr] = FALSE;
+ }
}
if (key_status == KEY_PRESSED)
if (tape.single_step && tape.recording && tape.pausing)
{
- if (key_status == KEY_PRESSED &&
- (key_action & (KEY_MOTION | KEY_BUTTON_1)))
+ if (key_status == KEY_PRESSED && key_action & KEY_MOTION)
{
TapeTogglePause(TAPE_TOGGLE_AUTOMATIC);
- if (key_action & KEY_MOTION)
+ /* if snap key already pressed, don't snap when releasing (below) */
+ if (stored_player[pnr].action & KEY_BUTTON_SNAP)
+ element_snapped[pnr] = TRUE;
+
+ /* if drop key already pressed, don't drop when releasing (below) */
+ if (stored_player[pnr].action & KEY_BUTTON_DROP)
+ element_dropped[pnr] = TRUE;
+ }
+#if 1
+ else if (key_status == KEY_PRESSED && key_action & KEY_BUTTON_DROP)
+ {
+ if (level.game_engine_type == GAME_ENGINE_TYPE_EM ||
+ level.game_engine_type == GAME_ENGINE_TYPE_SP)
{
- if (stored_player[pnr].action & KEY_BUTTON_2)
- element_dropped[pnr] = TRUE;
+#if 0
+ printf("::: drop key pressed\n");
+#endif
+
+ if (level.game_engine_type == GAME_ENGINE_TYPE_SP &&
+ getRedDiskReleaseFlag_SP() == 0)
+ stored_player[pnr].action &= ~KEY_BUTTON_DROP;
+
+ TapeTogglePause(TAPE_TOGGLE_AUTOMATIC);
}
}
- else if (key_status == KEY_RELEASED &&
- (key_action & KEY_BUTTON_2))
+#endif
+ else if (key_status == KEY_RELEASED && key_action & KEY_BUTTON)
{
- if (!element_dropped[pnr])
+ if (key_action & KEY_BUTTON_SNAP)
{
- TapeTogglePause(TAPE_TOGGLE_AUTOMATIC);
+ /* if snap key was released without moving (see above), snap now */
+ if (!element_snapped[pnr])
+ {
+ TapeTogglePause(TAPE_TOGGLE_AUTOMATIC);
- stored_player[pnr].action |= KEY_BUTTON_2;
- clear_button_2[pnr] = TRUE;
+ stored_player[pnr].action |= KEY_BUTTON_SNAP;
+
+ /* clear delayed snap button on next event */
+ clear_snap_button[pnr] = TRUE;
+ }
+
+ element_snapped[pnr] = FALSE;
}
- element_dropped[pnr] = FALSE;
+#if 1
+ if (key_action & KEY_BUTTON_DROP &&
+ level.game_engine_type == GAME_ENGINE_TYPE_RND)
+ {
+ /* if drop key was released without moving (see above), drop now */
+ if (!element_dropped[pnr])
+ {
+ TapeTogglePause(TAPE_TOGGLE_AUTOMATIC);
+
+ if (level.game_engine_type != GAME_ENGINE_TYPE_SP ||
+ getRedDiskReleaseFlag_SP() != 0)
+ stored_player[pnr].action |= KEY_BUTTON_DROP;
+
+ /* clear delayed drop button on next event */
+ clear_drop_button[pnr] = TRUE;
+ }
+
+ element_dropped[pnr] = FALSE;
+ }
+#endif
}
}
-#if 1
else if (tape.recording && tape.pausing)
{
/* prevent key release events from un-pausing a paused game */
- if (key_status == KEY_PRESSED &&
- (key_action & KEY_ACTION))
+ if (key_status == KEY_PRESSED && key_action & KEY_ACTION)
TapeTogglePause(TAPE_TOGGLE_MANUAL);
}
-#else
- else if (tape.recording && tape.pausing && (key_action & KEY_ACTION))
- TapeTogglePause(TAPE_TOGGLE_MANUAL);
-#endif
}
}
else
}
}
+static void CheckSingleStepMode(struct PlayerInfo *player)
+{
+ if (tape.single_step && tape.recording && !tape.pausing)
+ {
+ /* as it is called "single step mode", just return to pause mode when the
+ player stopped moving after one tile (or never starts moving at all) */
+ if (!player->is_moving && !player->is_pushing)
+ {
+ TapeTogglePause(TAPE_TOGGLE_AUTOMATIC);
+ SnapField(player, 0, 0); /* stop snapping */
+ }
+ }
+}
+
static byte PlayerActions(struct PlayerInfo *player, byte player_action)
{
boolean moved = FALSE, snapped = FALSE, dropped = FALSE;
moved = MovePlayer(player, dx, dy);
}
- if (tape.single_step && tape.recording && !tape.pausing)
- {
-#if 1
- /* as it is called "single step mode", just return to pause mode when the
- player stopped moving after one tile (or never starts moving at all) */
- if (!player->is_moving)
-#else
- /* this is buggy: there are quite some cases where the single step mode
- does not return to pause mode (like pushing things that don't move
- or simply by trying to run against a wall) */
- if (button1 || (dropped && !moved))
-#endif
- {
- TapeTogglePause(TAPE_TOGGLE_AUTOMATIC);
- SnapField(player, 0, 0); /* stop snapping */
- }
- }
+ CheckSingleStepMode(player);
SetPlayerWaiting(player, FALSE);
player->is_dropping_pressed = FALSE;
player->drop_pressed_delay = 0;
+ CheckSingleStepMode(player);
+
return 0;
}
}
void GameActions_EM(byte action[MAX_PLAYERS], boolean warp_mode)
{
int i;
+ boolean player_is_dropping = FALSE;
#if 0
static int foo = -1;
DrawGameDoorValues_EM();
}
- CheckSingleStepMode_EM(action, frame, game_em.any_player_moving);
+ for (i = 0; i < MAX_PLAYERS; i++)
+ if (ply[i].joy_drop &&
+ ply[i].dynamite &&
+ ply[i].dynamite_cnt > 0 &&
+ ply[i].dynamite_cnt < 5)
+ player_is_dropping = TRUE;
+
+ CheckSingleStepMode_EM(action, frame, game_em.any_player_moving,
+ player_is_dropping);
#if 1
game_animscreen();
}
} // loc_g_5E8B:
+#if 0
+ printf("::: RedDiskReleaseFlag == %d\n", RedDiskReleaseFlag);
+#endif
+
bl = DemoKeyCode;
if (bl != 0) // a key was pressed!
goto locKeyPressed5FCF;
extern int map_key_RND_to_SP(int);
extern int map_key_SP_to_RND(int);
+extern int getRedDiskReleaseFlag_SP();
+
#endif /* GAME_SP_EXPORT_H */
if (!warp_mode) /* do not redraw values in warp mode */
DrawGameDoorValues_SP();
- CheckSingleStepMode_SP(PlayField16[MurphyPosIndex] != fiMurphy);
+ CheckSingleStepMode_SP(PlayField16[MurphyPosIndex] == fiMurphy,
+ HighByte(PlayField16[MurphyPosIndex]) == 0x2A);
for (x = DisplayMinX; x <= DisplayMaxX; x++)
for (y = DisplayMinY; y <= DisplayMaxY; y++)
GfxFrame[x][y]++;
}
+
+int getRedDiskReleaseFlag_SP()
+{
+ return RedDiskReleaseFlag;
+}
#define PROGRAM_VERSION_MAJOR 3
#define PROGRAM_VERSION_MINOR 3
#define PROGRAM_VERSION_PATCH 0
-#define PROGRAM_VERSION_BUILD 1
+#define PROGRAM_VERSION_BUILD 2
#define PROGRAM_TITLE_STRING "Rocks'n'Diamonds"
#define PROGRAM_AUTHOR_STRING "Holger Schemel"
}
void CheckSingleStepMode_EM(byte action[MAX_PLAYERS], int frame,
- boolean any_player_moving)
+ boolean any_player_moving,
+ boolean player_is_dropping)
{
int i;
if (action[i] != JOY_NO_ACTION)
active_players = TRUE;
- if (frame == 0)
+ // if (frame == 0)
+ if (frame == 0 && !player_is_dropping)
TapeTogglePause(TAPE_TOGGLE_AUTOMATIC);
}
}
-void CheckSingleStepMode_SP(boolean murphy_is_moving)
+void CheckSingleStepMode_SP(boolean murphy_is_waiting,
+ boolean murphy_is_dropping)
{
+#if 0
+ printf("::: waiting: %d, dropping: %d\n",
+ murphy_is_waiting, murphy_is_dropping);
+#endif
+
if (tape.single_step && tape.recording && !tape.pausing)
{
- if (!murphy_is_moving)
+ // if (murphy_is_waiting || murphy_is_dropping)
+ if (murphy_is_waiting)
+ {
+#if 0
+ printf("::: murphy is waiting -> pause mode\n");
+#endif
+
TapeTogglePause(TAPE_TOGGLE_AUTOMATIC);
+ }
}
}