X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Fgame_bd%2Fbd_cave.c;h=7a5766d72616be39a263eb053eaa02cbefd59c0e;hb=bd560c53129c84976b87827f1978ddf8de4ed57a;hp=b0f1573ef52d96992e70bb6aa6cccdc1680ec9cc;hpb=e25acb01746ef65a1c5d4919b0e7c2c5d48b6807;p=rocksndiamonds.git diff --git a/src/game_bd/bd_cave.c b/src/game_bd/bd_cave.c index b0f1573e..7a5766d7 100644 --- a/src/game_bd/bd_cave.c +++ b/src/game_bd/bd_cave.c @@ -14,9 +14,6 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include -#include - #include "main_bd.h" @@ -81,7 +78,7 @@ static const char* scheduling_filename[] = "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 */ @@ -105,7 +102,7 @@ GdDirection gd_direction_from_string(const char *str) { int i; - for (i = 1; ibdcff 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(); @@ -323,8 +319,8 @@ void gd_cave_init(void) /* 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) @@ -333,12 +329,15 @@ GdElement gd_get_element_from_string (const char *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; } @@ -366,7 +365,7 @@ void gd_cave_set_gdash_defaults(GdCave* cave) } /* 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; @@ -414,26 +413,25 @@ int gd_add_highscore(GdHighScore *highscores, const char *name, int score) 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; } @@ -448,7 +446,7 @@ GdCave *gd_cave_new(void) 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); + cave->tags = create_hashtable(gd_str_case_hash, gd_str_case_equal, free, free); gd_cave_set_gdash_defaults(cave); @@ -475,12 +473,12 @@ GdCave *gd_cave_new(void) 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++) @@ -495,17 +493,17 @@ gpointer gd_cave_map_new_for_cave(const GdCave *cave, const int cell_size) 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; @@ -513,9 +511,9 @@ gpointer gd_cave_map_dup_size(const GdCave *cave, const gpointer map, const int 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; @@ -535,15 +533,15 @@ void gd_cave_free(GdCave *cave) 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 strings */ for (i = 0; gd_cave_properties[i].identifier != NULL; i++) if (gd_cave_properties[i].type == GD_TYPE_LONGSTRING) - checked_free(G_STRUCT_MEMBER(char *, cave, gd_cave_properties[i].offset)); + checked_free(STRUCT_MEMBER(char *, cave, gd_cave_properties[i].offset)); /* map */ gd_cave_map_free(cave->map); @@ -555,20 +553,20 @@ void gd_cave_free(GdCave *cave) 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 */ @@ -577,13 +575,13 @@ void gd_cave_copy(GdCave *dest, const GdCave *src) 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); @@ -591,8 +589,8 @@ void gd_cave_copy(GdCave *dest, const GdCave *src) /* for longstrings */ for (i = 0; gd_cave_properties[i].identifier != NULL; i++) if (gd_cave_properties[i].type == GD_TYPE_LONGSTRING) - G_STRUCT_MEMBER(char *, dest, gd_cave_properties[i].offset) = - getStringCopy(G_STRUCT_MEMBER(char *, src, gd_cave_properties[i].offset)); + 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; @@ -600,26 +598,26 @@ void gd_cave_copy(GdCave *dest, const GdCave *src) /* 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. */ @@ -776,18 +774,6 @@ void gd_cave_c64_random_set_seed(GdCave *cave, int seed1, int seed2) 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). @@ -1157,10 +1143,10 @@ void gd_drawcave_game(const GdCave *cave, int **element_buffer, int **gfx_buffer { /* 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; } } @@ -1293,7 +1279,7 @@ void gd_drawcave_game(const GdCave *cave, int **element_buffer, int **gfx_buffer /* 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; @@ -1389,8 +1375,7 @@ GdReplay *gd_replay_new(void) GdReplay *rep; rep = checked_calloc(sizeof(GdReplay)); - - rep->movements = g_byte_array_new(); + rep->movements = checked_calloc(sizeof(GdReplayMovements)); return rep; } @@ -1399,19 +1384,18 @@ GdReplay *gd_replay_new_from_replay(GdReplay *orig) { GdReplay *rep; - rep = g_memdup(orig, sizeof(GdReplay)); + rep = get_memcpy(orig, sizeof(GdReplay)); /* replicate dynamic data */ rep->comment = getStringCopy(orig->comment); - rep->movements = g_byte_array_new(); - g_byte_array_append(rep->movements, orig->movements->data, orig->movements->len); + rep->movements = get_memcpy(orig->movements, sizeof(GdReplayMovements)); return rep; } void gd_replay_free(GdReplay *replay) { - g_byte_array_free(replay->movements, TRUE); + checked_free(replay->movements); checked_free(replay->comment); free(replay); } @@ -1420,37 +1404,23 @@ void gd_replay_free(GdReplay *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; @@ -1466,11 +1436,10 @@ void gd_cave_adler_checksum_more(GdCave *cave, guint32 *a, guint32 *b) } /* 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;