summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.txt11
-rw-r--r--bowshock/GNUmakefile1
-rw-r--r--bowshock/include/bow/bs.h10
-rw-r--r--bowshock/include/bow/sav.h7
-rw-r--r--bowshock/source/bs/gendat.c6
-rw-r--r--bowshock/source/bs/init.c136
-rw-r--r--bowshock/source/bs/initdat.c33
-rw-r--r--bowshock/source/bs/loop.c4
-rw-r--r--bowshock/source/bs/quit.c2
-rw-r--r--bowshock/source/gfx/initgfx.c4
-rw-r--r--bowshock/source/lgc/grav.c2
-rw-r--r--bowshock/source/sav/cont.c64
-rw-r--r--bowshock/source/sav/sav.c17
13 files changed, 245 insertions, 52 deletions
diff --git a/CHANGELOG.txt b/CHANGELOG.txt
index 502b2ec..6f920f2 100644
--- a/CHANGELOG.txt
+++ b/CHANGELOG.txt
@@ -1,3 +1,14 @@
+# 5
+
+* Update save data format;
+* Add continue routine;
+* Read command line parameters;
+* Set SIGINT handler;
+* Print quote on start;
+* Add log function for errors;
+* Update flux usage;
+* Optimise grav;
+
# 4
* Add simple save routine;
diff --git a/bowshock/GNUmakefile b/bowshock/GNUmakefile
index eaf09d3..e6b4a9e 100644
--- a/bowshock/GNUmakefile
+++ b/bowshock/GNUmakefile
@@ -48,6 +48,7 @@ OBJS := \
source/info/shipmass.o \
source/lgc/grav.o \
source/lgc/mv.o \
+ source/sav/cont.o \
source/sav/sav.o
BIN := bowshock.elf
diff --git a/bowshock/include/bow/bs.h b/bowshock/include/bow/bs.h
index b3514da..4836713 100644
--- a/bowshock/include/bow/bs.h
+++ b/bowshock/include/bow/bs.h
@@ -3,6 +3,7 @@
#define constexpr static const
+#include <signal.h>
#include <stdio.h>
#include <zap/bs.h>
@@ -14,6 +15,8 @@
#define bow_log(msg,...) bow_rawlog("\x1B[1m%s\x1B[0m: " msg "\n",bow_sym __VA_OPT__(,) __VA_ARGS__)
+#define bow_logerr(msg,...) bow_log("\x1B[38;5;197m[ERROR]\x1B[0m " msg __VA_OPT__(,) __VA_ARGS__)
+
#if bow_dbg
#define bow_dbglog(msg,...) bow_log(msg __VA_OPT__ (,) __VA_ARGS__)
@@ -24,7 +27,7 @@
#define bow_logxyz(xyz) ((void)0x0u)
#endif
-constexpr zap_i04 bow_ver = 0x4u;
+constexpr zap_i04 bow_ver = 0x5u;
constexpr zap_sz bow_cmdrnmlen = 0xEu;
@@ -98,7 +101,7 @@ typedef struct {
bow_xyz vel;
double mass;
union {
- bow_world worldtyp;
+ bow_world worldtyp;
bow_ship shiptyp;
bow_star startyp;
bow_station stationtyp;
@@ -108,9 +111,12 @@ typedef struct {
typedef struct {
char nm[bow_cmdrnmlen + 0x1u];
zap_i04 sysid;
+ zap_i04 tm; // 1728th of a second
bow_obj ship;
} bow_playdat;
+extern sig_atomic_t volatile bow_gotintr;
+
void bow_gendat( bow_playdat * playdat);
void bow_initdat(bow_playdat * playdat,char const * * savpth);
diff --git a/bowshock/include/bow/sav.h b/bowshock/include/bow/sav.h
index be5978d..23df6f0 100644
--- a/bowshock/include/bow/sav.h
+++ b/bowshock/include/bow/sav.h
@@ -5,13 +5,16 @@
#include <zap/bs.h>
-constexpr zap_i04 bow_savfmtver = 0x3u;
+constexpr zap_i04 bow_savfmtver = 0x4u;
typedef struct {
zap_i04 fmtver;
char cmdrnm[bow_cmdrnmlen];
zap_i04 sysid;
- bow_obj ship;
+ zap_i04 tm;
+ bow_xyz shippos;
+ bow_xyz shiprot;
+ bow_xyz shipvel;
} bow_savdat;
void bow_cont(char const * fil,bow_playdat * dat);
diff --git a/bowshock/source/bs/gendat.c b/bowshock/source/bs/gendat.c
index 95516c6..47c131f 100644
--- a/bowshock/source/bs/gendat.c
+++ b/bowshock/source/bs/gendat.c
@@ -2,7 +2,6 @@
#include <bow/info.h>
-#include <flux.h>
#include <zap/mem.h>
#include <string.h>
@@ -10,7 +9,8 @@
void bow_gendat(bow_playdat * const playdatptr) {
bow_log("generating data");
bow_playdat playdat;
- memcpy(&playdat,playdatptr,sizeof (playdat));
+ zap_cp(&playdat,playdatptr,sizeof (playdat));
+ playdat.ship.typ = bow_objtyp_ship;
playdat.ship.mass = bow_shipmass(playdat.ship.shiptyp);
- memcpy(playdatptr,&playdat,sizeof (playdat));
+ zap_cp(playdatptr,&playdat,sizeof (playdat));
}
diff --git a/bowshock/source/bs/init.c b/bowshock/source/bs/init.c
index 64c7d85..6ccf132 100644
--- a/bowshock/source/bs/init.c
+++ b/bowshock/source/bs/init.c
@@ -3,24 +3,144 @@
#include <bow/gfx.h>
#include <bow/sav.h>
-#include <flux.h>
#include <inttypes.h>
+#include <signal.h>
#include <stdlib.h>
+#include <time.h>
+#include <zap/str.h>
bow_stat bow_loop(bow_playdat * playdat);
-[[noreturn]] void bow_init(void) {
+sig_atomic_t volatile bow_gotintr;
+
+static void bow_intrhandl(int const sig) {
+ signal(sig,bow_intrhandl); // Ignore the return value.
+ bow_gotintr = 0x1;
+}
+
+int main(int const argc,char const * const * argv) {
+ char const * const prognm = argv[0x0u];
+ if (argc > 0x1) {
+ char const * const * const stop = argv + (zap_sz)argc;
+ while (argv++ != stop) {
+ char const * const arg = *argv;
+ if (zap_streq(arg,"--help")) {
+ bow_rawlog(
+ "\n"
+ "bowshock %" PRIXLEAST64 "\n"
+ "Copyright 2022-2023 Gabriel Jensen\n"
+ "\n"
+ "Usage: %s [savefile]\n"
+ "\n",
+ bow_ver,prognm);
+ return EXIT_SUCCESS;
+ }
+ bow_logerr("invalid parameter \"%s\"",arg);
+ }
+ }
+ srand((unsigned int)time(nullptr));
+ {
+ zap_i8 const quotid = (unsigned int)rand() % 0x14u;
+ char const * quot;
+ char const * src;
+ switch (quotid) {
+ default:
+ bow_logerr("invalid quote identifier (%" PRIXLEAST8 ")",quotid);
+ [[fallthrough]];
+ case 0x0u:
+ quot = "You gotta be heaven to see heaven.";
+ src = "Jim Carrey";
+ break;
+ case 0x1u:
+ quot = "Though it's the end of the world, don't blame yourself, now.";
+ src = "Porter Robinson";
+ break;
+ case 0x2u:
+ quot = "The future will be better tomorrow.";
+ src = "Dan Quayle";
+ break;
+ case 0x3u:
+ quot = "Sir, an equation has no meaning for me unless it expresses a thought of god.";
+ src = "Srinivasa Ramanujan Aiyangar";
+ break;
+ case 0x4u:
+ quot = "Amīcus Platō amīcus Aristotelēs magis amīca vēritās.";
+ src = "Isaac Newton";
+ break;
+ case 0x5u:
+ quot = "I have studied these things \u2013 you have not.";
+ src = "Isaac Newton";
+ break;
+ case 0x6u:
+ quot = "La construction d'une machine propre à exprimer tous les sons de nos paroles, avec toutes les articulations, serait sans doute une décourverte bien importante.\n... La chose ne me paraît pas impossible.";
+ src = "Leonhard Euler";
+ break;
+ case 0x7u:
+ quot = "In mathematics, you don't understand things, you just get used to them.";
+ src = "John von Neumann";
+ break;
+ case 0x8u:
+ quot = "Being a language, mathematics may be used not only to inform, but also \u2013 among other things \u2013 to seduce.";
+ src = "Benoît B. Mandelbrot";
+ break;
+ case 0x9u:
+ quot = "The real question is not whether machines think, but whether men do.";
+ src = "Burrhus Frederic Skinner";
+ break;
+ case 0xAu:
+ quot = "Those who are not shocked when they first come across quantum theory cannot possibly have understood it.";
+ src = "Niels Henrik David Bohr";
+ case 0xBu:
+ quot = "Every sentence I utter must be understood not as an affirmation, but as a question.";
+ src = "Niels Henrik David Bohr";
+ break;
+ case 0xCu:
+ quot = "We will now discuss in a little more detail the struggle for existence.";
+ src = "Charles Robert Darwin";
+ break;
+ case 0xDu:
+ quot = "不患人之不己知,患不知人也。";
+ src = "孔丘";
+ break;
+ case 0xEu:
+ quot = "We don't know a millionth of one percent about anything.";
+ src = "Thomas Alva Edison";
+ break;
+ case 0xFu:
+ quot = "My goal is simple. It is a complete understanding of the universe, why it is as it is, and why it exists at all.";
+ src = "Stephen William Hawking";
+ break;
+ case 0x10u:
+ quot = "Equipped with his five senses, man explores the universe around him and calls the adventure Science.";
+ src = "Edwin Powell Hubble";
+ break;
+ case 0x11u:
+ quot = "I can say this. I believe that the human mind, or even the mind of a cat, is more interesting in its complexity than an entire galaxy if it is devoid of life.";
+ src = "Martin Gardner";
+ break;
+ case 0x12u:
+ quot = "I'm always right. This time I'm just more right than usual.";
+ src = "Linus Benedict Torvalds";
+ break;
+ case 0x13u:
+ quot = "I'm an instant star. Just add water and stir.";
+ src = "David Robert Jones";
+ break;
+ }
+ bow_rawlog("\n%s\n\u2014 %s\n\n",quot,src);
+ }
+ bow_rawlog("\x1B[0m\x1B[1mBowshock\x1B[0m %" PRIXLEAST64 " \u2013 Copyright 2022\u20102023, \x1B[1mGabriel Jensen\x1B[0m.\n\n",bow_ver);
+ bow_log("initialising");
+ bow_gotintr = 0x0;
+ if (signal(SIGINT,bow_intrhandl) == SIG_ERR) {
+ bow_log("unable to set signal handler");
+ bow_quit(bow_stat_err);
+ }
char const * savpth;
bow_playdat playdat;
- bow_rawlog("\x1B[0m\x1B[1mBowshock\x1B[0m %" PRIX64 " \u2013 Copyright 2022\u20102023, \x1B[1mGabriel Jensen\x1B[0m.\n\n",bow_ver);
- bow_log("initialising");
bow_initdat(&playdat,&savpth);
bow_initgfx();
bow_loop(&playdat);
bow_sav(savpth,&playdat);
bow_quit(bow_stat_ok);
}
-
-int main(void) {
- bow_init();
-}
diff --git a/bowshock/source/bs/initdat.c b/bowshock/source/bs/initdat.c
index 0bba930..258949c 100644
--- a/bowshock/source/bs/initdat.c
+++ b/bowshock/source/bs/initdat.c
@@ -1,17 +1,16 @@
#define bow_sym "initdat"
-#include <bow/bs.h>
+#include <bow/sav.h>
-#include <flux.h>
+#include <flux/stats.h>
#include <stdlib.h>
-#include <string.h>
#include <zap/mem.h>
#include <zap/str.h>
#define bow_setstr(ptr,len,str) ((void)(ptr = str,len = sizeof (str)))
static char * bow_getsavpth(void) {
- char const * hmdir = getenv("HOME");
+ char const * hmdir = flux_hmdir();
zap_sz hmdirlen;
char const * filnm;
zap_sz filnmlen;
@@ -27,10 +26,10 @@ static char * bow_getsavpth(void) {
bow_log("unable to allocate memory");
bow_quit(bow_stat_err);
}
- memcpy(pth,hmdir,hmdirlen);
+ zap_cp(pth,hmdir,hmdirlen);
pth += hmdirlen;
*pth++ = '/';
- memcpy(pth,filnm,filnmlen);
+ zap_cp(pth,filnm,filnmlen);
pth += filnmlen;
*pth++ = '\x0';
pth -= pthsz;
@@ -40,25 +39,9 @@ static char * bow_getsavpth(void) {
void bow_initdat(bow_playdat * const playdatptr,char const * * const savpthptr) {
bow_log("initialising data");
char const * savpth = bow_getsavpth();
- bow_playdat playdat = {
- .nm = "Caelum\x0\x0\x0\x0\x0\x0\x0\x0\x0",
- .sysid = 0x0u,
- .ship = {
- .typ = bow_objtyp_ship,
- .pos = {
- .x = 0x0.0p0,
- .y = 0x0.0p0,
- .z = 0x0.0p0,
- },
- .vel = {
- .x = 0x0.0p0,
- .y = 0x0.0p0,
- .z = 0x0.0p0,
- },
- .shiptyp = bow_ship_aq,
- },
- };
+ bow_playdat playdat;
+ bow_cont(savpth,&playdat);
bow_gendat(&playdat);
*savpthptr = savpth;
- memcpy(playdatptr,&playdat,sizeof (playdat));
+ zap_cp(playdatptr,&playdat,sizeof (playdat));
}
diff --git a/bowshock/source/bs/loop.c b/bowshock/source/bs/loop.c
index 1ca5238..b9506a1 100644
--- a/bowshock/source/bs/loop.c
+++ b/bowshock/source/bs/loop.c
@@ -39,6 +39,10 @@ bow_stat bow_loop(bow_playdat * playdatptr) {
star1.vel.x = -sqrt(bow_gravconst*star0.mass/0x100.0p0)/0x2.0p0; // orbital speed
bool stop = false;
for (zap_i04 i = 0x0u;!stop;) {
+ if (bow_gotintr) {
+ bow_log("got interrupt");
+ glfwSetWindowShouldClose(bow_gfxdat.win,GLFW_TRUE);
+ }
if (glfwWindowShouldClose(bow_gfxdat.win)) break;
// Calculate gravitations:
bow_grav(&star0,&star1);
diff --git a/bowshock/source/bs/quit.c b/bowshock/source/bs/quit.c
index 9443ac3..bb28b1f 100644
--- a/bowshock/source/bs/quit.c
+++ b/bowshock/source/bs/quit.c
@@ -4,8 +4,6 @@
#include <bow/info.h>
#include <GLFW/glfw3.h>
-#include <flux.h>
-#include <stdio.h>
#include <stdlib.h>
void bow_quit(bow_stat const stat) {
diff --git a/bowshock/source/gfx/initgfx.c b/bowshock/source/gfx/initgfx.c
index a2bcfb0..23576e5 100644
--- a/bowshock/source/gfx/initgfx.c
+++ b/bowshock/source/gfx/initgfx.c
@@ -9,14 +9,14 @@ typeof (bow_gfxdat) bow_gfxdat;
void bow_initgfx(void) {
bow_log("initialising graphics");
if (!glfwInit()) {
- bow_log("unable to initialise glfw");
+ bow_logerr("unable to initialise glfw");
bow_quit(bow_stat_err);
}
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR,0x3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR,0x0);
GLFWwindow * win = glfwCreateWindow(0x300,0x200,"Bowshock",nullptr,nullptr);
if (win == nullptr) {
- bow_log("unable to open window");
+ bow_logerr("unable to open window");
bow_quit(bow_stat_err);
}
glfwMakeContextCurrent(win);
diff --git a/bowshock/source/lgc/grav.c b/bowshock/source/lgc/grav.c
index 0542b7e..c32b418 100644
--- a/bowshock/source/lgc/grav.c
+++ b/bowshock/source/lgc/grav.c
@@ -13,7 +13,7 @@ void bow_grav(bow_obj * objptr,bow_obj const * parptr) {
double const distx = par.pos.x-obj.pos.x;
double const disty = par.pos.y-obj.pos.y;
double const distz = par.pos.z-obj.pos.z;
- double const dist = sqrt(pow(distx,0x2.0p0)+pow(disty,0x2.0p0)+pow(distz,0x2.0p0));
+ double const dist = sqrt(distx*distx+disty*disty+distz*distz);
double const acc = bow_gravconst*par.mass/pow(dist,2.0);
double const angy = atan2(disty,distx);
double const angz = atan2(distz,distx);
diff --git a/bowshock/source/sav/cont.c b/bowshock/source/sav/cont.c
new file mode 100644
index 0000000..3d201d9
--- /dev/null
+++ b/bowshock/source/sav/cont.c
@@ -0,0 +1,64 @@
+#define bow_sym "sav"
+
+#include <bow/sav.h>
+
+#include <flux/io.h>
+#include <zap/mem.h>
+
+void bow_cont(char const * const pth,bow_playdat * const playdatptr) {
+ bow_log("loading save file at \"%s\"",pth);
+ flux_fil * fil;
+ flux_err err = flux_op(&fil,pth,flux_md_rd,flux_keep);
+ if (err != flux_err_ok) {
+ bow_logerr("unable to open save file \"%s\"",pth);
+ goto new;
+ }
+ bow_savdat dat;
+ err = flux_rd(&dat,fil,sizeof (dat),nullptr);
+ if (err != flux_err_ok) {
+ flux_cl(fil);
+ if (err == flux_err_eof) {
+ bow_logerr("corrupt save file at \"%s\"",pth);
+ }
+ else bow_logerr("unable to read file at \"%s\"",pth);
+ goto new;
+ }
+ flux_cl(fil);
+ if (dat.fmtver != bow_savfmtver) {
+ bow_logerr("invalid format of save file at \"%s\"",pth);
+ goto new;
+ }
+ bow_playdat playdat = {
+ .sysid = dat.sysid,
+ .tm = dat.tm,
+ .ship.pos = dat.shippos,
+ .ship.rot = dat.shiprot,
+ .ship.vel = dat.shipvel,
+ };
+ zap_cp(playdat.nm,dat.cmdrnm,bow_cmdrnmlen);
+ playdat.nm[bow_cmdrnmlen] = '\x0';
+ bow_log("welcome back commander %s",playdat.nm);
+ goto ret;
+new:
+ playdat = (bow_playdat) {
+ .nm = "Caelum\x0\x0\x0\x0\x0\x0\x0\x0\x0",
+ .sysid = 0x0u,
+ .tm = 0x1E187E00000u, // 256 julian years after the Unix Epoch.
+ .ship = {
+ .pos = {
+ .x = 0x0.0p0,
+ .y = 0x0.0p0,
+ .z = 0x0.0p0,
+ },
+ .vel = {
+ .x = 0x0.0p0,
+ .y = 0x0.0p0,
+ .z = 0x0.0p0,
+ },
+ .shiptyp = bow_ship_aq,
+ },
+ };
+ bow_log("generated commander %s",playdat.nm);
+ret:
+ zap_cp(playdatptr,&playdat,sizeof (playdat));
+}
diff --git a/bowshock/source/sav/sav.c b/bowshock/source/sav/sav.c
index dc32399..a59621d 100644
--- a/bowshock/source/sav/sav.c
+++ b/bowshock/source/sav/sav.c
@@ -2,30 +2,33 @@
#include <bow/sav.h>
-#include <flux.h>
+#include <flux/io.h>
#include <zap/mem.h>
void bow_sav(char const * const pth,bow_playdat const * const playdatptr) {
bow_log("saving commander %s at \"%s\"",playdatptr->nm,pth);
- flux_fil fil;
+ flux_fil * fil;
flux_err err = flux_mkfil(&fil,pth,0644);
if (err != flux_err_ok) {
if (err != flux_err_exist) {
- bow_log("unable to open save file \"%s\"",pth);
+ bow_logerr("unable to open save file \"%s\"",pth);
bow_quit(bow_stat_err);
}
err = flux_op(&fil,pth,flux_md_wr,flux_disc);
if (err != flux_err_ok) {
- bow_log("unable to create save file \"%s\"",pth);
+ bow_logerr("unable to create save file \"%s\"",pth);
bow_quit(bow_stat_err);
}
}
bow_playdat playdat;
zap_cp(&playdat,playdatptr,sizeof (playdat));
bow_savdat dat = {
- .fmtver = bow_savfmtver,
- .sysid = playdat.sysid,
- .ship = playdat.ship,
+ .fmtver = bow_savfmtver,
+ .sysid = playdat.sysid,
+ .tm = playdat.tm,
+ .shippos = playdat.ship.pos,
+ .shiprot = playdat.ship.rot,
+ .shipvel = playdat.ship.vel,
};
zap_cp(dat.cmdrnm,playdat.nm,bow_cmdrnmlen);
flux_wr(fil,&dat,sizeof (dat));