-#define COMPILE_DATE_STRING "[2005-03-06 23:19]"
+#define COMPILE_DATE_STRING "[2005-03-14 01:11]"
static struct ValueTextInfo options_move_stepsize[] =
{
+ { 0, "not moving" },
{ 1, "very slow" },
{ 2, "slow" },
{ 4, "normal" },
return position;
}
+inline static int getElementMoveStepsize(int x, int y)
+{
+ int element = Feld[x][y];
+ int direction = MovDir[x][y];
+ int dx = (direction == MV_LEFT ? -1 : direction == MV_RIGHT ? +1 : 0);
+ int dy = (direction == MV_UP ? -1 : direction == MV_DOWN ? +1 : 0);
+ int horiz_move = (dx != 0);
+ int sign = (horiz_move ? dx : dy);
+ int step = sign * element_info[element].move_stepsize;
+
+ /* special values for move stepsize for spring and things on conveyor belt */
+ if (horiz_move)
+ {
+#if 0
+ if (element == EL_SPRING)
+ step = sign * MOVE_STEPSIZE_NORMAL * 2;
+ else if (CAN_FALL(element) && !CAN_MOVE(element) &&
+ y < lev_fieldy - 1 && IS_BELT_ACTIVE(Feld[x][y + 1]))
+ step = sign * MOVE_STEPSIZE_NORMAL / 2;
+#else
+ if (CAN_FALL(element) &&
+ y < lev_fieldy - 1 && IS_BELT_ACTIVE(Feld[x][y + 1]))
+ step = sign * MOVE_STEPSIZE_NORMAL / 2;
+ else if (element == EL_SPRING)
+ step = sign * MOVE_STEPSIZE_NORMAL * 2;
+#endif
+ }
+
+ return step;
+}
+
void InitPlayerGfxAnimation(struct PlayerInfo *player, int action, int dir)
{
if (player->GfxAction != action || player->GfxDir != dir)
if (!WasJustMoving[x][y] || direction != MovDir[x][y])
ResetGfxAnimation(x, y);
+#if 1
+
+ MovDir[x][y] = direction;
+ GfxDir[x][y] = direction;
+ GfxAction[x][y] = (direction == MV_DOWN && CAN_FALL(element) ?
+ ACTION_FALLING : ACTION_MOVING);
+
+ if (getElementMoveStepsize(x, y) != 0)
+ {
+ if (Feld[newx][newy] == EL_EMPTY)
+ Feld[newx][newy] = EL_BLOCKED;
+
+ MovDir[newx][newy] = MovDir[x][y];
+ GfxFrame[newx][newy] = GfxFrame[x][y];
+ GfxRandom[newx][newy] = GfxRandom[x][y];
+ GfxAction[newx][newy] = GfxAction[x][y];
+ GfxDir[newx][newy] = GfxDir[x][y];
+ }
+
+#else
+
MovDir[newx][newy] = MovDir[x][y] = direction;
GfxDir[x][y] = direction;
GfxRandom[newx][newy] = GfxRandom[x][y];
GfxAction[newx][newy] = GfxAction[x][y];
GfxDir[newx][newy] = GfxDir[x][y];
+#endif
}
void Moving2Blocked(int x, int y, int *goes_to_x, int *goes_to_y)
Feld[x][y] = EL_TIMEGATE_SWITCH_ACTIVE;
}
-inline static int getElementMoveStepsize(int x, int y)
-{
- int element = Feld[x][y];
- int direction = MovDir[x][y];
- int dx = (direction == MV_LEFT ? -1 : direction == MV_RIGHT ? +1 : 0);
- int dy = (direction == MV_UP ? -1 : direction == MV_DOWN ? +1 : 0);
- int horiz_move = (dx != 0);
- int sign = (horiz_move ? dx : dy);
- int step = sign * element_info[element].move_stepsize;
-
- /* special values for move stepsize for spring and things on conveyor belt */
- if (horiz_move)
- {
-#if 0
- if (element == EL_SPRING)
- step = sign * MOVE_STEPSIZE_NORMAL * 2;
- else if (CAN_FALL(element) && !CAN_MOVE(element) &&
- y < lev_fieldy - 1 && IS_BELT_ACTIVE(Feld[x][y + 1]))
- step = sign * MOVE_STEPSIZE_NORMAL / 2;
-#else
- if (CAN_FALL(element) &&
- y < lev_fieldy - 1 && IS_BELT_ACTIVE(Feld[x][y + 1]))
- step = sign * MOVE_STEPSIZE_NORMAL / 2;
- else if (element == EL_SPRING)
- step = sign * MOVE_STEPSIZE_NORMAL * 2;
-#endif
- }
-
- return step;
-}
-
void Impact(int x, int y)
{
boolean lastline = (y == lev_fieldy-1);
boolean can_turn_right =
CUSTOM_ELEMENT_CAN_ENTER_FIELD(element, right_x,right_y);
+#if 1
+ if (getElementMoveStepsize(x, y) == 0)
+ return;
+#endif
+
if (move_pattern == MV_TURNING_LEFT)
MovDir[x][y] = left_dir;
else if (move_pattern == MV_TURNING_RIGHT)
boolean first_horiz = RND(2);
int new_move_dir = MovDir[x][y];
+#if 1
+ if (getElementMoveStepsize(x, y) == 0)
+ {
+ first_horiz = (ABS(attr_x - x) >= ABS(attr_y - y));
+ MovDir[x][y] &= (first_horiz ? MV_HORIZONTAL : MV_VERTICAL);
+
+ return;
+ }
+#endif
+
MovDir[x][y] =
new_move_dir & (first_horiz ? MV_HORIZONTAL : MV_VERTICAL);
Moving2Blocked(x, y, &newx, &newy);
#include "main.h"
void GetPlayerConfig(void);
+
+void DrawGameValue_Time(int);
void DrawGameDoorValues(void);
+
void InitGameSound();
void InitGame(void);
for (i = 2112; i < 2148; i++)
src[i] = src[i - 64];
}
+#if 0
+ else if (length >= 2106) /* !!! TEST ONLY: SHOW BROKEN LEVELS !!! */
+#else
else if (length >= 2106 &&
src[1983] == 116)
+#endif
{
/* ---------- this cave has V4 file format ---------- */
file_version = FILE_VERSION_EM_V4;
for (x = 0; x < WIDTH; x++)
Draw[y][x] = Cave[y][x];
+#if 1
+ lev.time_initial = lev.time_seconds;
+#else
lev.time_initial = (lev.time_seconds * 50 + 7) / 8;
+#endif
lev.time = lev.time_initial;
lev.required = lev.required_initial;
lev.home = lev.home_initial;
+ lev.killed_out_of_time = FALSE;
+
ply1.num = 0;
ply1.alive = ply1.alive_initial;
ply1.dynamite = 0;
#define SXSIZE (SCR_FIELDX * TILEX)
#define SYSIZE (SCR_FIELDY * TILEY)
-#define DISPLAY_TIME(x) (((x) * 8 + 49) / 50)
+#if 1
+#define FRAMES_PER_SECOND 50
+
+#define ROUNDED_DIVIDE(x, y) (((x) + (y) - 1) / (y))
+
+#define SECONDS_TO_FRAMES(x) ((x) * FRAMES_PER_SECOND)
+#define FRAMES_TO_SECONDS(x) ((x) / FRAMES_PER_SECOND)
+
+#define SECONDS_TO_CYCLES(x) ROUNDED_DIVIDE((x) * FRAMES_PER_SECOND, 8)
+#define CYCLES_TO_SECONDS(x) ROUNDED_DIVIDE((x) * 8, FRAMES_PER_SECOND)
+#define DISPLAY_TIME(x) ROUNDED_DIVIDE(x, FRAMES_PER_SECOND)
+
+#else
+
+#define DISPLAY_TIME(x) (((x) * 8 + 49) / 50)
+#endif
extern Bitmap *screenBitmap;
extern Bitmap *scoreBitmap;
}
}
+#if 1
+ DrawAllGameValues(lev.required, ply1.dynamite, lev.score,
+ lev.time, ply1.keys | ply2.keys);
+#else
DrawAllGameValues(lev.required, ply1.dynamite, lev.score,
DISPLAY_TIME(lev.time + 4), ply1.keys | ply2.keys);
+#endif
}
void RedrawPlayfield_EM()
void DrawGameDoorValues_EM()
{
+#if 1
+ DrawAllGameValues(lev.required, ply1.dynamite, lev.score,
+ lev.time, ply1.keys | ply2.keys);
+#else
DrawAllGameValues(lev.required, ply1.dynamite, lev.score,
DISPLAY_TIME(lev.time), ply1.keys | ply2.keys);
+#endif
}
if (game_frame_delay_value > 0) /* do not redraw values in warp mode */
DrawGameDoorValues_EM();
}
+
+#if 0
+ if (lev.time_initial == 0)
+ lev.time++;
+ else if (lev.time > 0)
+ lev.time--;
+#endif
+
+#if 0
+ if (lev.time_initial > 0 &&
+ lev.time > 0 && lev.time <= 50 && lev.time % 5 == 0 && setup.time_limit)
+ play_sound(-1, -1, SAMPLE_time);
+#endif
}
struct LEVEL
{
- unsigned int home_initial; /* number of players (initial) */
- unsigned int home; /* number of players not yet at home */
- /* 0 == all players at home */
-
- unsigned int width; /* playfield width */
- unsigned int height; /* playfield height */
-
- unsigned int time_seconds; /* available time (seconds) */
- unsigned int time_initial; /* available time (initial) */
- unsigned int time; /* time remaining (runtime) */
-
- unsigned int required_initial; /* emeralds needed (initial) */
- unsigned int required; /* emeralds needed (runtime) */
-
- unsigned int score; /* score */
-
- /* fill in all below /every/ time you read a level */
- unsigned int alien_score; /* alien popped by stone/spring score */
- unsigned int amoeba_time; /* amoeba speed */
- unsigned int android_move_cnt_initial; /* android move time counter (initial) */
- unsigned int android_move_cnt; /* android move time counter */
- unsigned int android_move_time; /* android move reset time */
- unsigned int android_clone_cnt_initial; /* android clone time counter (initial) */
- unsigned int android_clone_cnt; /* android clone time counter */
- unsigned int android_clone_time; /* android clone reset time */
- unsigned int ball_cnt; /* ball time counter */
- unsigned int ball_pos; /* ball array pos counter */
- unsigned int ball_random; /* ball is random flag */
- unsigned int ball_state_initial; /* ball currently on flag (initial) */
- unsigned int ball_state; /* ball currently on flag */
- unsigned int ball_time; /* ball reset time */
- unsigned int bug_score; /* bug popped by stone/spring score */
- unsigned int diamond_score; /* diamond collect score */
- unsigned int dynamite_score; /* dynamite collect scoer*/
- unsigned int eater_pos; /* eater array pos */
- unsigned int eater_score; /* eater popped by stone/spring score */
- unsigned int emerald_score; /* emerald collect score */
- unsigned int exit_score; /* exit score */
- unsigned int key_score; /* key collect score */
- unsigned int lenses_cnt_initial; /* lenses time counter (initial) */
- unsigned int lenses_cnt; /* lenses time counter */
- unsigned int lenses_score; /* lenses collect score */
- unsigned int lenses_time; /* lenses reset time */
- unsigned int magnify_cnt_initial; /* magnify time counter (initial) */
- unsigned int magnify_cnt; /* magnify time counter */
- unsigned int magnify_score; /* magnify collect score */
- unsigned int magnify_time; /* magnify reset time */
- unsigned int nut_score; /* nut crack score */
- unsigned int shine_cnt; /* shine counter for emerald/diamond */
- unsigned int slurp_score; /* slurp alien score */
- unsigned int tank_score; /* tank popped by stone/spring */
- unsigned int wheel_cnt_initial; /* wheel time counter (initial) */
- unsigned int wheel_cnt; /* wheel time counter */
- unsigned int wheel_x_initial; /* wheel x pos (initial) */
- unsigned int wheel_x; /* wheel x pos */
- unsigned int wheel_y_initial; /* wheel y pos (initial) */
- unsigned int wheel_y; /* wheel y pos */
- unsigned int wheel_time; /* wheel reset time */
- unsigned int wind_cnt_initial; /* wind time counter (initial) */
- unsigned int wind_cnt; /* wind time counter */
- unsigned int wind_direction_initial;/* wind direction (initial) */
- unsigned int wind_direction; /* wind direction */
- unsigned int wind_time; /* wind reset time */
- unsigned int wonderwall_state_initial; /* wonderwall currently on flag (initial) */
- unsigned int wonderwall_state; /* wonderwall currently on flag */
- unsigned int wonderwall_time_initial;/* wonderwall time (initial) */
- unsigned int wonderwall_time; /* wonderwall time */
- unsigned short eater_array[8][9]; /* eater data */
- unsigned short ball_array[8][8]; /* ball data */
- unsigned short android_array[TILE_MAX]; /* android clone table */
+ unsigned int home_initial; /* number of players (initial) */
+ unsigned int home; /* number of players not yet at home */
+ /* 0 == all players at home */
+
+ unsigned int width; /* playfield width */
+ unsigned int height; /* playfield height */
+
+ unsigned int time_seconds; /* available time (seconds) */
+ unsigned int time_initial; /* available time (initial) */
+ unsigned int time; /* time remaining (runtime) */
+
+ boolean killed_out_of_time; /* kill player due to time out */
+
+ unsigned int required_initial; /* emeralds needed (initial) */
+ unsigned int required; /* emeralds needed (runtime) */
+
+ unsigned int score; /* score */
+
+ /* all below entries must be filled every time a level is read */
+
+ unsigned int alien_score; /* score for killing alien */
+ unsigned int amoeba_time; /* amoeba speed */
+ unsigned int android_move_cnt_initial;/* android move counter (initial) */
+ unsigned int android_move_cnt; /* android move counter */
+ unsigned int android_move_time; /* android move reset time */
+ unsigned int android_clone_cnt_initial;/* android clone counter (initial) */
+ unsigned int android_clone_cnt; /* android clone counter */
+ unsigned int android_clone_time; /* android clone reset time */
+ unsigned int ball_cnt; /* ball counter */
+ unsigned int ball_pos; /* ball array pos counter */
+ unsigned int ball_random; /* ball is random flag */
+ unsigned int ball_state_initial; /* ball active flag (initial) */
+ unsigned int ball_state; /* ball active flag */
+ unsigned int ball_time; /* ball reset time */
+ unsigned int bug_score; /* score for killing bug */
+ unsigned int diamond_score; /* score for collecting diamond */
+ unsigned int dynamite_score; /* score for collecting dynamite */
+ unsigned int eater_pos; /* eater array pos */
+ unsigned int eater_score; /* score for killing eater */
+ unsigned int emerald_score; /* score for collecting emerald */
+ unsigned int exit_score; /* score for entering exit */
+ unsigned int key_score; /* score for colleting key */
+ unsigned int lenses_cnt_initial; /* lenses counter (initial) */
+ unsigned int lenses_cnt; /* lenses counter */
+ unsigned int lenses_score; /* score for collecting lenses */
+ unsigned int lenses_time; /* lenses reset time */
+ unsigned int magnify_cnt_initial; /* magnify counter (initial) */
+ unsigned int magnify_cnt; /* magnify counter */
+ unsigned int magnify_score; /* score for collecting magnifier */
+ unsigned int magnify_time; /* magnify reset time */
+ unsigned int nut_score; /* score for cracking nut */
+ unsigned int shine_cnt; /* shine counter for emerald/diamond */
+ unsigned int slurp_score; /* score for slurping alien */
+ unsigned int tank_score; /* score for killing tank */
+ unsigned int wheel_cnt_initial; /* wheel counter (initial) */
+ unsigned int wheel_cnt; /* wheel counter */
+ unsigned int wheel_x_initial; /* wheel x pos (initial) */
+ unsigned int wheel_x; /* wheel x pos */
+ unsigned int wheel_y_initial; /* wheel y pos (initial) */
+ unsigned int wheel_y; /* wheel y pos */
+ unsigned int wheel_time; /* wheel reset time */
+ unsigned int wind_cnt_initial; /* wind counter (initial) */
+ unsigned int wind_cnt; /* wind time counter */
+ unsigned int wind_direction_initial; /* wind direction (initial) */
+ unsigned int wind_direction; /* wind direction */
+ unsigned int wind_time; /* wind reset time */
+ unsigned int wonderwall_state_initial;/* wonderwall active flag (initial) */
+ unsigned int wonderwall_state; /* wonderwall active flag */
+ unsigned int wonderwall_time_initial; /* wonderwall time (initial) */
+ unsigned int wonderwall_time; /* wonderwall time */
+ unsigned short eater_array[8][9]; /* eater data */
+ unsigned short ball_array[8][8]; /* ball data */
+ unsigned short android_array[TILE_MAX];/* android clone table */
};
struct PLAYER
{
int file_version;
+ unsigned short cave[EM_MAX_CAVE_WIDTH][EM_MAX_CAVE_HEIGHT];
+
struct LEVEL *lev;
struct PLAYER *ply1, *ply2;
-
- unsigned short cave[EM_MAX_CAVE_WIDTH][EM_MAX_CAVE_HEIGHT];
};
struct GraphicInfo_EM
if (!ply->alive)
return FALSE;
- if (lev.time_initial > 0 && lev.time == 0)
+#if 1
+ if (lev.killed_out_of_time && setup.time_limit)
+ return TRUE;
+#else
+ if (lev.time_initial > 0 && lev.time == 0 && setup.time_limit)
return TRUE;
+#endif
switch(Cave[y-1][x])
{
case Xexit_3:
play_element_sound(x, y, SAMPLE_exit_leave, Xexit_1);
- if (--lev.home == 0 && lev.time_initial > 0) /* game won */
+ lev.home--;
+
+#if 0
+ /* !!! CHECK SCORE CALCULATION !!! */
+ if (lev.home == 0 && lev.time_initial > 0) /* game won */
lev.score += lev.time * lev.exit_score / 100;
+#endif
ply->anim = SPR_walk + anim;
ply->x = x;
if (lev.score > 9999)
lev.score = 9999;
+#if 0
#if 1
if (lev.time_initial == 0)
lev.time++;
- else if (lev.time)
+ else if (lev.time > 0)
lev.time--;
#else
if (lev.time)
lev.time--;
+#endif
#endif
if (lev.android_move_cnt-- == 0)
if (lev.wonderwall_time && lev.wonderwall_state)
lev.wonderwall_time--;
+#if 0
if (lev.time_initial > 0 &&
- lev.time > 0 && lev.time <= 50 && lev.time % 5 == 0)
+ lev.time > 0 && lev.time <= 50 && lev.time % 5 == 0 && setup.time_limit)
play_sound(-1, -1, SAMPLE_time);
+#endif
if (lev.wheel_cnt)
play_element_sound(lev.wheel_x, lev.wheel_y, SAMPLE_wheel, Xwheel);
TimeFrames = 0;
TapeTime++;
+ if (!level.use_step_counter)
+ {
+ TimePlayed++;
+
+ if (TimeLeft > 0)
+ {
+ TimeLeft--;
+
+ if (TimeLeft <= 10 && setup.time_limit)
+ PlaySoundStereo(SND_GAME_RUNNING_OUT_OF_TIME, SOUND_MIDDLE);
+
+ DrawGameValue_Time(TimeLeft);
+
+ if (!TimeLeft && setup.time_limit)
+ level.native_em_level->lev->killed_out_of_time = TRUE;
+ }
+ else if (level.time == 0 && level.native_em_level->lev->home > 0)
+ DrawGameValue_Time(TimePlayed);
+
+ level.native_em_level->lev->time =
+ (level.time == 0 ? TimePlayed : TimeLeft);
+ }
+
if (tape.recording || tape.playing)
DrawVideoDisplay(VIDEO_STATE_TIME_ON, TapeTime);
}