hiscore.c (2475B)
1 /* This program is licensed under the terms of GNU GPL v3 or (at your option) 2 * any later version. Copyright (C) 2025 Страхиња Радић. 3 * See the file LICENSE for exact copyright and license details. */ 4 5 #include "hiscore.h" 6 7 #include <SDL3/SDL.h> 8 #include <assert.h> 9 #include <stdlib.h> 10 #include <string.h> 11 12 int 13 hs_add(struct HiScoreEntry** table, const char* name, const int name_len, 14 const int score) 15 { 16 struct HiScoreEntry* p = NULL; 17 struct HiScoreEntry* q = NULL; 18 19 assert((table != NULL) && (*table != NULL)); 20 21 p = *table; 22 while (p < *table + HI_SCORE_MAX) 23 { 24 assert(p != NULL); 25 if (p->score < score) 26 { 27 q = *table + HI_SCORE_MAX - 1; 28 while (q != p) 29 { 30 hs_assign_ss(q - 1, q); 31 q--; 32 } 33 hs_assign_ps(name, name_len, score, p); 34 break; 35 } 36 p++; 37 } 38 39 return 0; 40 } 41 42 int 43 hs_assign_ps(const char* name, const int name_len, const int score, 44 struct HiScoreEntry* dest) 45 { 46 char* new_name = NULL; 47 48 assert(dest != NULL); 49 50 if (!name || !name_len) 51 goto hs_assign_ps_skip_name; 52 53 if (dest->name_len < name_len) 54 { 55 new_name = realloc(dest->name, name_len); 56 if (!new_name) 57 { 58 SDL_LogError(SDL_LOG_CATEGORY_ERROR, "realloc failed"); 59 return 1; 60 } 61 } 62 memccpy(dest->name, name, 0, name_len); 63 64 hs_assign_ps_skip_name: 65 dest->name_len = name_len; 66 dest->score = score; 67 return 0; 68 } 69 70 int 71 hs_assign_ss(const struct HiScoreEntry* source, struct HiScoreEntry* dest) 72 { 73 char* new_name = NULL; 74 75 assert((source != NULL) && (dest != NULL)); 76 77 if (!source->name) 78 goto hs_assign_ss_skip_name; 79 80 if (dest->name_len < source->name_len) 81 { 82 new_name = realloc(dest->name, source->name_len); 83 if (!new_name) 84 { 85 SDL_LogError(SDL_LOG_CATEGORY_ERROR, "realloc failed"); 86 return 1; 87 } 88 } 89 memccpy(dest->name, source->name, 0, source->name_len); 90 91 hs_assign_ss_skip_name: 92 dest->name_len = source->name_len; 93 dest->score = source->score; 94 return 0; 95 } 96 97 int 98 hs_init(struct HiScoreEntry** table) 99 { 100 struct HiScoreEntry* p = NULL; 101 int len = sizeof(HI_SCORE_DEFAULT_NAME); 102 103 assert(table != NULL); 104 *table = malloc(HI_SCORE_MAX * sizeof(struct HiScoreEntry)); 105 if (!*table) 106 goto hs_init_malloc_error; 107 for (p = *table; p < *table + HI_SCORE_MAX; p++) 108 { 109 p->name = malloc(len); 110 if (!p->name) 111 goto hs_init_malloc_error; 112 memccpy(p->name, HI_SCORE_DEFAULT_NAME, 0, len); 113 p->name_len = len; 114 p->score = 0; 115 } 116 117 return 0; 118 119 hs_init_malloc_error: 120 SDL_LogError(SDL_LOG_CATEGORY_ERROR, "malloc failed"); 121 return 1; 122 }