diff options
-rw-r--r-- | CHANGELOG.txt | 11 | ||||
-rw-r--r-- | bowshock/GNUmakefile | 1 | ||||
-rw-r--r-- | bowshock/include/bow/bs.h | 10 | ||||
-rw-r--r-- | bowshock/include/bow/sav.h | 7 | ||||
-rw-r--r-- | bowshock/source/bs/gendat.c | 6 | ||||
-rw-r--r-- | bowshock/source/bs/init.c | 136 | ||||
-rw-r--r-- | bowshock/source/bs/initdat.c | 33 | ||||
-rw-r--r-- | bowshock/source/bs/loop.c | 4 | ||||
-rw-r--r-- | bowshock/source/bs/quit.c | 2 | ||||
-rw-r--r-- | bowshock/source/gfx/initgfx.c | 4 | ||||
-rw-r--r-- | bowshock/source/lgc/grav.c | 2 | ||||
-rw-r--r-- | bowshock/source/sav/cont.c | 64 | ||||
-rw-r--r-- | bowshock/source/sav/sav.c | 17 |
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)); |