added saving native BDCFF file with cheat code ":save-native-level"
[rocksndiamonds.git] / src / game_bd / bd_cave.c
index b0f1573ef52d96992e70bb6aa6cccdc1680ec9cc..4c5b4287a6f5dae50cc5fbb7a71c725b5a0a41e1 100644 (file)
@@ -14,9 +14,6 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include <glib.h>
-#include <glib/gi18n.h>
-
 #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; 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;
 
@@ -128,7 +125,7 @@ GdScheduling gd_scheduling_from_string(const char *str)
 {
   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;
 
@@ -143,7 +140,7 @@ GdScheduling gd_scheduling_from_string(const char *str)
   "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)
 {
@@ -151,7 +148,7 @@ void gd_struct_set_defaults_from_array(gpointer str,
 
   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;
@@ -237,7 +234,7 @@ 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++)
+  for (i = 0; i < ARRAY_SIZE(gd_char_to_element); i++)
     gd_char_to_element[i] = O_UNKNOWN;
 
   /* then set fixed characters */
@@ -247,7 +244,7 @@ void gd_create_char_to_element_table(void)
 
     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;
@@ -256,7 +253,7 @@ 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)
+GdElement gd_get_element_from_character (byte character)
 {
   if (gd_char_to_element[character] != O_UNKNOWN)
     return gd_char_to_element[character];
@@ -275,46 +272,45 @@ void gd_cave_init(void)
 
   /* 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();
@@ -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,16 +774,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;
 }
 
 /*
@@ -1157,10 +1175,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 +1311,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 +1407,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 +1416,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 +1436,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,18 +1468,11 @@ 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;
 }
-
-/* return c64 color with index. */
-GdColor gd_c64_color(int index)
-{
-  return (GD_COLOR_TYPE_C64 << 24) + index;
-}