* The player_get function will also behave for lava as it does for space.
*/
-#include <glib.h>
-
#include "main_bd.h"
}
}
+static inline int getx(const GdCave *cave, const int x, const int y)
+{
+ return cave->getx(cave, x, y);
+}
+
+static inline int gety(const GdCave *cave, const int x, const int y)
+{
+ return cave->gety(cave, x, y);
+}
+
+/* perfect (non-lineshifting) GET x/y functions; returns range corrected x/y position */
+static inline int getx_perfect(const GdCave *cave, const int x, const int y)
+{
+ return (x + cave->w) % cave->w;
+}
+
+static inline int gety_perfect(const GdCave *cave, const int x, const int y)
+{
+ return (y + cave->h) % cave->h;
+}
+
+/* line shifting GET x/y function; returns range corrected x/y position */
+static inline int getx_shift(const GdCave *cave, int x, int y)
+{
+ return (x + cave->w) % cave->w;
+}
+
+static inline int gety_shift(const GdCave *cave, int x, int y)
+{
+ return ((x < 0 ? y - 1 : x >= cave->w ? y + 1 : y) + cave->h) % cave->h;
+}
+
static inline GdElement *getp(const GdCave *cave, const int x, const int y)
{
return cave->getp(cave, x, y);
static inline boolean is_space_dir(const GdCave *cave, const int x, const int y,
const GdDirection dir)
{
- GdElement e = get_dir(cave, x, y, dir)&O_MASK;
+ GdElement e = get_dir(cave, x, y, dir) & O_MASK;
return (e == O_SPACE || e == O_LAVA);
}
+static inline void store_dir_buffer(GdCave *cave, const int x, const int y, const GdDirection dir)
+{
+ /* raw values without range correction */
+ int raw_x = x + gd_dx[dir];
+ int raw_y = y + gd_dy[dir];
+ /* final values with range correction */
+ int new_x = getx(cave, raw_x, raw_y);
+ int new_y = gety(cave, raw_x, raw_y);
+ int new_dir = (dir > GD_MV_TWICE ? dir - GD_MV_TWICE : dir);
+
+ game_bd.game->dir_buffer[new_y][new_x] = new_dir;
+}
+
/* store an element at the given position */
static inline void store(GdCave *cave, const int x, const int y, const GdElement element)
{
static inline void store_dir(GdCave *cave, const int x, const int y,
const GdDirection dir, const GdElement element)
{
- store(cave, x + gd_dx[dir], y + gd_dy[dir], element|SCANNED);
+ store_dir_buffer(cave, x, y, dir);
+ store(cave, x + gd_dx[dir], y + gd_dy[dir], element | SCANNED);
}
/* store an element to a neighbouring cell */
static inline void store_dir_no_scanned(GdCave *cave, const int x, const int y,
const GdDirection dir, const GdElement element)
{
+ store_dir_buffer(cave, x, y, dir);
store(cave, x + gd_dx[dir], y + gd_dy[dir], element);
}
}
if (is_space_dir(cave, x, y, GD_MV_TWICE + player_move) &&
- g_rand_int_range(cave->random, 0, 1000000) < prob)
+ gd_rand_int_range(cave->random, 0, 1000000) < prob)
{
/* if decided that he will be able to push, */
store_dir(cave, x, y, GD_MV_TWICE + player_move, what);
{
play_sound_of_element(cave, O_DIAMOND, x, y); /* always play diamond sound */
- if (cave->magic_wall_state==GD_MW_DORMANT)
+ if (cave->magic_wall_state == GD_MW_DORMANT)
cave->magic_wall_state = GD_MW_ACTIVE;
- if (cave->magic_wall_state==GD_MW_ACTIVE &&
+ if (cave->magic_wall_state == GD_MW_ACTIVE &&
is_space_dir(cave, x, y, GD_MV_TWICE+fall_dir))
{
/* if magic wall active and place underneath, it turns element
/* set cave get function; to implement perfect or lineshifting borders */
if (cave->lineshift)
+ {
cave->getp = getp_shift;
+ cave->getx = getx_shift;
+ cave->gety = gety_shift;
+ }
else
+ {
cave->getp = getp_perfect;
+ cave->getx = getx_perfect;
+ cave->gety = gety_perfect;
+ }
/* increment this. if the scan routine comes across player, clears it (sets to zero). */
if (cave->player_seen_ago < 100)
for (x = 0; x < cave->w; x++)
{
/* timer for the cell > 0? */
- if (cave->hammered_reappear[y][x]>0)
+ if (cave->hammered_reappear[y][x] > 0)
{
/* decrease timer */
cave->hammered_reappear[y][x]--;
{
/* if we find a scanned element, change it to the normal one, and that's all. */
/* this is required, for example for chasing stones, which have moved, always passing slime! */
- if (get(cave, x, y)&SCANNED)
+ if (get(cave, x, y) & SCANNED)
{
store(cave, x, y, get(cave, x, y) & ~SCANNED);
cave->player_seen_ago = 0;
/* bd4 intermission caves have many players. so if one of them has exited,
* do not change the flag anymore. so this if () is needed */
- if (cave->player_state!=GD_PL_EXITED)
+ if (cave->player_state != GD_PL_EXITED)
cave->player_state = GD_PL_LIVING;
/* check for pneumatic hammer things */
/* try to push element; if successful, break */
push = do_push(cave, x, y, player_move, player_fire);
if (push)
+ {
remains = O_SPACE;
+ }
else
+ {
switch (what)
{
case O_BOMB:
default:
/* get element - process others.
if cannot get, player_get_element will return the same */
- remains = player_get_element (cave, what, x, y);
+ remains = player_get_element(cave, what, x, y);
break;
}
+ }
if (remains != what || remains == O_SPACE)
{
/* player fire is false... */
if (do_push(cave, x, y, player_move, FALSE))
+ {
remains = O_SPACE;
+ }
else
{
switch (what)
player_move parameter) */
/* only allow changing direction if the new dir is not diagonal */
if (cave->gravity_switch_active &&
- (player_move==GD_MV_LEFT ||
- player_move==GD_MV_RIGHT ||
- player_move==GD_MV_UP ||
- player_move==GD_MV_DOWN))
+ (player_move == GD_MV_LEFT ||
+ player_move == GD_MV_RIGHT ||
+ player_move == GD_MV_UP ||
+ player_move == GD_MV_DOWN))
{
gd_sound_play(cave, GD_S_SWITCH_GRAVITY, what, x, y);
cave->gravity_will_change =
cave->player_seen_ago = 0;
/* bd4 intermission caves have many players. so if one of them has exited,
* do not change the flag anymore. so this if () is needed */
- if (cave->player_state!=GD_PL_EXITED)
+ if (cave->player_state != GD_PL_EXITED)
cave->player_state = GD_PL_LIVING;
if (player_fire)
}
cave->player_seen_ago = 0;
- if (cave->player_state!=GD_PL_EXITED)
+ if (cave->player_state != GD_PL_EXITED)
cave->player_state = GD_PL_LIVING;
/* if hammering time is up, becomes a normal player again. */
{
const GdDirection *creature_move;
boolean ccw = rotates_ccw(cave, x, y); /* check if default is counterclockwise */
- GdElement base; /* base element number (which is like O_***_1) */
+ GdElement base = -1; /* base element number (which is like O_***_1) */
int dir, dirn, dirp; /* direction */
if (get(cave, x, y) >= O_FIREFLY_1 &&
get(cave, x, y) <= O_ALT_BUTTER_4)
base = O_ALT_BUTTER_1;
- dir = get(cave, x, y)-base; /* facing where */
+ dir = get(cave, x, y) - base; /* facing where */
creature_move = cave->creatures_backwards ? creature_chdir : creature_dir;
/* now change direction if backwards */
{
int px = cave->px[0];
int py = cave->py[0];
- boolean horizontal = g_rand_boolean(cave->random);
+ boolean horizontal = gd_rand_boolean(cave->random);
boolean dont_move = FALSE;
int i = 3;
int i;
GdElement made_sound_of = O_NONE;
- for (i = 0; i < G_N_ELEMENTS (biter_try); i++)
+ for (i = 0; i < ARRAY_SIZE (biter_try); i++)
{
if (is_element_dir(cave, x, y, biter_move[dir], biter_try[i]))
{
}
}
- if (i == G_N_ELEMENTS(biter_try))
+ if (i == ARRAY_SIZE(biter_try))
/* i = number of elements in array: could not move, so just turn */
store(cave, x, y, O_BITER_1 + dirp);
else if (biter_try[i] == O_STONE)
/* is space over the bladder? */
if (is_space_dir(cave, x, y, opposite[grav_compat]))
{
- if (get(cave, x, y)==O_BLADDER_8)
+ if (get(cave, x, y) == O_BLADDER_8)
{
/* if it is a bladder 8, really move up */
move(cave, x, y, opposite[grav_compat], O_BLADDER_1);
};
GdDirection random_dir;
- random_dir = dirs[g_rand_int_range(cave->random, 0, G_N_ELEMENTS(dirs))];
+ random_dir = dirs[gd_rand_int_range(cave->random, 0, ARRAY_SIZE(dirs))];
if (is_space_dir(cave, x, y, random_dir))
{
move(cave, x, y, random_dir, O_GHOST);
}
/* if alive, check in which dir to grow (or not) */
- if (cave->amoeba_state==GD_AM_AWAKE)
+ if (cave->amoeba_state == GD_AM_AWAKE)
{
- if (g_rand_int_range(cave->random, 0, 1000000) < cave->amoeba_growth_prob)
+ if (gd_rand_int_range(cave->random, 0, 1000000) < cave->amoeba_growth_prob)
{
- switch (g_rand_int_range(cave->random, 0, 4))
+ switch (gd_rand_int_range(cave->random, 0, 4))
{
/* decided to grow, choose a random direction. */
case 0: /* let this be up. numbers indifferent. */
/* if it is alive, decide if it attempts to grow */
if (cave->amoeba_2_state == GD_AM_AWAKE)
- if (g_rand_int_range(cave->random, 0, 1000000) < cave->amoeba_2_growth_prob)
+ if (gd_rand_int_range(cave->random, 0, 1000000) < cave->amoeba_2_growth_prob)
{
- switch (g_rand_int_range(cave->random, 0, 4))
+ switch (gd_rand_int_range(cave->random, 0, 4))
{
/* decided to grow, choose a random direction. */
case 0: /* let this be up. numbers indifferent. */
case O_ACID:
/* choose randomly, if it spreads */
- if (g_rand_int_range(cave->random, 0, 1000000) <= cave->acid_spread_ratio)
+ if (gd_rand_int_range(cave->random, 0, 1000000) <= cave->acid_spread_ratio)
{
/* the current one explodes */
store(cave, x, y, cave->acid_turns_to);
if (((get(cave, x, y) == O_H_EXPANDING_WALL ||
get(cave, x, y) == O_H_EXPANDING_STEEL_WALL) &&
!cave->expanding_wall_changed) ||
- ((get(cave, x, y)==O_V_EXPANDING_WALL ||
- get(cave, x, y)==O_V_EXPANDING_STEEL_WALL) &&
+ ((get(cave, x, y) == O_V_EXPANDING_WALL ||
+ get(cave, x, y) == O_V_EXPANDING_STEEL_WALL) &&
cave->expanding_wall_changed))
{
if (is_space_dir(cave, x, y, GD_MV_LEFT))
#if 1
; // to make compilers happy ...
#else
- g_print("Step[%03d]", cave->frame); /* XXX */
+ Info("Step[%03d]", cave->frame); /* XXX */
#endif
int rrr = gd_cave_c64_random(cave);
#if 1
#else
- g_print(".Rand[%03d].Perm[%03d].Result[%d]\n", rrr, cave->slime_permeability_c64,
- (rrr & cave->slime_permeability_c64) == 0);
+ Info(".Rand[%03d].Perm[%03d].Result[%d]\n", rrr, cave->slime_permeability_c64,
+ (rrr & cave->slime_permeability_c64) == 0);
#endif
/*
- * unpredictable: g_rand_int
+ * unpredictable: gd_rand_int
* predictable: c64 predictable random generator.
* for predictable, a random number is generated,
* whether or not it is even possible that the stone will be able to pass.
*/
- if (cave->slime_predictable ? ((rrr /* XXX */ & cave->slime_permeability_c64) == 0) : g_rand_int_range(cave->random, 0, 1000000) < cave->slime_permeability)
+ if (cave->slime_predictable ? ((rrr /* XXX */ & cave->slime_permeability_c64) == 0) : gd_rand_int_range(cave->random, 0, 1000000) < cave->slime_permeability)
{
GdDirection grav = cave->gravity;
GdDirection oppos = opposite[cave->gravity];
store_dir(cave, x, y, oppos, O_BLADDER_1);
play_sound_of_element(cave, O_SLIME, x, y);
}
- else if (get_dir(cave, x, y, grav)==O_FLYING_STONE)
+ else if (get_dir(cave, x, y, grav) == O_FLYING_STONE)
{
store_dir(cave, x, y, grav, O_SPACE);
store_dir(cave, x, y, oppos, O_FLYING_STONE_F);
play_sound_of_element(cave, O_SLIME, x, y);
}
- else if (get_dir(cave, x, y, grav)==O_FLYING_DIAMOND)
+ else if (get_dir(cave, x, y, grav) == O_FLYING_DIAMOND)
{
store_dir(cave, x, y, grav, O_SPACE);
store_dir(cave, x, y, oppos, O_FLYING_DIAMOND_F);
O_WAITING_STONE, O_BITER_1
};
- store(cave, x, y, ghost_explode[g_rand_int_range(cave->random, 0, G_N_ELEMENTS(ghost_explode))]);
+ store(cave, x, y, ghost_explode[gd_rand_int_range(cave->random, 0, ARRAY_SIZE(ghost_explode))]);
}
break;
/* this loop finds the coordinates of the player. needed for scrolling and chasing stone.*/
/* but we only do this, if a living player was found. if not yet, the setup
routine coordinates are used */
- if (cave->player_state==GD_PL_LIVING)
+ if (cave->player_state == GD_PL_LIVING)
{
if (cave->active_is_first_found)
{
}
/* record coordinates of player for chasing stone */
- for (i = 0; i < G_N_ELEMENTS(cave->px) - 1; i++)
+ for (i = 0; i < ARRAY_SIZE(cave->px) - 1; i++)
{
cave->px[i] = cave->px[i + 1];
cave->py[i] = cave->py[i + 1];
}
- cave->px[G_N_ELEMENTS(cave->px) - 1] = cave->player_x;
- cave->py[G_N_ELEMENTS(cave->py) - 1] = cave->player_y;
+ cave->px[ARRAY_SIZE(cave->px) - 1] = cave->player_x;
+ cave->py[ARRAY_SIZE(cave->py) - 1] = cave->player_y;
/* SCHEDULING */