X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Fgame_bd%2Fbd_cave.c;h=ea56d6da706c612ed61196792269e7db2e70f538;hb=4eff89df72ffc45c4ad59fcd01860eb8f4179b9c;hp=2ffb071e365097f3b117888785b61a8c606bd91d;hpb=7fb08abe58b2c84e36a5ed247d2103e08ae98aa4;p=rocksndiamonds.git diff --git a/src/game_bd/bd_cave.c b/src/game_bd/bd_cave.c index 2ffb071e..ea56d6da 100644 --- a/src/game_bd/bd_cave.c +++ b/src/game_bd/bd_cave.c @@ -14,14 +14,11 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include -#include - #include "main_bd.h" -/* arrays for movements */ -/* also no1 and bd2 cave data import helpers; line direction coordinates */ +// arrays for movements +// also no1 and bd2 cave data import helpers; line direction coordinates const int gd_dx[] = { 0, 0, 1, 1, 1, 0, -1, -1, -1, 0, 2, 2, 2, 0, -2, -2, -2 @@ -31,8 +28,8 @@ const int gd_dy[] = 0, -1, -1, 0, 1, 1, 1, 0, -1, -2, -2, 0, 2, 2, 2, 0, -2 }; -/* TRANSLATORS: - None here means "no direction to move"; when there is no gravity while stirring the pot. */ +// TRANSLATORS: +// None here means "no direction to move"; when there is no gravity while stirring the pot. static const char* direction_name[] = { N_("None"), @@ -81,16 +78,16 @@ 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 */ +// color of flashing the screen, gate opening to exit const GdColor gd_flash_color = 0xFFFFC0; -/* selected object in editor */ +// selected object in editor const GdColor gd_select_color = 0x8080FF; -/* direction to string and vice versa */ +// direction to string and vice versa const char *gd_direction_get_visible_name(GdDirection dir) { return direction_name[dir]; @@ -105,7 +102,7 @@ GdDirection gd_direction_from_string(const char *str) { int i; - for (i = 1; i properties[n].max) @@ -196,7 +193,7 @@ void gd_struct_set_defaults_from_array(gpointer str, break; case GD_TYPE_PROBABILITY: - /* floats are stored as integer, /million; but are integers */ + // floats are stored as integer, /million; but are integers if (defaults[i].defval < 0 || defaults[i].defval > 1000000) Warn("integer property %s out of range", properties[n].identifier); @@ -228,26 +225,27 @@ void gd_struct_set_defaults_from_array(gpointer str, } } -/* creates the character->element conversion table; using - the fixed-in-the-bdcff characters. later, this table - may be filled with more elements. +/* + creates the character->element conversion table; using + the fixed-in-the-bdcff characters. later, this table + may be filled with more elements. */ void gd_create_char_to_element_table(void) { int i; - /* fill all with unknown */ - for (i = 0; i < G_N_ELEMENTS(gd_char_to_element); i++) + // fill all with unknown + for (i = 0; i < ARRAY_SIZE(gd_char_to_element); i++) gd_char_to_element[i] = O_UNKNOWN; - /* then set fixed characters */ + // then set fixed characters for (i = 0; i < O_MAX; i++) { int c = gd_elements[i].character; 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; @@ -255,8 +253,8 @@ void gd_create_char_to_element_table(void) } } -/* search the element database for the specified character, and return the element. */ -GdElement gd_get_element_from_character (guint8 character) +// search the element database for the specified character, and return the element. +GdElement gd_get_element_from_character (byte character) { if (gd_char_to_element[character] != O_UNKNOWN) return gd_char_to_element[character]; @@ -273,58 +271,57 @@ void gd_cave_init(void) { int i; - /* 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); + // put names to a hash table + // this is a helper for file read operations + // 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)); - /* ^^^ do not free "key", as hash table needs it during the whole time! */ + 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)); - /* once again, do not free "key" ^^^ */ + 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)); - - /* compatibility with old bd-faq (pre disassembly of bladder) */ - g_hash_table_insert(name_to_element, "BLADDERd9", GINT_TO_POINTER(O_BLADDER_8)); - - /* create table to show errors at the start of the application */ + // for compatibility with tim stridmann's memorydump->bdcff converter... .... ... + 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) + 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 */ +// 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 +330,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; } @@ -357,7 +357,7 @@ void gd_cave_set_gdash_defaults(GdCave* cave) gd_cave_set_defaults_from_array(cave, gd_cave_defaults_gdash); - /* these did not fit into the descriptor array */ + // these did not fit into the descriptor array for (i = 0; i < 5; i++) { cave->level_rand[i] = i; @@ -365,8 +365,8 @@ void gd_cave_set_gdash_defaults(GdCave* cave) } } -/* for quicksort. compares two highscores. */ -int gd_highscore_compare(gconstpointer a, gconstpointer b) +// for quicksort. compares two highscores. +int gd_highscore_compare(const void *a, const void *b) { const GdHighScore *ha = a; const GdHighScore *hb = b; @@ -389,10 +389,10 @@ boolean gd_has_highscore(GdHighScore *hs) return hs[0].score > 0; } -/* return true if score achieved is a highscore */ +// return true if score achieved is a highscore boolean gd_is_highscore(GdHighScore *scores, int score) { - /* if score is above zero AND bigger than the last one */ + // if score is above zero AND bigger than the last one if (score > 0 && score > scores[GD_HIGHSCORE_NUM-1].score) return TRUE; @@ -406,34 +406,33 @@ int gd_add_highscore(GdHighScore *highscores, const char *name, int score) if (!gd_is_highscore(highscores, score)) return -1; - /* overwrite the last one */ + // overwrite the last one gd_strcpy(highscores[GD_HIGHSCORE_NUM-1].name, name); highscores[GD_HIGHSCORE_NUM-1].score = score; - /* and sort */ + // and sort 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) +// for the case-insensitive hash keys +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; } @@ -443,54 +442,49 @@ guint gd_str_case_hash(gconstpointer v) */ 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); + // hash table which stores unknown tags as strings. + cave->tags = create_hashtable(gd_str_case_hash, gd_str_case_equal, free, free); gd_cave_set_gdash_defaults(cave); return cave; } -/* cave maps. - cave maps are continuous areas in memory. the allocated memory - is width * height * bytes_per_cell long. - the cave map[0] stores the pointer given by g_malloc(). - the map itself is also an allocated array of pointers to the - beginning of rows. - therefore: - rows = new (pointers to rows); - rows[0] = new map - rows[1..h-1] = rows[0] + width * bytes - - freeing this: - free(rows[0]) - free(rows) +/* + cave maps. + cave maps are continuous areas in memory. the allocated memory + is width * height * bytes_per_cell long. + the cave map[0] stores the pointer given by g_malloc(). + the map itself is also an allocated array of pointers to the + beginning of rows. + therefore: + rows = new (pointers to rows); + rows[0] = new map + rows[1..h-1] = rows[0] + width * bytes + + freeing this: + free(rows[0]) + free(rows) */ /* 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++) - /* base pointer + num_of_bytes_per_element * width * number_of_row; as sizeof(char) = 1 */ + // base pointer + num_of_bytes_per_element * width * number_of_row; as sizeof(char) = 1 rows[y] = (char *)rows[0] + cell_size * cave->w * y; return rows; @@ -501,17 +495,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; @@ -519,9 +513,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; @@ -541,94 +535,94 @@ 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 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); + if (gd_cave_properties[i].type == GD_TYPE_LONGSTRING) + checked_free(STRUCT_MEMBER(char *, cave, gd_cave_properties[i].offset)); - /* map */ + // map gd_cave_map_free(cave->map); - /* rendered data */ + // rendered data gd_cave_map_free(cave->objects_order); - /* hammered walls to reappear data */ + // hammered walls to reappear data gd_cave_map_free(cave->hammered_reappear); - /* free objects */ - g_list_foreach(cave->objects, (GFunc) free, NULL); - g_list_free (cave->objects); + // free 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); + // free replays + list_foreach(cave->replays, (list_fn) gd_replay_free, NULL); + list_free(cave->replays); - /* freeing main pointer */ + // 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 */ +// copy cave from src to destination, with duplicating dynamically allocated data void gd_cave_copy(GdCave *dest, const GdCave *src) { int i; - /* copy entire data */ - g_memmove(dest, src, sizeof(GdCave)); + // copy entire data + memmove(dest, src, sizeof(GdCave)); + + // but duplicate dynamic data + dest->tags = create_hashtable(gd_str_case_hash, gd_str_case_equal, free, free); - /* but duplicate dynamic data */ - dest->tags = g_hash_table_new_full(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 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); + if (gd_cave_properties[i].type == GD_TYPE_LONGSTRING) + STRUCT_MEMBER(char *, dest, gd_cave_properties[i].offset) = + getStringCopy(STRUCT_MEMBER(char *, src, gd_cave_properties[i].offset)); - /* no reason to copy this */ + // no reason to copy this dest->objects_order = NULL; - /* copy objects list */ + // 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 = NULL; // new empty list + for (iter = src->objects; iter != NULL; iter = iter->next) // do a deep copy + dest->objects = list_append(dest->objects, get_memcpy (iter->data, sizeof (GdObject))); } - /* copy replays */ + // 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)); + for (iter = src->replays; iter != NULL; iter = iter->next) // do a deep copy + dest->replays = list_append(dest->replays, gd_replay_new_from_replay(iter->data)); } - /* copy random number generator */ + // 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. */ +// create new cave, which is a copy of the cave given. GdCave *gd_cave_new_from_cave(const GdCave *orig) { GdCave *cave; @@ -644,24 +638,25 @@ GdCave *gd_cave_new_from_cave(const GdCave *orig) Performs range checking. If wraparound objects are selected, wraps around x coordinates, with or without lineshift. (The y coordinate is not wrapped, as it did not work like that on the c64) - order is a pointer to the GdObject describing this object. Thus the editor can identify which cell was created by which object. + order is a pointer to the GdObject describing this object. Thus the editor can identify + which cell was created by which object. */ void gd_cave_store_rc(GdCave *cave, int x, int y, const GdElement element, const void *order) { - /* if we do not need to draw, exit now */ + // if we do not need to draw, exit now if (element == O_NONE) return; - /* check bounds */ + // check bounds if (cave->wraparound_objects) { if (cave->lineshift) { - /* fit x coordinate within range, with correcting y at the same time */ + // fit x coordinate within range, with correcting y at the same time while (x < 0) { - x += cave->w; /* out of bounds on the left... */ - y--; /* previous row */ + x += cave->w; // out of bounds on the left... + y--; // previous row } while (x >= cave->w) @@ -670,20 +665,20 @@ void gd_cave_store_rc(GdCave *cave, int x, int y, const GdElement element, const y++; } - /* lineshifting does not fix the y coordinates. - if out of bounds, element will not be displayed. */ - /* if such an object appeared in the c64 game, well, it was a buffer overrun. */ + // lineshifting does not fix the y coordinates. + // if out of bounds, element will not be displayed. + // if such an object appeared in the c64 game, well, it was a buffer overrun. } else { - /* non lineshifting: changing x does not change y coordinate. */ + // non lineshifting: changing x does not change y coordinate. while (x < 0) x += cave->w; while (x >= cave->w) x -= cave->w; - /* after that, fix y coordinate */ + // after that, fix y coordinate while (y < 0) y += cave->h; @@ -692,8 +687,8 @@ void gd_cave_store_rc(GdCave *cave, int x, int y, const GdElement element, const } } - /* if the above wraparound code fixed the coordinates, this will always be true. */ - /* but see the above comment for lineshifting y coordinate */ + // if the above wraparound code fixed the coordinates, this will always be true. + // but see the above comment for lineshifting y coordinate if (x >= 0 && x < cave->w && y >= 0 && y < cave->h) { cave->map[y][x] = element; @@ -703,16 +698,16 @@ void gd_cave_store_rc(GdCave *cave, int x, int y, const GdElement element, const GdElement gd_cave_get_rc(const GdCave *cave, int x, int y) { - /* always fix coordinates as if cave was wraparound. */ + // always fix coordinates as if cave was wraparound. - /* fix x coordinate */ + // fix x coordinate if (cave->lineshift) { - /* fit x coordinate within range, with correcting y at the same time */ + // fit x coordinate within range, with correcting y at the same time while (x < 0) { - x += cave->w; /* out of bounds on the left... */ - y--; /* previous row */ + x += cave->w; // out of bounds on the left... + y--; // previous row } while (x >= cave->w) { @@ -722,7 +717,7 @@ GdElement gd_cave_get_rc(const GdCave *cave, int x, int y) } else { - /* non lineshifting: changing x does not change y coordinate. */ + // non lineshifting: changing x does not change y coordinate. while (x < 0) x += cave->w; @@ -730,7 +725,7 @@ GdElement gd_cave_get_rc(const GdCave *cave, int x, int y) x -= cave->w; } - /* after that, fix y coordinate */ + // after that, fix y coordinate while (y < 0) y += cave->h; @@ -782,16 +777,36 @@ 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) +void gd_cave_set_random_c64_colors(GdCave *cave) { - int t = *i1; - *i1 = *i2; - *i2 = t; + const int bright_colors[] = { 1, 3, 7 }; + const int dark_colors[] = { 2, 6, 8, 9, 11 }; + + // always black + cave->colorb = gd_c64_color(0); + cave->color0 = gd_c64_color(0); + + // choose some bright color for brick + cave->color3 = gd_c64_color(bright_colors[gd_random_int_range(0, ARRAY_SIZE(bright_colors))]); + + // choose a dark color for dirt, but should not be == color of brick + do + { + cave->color1 = gd_c64_color(dark_colors[gd_random_int_range(0, ARRAY_SIZE(dark_colors))]); + } + while (cave->color1 == cave->color3); // so it is not the same as color 1 + + // choose any but black for steel wall, but should not be == brick or dirt + do + { + // between 1 and 15 - do not use black for this. + cave->color2 = gd_c64_color(gd_random_int_range(1, 16)); + } + while (cave->color1 == cave->color2 || cave->color2 == cave->color3); // so colors are not the same + + // copy amoeba and slime color + cave->color4 = cave->color3; + cave->color5 = cave->color1; } /* @@ -812,15 +827,15 @@ void gd_cave_auto_shrink(GdCave *cave) } empty; - /* set to maximum size, then try to shrink */ + // set to maximum size, then try to shrink cave->x1 = 0; cave->y1 = 0; cave->x2 = cave->w - 1; cave->y2 = cave->h - 1; - /* search for empty, steel-wall-only last rows. */ - /* clear all lines, which are only steel wall. - * and clear only one line, which is steel wall, but also has a player or an outbox. */ + // search for empty, steel-wall-only last rows. + // clear all lines, which are only steel wall. + // and clear only one line, which is steel wall, but also has a player or an outbox. empty = STEEL_ONLY; do @@ -831,7 +846,7 @@ void gd_cave_auto_shrink(GdCave *cave) { switch (gd_cave_get_rc (cave, x, y)) { - /* if steels only, this is to be deleted. */ + // if steels only, this is to be deleted. case O_STEEL: break; @@ -841,26 +856,26 @@ void gd_cave_auto_shrink(GdCave *cave) if (empty == STEEL_OR_OTHER) empty = NO_SHRINK; - /* if this, delete only this one, and exit. */ + // if this, delete only this one, and exit. if (empty == STEEL_ONLY) empty = STEEL_OR_OTHER; break; default: - /* anything else, that should be left in the cave. */ + // anything else, that should be left in the cave. empty = NO_SHRINK; break; } } } - /* shrink if full steel or steel and player/outbox. */ + // shrink if full steel or steel and player/outbox. if (empty != NO_SHRINK) - cave->y2--; /* one row shorter */ + cave->y2--; // one row shorter } - while (empty == STEEL_ONLY); /* if found just steels, repeat. */ + while (empty == STEEL_ONLY); // if found just steels, repeat. - /* search for empty, steel-wall-only first rows. */ + // search for empty, steel-wall-only first rows. empty = STEEL_ONLY; do @@ -877,11 +892,11 @@ void gd_cave_auto_shrink(GdCave *cave) case O_PRE_OUTBOX: case O_PRE_INVIS_OUTBOX: case O_INBOX: - /* shrink only lines, which have only ONE player or outbox. - this is for bd4 intermission 2, for example. */ - if (empty==STEEL_OR_OTHER) + // shrink only lines, which have only ONE player or outbox. + // this is for bd4 intermission 2, for example. + if (empty == STEEL_OR_OTHER) empty = NO_SHRINK; - if (empty==STEEL_ONLY) + if (empty == STEEL_ONLY) empty = STEEL_OR_OTHER; break; @@ -895,9 +910,9 @@ void gd_cave_auto_shrink(GdCave *cave) if (empty != NO_SHRINK) cave->y1++; } - while (empty == STEEL_ONLY); /* if found one, repeat. */ + while (empty == STEEL_ONLY); // if found one, repeat. - /* empty last columns. */ + // empty last columns. empty = STEEL_ONLY; do @@ -914,9 +929,9 @@ void gd_cave_auto_shrink(GdCave *cave) case O_PRE_OUTBOX: case O_PRE_INVIS_OUTBOX: case O_INBOX: - if (empty==STEEL_OR_OTHER) + if (empty == STEEL_OR_OTHER) empty = NO_SHRINK; - if (empty==STEEL_ONLY) + if (empty == STEEL_ONLY) empty = STEEL_OR_OTHER; break; @@ -927,14 +942,14 @@ void gd_cave_auto_shrink(GdCave *cave) } } - /* just remember that one column shorter. - free will know the size of memchunk, no need to realloc! */ + // just remember that one column shorter. + // free will know the size of memchunk, no need to realloc! if (empty != NO_SHRINK) cave->x2--; } - while (empty == STEEL_ONLY); /* if found one, repeat. */ + while (empty == STEEL_ONLY); // if found one, repeat. - /* empty first columns. */ + // empty first columns. empty = STEEL_ONLY; do @@ -951,9 +966,9 @@ void gd_cave_auto_shrink(GdCave *cave) case O_PRE_OUTBOX: case O_PRE_INVIS_OUTBOX: case O_INBOX: - if (empty==STEEL_OR_OTHER) + if (empty == STEEL_OR_OTHER) empty = NO_SHRINK; - if (empty==STEEL_ONLY) + if (empty == STEEL_ONLY) empty = STEEL_OR_OTHER; break; @@ -967,16 +982,17 @@ void gd_cave_auto_shrink(GdCave *cave) if (empty != NO_SHRINK) cave->x1++; } - while (empty == STEEL_ONLY); /* if found one, repeat. */ + while (empty == STEEL_ONLY); // if found one, repeat. } -/* check if cave visible part coordinates - are outside cave sizes, or not in the right order. - correct them if needed. +/* + check if cave visible part coordinates + are outside cave sizes, or not in the right order. + correct them if needed. */ void gd_cave_correct_visible_size(GdCave *cave) { - /* change visible coordinates if they do not point to upperleft and lowerright */ + // change visible coordinates if they do not point to upperleft and lowerright if (cave->x2 < cave->x1) { int t = cave->x2; @@ -1053,18 +1069,18 @@ static void cave_set_ckdelay_extra_for_animation(GdCave *cave) cave->ckdelay_extra_for_animation += 2600; } -/* do some init - setup some cave variables before the game. */ +// do some init - setup some cave variables before the game. void gd_cave_setup_for_game(GdCave *cave) { int x, y; cave_set_ckdelay_extra_for_animation(cave); - /* find the player which will be the one to scroll to at the beginning of the game - (before the player's birth) */ + // find the player which will be the one to scroll to at the beginning of the game + // (before the player's birth) if (cave->active_is_first_found) { - /* uppermost player is active */ + // uppermost player is active for (y = cave->h - 1; y >= 0; y--) { for (x = cave->w - 1; x >= 0; x--) @@ -1079,7 +1095,7 @@ void gd_cave_setup_for_game(GdCave *cave) } else { - /* lowermost player is active */ + // lowermost player is active for (y = 0; y < cave->h; y++) { for (x = 0; x < cave->w; x++) @@ -1093,7 +1109,7 @@ void gd_cave_setup_for_game(GdCave *cave) } } - /* select number of milliseconds (for pal and ntsc) */ + // select number of milliseconds (for pal and ntsc) cave->timing_factor = cave->pal_timing ? 1200 : 1000; cave->time *= cave->timing_factor; @@ -1106,16 +1122,16 @@ void gd_cave_setup_for_game(GdCave *cave) cave->hammered_reappear = gd_cave_map_new(cave, int); } -/* cave diamonds needed can be set to n<=0. */ -/* if so, count the diamonds at the time of the hatching, and decrement that value from */ -/* the number of diamonds found. */ -/* of course, this function is to be called from the cave engine, at the exact time of hatching. */ +// cave diamonds needed can be set to n<=0. +// if so, count the diamonds at the time of the hatching, and decrement that value from +// the number of diamonds found. +// of course, this function is to be called from the cave engine, at the exact time of hatching. void gd_cave_count_diamonds(GdCave *cave) { int x, y; - /* if automatically counting diamonds. if this was negative, - * the sum will be this less than the number of all the diamonds in the cave */ + // if automatically counting diamonds. if this was negative, + // the sum will be this less than the number of all the diamonds in the cave if (cave->diamonds_needed <= 0) { for (y = 0; y < cave->h; y++) @@ -1123,23 +1139,24 @@ void gd_cave_count_diamonds(GdCave *cave) if (cave->map[y][x] == O_DIAMOND) cave->diamonds_needed++; - /* if still below zero, let this be 0, so gate will be open immediately */ + // if still below zero, let this be 0, so gate will be open immediately if (cave->diamonds_needed < 0) cave->diamonds_needed = 0; } } -/* takes a cave and a gfx buffer, and fills the buffer with cell indexes. - the indexes might change if bonus life flash is active (small lines in - "SPACE" cells), - for the paused state (which is used in gdash but not in sdash) - yellowish - color. - also one can select the animation frame (0..7) to draw the cave on. so the - caller manages - increasing that. - - if a cell is changed, it is flagged with GD_REDRAW; the flag can be cleared - by the caller. +/* + takes a cave and a gfx buffer, and fills the buffer with cell indexes. + the indexes might change if bonus life flash is active (small lines in + "SPACE" cells), + for the paused state (which is used in gdash but not in sdash) - yellowish + color. + also one can select the animation frame (0..7) to draw the cave on. so the + caller manages + increasing that. + + if a cell is changed, it is flagged with GD_REDRAW; the flag can be cleared + by the caller. */ void gd_drawcave_game(const GdCave *cave, int **element_buffer, int **gfx_buffer, boolean bonus_life_flash, int animcycle, boolean hate_invisible_outbox) @@ -1152,21 +1169,21 @@ void gd_drawcave_game(const GdCave *cave, int **element_buffer, int **gfx_buffer if (cave->last_direction) { - /* he is moving, so stop blinking and tapping. */ + // he is moving, so stop blinking and tapping. player_blinking = 0; player_tapping = 0; } else { - /* he is idle, so animations can be done. */ + // he is idle, so animations can be done. if (animcycle == 0) { - /* 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; + // blinking and tapping is started at the beginning of animation sequences. + // 1/4 chance of blinking, every sequence. + 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) + // 1/16 chance of starting or stopping tapping. + if (gd_random_int_range(0, 16) == 0) player_tapping = !player_tapping; } } @@ -1199,11 +1216,11 @@ void gd_drawcave_game(const GdCave *cave, int **element_buffer, int **gfx_buffer elemdrawing[O_REPLICATOR_SWITCH] = gd_elements[cave->replicators_active ? O_REPLICATOR_SWITCH_ON : O_REPLICATOR_SWITCH_OFF].image_game; if (cave->replicators_active) - /* if the replicators are active, animate them. */ + // if the replicators are active, animate them. elemmapping[O_REPLICATOR] = O_REPLICATOR_ACTIVE; if (!cave->replicators_active) - /* if the replicators are inactive, do not animate them. */ + // if the replicators are inactive, do not animate them. elemdrawing[O_REPLICATOR] = ABS(elemdrawing[O_REPLICATOR]); elemmapping[O_CONVEYOR_SWITCH] = (cave->conveyor_belts_active ? O_CONVEYOR_SWITCH_ON : O_CONVEYOR_SWITCH_OFF); @@ -1211,7 +1228,7 @@ void gd_drawcave_game(const GdCave *cave, int **element_buffer, int **gfx_buffer if (cave->conveyor_belts_direction_changed) { - /* if direction is changed, animation is changed. */ + // if direction is changed, animation is changed. int temp; elemmapping[O_CONVEYOR_LEFT] = O_CONVEYOR_RIGHT; @@ -1232,23 +1249,23 @@ void gd_drawcave_game(const GdCave *cave, int **element_buffer, int **gfx_buffer if (cave->conveyor_belts_active) { - /* keep potentially changed direction */ + // keep potentially changed direction int offset = (O_CONVEYOR_LEFT_ACTIVE - O_CONVEYOR_LEFT); - /* if they are running, animate them. */ + // if they are running, animate them. elemmapping[O_CONVEYOR_LEFT] += offset; elemmapping[O_CONVEYOR_RIGHT] += offset; } if (!cave->conveyor_belts_active) { - /* if they are not running, do not animate them. */ + // if they are not running, do not animate them. elemdrawing[O_CONVEYOR_LEFT] = ABS(elemdrawing[O_CONVEYOR_LEFT]); elemdrawing[O_CONVEYOR_RIGHT] = ABS(elemdrawing[O_CONVEYOR_RIGHT]); } if (animcycle & 2) { - /* also a hack, like biter_switch */ + // also a hack, like biter_switch elemdrawing[O_PNEUMATIC_ACTIVE_LEFT] += 2; elemdrawing[O_PNEUMATIC_ACTIVE_RIGHT] += 2; elemdrawing[O_PLAYER_PNEUMATIC_LEFT] += 2; @@ -1257,7 +1274,7 @@ void gd_drawcave_game(const GdCave *cave, int **element_buffer, int **gfx_buffer if ((cave->last_direction) == GD_MV_STILL) { - /* player is idle. */ + // player is idle. if (player_blinking && player_tapping) { map = O_PLAYER_TAP_BLINK; @@ -1286,7 +1303,7 @@ void gd_drawcave_game(const GdCave *cave, int **element_buffer, int **gfx_buffer } else { - /* of course this is GD_MV_RIGHT. */ + // of course this is GD_MV_RIGHT. map = O_PLAYER_RIGHT; draw = gd_elements[O_PLAYER_RIGHT].image_game; } @@ -1297,9 +1314,9 @@ void gd_drawcave_game(const GdCave *cave, int **element_buffer, int **gfx_buffer elemdrawing[O_PLAYER] = draw; elemdrawing[O_PLAYER_GLUED] = draw; - /* 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) + // 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) { elemmapping[O_PLAYER_BOMB] = map; elemdrawing[O_PLAYER_BOMB] = draw; @@ -1311,26 +1328,26 @@ void gd_drawcave_game(const GdCave *cave, int **element_buffer, int **gfx_buffer elemmapping[O_OUTBOX] = (cave->inbox_flash_toggle ? O_OUTBOX_OPEN : O_OUTBOX_CLOSED); elemdrawing[O_OUTBOX] = gd_elements[cave->inbox_flash_toggle ? O_OUTBOX_OPEN : O_OUTBOX_CLOSED].image_game; - /* hack, not fit into gd_elements */ + // hack, not fit into gd_elements elemmapping[O_BITER_SWITCH] = O_BITER_SWITCH_1 + cave->biter_delay_frame; - /* hack, not fit into gd_elements */ + // hack, not fit into gd_elements elemdrawing[O_BITER_SWITCH] = gd_elements[O_BITER_SWITCH].image_game + cave->biter_delay_frame; - /* visual effects */ + // visual effects elemmapping[O_DIRT] = cave->dirt_looks_like; elemmapping[O_EXPANDING_WALL] = cave->expanding_wall_looks_like; elemmapping[O_V_EXPANDING_WALL] = cave->expanding_wall_looks_like; elemmapping[O_H_EXPANDING_WALL] = cave->expanding_wall_looks_like; elemmapping[O_AMOEBA_2] = cave->amoeba_2_looks_like; - /* visual effects */ + // visual effects elemdrawing[O_DIRT] = elemdrawing[cave->dirt_looks_like]; elemdrawing[O_EXPANDING_WALL] = elemdrawing[cave->expanding_wall_looks_like]; elemdrawing[O_V_EXPANDING_WALL] = elemdrawing[cave->expanding_wall_looks_like]; elemdrawing[O_H_EXPANDING_WALL] = elemdrawing[cave->expanding_wall_looks_like]; elemdrawing[O_AMOEBA_2] = elemdrawing[cave->amoeba_2_looks_like]; - /* change only graphically */ + // change only graphically if (hate_invisible_outbox) { elemmapping[O_PRE_INVIS_OUTBOX] = O_PRE_OUTBOX; @@ -1349,27 +1366,27 @@ void gd_drawcave_game(const GdCave *cave, int **element_buffer, int **gfx_buffer { GdElement actual = cave->map[y][x]; - /* if covered, real element is not important */ + // if covered, real element is not important if (actual & COVERED) map = O_COVERED; else map = elemmapping[actual]; - /* if covered, real element is not important */ + // if covered, real element is not important if (actual & COVERED) draw = gd_elements[O_COVERED].image_game; else draw = elemdrawing[actual]; - /* if negative, animated. */ + // if negative, animated. if (draw < 0) draw = -draw + animcycle; - /* flash */ + // flash if (cave->gate_open_flash) draw += GD_NUM_OF_CELLS; - /* set to buffer, with caching */ + // set to buffer, with caching if (element_buffer[y][x] != map) element_buffer[y][x] = map; @@ -1379,12 +1396,15 @@ void gd_drawcave_game(const GdCave *cave, int **element_buffer, int **gfx_buffer } } -/* cave time is rounded _UP_ to seconds. so at the exact moment when it - changes from - 2sec remaining to 1sec remaining, the player has exactly one second. - when it changes - to zero, it is the exact moment of timeout. */ -/* internal time is milliseconds (or 1200 milliseconds for pal timing). */ +/* + cave time is rounded _UP_ to seconds. so at the exact moment when it + changes from + 2sec remaining to 1sec remaining, the player has exactly one second. + when it changes + to zero, it is the exact moment of timeout. + + internal time is milliseconds (or 1200 milliseconds for pal timing). +*/ int gd_cave_time_show(const GdCave *cave, int internal_time) { return (internal_time + cave->timing_factor - 1) / cave->timing_factor; @@ -1395,10 +1415,7 @@ GdReplay *gd_replay_new(void) 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; } @@ -1407,157 +1424,43 @@ 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 = g_string_new(orig->comment->str); - rep->movements = g_byte_array_new(); - g_byte_array_append(rep->movements, orig->movements->data, orig->movements->len); + // replicate dynamic data + 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); } -/* store movement in a replay */ +// store movement in a 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); - - return TRUE; -} - -void gd_replay_rewind(GdReplay *replay) -{ - replay->current_playing_pos = 0; -} - -#define REPLAY_BDCFF_UP "u" -#define REPLAY_BDCFF_UP_RIGHT "ur" -#define REPLAY_BDCFF_RIGHT "r" -#define REPLAY_BDCFF_DOWN_RIGHT "dr" -#define REPLAY_BDCFF_DOWN "d" -#define REPLAY_BDCFF_DOWN_LEFT "dl" -#define REPLAY_BDCFF_LEFT "l" -#define REPLAY_BDCFF_UP_LEFT "ul" -/* when not moving */ -#define REPLAY_BDCFF_STILL "." -/* when the fire is pressed */ -#define REPLAY_BDCFF_FIRE "F" -#define REPLAY_BDCFF_SUICIDE "k" - -static char *direction_to_bdcff(GdDirection mov) -{ - switch (mov) - { - /* not moving */ - case GD_MV_STILL: return REPLAY_BDCFF_STILL; - - /* directions */ - case GD_MV_UP: return REPLAY_BDCFF_UP; - case GD_MV_UP_RIGHT: return REPLAY_BDCFF_UP_RIGHT; - case GD_MV_RIGHT: return REPLAY_BDCFF_RIGHT; - case GD_MV_DOWN_RIGHT: return REPLAY_BDCFF_DOWN_RIGHT; - case GD_MV_DOWN: return REPLAY_BDCFF_DOWN; - case GD_MV_DOWN_LEFT: return REPLAY_BDCFF_DOWN_LEFT; - case GD_MV_LEFT: return REPLAY_BDCFF_LEFT; - case GD_MV_UP_LEFT: return REPLAY_BDCFF_UP_LEFT; - - default: - return REPLAY_BDCFF_STILL; - } -} - -/* same as above; pressing fire will be a capital letter. */ -static char *direction_fire_to_bdcff(GdDirection dir, boolean fire) -{ - static char mov[10]; - - strcpy(mov, direction_to_bdcff(dir)); - - if (fire) - { - int i; - - for (i = 0; mov[i] != 0; i++) - mov[i] = g_ascii_toupper(mov[i]); - } - - return mov; -} - -char *gd_replay_movements_to_bdcff(GdReplay *replay) -{ - int pos; - GString *str; - - str = g_string_new(NULL); - - for (pos = 0; pos < replay->movements->len; pos++) + if (replay->movements->len < MAX_REPLAY_LEN) { - int num = 1; - guint8 data; + replay->movements->data[replay->movements->len++] = data[0]; - /* if this is not the first movement, append a space. */ - if (str->len != 0) - g_string_append_c(str, ' '); - - /* if same byte appears, count number of occurrences - something like an rle compression. */ - /* be sure not to cross the array boundaries */ - while (pos < replay->movements->len - 1 && - replay->movements->data[pos] == replay->movements->data[pos + 1]) - { - pos++; - num++; - } - - data = replay->movements->data[pos]; - - if (data & GD_REPLAY_SUICIDE_MASK) - g_string_append(str, REPLAY_BDCFF_SUICIDE); - - g_string_append(str, direction_fire_to_bdcff(data & GD_REPLAY_MOVE_MASK, - data & GD_REPLAY_FIRE_MASK)); - - if (num != 1) - g_string_append_printf(str, "%d", num); + if (replay->movements->len == MAX_REPLAY_LEN) + Warn("BD replay truncated: size exceeds maximum replay size %d", MAX_REPLAY_LEN); } - - return g_string_free(str, FALSE); } -/* 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) +// calculate adler checksum for a rendered cave; this can be used for more caves. +void gd_cave_adler_checksum_more(GdCave *cave, unsigned int *a, unsigned int *b) { int x, y; @@ -1572,19 +1475,12 @@ 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) +// calculate adler checksum for a single rendered 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; } - -/* return c64 color with index. */ -GdColor gd_c64_color(int index) -{ - return (GD_COLOR_TYPE_C64 << 24) + index; -}