commit 2f035ddc318bb9f36f4f47f25e72a9fc8099dc02
parent 7764da9b07dd6cb206fe2bdd6160fa19dc6d8b2c
Author: hhvn <dev@hhvn.uk>
Date: Sun, 15 Jan 2023 22:19:09 +0000
Empires
Diffstat:
7 files changed, 194 insertions(+), 28 deletions(-)
diff --git a/src/empires.c b/src/empires.c
@@ -0,0 +1,113 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "main.h"
+
+void
+emp_free(Empire *e) {
+ free(e->name);
+ free(e);
+}
+
+Empire *
+emp_byid(Save *s, char *id) {
+ int i;
+
+ for (i = EMP_FIRST; i < EMP_MAX; i++)
+ if (s->emp[i] && streq(s->emp[i]->id, id))
+ return s->emp[i];
+ return NULL;
+}
+
+Empire *
+emp_byname(Save *s, char *name) {
+ int i;
+
+ for (i = EMP_FIRST; i < EMP_MAX; i++)
+ if (s->emp[i] && streq(s->emp[i]->name, name))
+ return s->emp[i];
+ return NULL;
+}
+
+static int
+emp_add(Save *s, Empire *e) {
+ int i;
+
+ for (i = EMP_FIRST; i < EMP_MAX; i++){
+ if (!s->emp[i]) {
+ s->emp[i] = e;
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+Empire *
+emp_init(Save *s, int player, char *id, char *name) {
+ Empire *e = emalloc(sizeof(Empire));
+
+ e->player = 0;
+ snprintf(e->id, sizeof(e->id), "%s", id);
+ e->name = estrdup(name);
+
+ if (s->emp[EMP_PLAYER] && player)
+ warning("player already exists in this save");
+ else
+ e->player = player;
+
+ if (e->player) {
+ e->db = smprintf("%s/player", s->db.emp);
+ e->eid = EMP_PLAYER;
+ s->emp[e->eid] = e;
+ } else {
+ e->db = smprintf("%s/%s", s->db.emp, id);
+ e->eid = emp_add(s, e);
+ }
+
+ return e;
+}
+
+void
+emp_gen(Save *s, int n) {
+ char name[9];
+ char id[4];
+ int i;
+
+ for (i = 1; i <= n; i++) {
+ /* TODO: take names & ids from list */
+ snprintf(name, sizeof(name), "Empire %d", i);
+ snprintf(id, 4, "EM%d", i);
+ emp_init(s, 0, id, name);
+ }
+}
+
+void
+emp_write(Save *s) {
+ char *names[EMP_MAX];
+ char *ids[EMP_MAX];
+ int i;
+
+ for (i = 0; s->emp[i]; i++) {
+ names[i] = s->emp[i]->name;
+ ids[i] = s->emp[i]->id;
+ }
+
+ bdbset(s->db.emp, "index",
+ 'S', "names", names, i,
+ 'S', "ids", ids, i);
+}
+
+void
+emp_read(Save *s) {
+ char *names[EMP_MAX];
+ char *ids[EMP_MAX];
+ int i;
+
+ bdbget(s->db.emp, "index",
+ 'S', "names", &names, EMP_MAX,
+ 'S', "ids", &ids, EMP_MAX);
+
+ for (i = 0; i < EMP_MAX && names[i]; i++)
+ emp_init(s, !i, ids[i], names[i]);
+}
diff --git a/src/main.c b/src/main.c
@@ -30,7 +30,6 @@ main(void) {
int view_prev;
struct sigaction sa;
-
sa.sa_handler = sighandler;
sa.sa_flags = SA_RESTART;
sigemptyset(&sa.sa_mask);
diff --git a/src/main.h b/src/main.h
@@ -232,7 +232,17 @@ int save_changed(void);
void save_write(void);
int save_delete(char *name);
int save_exists(char *name);
-int save_create(char *name);
+int save_create(char *name, char *emp, char *eid);
+
+/* empires.c */
+extern Empire *emp[EMP_MAX];
+void emp_free(Empire *e);
+Empire *emp_byid(Save *s, char *id);
+Empire *emp_byname(Save *s, char *name);
+Empire *emp_init(Save *s, int player, char *id, char *name);
+void emp_gen(Save *s, int n);
+void emp_read(Save *s);
+void emp_write(Save *s);
/* ../data/dirs.c */
int dirs_write(char *dir, char *to);
diff --git a/src/save.c b/src/save.c
@@ -8,11 +8,15 @@
static void
save_free(void) {
+ int i;
+
free(save->db.dir);
- free(save->db.races);
+ free(save->db.emp);
free(save->db.systems);
free(save->db.fleets);
tree_delete_root(&save->systems, sys_tree_free);
+ for (i = 0; i < EMP_MAX; i++)
+ emp_free(save->emp[i]);
free(save);
}
@@ -31,14 +35,17 @@ save_read(char *name) {
snprintf(dir, sizeof(dir), "%s/%s", SAVEDIR, name);
memset(&save->systems, 0, sizeof(save->systems));
+ memset(&save->emp, 0, sizeof(save->emp));
dbdeclare(dir);
save->db.dir = nstrdup(dir);
- save->db.races = smprintf("%s/Races", dir);
+ save->db.emp = smprintf("%s/Empires", dir);
save->db.systems = smprintf("%s/Systems", dir);
save->db.fleets = smprintf("%s/Fleets", dir);
sys_tree_load();
+ emp_read(save);
+
if ((str = dbget(save->db.dir, "index", "homesystem")))
save->homesys = sys_get(str);
else
@@ -47,6 +54,7 @@ save_read(char *name) {
for (i = 0; i < VIEW_LAST; i++)
if (view_init[i])
view_init[i]();
+
return;
};
@@ -62,6 +70,7 @@ save_write(void) {
if (view_main.sys)
dbset(save->db.dir, "index", "selsystem", view_main.sys->name);
dbsettree(save->db.systems, &save->systems, sys_tree_setter);
+ emp_write(save);
dbwrite(save->db.dir);
}
@@ -83,8 +92,9 @@ save_exists(char *name) {
return 0;
}
+/* TODO: struct SaveConfig */
int
-save_create(char *name) {
+save_create(char *name, char *emp, char *eid) {
char path[PATH_MAX];
snprintf(path, sizeof(path), "%s/%s/Systems", SAVEDIR, name);
@@ -101,5 +111,8 @@ save_create(char *name) {
save_delete(name);
dbset(save->db.dir, "index", "homesystem", "Sol");
+ emp_init(save, 1, eid, emp);
+ emp_gen(save, EMP_MAX - 1);
+
return 0;
}
diff --git a/src/struct.h b/src/struct.h
@@ -105,14 +105,32 @@ typedef struct {
Vector lypos;
} System;
+/* empires.c */
+#define EMP_MAX 10 /* including EMP_NONE and EMP_PLAYER */
+enum EID {
+ EMP_PLAYER,
+ EMP_FIRST = EMP_PLAYER,
+ EMP_LAST = EMP_MAX,
+};
+
+typedef struct {
+ int player;
+ char *db;
+ /* AI *ai */
+ int eid;
+ char id[4];
+ char *name;
+} Empire;
+
/* save.c */
typedef struct {
struct {
char *dir;
- char *races;
+ char *emp;
char *systems;
char *fleets;
} db;
+ Empire *emp[EMP_MAX];
Tree systems;
System *homesys;
} Save;
diff --git a/src/views/smenu.c b/src/views/smenu.c
@@ -13,7 +13,6 @@
#define LOAD_W 300
#define LOAD_H 350
#define LOAD_NAMEW 100
-#define BUTTON_W 50
enum {
SMENU_LOAD_LOAD,
@@ -55,11 +54,26 @@ View_smenu view_smenu = {
},
.new = {
.disp = 0,
- .name = {
- .placeholder = "Save name",
- .onenter = newhandler_actual,
+ .form = {
+ .elems = {
+ FORM_INPUT(1, "Name", &view_smenu.new.name),
+ FORM_SUBFORM("Empire"),
+ FORM_INPUT(1, "Empire name", &view_smenu.new.emp.name),
+ FORM_NEWLINE(),
+ FORM_INPUT(1, "Empire ID", &view_smenu.new.emp.id),
+ FORM_END()
+ },
+ .buttons = {
+ &view_smenu.new.create,
+ &view_smenu.new.back,
+ },
},
- .create = {1, "Create", NULL, 0, .submit = &view_smenu.new.name},
+ .name = { .onenter = gui_input_next, },
+ .emp = {
+ .name = { .onenter = gui_input_next, },
+ .id = { .onenter = gui_input_next, },
+ },
+ .create = {1, "Create", newhandler_actual, 0, .submit = &view_smenu.new.form},
.back = {1, "Back", newhandler_actual, SMENU_BACK},
},
.cont = {
@@ -171,13 +185,13 @@ newhandler_actual(int type, void *elem) {
if (type == GUI_BUTTON) {
b = elem;
if (b->arg == SMENU_BACK) {
- gui_input_clear(&v->new.name);
+ gui_form_clear(&v->new.form);
v->new.disp = 0;
return 1;
}
}
- if (save_create(v->new.name.str) == -1)
+ if (save_create(v->new.name.str, v->new.emp.name.str, v->new.emp.id.str) == -1)
error(1, "failed to create new save\n");
/* TODO: error handling that doesn't just cause an exit? */
loadadd(v->new.name.str, time(NULL));
@@ -337,7 +351,7 @@ view_smenu_draw(void) {
if (v->new.disp) {
w = PAD * 2 + 300;
- h = PAD * 3 + FONT_SIZE + BUTTON_HEIGHT;
+ h = 500;
x = (screen.w - w) / 2;
y = (screen.h - h) / 2;
@@ -346,16 +360,10 @@ view_smenu_draw(void) {
x += PAD;
y += PAD;
- gui_input(x, y, 300, &v->new.name);
-
- v->new.create.enabled =
- v->new.name.str[0] ? 1 : 0;
- x += w - 50 - PAD * 2,
- gui_button(x, y + PAD * 2, 50, &v->new.create);
+ v->new.create.enabled = gui_form_filled(&v->new.form);
- x -= 50 + PAD;
- gui_button(x, y + PAD * 2, 50, &v->new.back);
+ gui_form(x, y, w - PAD * 2, h - PAD * 2, &v->new.form);
} else if (v->save.check) {
w = PAD * 2 + ui_textsize(v->save.msg);
h = PAD * 3 + FONT_SIZE + BUTTON_HEIGHT;
@@ -389,15 +397,15 @@ view_smenu_draw(void) {
gui_treeview(x, y, LOAD_W, LOAD_H, &v->load.savelist);
- x += w - BUTTON_W - PAD * 2;
+ x += w - BUTTON_DEFW - PAD * 2;
y += h - PAD * 2 - BUTTON_HEIGHT;
- gui_button(x, y, BUTTON_W, &v->load.load);
+ gui_button(x, y, BUTTON_DEFW, &v->load.load);
- x -= BUTTON_W + PAD;
- gui_button(x, y, BUTTON_W, &v->load.delete);
+ x -= BUTTON_DEFW + PAD;
+ gui_button(x, y, BUTTON_DEFW, &v->load.delete);
- x -= BUTTON_W + PAD;
- gui_button(x, y, BUTTON_W, &v->load.back);
+ x -= BUTTON_DEFW + PAD;
+ gui_button(x, y, BUTTON_DEFW, &v->load.back);
} else {
ui_draw_rect(EXPLODE_RECT(v->main), bg);
ui_draw_border_around(EXPLODE_RECT(v->main), 1);
diff --git a/src/views/struct.h b/src/views/struct.h
@@ -90,7 +90,12 @@ typedef struct {
Button b[SMENU_LAST];
struct {
int disp;
+ Form form;
Input name;
+ struct {
+ Input name;
+ Input id;
+ } emp;
Button create;
Button back;
} new;