summaryrefslogtreecommitdiff
path: root/procyon/source
diff options
context:
space:
mode:
Diffstat (limited to 'procyon/source')
-rw-r--r--procyon/source/bs/cont.c79
-rw-r--r--procyon/source/bs/dbglog.c11
-rw-r--r--procyon/source/bs/exit.c15
-rw-r--r--procyon/source/bs/init.c51
-rw-r--r--procyon/source/bs/sav.c35
-rw-r--r--procyon/source/bs/shipnm.c70
-rw-r--r--procyon/source/gfx/initgfx.c22
-rw-r--r--procyon/source/main.c24
8 files changed, 307 insertions, 0 deletions
diff --git a/procyon/source/bs/cont.c b/procyon/source/bs/cont.c
new file mode 100644
index 0000000..61907fc
--- /dev/null
+++ b/procyon/source/bs/cont.c
@@ -0,0 +1,79 @@
+#include <acm/bs.h>
+
+#include <flux.h>
+#include <inttypes.h>
+#include <zap/mem.h>
+
+static_assert(sizeof (acm_dflplnm) == acm_plnmlen);
+
+void acm_cont(acm_pldat * const _pldat) {
+ acm_log("Continuing\n");
+ acm_pldat pldat;
+ uint_least64_t savver;
+ flux_err fluxerr;
+ flux_fil savfil;
+ fluxerr = flux_op(&savfil,acm_dat.savloc,flux_md_rd,flux_keep);
+ if (fluxerr) {
+ acm_log("Unable to open save file, starting new game: %s\n",flux_errstr(fluxerr));
+ goto new;
+ }
+ fluxerr = flux_rd(savfil,sizeof (savver),&savver,nullptr);
+ if (!fluxerr) {
+ fluxerr = flux_rd(savfil,sizeof (pldat),&pldat,nullptr);
+ }
+ flux_cl(savfil);
+ if (fluxerr) {
+ acm_log("Unable to read save file, starting new game: %s\n",flux_errstr(fluxerr));
+ goto new;
+ }
+ if (savver != acm_savver) {
+ printf("Old save version (%" PRIXLEAST64 "), starting new game: %s\n",savver,flux_errstr(fluxerr));
+ goto new;
+ }
+ acm_log("Validating commander name\n");
+ bool validnm = false;
+ for (zap_sz n = 0x0u;n < acm_plnmlen + 0x1u;++n) {
+ if (pldat.nm[n] == '\x0') {
+ if (n == 0x0u) {
+ break;
+ }
+ validnm = true;
+ break;
+ }
+ }
+ if (!validnm) {
+ acm_log("Invalid commander name (corrupt save file), starting new game\n");
+ acm_log(
+ "Commander name:\n"
+ " %hhX %hhX %hhX %hhX\n"
+ " %hhX %hhX %hhX %hhX\n"
+ " %hhX %hhX %hhX %hhX\n"
+ " %hhX %hhX %hhX %hhX\n"
+ " %hhX\n",
+ pldat.nm[0x0u],pldat.nm[0x1u],pldat.nm[0x2u],pldat.nm[0x3u],
+ pldat.nm[0x4u],pldat.nm[0x5u],pldat.nm[0x6u],pldat.nm[0x7u],
+ pldat.nm[0x8u],pldat.nm[0x9u],pldat.nm[0xAu],pldat.nm[0xBu],
+ pldat.nm[0xCu],pldat.nm[0xDu],pldat.nm[0xEu],pldat.nm[0xFu],
+ pldat.nm[0x10u]
+ );
+ goto new;
+ }
+ printf("Loaded CMDR %s, %s @ %" PRIiLEAST64 "\n",pldat.nm,acm_shipnm(pldat.ship),pldat.tm);
+ *_pldat = pldat;
+ return;
+new:;
+ pldat.heat = 0x120u; /* 288K */
+ pldat.pos.px = 0x0u;
+ pldat.pos.py = 0x0u;
+ pldat.pos.pz = 0x0u;
+ pldat.pos.rx = 0x0u;
+ pldat.pos.ry = 0x0u;
+ pldat.pos.rz = 0x0u;
+ pldat.pos.vx = 0x0u;
+ pldat.pos.vy = 0x0u;
+ pldat.pos.vz = 0x0u;
+ pldat.ship = acm_ship_side;
+ pldat.tm = 0x9679C2B40u; /* 3250-01-01T12:00:00Z */
+ zap_memcp(acm_dflplnm,acm_plnmlen + 0x1u,pldat.nm);
+ *_pldat = pldat;
+}
diff --git a/procyon/source/bs/dbglog.c b/procyon/source/bs/dbglog.c
new file mode 100644
index 0000000..d04174f
--- /dev/null
+++ b/procyon/source/bs/dbglog.c
@@ -0,0 +1,11 @@
+#include <acm/bs.h>
+
+#include <stdarg.h>
+#include <stdio.h>
+
+void acm_dbglog(char const * const _fmt,...) {
+ va_list args;
+ va_start(args,_fmt);
+ vfprintf(stderr,_fmt,args);
+ va_end(args);
+}
diff --git a/procyon/source/bs/exit.c b/procyon/source/bs/exit.c
new file mode 100644
index 0000000..e49dfc9
--- /dev/null
+++ b/procyon/source/bs/exit.c
@@ -0,0 +1,15 @@
+#include <acm/bs.h>
+
+#include <GLFW/glfw3.h>
+#include <stdlib.h>
+
+void acm_exit(acm_stat const _stat) {
+ int const cstat = _stat == acm_stat_ok ? EXIT_SUCCESS : EXIT_FAILURE;
+ free((void *)acm_dat.savloc);
+ if (acm_dat.gfxisinit) {
+ glfwDestroyWindow(acm_dat.win);
+ glfwTerminate();
+ }
+ acm_log("Done (%X)\n",cstat);
+ exit(cstat);
+}
diff --git a/procyon/source/bs/init.c b/procyon/source/bs/init.c
new file mode 100644
index 0000000..1f4c57e
--- /dev/null
+++ b/procyon/source/bs/init.c
@@ -0,0 +1,51 @@
+#include <acm/gfx.h>
+
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <zap/mem.h>
+
+sig_atomic_t volatile acm_gotintr;
+
+typeof (acm_dat) acm_dat;
+
+static char * acm_getsavloc(void) {
+ char const * const hmdir = getenv("HOME");
+ if (hmdir == nullptr) {
+ fprintf(stderr,"Unable to get home directory (HOME not set)\n");
+ acm_exit(acm_stat_err);
+ }
+ char const * const savfilnm = ".procyon-save";
+ zap_sz const hmdirlen = zap_strlen(hmdir);
+ zap_sz const savfilnmlen = zap_strlen(savfilnm);
+ zap_sz const savloclen = hmdirlen + 0x1u + savfilnmlen;
+ char * savloc = malloc(savloclen + 0x1u);
+ if (savloc == nullptr) {
+ fprintf(stderr,"Unable allocate memory\n");
+ acm_exit(acm_stat_err);
+ }
+ zap_memcp(hmdir,hmdirlen,savloc);
+ savloc[hmdirlen] = '/';
+ zap_memcp(savfilnm,savfilnmlen,savloc + hmdirlen + 0x1u);
+ savloc[savloclen] = 0x0u;
+ return savloc;
+}
+
+static void acm_intrhandl(int const _sig) {
+ signal(_sig,acm_intrhandl); /* Ignore the return value. */
+ acm_gotintr = 0x1;
+}
+
+void acm_init(void) {
+ acm_gotintr = 0x0;
+ acm_dat.gfxisinit = false;
+ acm_dat.win = nullptr;
+ acm_log("Initialising data\n");
+ acm_dat.savloc = acm_getsavloc();
+ acm_log("Initialising signal handlers\n");
+ if (signal(SIGINT,acm_intrhandl) == SIG_ERR) {
+ fprintf(stderr,"Unable to set SIGINT handler\n");
+ acm_exit(acm_stat_err);
+ }
+ acm_initgfx();
+}
diff --git a/procyon/source/bs/sav.c b/procyon/source/bs/sav.c
new file mode 100644
index 0000000..1e0b226
--- /dev/null
+++ b/procyon/source/bs/sav.c
@@ -0,0 +1,35 @@
+#include <acm/bs.h>
+
+#include <flux.h>
+#include <stdio.h>
+
+void acm_sav(acm_pldat const * const _pldat) {
+ acm_log("Saving\n");
+ flux_err fluxerr;
+ flux_fil savfil;
+ fluxerr = flux_mkfil(&savfil,acm_dat.savloc,0644u);
+ if (fluxerr) {
+ if (fluxerr != flux_err_exist) {
+ fprintf(stderr,"Unable to create save file (\"%s\"): %s\n",acm_dat.savloc,flux_errstr(fluxerr));
+ acm_exit(acm_stat_err);
+ }
+ acm_log("Save file already exists, overwritting\n");
+ fluxerr = flux_op(&savfil,acm_dat.savloc,flux_md_wr,flux_disc);
+ if (fluxerr) {
+ fprintf(stderr,"Unable to open save file: %s\n",flux_errstr(fluxerr));
+ acm_exit(acm_stat_err);
+ }
+ }
+ {
+ uint_least64_t const savver = acm_savver;
+ fluxerr = flux_wr(savfil,&savver,sizeof (savver));
+ }
+ if (!fluxerr) {
+ fluxerr = flux_wr(savfil,_pldat,sizeof (*_pldat));
+ }
+ if (fluxerr) {
+ fprintf(stderr,"Unable to write to save file: %s\n",flux_errstr(fluxerr));
+ acm_exit(acm_stat_err);
+ }
+ flux_cl(savfil);
+}
diff --git a/procyon/source/bs/shipnm.c b/procyon/source/bs/shipnm.c
new file mode 100644
index 0000000..dcbd6fb
--- /dev/null
+++ b/procyon/source/bs/shipnm.c
@@ -0,0 +1,70 @@
+#include <acm/bs.h>
+
+char const * acm_shipnm(acm_ship const _ship) {
+ switch (_ship) {
+ case acm_ship_add:
+ return "Adder";
+ case acm_ship_ana:
+ return "Anaconda";
+ case acm_ship_asp:
+ return "Asp";
+ case acm_ship_boa:
+ return "Boa";
+ case acm_ship_cob:
+ return "Cobra";
+ case acm_ship_con:
+ return "Constrictor";
+ case acm_ship_cou:
+ return "Courier";
+ case acm_ship_cyg:
+ return "Cygnus";
+ case acm_ship_dov:
+ return "Dove";
+ case acm_ship_eag:
+ return "Eagle";
+ case acm_ship_falc:
+ return "Falcon";
+ case acm_ship_fer:
+ return "Fer-de-lance";
+ case acm_ship_frei:
+ return "Freighter";
+ case acm_ship_geck:
+ return "Gecko";
+ case acm_ship_haul:
+ return "Hauler";
+ case acm_ship_hawk:
+ return "Hawk";
+ case acm_ship_keel:
+ return "Keelback";
+ case acm_ship_kes:
+ return "Kestral";
+ case acm_ship_krait:
+ return "Krait";
+ case acm_ship_lift:
+ return "Lifter";
+ case acm_ship_lion:
+ return "Lion";
+ case acm_ship_mamba:
+ return "Mamba";
+ case acm_ship_moray:
+ return "Moray";
+ case acm_ship_osp:
+ return "Osprey";
+ case acm_ship_pan:
+ return "Panther";
+ case acm_ship_puma:
+ return "Puma";
+ case acm_ship_py:
+ return "Python";
+ case acm_ship_shut:
+ return "Shuttle";
+ case acm_ship_side:
+ return "Sidewinder";
+ case acm_ship_tran:
+ return "Transporter";
+ case acm_ship_vip:
+ return "Viper";
+ case acm_ship_vult:
+ return "Vulture";
+ }
+}
diff --git a/procyon/source/gfx/initgfx.c b/procyon/source/gfx/initgfx.c
new file mode 100644
index 0000000..d60e393
--- /dev/null
+++ b/procyon/source/gfx/initgfx.c
@@ -0,0 +1,22 @@
+#include <acm/gfx.h>
+
+#include <GLFW/glfw3.h>
+
+void acm_initgfx(void) {
+ acm_log("Initialising graphics\n");
+ if (!glfwInit()) {
+ fprintf(stderr,"Unable to initialise GLFW\n");
+ acm_exit(acm_stat_err);
+ }
+ GLFWwindow * win = glfwCreateWindow(0x300,0x200,"Procyon",nullptr,nullptr);
+ if (win == nullptr) {
+ fprintf(stderr,"Unable to open window\n");
+ goto abrt;
+ }
+ glfwMakeContextCurrent(win);
+ acm_dat.win = win;
+ return;
+abrt:;
+ glfwTerminate();
+ acm_exit(acm_stat_err);
+}
diff --git a/procyon/source/main.c b/procyon/source/main.c
new file mode 100644
index 0000000..84168ba
--- /dev/null
+++ b/procyon/source/main.c
@@ -0,0 +1,24 @@
+#include <acm/bs.h>
+
+#include <flux.h>
+#include <inttypes.h>
+#include <stdio.h>
+
+int main(int const argc,[[maybe_unused]] char const * const * const argv) {
+ acm_dat.gfxisinit = false;
+ if (argc > 0x1) {
+ fprintf(stderr,"Ignoring terminal options\n");
+ }
+ printf("Procyon, %" PRIxLEAST64 " - Copyright 2022 Gabriel Jensen.\n",acm_ver);
+ acm_init();
+ acm_cont(&acm_dat.pldat);
+ acm_log("Ready\n");
+ while (!glfwWindowShouldClose(acm_dat.win)) {
+ if (acm_gotintr) {
+ fprintf(stderr,"Got interrupt, stopping\n");
+ glfwSetWindowShouldClose(acm_dat.win,0x1);
+ }
+ }
+ acm_sav(&acm_dat.pldat);
+ acm_exit(acm_stat_ok);
+}