* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#include <glib.h>
-#include <glib/gi18n.h>
-
#include "main_bd.h"
"bd2ckatari"
};
-static GHashTable *name_to_element;
+static HashTable *name_to_element;
GdElement gd_char_to_element[256];
/* color of flashing the screen, gate opening to exit */
{
int i;
- for (i = 1; i<G_N_ELEMENTS(direction_filename); i++)
+ for (i = 1; i < ARRAY_SIZE(direction_filename); i++)
if (strcasecmp(str, direction_filename[i]) == 0)
return (GdDirection) i;
{
int i;
- for (i = 0; i < G_N_ELEMENTS(scheduling_filename); i++)
+ for (i = 0; i < ARRAY_SIZE(scheduling_filename); i++)
if (strcasecmp(str, scheduling_filename[i]) == 0)
return (GdScheduling) i;
"properties" describes the structure and its pointers,
"defaults" are the pieces of data which will be copied to str.
*/
-void gd_struct_set_defaults_from_array(gpointer str,
+void gd_struct_set_defaults_from_array(void *str,
const GdStructDescriptor *properties,
GdPropertyDefault *defaults)
{
for (i = 0; defaults[i].offset != -1; i++)
{
- gpointer pvalue = G_STRUCT_MEMBER_P(str, defaults[i].offset);
+ void *pvalue = STRUCT_MEMBER_P(str, defaults[i].offset);
/* these point to the same, but to avoid the awkward cast syntax */
int *ivalue = pvalue;
GdElement *evalue = pvalue;
int i;
/* fill all with unknown */
- for (i = 0; i < G_N_ELEMENTS(gd_char_to_element); i++)
+ for (i = 0; i < ARRAY_SIZE(gd_char_to_element); i++)
gd_char_to_element[i] = O_UNKNOWN;
/* then set fixed characters */
if (c)
{
- if (gd_char_to_element[c]!=O_UNKNOWN)
+ if (gd_char_to_element[c] != O_UNKNOWN)
Warn("Character %c already used for element %x", c, gd_char_to_element[c]);
gd_char_to_element[c] = i;
}
/* search the element database for the specified character, and return the element. */
-GdElement gd_get_element_from_character (guint8 character)
+GdElement gd_get_element_from_character (byte character)
{
if (gd_char_to_element[character] != O_UNKNOWN)
return gd_char_to_element[character];
/* put names to a hash table */
/* this is a helper for file read operations */
- /* maps g_strdupped strings to elemenets (integers) */
- name_to_element = g_hash_table_new_full(gd_str_case_hash, gd_str_case_equal,
- free, NULL);
+ /* maps copied strings to elements (integers) */
+ name_to_element = create_hashtable(gd_str_case_hash, gd_str_case_equal, NULL, NULL);
for (i = 0; i < O_MAX; i++)
{
char *key;
- key = g_ascii_strup(gd_elements[i].filename, -1);
+ key = getStringToUpper(gd_elements[i].filename);
- if (g_hash_table_lookup_extended(name_to_element, key, NULL, NULL))
+ if (hashtable_exists(name_to_element, key)) /* hash value may be 0 */
Warn("Name %s already used for element %x", key, i);
- g_hash_table_insert(name_to_element, key, GINT_TO_POINTER(i));
+ hashtable_insert(name_to_element, key, INT_TO_PTR(i));
/* ^^^ do not free "key", as hash table needs it during the whole time! */
- key = g_strdup_printf("SCANNED_%s", key); /* new string */
+ key = getStringCat2("SCANNED_", key); /* new string */
- g_hash_table_insert(name_to_element, key, GINT_TO_POINTER(i));
+ hashtable_insert(name_to_element, key, INT_TO_PTR(i));
/* once again, do not free "key" ^^^ */
}
/* for compatibility with tim stridmann's memorydump->bdcff converter... .... ... */
- g_hash_table_insert(name_to_element, "HEXPANDING_WALL", GINT_TO_POINTER(O_H_EXPANDING_WALL));
- g_hash_table_insert(name_to_element, "FALLING_DIAMOND", GINT_TO_POINTER(O_DIAMOND_F));
- g_hash_table_insert(name_to_element, "FALLING_BOULDER", GINT_TO_POINTER(O_STONE_F));
- g_hash_table_insert(name_to_element, "EXPLOSION1S", GINT_TO_POINTER(O_EXPLODE_1));
- g_hash_table_insert(name_to_element, "EXPLOSION2S", GINT_TO_POINTER(O_EXPLODE_2));
- g_hash_table_insert(name_to_element, "EXPLOSION3S", GINT_TO_POINTER(O_EXPLODE_3));
- g_hash_table_insert(name_to_element, "EXPLOSION4S", GINT_TO_POINTER(O_EXPLODE_4));
- g_hash_table_insert(name_to_element, "EXPLOSION5S", GINT_TO_POINTER(O_EXPLODE_5));
- g_hash_table_insert(name_to_element, "EXPLOSION1D", GINT_TO_POINTER(O_PRE_DIA_1));
- g_hash_table_insert(name_to_element, "EXPLOSION2D", GINT_TO_POINTER(O_PRE_DIA_2));
- g_hash_table_insert(name_to_element, "EXPLOSION3D", GINT_TO_POINTER(O_PRE_DIA_3));
- g_hash_table_insert(name_to_element, "EXPLOSION4D", GINT_TO_POINTER(O_PRE_DIA_4));
- g_hash_table_insert(name_to_element, "EXPLOSION5D", GINT_TO_POINTER(O_PRE_DIA_5));
- g_hash_table_insert(name_to_element, "WALL2", GINT_TO_POINTER(O_STEEL_EXPLODABLE));
+ hashtable_insert(name_to_element, "HEXPANDING_WALL", INT_TO_PTR(O_H_EXPANDING_WALL));
+ hashtable_insert(name_to_element, "FALLING_DIAMOND", INT_TO_PTR(O_DIAMOND_F));
+ hashtable_insert(name_to_element, "FALLING_BOULDER", INT_TO_PTR(O_STONE_F));
+ hashtable_insert(name_to_element, "EXPLOSION1S", INT_TO_PTR(O_EXPLODE_1));
+ hashtable_insert(name_to_element, "EXPLOSION2S", INT_TO_PTR(O_EXPLODE_2));
+ hashtable_insert(name_to_element, "EXPLOSION3S", INT_TO_PTR(O_EXPLODE_3));
+ hashtable_insert(name_to_element, "EXPLOSION4S", INT_TO_PTR(O_EXPLODE_4));
+ hashtable_insert(name_to_element, "EXPLOSION5S", INT_TO_PTR(O_EXPLODE_5));
+ hashtable_insert(name_to_element, "EXPLOSION1D", INT_TO_PTR(O_PRE_DIA_1));
+ hashtable_insert(name_to_element, "EXPLOSION2D", INT_TO_PTR(O_PRE_DIA_2));
+ hashtable_insert(name_to_element, "EXPLOSION3D", INT_TO_PTR(O_PRE_DIA_3));
+ hashtable_insert(name_to_element, "EXPLOSION4D", INT_TO_PTR(O_PRE_DIA_4));
+ hashtable_insert(name_to_element, "EXPLOSION5D", INT_TO_PTR(O_PRE_DIA_5));
+ hashtable_insert(name_to_element, "WALL2", INT_TO_PTR(O_STEEL_EXPLODABLE));
/* compatibility with old bd-faq (pre disassembly of bladder) */
- g_hash_table_insert(name_to_element, "BLADDERd9", GINT_TO_POINTER(O_BLADDER_8));
+ hashtable_insert(name_to_element, "BLADDERd9", INT_TO_PTR(O_BLADDER_8));
/* create table to show errors at the start of the application */
gd_create_char_to_element_table();
/* search the element database for the specified name, and return the element */
GdElement gd_get_element_from_string (const char *string)
{
- char *upper = g_ascii_strup(string, -1);
- gpointer value;
+ char *upper = getStringToUpper(string);
+ void *value;
boolean found;
if (!string)
return O_UNKNOWN;
}
- found = g_hash_table_lookup_extended(name_to_element, upper, NULL, &value);
+ found = hashtable_exists(name_to_element, upper); /* hash value may be 0 */
+ if (found)
+ value = hashtable_search(name_to_element, upper);
free(upper);
if (found)
- return (GdElement) (GPOINTER_TO_INT(value));
+ return (GdElement) (PTR_TO_INT(value));
+
+ Warn("Invalid string representing element: '%s'", string);
- Warn("Invalid string representing element: %s", string);
return O_UNKNOWN;
}
}
/* for quicksort. compares two highscores. */
-int gd_highscore_compare(gconstpointer a, gconstpointer b)
+int gd_highscore_compare(const void *a, const void *b)
{
const GdHighScore *ha = a;
const GdHighScore *hb = b;
qsort(highscores, GD_HIGHSCORE_NUM, sizeof(GdHighScore), gd_highscore_compare);
for (i = 0; i < GD_HIGHSCORE_NUM; i++)
- if (g_str_equal(highscores[i].name, name) && highscores[i].score == score)
+ if (strEqual(highscores[i].name, name) && highscores[i].score == score)
return i;
return -1;
}
/* for the case-insensitive hash keys */
-boolean gd_str_case_equal(gconstpointer s1, gconstpointer s2)
+int gd_str_case_equal(void *s1, void *s2)
{
return strcasecmp(s1, s2) == 0;
}
-guint gd_str_case_hash(gconstpointer v)
+unsigned int gd_str_case_hash(void *v)
{
- char *upper;
- guint hash;
+ char *upper = getStringToUpper(v);
+ unsigned int hash = get_hash_from_string(upper);
- upper = g_ascii_strup(v, -1);
- hash = g_str_hash(v);
free(upper);
+
return hash;
}
*/
GdCave *gd_cave_new(void)
{
- int i;
GdCave *cave;
cave = checked_calloc(sizeof(GdCave));
/* hash table which stores unknown tags as strings. */
- cave->tags = g_hash_table_new_full(gd_str_case_hash, gd_str_case_equal, free, free);
-
- /* for strings */
- for (i = 0; gd_cave_properties[i].identifier != NULL; i++)
- if (gd_cave_properties[i].type == GD_TYPE_LONGSTRING)
- G_STRUCT_MEMBER(GString *, cave, gd_cave_properties[i].offset) = g_string_new(NULL);
+ cave->tags = create_hashtable(gd_str_case_hash, gd_str_case_equal, free, free);
gd_cave_set_gdash_defaults(cave);
allocate a cave map-like array, and initialize to zero.
one cell is cell_size bytes long.
*/
-gpointer gd_cave_map_new_for_cave(const GdCave *cave, const int cell_size)
+void *gd_cave_map_new_for_cave(const GdCave *cave, const int cell_size)
{
- gpointer *rows; /* this is void**, pointer to array of ... */
+ void **rows; /* this is void**, pointer to array of ... */
int y;
- rows = checked_malloc((cave->h) * sizeof(gpointer));
+ rows = checked_malloc((cave->h) * sizeof(void *));
rows[0] = checked_calloc(cell_size * cave->w * cave->h);
for (y = 1; y < cave->h; y++)
if map is null, this also returns null.
*/
-gpointer gd_cave_map_dup_size(const GdCave *cave, const gpointer map, const int cell_size)
+void *gd_cave_map_dup_size(const GdCave *cave, const void *map, const int cell_size)
{
- gpointer *rows;
- gpointer *maplines = (gpointer *)map;
+ void **rows;
+ void **maplines = (void **)map;
int y;
if (!map)
return NULL;
- rows = checked_malloc((cave->h) * sizeof(gpointer));
- rows[0] = g_memdup (maplines[0], cell_size * cave->w * cave->h);
+ rows = checked_malloc((cave->h) * sizeof(void *));
+ rows[0] = get_memcpy (maplines[0], cell_size * cave->w * cave->h);
for (y = 1; y < cave->h; y++)
rows[y] = (char *)rows[0] + cell_size * cave->w * y;
return rows;
}
-void gd_cave_map_free(gpointer map)
+void gd_cave_map_free(void *map)
{
- gpointer *maplines = (gpointer *) map;
+ void **maplines = (void **) map;
if (!map)
return;
return;
if (cave->tags)
- g_hash_table_destroy(cave->tags);
+ hashtable_destroy(cave->tags);
- if (cave->random) /* random generator is a GRand * */
- g_rand_free(cave->random);
+ if (cave->random) /* random generator is a GdRand * */
+ gd_rand_free(cave->random);
- /* free GStrings */
+ /* free strings */
for (i = 0; gd_cave_properties[i].identifier != NULL; i++)
if (gd_cave_properties[i].type == GD_TYPE_LONGSTRING)
- g_string_free(G_STRUCT_MEMBER(GString *, cave, gd_cave_properties[i].offset), TRUE);
+ checked_free(STRUCT_MEMBER(char *, cave, gd_cave_properties[i].offset));
/* map */
gd_cave_map_free(cave->map);
gd_cave_map_free(cave->hammered_reappear);
/* free objects */
- g_list_foreach(cave->objects, (GFunc) free, NULL);
- g_list_free (cave->objects);
+ list_foreach(cave->objects, (list_fn) free, NULL);
+ list_free(cave->objects);
/* free replays */
- g_list_foreach(cave->replays, (GFunc) gd_replay_free, NULL);
- g_list_free(cave->replays);
+ list_foreach(cave->replays, (list_fn) gd_replay_free, NULL);
+ list_free(cave->replays);
/* freeing main pointer */
free (cave);
}
-static void hash_copy_foreach(const char *key, const char *value, GHashTable *dest)
+static void hash_copy_foreach(const char *key, const char *value, HashTable *dest)
{
- g_hash_table_insert(dest, g_strdup(key), g_strdup(value));
+ hashtable_insert(dest, getStringCopy(key), getStringCopy(value));
}
/* copy cave from src to destination, with duplicating dynamically allocated data */
int i;
/* copy entire data */
- g_memmove(dest, src, sizeof(GdCave));
+ memmove(dest, src, sizeof(GdCave));
/* but duplicate dynamic data */
- dest->tags = g_hash_table_new_full(gd_str_case_hash, gd_str_case_equal,
- free, free);
+ dest->tags = create_hashtable(gd_str_case_hash, gd_str_case_equal, free, free);
+
if (src->tags)
- g_hash_table_foreach(src->tags, (GHFunc) hash_copy_foreach, dest->tags);
+ hashtable_foreach(src->tags, (hashtable_fn)hash_copy_foreach, dest->tags);
dest->map = gd_cave_map_dup(src, map);
dest->hammered_reappear = gd_cave_map_dup(src, hammered_reappear);
/* for longstrings */
for (i = 0; gd_cave_properties[i].identifier != NULL; i++)
if (gd_cave_properties[i].type == GD_TYPE_LONGSTRING)
- G_STRUCT_MEMBER(GString *, dest, gd_cave_properties[i].offset) =
- g_string_new(G_STRUCT_MEMBER(GString *, src, gd_cave_properties[i].offset)->str);
+ STRUCT_MEMBER(char *, dest, gd_cave_properties[i].offset) =
+ getStringCopy(STRUCT_MEMBER(char *, src, gd_cave_properties[i].offset));
/* no reason to copy this */
dest->objects_order = NULL;
/* copy objects list */
if (src->objects)
{
- GList *iter;
+ List *iter;
dest->objects = NULL; /* new empty list */
for (iter = src->objects; iter != NULL; iter = iter->next) /* do a deep copy */
- dest->objects = g_list_append(dest->objects, g_memdup (iter->data, sizeof (GdObject)));
+ dest->objects = list_append(dest->objects, get_memcpy (iter->data, sizeof (GdObject)));
}
/* copy replays */
if (src->replays)
{
- GList *iter;
+ List *iter;
dest->replays = NULL;
for (iter = src->replays; iter != NULL; iter = iter->next) /* do a deep copy */
- dest->replays = g_list_append(dest->replays, gd_replay_new_from_replay(iter->data));
+ dest->replays = list_append(dest->replays, gd_replay_new_from_replay(iter->data));
}
/* copy random number generator */
if (src->random)
- dest->random = g_rand_copy(src->random);
+ dest->random = gd_rand_copy(src->random);
}
/* create new cave, which is a copy of the cave given. */
gd_c64_random_set_seed(&cave->c64_rand, seed1, seed2);
}
-/*
- select random colors for a given cave.
- this function will select colors so that they should look somewhat nice; for example
- brick walls won't be the darkest color, for example.
-*/
-static inline void swap(int *i1, int *i2)
-{
- int t = *i1;
- *i1 = *i2;
- *i2 = t;
-}
-
/*
shrink cave
if last line or last row is just steel wall (or (invisible) outbox).
{
/* blinking and tapping is started at the beginning of animation sequences. */
/* 1/4 chance of blinking, every sequence. */
- player_blinking = g_random_int_range(0, 4) == 0;
+ player_blinking = gd_random_int_range(0, 4) == 0;
/* 1/16 chance of starting or stopping tapping. */
- if (g_random_int_range(0, 16) == 0)
+ if (gd_random_int_range(0, 16) == 0)
player_tapping = !player_tapping;
}
}
/* player with bomb does not blink or tap - no graphics drawn for that.
running is drawn using w/o bomb cells */
- if (cave->last_direction!=GD_MV_STILL)
+ if (cave->last_direction != GD_MV_STILL)
{
elemmapping[O_PLAYER_BOMB] = map;
elemdrawing[O_PLAYER_BOMB] = draw;
GdReplay *rep;
rep = checked_calloc(sizeof(GdReplay));
-
- /* create dynamic objects */
- rep->comment = g_string_new(NULL);
- rep->movements = g_byte_array_new();
+ rep->movements = checked_calloc(sizeof(GdReplayMovements));
return rep;
}
{
GdReplay *rep;
- rep = g_memdup(orig, sizeof(GdReplay));
+ rep = get_memcpy(orig, sizeof(GdReplay));
/* replicate dynamic data */
- rep->comment = g_string_new(orig->comment->str);
- rep->movements = g_byte_array_new();
- g_byte_array_append(rep->movements, orig->movements->data, orig->movements->len);
+ rep->comment = getStringCopy(orig->comment);
+ rep->movements = get_memcpy(orig->movements, sizeof(GdReplayMovements));
return rep;
}
void gd_replay_free(GdReplay *replay)
{
- g_byte_array_free(replay->movements, TRUE);
- g_string_free(replay->comment, TRUE);
+ checked_free(replay->movements);
+ checked_free(replay->comment);
free(replay);
}
void gd_replay_store_movement(GdReplay *replay, GdDirection player_move,
boolean player_fire, boolean suicide)
{
- guint8 data[1];
+ byte data[1];
data[0] = ((player_move) |
(player_fire ? GD_REPLAY_FIRE_MASK : 0) |
(suicide ? GD_REPLAY_SUICIDE_MASK : 0));
- g_byte_array_append(replay->movements, data, 1);
-}
-
-/* get next available movement from a replay; store variables to player_move,
- player_fire, suicide */
-/* return true if successful */
-boolean gd_replay_get_next_movement(GdReplay *replay, GdDirection *player_move,
- boolean *player_fire, boolean *suicide)
-{
- guint8 data;
-
- /* if no more available movements */
- if (replay->current_playing_pos >= replay->movements->len)
- return FALSE;
-
- data = replay->movements->data[replay->current_playing_pos++];
- *suicide = (data & GD_REPLAY_SUICIDE_MASK) != 0;
- *player_fire = (data & GD_REPLAY_FIRE_MASK) != 0;
- *player_move = (data & GD_REPLAY_MOVE_MASK);
+ if (replay->movements->len < MAX_REPLAY_LEN)
+ {
+ replay->movements->data[replay->movements->len++] = data[0];
- return TRUE;
+ if (replay->movements->len == MAX_REPLAY_LEN)
+ Warn("BD replay truncated: size exceeds maximum replay size %d", MAX_REPLAY_LEN);
+ }
}
/* calculate adler checksum for a rendered cave; this can be used for more caves. */
-void gd_cave_adler_checksum_more(GdCave *cave, guint32 *a, guint32 *b)
+void gd_cave_adler_checksum_more(GdCave *cave, unsigned int *a, unsigned int *b)
{
int x, y;
}
/* calculate adler checksum for a single rendered cave. */
-guint32
-gd_cave_adler_checksum(GdCave *cave)
+unsigned int gd_cave_adler_checksum(GdCave *cave)
{
- guint32 a = 1;
- guint32 b = 0;
+ unsigned int a = 1;
+ unsigned int b = 0;
gd_cave_adler_checksum_more(cave, &a, &b);
return (b << 16) + a;