чување 5d62a1e1a90136e85282d7d1e8b3b6a5052e245b
родитељ b5d653f1827968443098ae436d8db44ca192d595
Аутор: Страхиња Радић <sr@strahinja.org>
Датум: Wed, 15 Oct 2025 00:05:01 +0200
WIP highscores
Diffstat:
измењених датотека: 5, додавања: 165(+), брисања: 2(-)
diff --git a/Makefile b/Makefile
@@ -24,6 +24,8 @@ makedate:
makeversion:
sh lib/makeversion -l
+hiscore.o: hiscore.c
+
linije.o: linije.c local.h version.h
version.h: version.h.in date version
diff --git a/config.mk b/config.mk
@@ -11,9 +11,9 @@ INCLUDE = -I/usr/include
#INCLUDE = -I/usr/local/include
INSTALL = install
LIBS = -lSDL3_image -lSDL3 -lm
-SRC = linije.c
+SRC = hiscore.c linije.c
HEADERS = local.h
-OBJS = linije.o
+OBJS = hiscore.o linije.o
PREFIX = /usr/local
PROG = linije
diff --git a/hiscore.c b/hiscore.c
@@ -0,0 +1,122 @@
+/* This program is licensed under the terms of GNU GPL v3 or (at your option)
+ * any later version. Copyright (C) 2025 Страхиња Радић.
+ * See the file LICENSE for exact copyright and license details. */
+
+#include "hiscore.h"
+
+#include <SDL3/SDL.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+int
+hs_add(struct HiScoreEntry** table, const char* name, const int name_len,
+ const int score)
+{
+ struct HiScoreEntry* p = NULL;
+ struct HiScoreEntry* q = NULL;
+
+ assert((table != NULL) && (*table != NULL));
+
+ p = *table;
+ while (p < *table + HI_SCORE_MAX)
+ {
+ assert(p != NULL);
+ if (p->score < score)
+ {
+ q = *table + HI_SCORE_MAX - 1;
+ while (q != p)
+ {
+ hs_assign_ss(q - 1, q);
+ q--;
+ }
+ hs_assign_ps(name, name_len, score, p);
+ break;
+ }
+ p++;
+ }
+
+ return 0;
+}
+
+int
+hs_assign_ps(const char* name, const int name_len, const int score,
+ struct HiScoreEntry* dest)
+{
+ char* new_name = NULL;
+
+ assert(dest != NULL);
+
+ if (!name || !name_len)
+ goto hs_assign_ps_skip_name;
+
+ if (dest->name_len < name_len)
+ {
+ new_name = realloc(dest->name, name_len);
+ if (!new_name)
+ {
+ SDL_LogError(SDL_LOG_CATEGORY_ERROR, "realloc failed");
+ return 1;
+ }
+ }
+ memccpy(dest->name, name, 0, name_len);
+
+hs_assign_ps_skip_name:
+ dest->name_len = name_len;
+ dest->score = score;
+ return 0;
+}
+
+int
+hs_assign_ss(const struct HiScoreEntry* source, struct HiScoreEntry* dest)
+{
+ char* new_name = NULL;
+
+ assert((source != NULL) && (dest != NULL));
+
+ if (!source->name)
+ goto hs_assign_ss_skip_name;
+
+ if (dest->name_len < source->name_len)
+ {
+ new_name = realloc(dest->name, source->name_len);
+ if (!new_name)
+ {
+ SDL_LogError(SDL_LOG_CATEGORY_ERROR, "realloc failed");
+ return 1;
+ }
+ }
+ memccpy(dest->name, source->name, 0, source->name_len);
+
+hs_assign_ss_skip_name:
+ dest->name_len = source->name_len;
+ dest->score = source->score;
+ return 0;
+}
+
+int
+hs_init(struct HiScoreEntry** table)
+{
+ struct HiScoreEntry* p = NULL;
+ int len = sizeof(HI_SCORE_DEFAULT_NAME);
+
+ assert(table != NULL);
+ *table = malloc(HI_SCORE_MAX * sizeof(struct HiScoreEntry));
+ if (!*table)
+ goto hs_init_malloc_error;
+ for (p = *table; p < *table + HI_SCORE_MAX; p++)
+ {
+ p->name = malloc(len);
+ if (!p->name)
+ goto hs_init_malloc_error;
+ memccpy(p->name, HI_SCORE_DEFAULT_NAME, 0, len);
+ p->name_len = len;
+ p->score = 0;
+ }
+
+ return 0;
+
+hs_init_malloc_error:
+ SDL_LogError(SDL_LOG_CATEGORY_ERROR, "malloc failed");
+ return 1;
+}
diff --git a/hiscore.h b/hiscore.h
@@ -0,0 +1,20 @@
+/* This program is licensed under the terms of GNU GPL v3 or (at your option)
+ * any later version. Copyright (C) 2025 Страхиња Радић.
+ * See the file LICENSE for exact copyright and license details. */
+
+#define HI_SCORE_DEFAULT_NAME "Unknown player"
+#define HI_SCORE_MAX 10
+
+struct HiScoreEntry {
+ char* name;
+ int name_len;
+ int score;
+};
+
+int hs_add(struct HiScoreEntry** table, const char* name, const int name_len,
+ const int score);
+int hs_assign(const struct HiScoreEntry* source, struct HiScoreEntry* dest);
+int hs_assign_ss(const struct HiScoreEntry* source, struct HiScoreEntry* dest);
+int hs_assign_ps(const char* name, const int name_len, const int score,
+ struct HiScoreEntry* dest);
+int hs_init(struct HiScoreEntry** table);
diff --git a/linije.c b/linije.c
@@ -16,6 +16,7 @@
#include "local.h"
#include "version.h"
+#include "hiscore.h"
/* clang-format off */
#define ANIM_SPEED 100 /* how long does it take for the animation to go
@@ -1734,6 +1735,8 @@ main(int argc, char** argv)
SDL_Event event;
struct Cell* c = NULL;
struct State state;
+ struct HiScoreEntry* hof = NULL;
+ struct HiScoreEntry* p = NULL;
struct timespec now;
SDL_FPoint coords;
float px, py;
@@ -1742,6 +1745,22 @@ main(int argc, char** argv)
int x, y;
init_state(&state);
+ hs_init(&hof);
+
+ /*
+ for (p = hof; p < hof + HI_SCORE_MAX; p++)
+ printf("%s (%d) -> %d\n", p->name, p->name_len, p->score);
+
+ hs_add(&hof, "Player 2 with a very long name",
+ sizeof("Player 2 with a very long name"), 2);
+ hs_add(&hof, "Player 1", sizeof("Player 1"), 50);
+ hs_add(&hof, "Strajder", sizeof("Strajder"), 250);
+ hs_add(&hof, "Player 3", sizeof("Player 3"), 44);
+
+ for (p = hof; p < hof + HI_SCORE_MAX; p++)
+ printf("%s (%d) -> %d\n", p->name, p->name_len, p->score);
+
+ return 0;*/
if (!SDL_Init(SDL_INIT_VIDEO))
{