diff options
-rw-r--r-- | CHANGELOG.txt | 14 | ||||
-rw-r--r-- | CREDITS.txt | 1 | ||||
-rw-r--r-- | bowshock/GNUmakefile | 56 | ||||
-rw-r--r-- | bowshock/include/bow/bs.h | 63 | ||||
-rw-r--r-- | bowshock/include/bow/gfx.h | 5 | ||||
-rw-r--r-- | bowshock/include/bow/info.h | 7 | ||||
-rw-r--r-- | bowshock/include/bow/lgc.h | 20 | ||||
-rw-r--r-- | bowshock/include/bow/sav.h | 49 | ||||
-rw-r--r-- | bowshock/source/bs/init.c | 24 | ||||
-rw-r--r-- | bowshock/source/bs/initdat.c | 2 | ||||
-rw-r--r-- | bowshock/source/bs/loop.c | 104 | ||||
-rw-r--r-- | bowshock/source/bs/quit.c | 3 | ||||
-rw-r--r-- | bowshock/source/gfx/initgfx.c | 2 | ||||
-rw-r--r-- | bowshock/source/info/objtypstr.c | 35 | ||||
-rw-r--r-- | bowshock/source/lgc/addobj.c | 20 | ||||
-rw-r--r-- | bowshock/source/lgc/freeobjs.c | 19 | ||||
-rw-r--r-- | bowshock/source/lgc/grav.c | 57 | ||||
-rw-r--r-- | bowshock/source/lgc/mv.c | 14 | ||||
-rw-r--r-- | bowshock/source/sav/cont.c | 74 | ||||
-rw-r--r-- | bowshock/source/sav/sav.c | 44 |
20 files changed, 448 insertions, 165 deletions
diff --git a/CHANGELOG.txt b/CHANGELOG.txt index a637ae1..c866da4 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,3 +1,17 @@ +# 0.7 + +* Make window fullscreen; +* Update object data (store both positional and rotational velocity); +* Update save format; +* Add credits file; +* Add more quotes; +* Standardise and optimise save format; +* Perform checks on save file; +* Fix bad module name; +* Use 'pragma once'; +* (Temporarily) define some constants as macros instead of as compile-time variables; +* Create object system; + # 0.6 * Update versioning: Use major.minor; diff --git a/CREDITS.txt b/CREDITS.txt new file mode 100644 index 0000000..c5c2214 --- /dev/null +++ b/CREDITS.txt @@ -0,0 +1 @@ +Gabriel Jensen diff --git a/bowshock/GNUmakefile b/bowshock/GNUmakefile index f68db40..ce22f4a 100644 --- a/bowshock/GNUmakefile +++ b/bowshock/GNUmakefile @@ -1,35 +1,42 @@ -LD := $(CC) +LD = $(CC) CFLAGS := \ -Iinclude \ - -Ofast \ -Wall \ -Wextra \ -Wpedantic \ + -Wno-attributes \ -Wno-gnu-folding-constant \ -Wno-gnu-empty-initializer \ -Wno-gnu-zero-variadic-macro-arguments \ -g \ -pipe \ - -std=c2x + -std=gnu2x ifeq "$(c2xcompat)" "true" CFLAGS := \ - $(CFLAGS) \ - -Dbool="_Bool" \ - -Dfalse="((_Bool)0x0u)" \ - -Dnullptr="((void *)0x0u)" \ - -Dstatic_assert="_Static_assert" \ - -Dthread_safe="_Thread_safe" \ - -Dtypeof="__typeof__" \ - -Dtrue="((_Bool)0x1u)" + $(CFLAGS) \ + -D"bool=_Bool" \ + -D"false=((_Bool)+0x0u)" \ + -D"nullptr=((void *)0x0u)" \ + -D"static_assert=_Static_assert" \ + -D"thread_safe=_Thread_safe" \ + -D"typeof=__typeof__" \ + -D"true=((_Bool)+0x1u)" \ + -D"unreachable()=__builtin_unreachable()" endif ifeq "$(debug)" "true" CFLAGS := \ - $(CFLAGS) \ - -Dbow_dbg=true \ + $(CFLAGS) \ + -D"bow_dbg=true" \ -Og +else +CFLAGS := \ + $(CFLAGS) \ + -D"_FORTIFY_SOURCE=2" \ + -DNDEBUG \ + -Ofast endif LDLIBS := \ @@ -41,16 +48,19 @@ LDLIBS := \ -lzap OBJS := \ - source/bs/gendat.o \ - source/bs/init.o \ - source/bs/initdat.o \ - source/bs/loop.o \ - source/bs/quit.o \ - source/gfx/initgfx.o \ - source/info/shipmass.o \ - source/lgc/grav.o \ - source/lgc/mv.o \ - source/sav/cont.o \ + source/bs/gendat.o \ + source/bs/init.o \ + source/bs/initdat.o \ + source/bs/loop.o \ + source/bs/quit.o \ + source/gfx/initgfx.o \ + source/info/objtypstr.o \ + source/info/shipmass.o \ + source/lgc/addobj.o \ + source/lgc/freeobjs.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 8af25b9..46cc4ec 100644 --- a/bowshock/include/bow/bs.h +++ b/bowshock/include/bow/bs.h @@ -1,12 +1,33 @@ -#if !defined(bow_hdr_bs) -#define bow_hdr_bs +#pragma once #define constexpr static const +#define _POSIX_C_SOURCE 200112l + +#if __STDC_VERSION__ <= 201710 +#error ISO/IEC 9899:2023 is required! +#endif + +//#if __STDC_IEC_60559_BFP__ < 202311 +//#error ISO/IEC 60559:2020 is required! +//#endif + +#pragma STDC FP_CONTRACT ON + +#include <limits.h> #include <signal.h> #include <stdio.h> #include <zap/bs.h> +static_assert(CHAR_BIT == 0x8,"Bytes must contain exactly eight bits."); + +static_assert(sizeof (zap_i01) == 0x2u); +static_assert(sizeof (zap_i02) == 0x4u); +static_assert(sizeof (zap_i04) == 0x8u); + +static_assert(sizeof (float) == 0x4u); +static_assert(sizeof (double) == 0x8u); + #if !defined(bow_sym) #error symbol not defined #endif @@ -28,9 +49,9 @@ #endif constexpr zap_i04 bow_vermaj = 0x0u; -constexpr zap_i04 bow_vermin = 0x6u; +constexpr zap_i04 bow_vermin = 0x7u; -constexpr zap_sz bow_cmdrnmlen = 0xEu; +#define bow_cmdrnmlen ((zap_sz)0xEu) typedef enum { bow_stat_ok = 0x0u, @@ -48,13 +69,13 @@ typedef enum { } bow_objtyp; typedef enum { - bow_world_amm, // ammonium world - bow_world_gas, // gas giant - bow_world_ice, // icy world - bow_world_rck, // rocky world - bow_world_lav, // lava world - bow_world_wat, // water world -} bow_world; + bow_wrld_amm, // ammonium world + bow_wrld_gas, // gas giant + bow_wrld_ice, // icy world + bow_wrld_rck, // rocky world + bow_wrld_lav, // lava world + bow_wrld_wat, // water world +} bow_wrld; typedef enum { bow_ship_aq, // aquila @@ -95,22 +116,30 @@ typedef struct { double z; } bow_xyz; -typedef struct { +typedef struct bow_priv_obj bow_obj; + +struct bow_priv_obj { bow_objtyp typ; bow_xyz pos; bow_xyz rot; // radians - bow_xyz vel; + bow_xyz posvel; + bow_xyz rotvel; double mass; union { - bow_world worldtyp; + bow_wrld wrldtyp; bow_ship shiptyp; bow_star startyp; bow_station stationtyp; }; -} bow_obj; + bow_obj * next; +}; typedef struct { - char nm[bow_cmdrnmlen + 0x1u]; + bow_obj * objs; +} bow_objroot; + +typedef struct { + char nm[bow_cmdrnmlen+0x1u]; zap_i04 tm; zap_i04 sysid; bow_obj ship; @@ -122,5 +151,3 @@ void bow_gendat( bow_playdat * playdat); void bow_initdat(bow_playdat * playdat,char const * * savpth); [[noreturn]] void bow_quit(bow_stat stat); - -#endif diff --git a/bowshock/include/bow/gfx.h b/bowshock/include/bow/gfx.h index 5aa8298..d6b858f 100644 --- a/bowshock/include/bow/gfx.h +++ b/bowshock/include/bow/gfx.h @@ -1,5 +1,4 @@ -#if !defined(bow_hdr_gfx) -#define bow_hdr_gfx +#pragma once #include <bow/bs.h> @@ -12,5 +11,3 @@ extern struct { } bow_gfxdat; void bow_initgfx(void); - -#endif diff --git a/bowshock/include/bow/info.h b/bowshock/include/bow/info.h index db7e152..09da580 100644 --- a/bowshock/include/bow/info.h +++ b/bowshock/include/bow/info.h @@ -1,8 +1,7 @@ -#if !defined(bow_hdr_info) -#define bow_hdr_info +#pragma once #include <bow/bs.h> -[[unsequenced]] double bow_shipmass(bow_ship id); +char const * bow_objtypstr(bow_objtyp typ); -#endif +[[unsequenced]] double bow_shipmass(bow_ship id); diff --git a/bowshock/include/bow/lgc.h b/bowshock/include/bow/lgc.h index b2f23eb..bea97e8 100644 --- a/bowshock/include/bow/lgc.h +++ b/bowshock/include/bow/lgc.h @@ -1,13 +1,19 @@ -#if !defined(bow_hdr_lgc) -#define bow_hdr_lgc +#pragma once #include <bow/bs.h> -constexpr double bow_timemod = 0x1p-10; // time modifier +#include <zap/bs.h> -constexpr double bow_gravconst = 0x1p0 * bow_timemod; // gravitational constant +constexpr double bow_distmod = 0x1p0; // distance modifier +constexpr double bow_massmod = 0x1p0; // mass modifier +constexpr double bow_tmmod = 0x1p0; // time modifier -void bow_grav(bow_obj * obj,bow_obj const * par); -void bow_mv( bow_obj * obj); +constexpr double bow_gravconst = 0x1.2589EFFFp-34 * (bow_distmod*bow_distmod*bow_distmod)/(bow_massmod*bow_tmmod*bow_tmmod); // gravitational constant (s^2*m*t^2) -#endif +bow_obj * bow_addobj( bow_objroot * root,bow_obj const * obj); +void bow_freeobjs(bow_objroot const * root); + +void bow_grav( bow_obj * obj, bow_obj * par); +void bow_gravobjs(bow_objroot const * root); +void bow_mv( bow_obj * obj); +void bow_mvobjs( bow_obj * objs); diff --git a/bowshock/include/bow/sav.h b/bowshock/include/bow/sav.h index e548a8e..defa9ad 100644 --- a/bowshock/include/bow/sav.h +++ b/bowshock/include/bow/sav.h @@ -1,24 +1,55 @@ -#if !defined(bow_hdr_sav) -#define bow_hdr_sav +#pragma once #include <bow/bs.h> #include <zap/bs.h> -constexpr zap_i04 bow_savfmtver = 0x5u; +constexpr zap_i04 bow_savver = 0x6u; + +#define bow_savlen ((zap_sz)((zap_sz)0x79u+(zap_sz)bow_cmdrnmlen)) + +/* + Save format: + + id: size [bytes]: format: + fmtver 8 unsigned + cmdrnm E UTF-8 + tm 8 unsigned + sysid 8 unsigned + shiptyp 1 unsigned + shipposx 8 binary64 + shipposy 8 binary64 + shipposz 8 binary64 + shiprotx 8 binary64 + shiproty 8 binary64 + shiprotz 8 binary64 + shipposvelx 8 binary64 + shipposvely 8 binary64 + shipposvelz 8 binary64 + shiprotvelx 8 binary64 + shiprotvely 8 binary64 + shiprotvelz 8 binary64 +*/ typedef struct { zap_i04 fmtver; char cmdrnm[bow_cmdrnmlen]; zap_i04 tm; zap_i04 sysid; - bow_ship shiptyp; - bow_xyz shippos; - bow_xyz shiprot; - bow_xyz shipvel; + zap_i8 shiptyp; + double shipposx; + double shipposy; + double shipposz; + double shiprotx; + double shiproty; + double shiprotz; + double shipposvelx; + double shipposvely; + double shipposvelz; + double shiprotvelx; + double shiprotvely; + double shiprotvelz; } bow_savdat; void bow_cont(char const * fil,bow_playdat * dat); void bow_sav( char const * fil,bow_playdat const * dat); - -#endif diff --git a/bowshock/source/bs/init.c b/bowshock/source/bs/init.c index 6280f10..323b12a 100644 --- a/bowshock/source/bs/init.c +++ b/bowshock/source/bs/init.c @@ -23,7 +23,7 @@ static void bow_intrhandl(int const sig) { 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; + char const * const * const stop = argv+(zap_sz)argc; while (argv++ != stop) { char const * const arg = *argv; if (zap_streq(arg,"--help")) { @@ -42,7 +42,7 @@ int main(int const argc,char const * const * argv) { } srand((unsigned int)time(nullptr)); { - zap_i8 const quotid = (unsigned int)rand() % 0x1Du; + zap_i8 const quotid = (unsigned int)rand() % 0x21u; char const * quot; char const * src; if (bow_getquot(",&src,quotid)) { @@ -51,8 +51,9 @@ int main(int const argc,char const * const * argv) { } bow_rawlog("\n%s\n\u2014 %s\n\n",quot,src); } - bow_rawlog("\x1B[0m\x1B[1mBowshock\x1B[0m %" PRIXLEAST64 ".%" PRIXLEAST64 " \u2013 Copyright 2022\u20102023, \x1B[1mGabriel Jensen\x1B[0m.\n\n",bow_vermaj,bow_vermin); + bow_rawlog("\x1B[0m\x1B[1mBowshock\x1B[0m %" PRIXLEAST64 ".%" PRIXLEAST64 " \u2013 Copyright 2022\u20102023 \x1B[1mGabriel Jensen\x1B[0m.\n\n",bow_vermaj,bow_vermin); bow_log("initialising"); + bow_dbglog("debug mode is enabled"); bow_gotintr = 0x0; if (signal(SIGINT,bow_intrhandl) == SIG_ERR) { bow_log("unable to set signal handler"); @@ -114,6 +115,7 @@ static bool bow_getquot(char const * * const quot,char const * * src,zap_i8 cons 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"; + break; case 0xBu: *quot = "Every sentence I utter must be understood not as an affirmation, but as a question."; *src = "Niels Henrik David Bohr"; @@ -186,6 +188,22 @@ static bool bow_getquot(char const * * const quot,char const * * src,zap_i8 cons *quot = "Can digital computers think?"; *src = "Alan Mathison Turing"; break; + case 0x1Du: + *quot = "That's one small step for a man, one giant leap for mankind."; + *src = "Neil Alden Armstrong"; + break; + case 0x1Eu: + *quot = "If you think it's simple, then you have misunderstood the problem."; + *src = "Bjarne Stroustrup"; + break; + case 0x1Fu: + *quot = "Controlling complexity is the essence of computer programming."; + *src = "Brian Wilson Kerningham"; + break; + case 0x20u: + *quot = "I have always wished for my computer to be as easy to use as my telephone. My wish has come true because I can no longer figure out how to use my telephone."; + *src = "Bjarne Stroustrup"; + break; } return false; } diff --git a/bowshock/source/bs/initdat.c b/bowshock/source/bs/initdat.c index 258949c..01c3cab 100644 --- a/bowshock/source/bs/initdat.c +++ b/bowshock/source/bs/initdat.c @@ -20,7 +20,7 @@ static char * bow_getsavpth(void) { } else hmdirlen = zap_strlen(hmdir); bow_setstr(filnm,filnmlen,".save.bowshock"); - zap_sz pthsz = hmdirlen + filnmlen + 0x2u; + zap_sz pthsz = hmdirlen+filnmlen+0x2u; char * pth = malloc(pthsz); if (pth == nullptr) { bow_log("unable to allocate memory"); diff --git a/bowshock/source/bs/loop.c b/bowshock/source/bs/loop.c index acdf81a..8693510 100644 --- a/bowshock/source/bs/loop.c +++ b/bowshock/source/bs/loop.c @@ -19,35 +19,65 @@ bow_stat bow_loop(bow_playdat * playdatptr) { zap_sz const imgsz = 0xFFFu * 0xFFFu * 0x3u; zap_i8 * img = malloc(imgsz); zap_fill(img,0x0u,imgsz); - bow_obj star = { - .pos = { + bow_objroot sysroot = { // For stellar bodies. + .objs = nullptr, + }; + [[maybe_unused]] bow_objroot objroot = { // For miscellaneous objects (canisters, ships...). + .objs = nullptr, + }; + bow_obj objtmp = { + .typ = bow_objtyp_star, + .pos = { .x = 0x0p0, .y = 0x0p0, .z = 0x0p0, }, - .typ = bow_objtyp_star, - .mass = 0x1'0000'0000p0, - }; - bow_obj wrld = { - .pos = { + .rot = { .x = 0x0p0, - .y = star.pos.y + 0x1'0000p0, + .y = 0x0p0, .z = 0x0p0, }, - .typ = bow_objtyp_wrld, - .mass = 0x1'0000p0, + .posvel = { + .x = 0x0p0, + .y = 0x0p0, + .z = 0x0p0, + }, + .rotvel = { + .x = 0x0p0, + .y = 0x0p0, + .z = 0x3.243F'6A89p0, + }, + .mass = 0x191930A5E75F0C191814000000p0, + .startyp = bow_star_g, + // next will be overwritten anyways. }; - bow_obj sat = { - .pos = { + bow_obj * const sol = bow_addobj(&sysroot,&objtmp); + objtmp = (bow_obj) { + .typ = bow_objtyp_wrld, + .pos = { .x = 0x0p0, - .y = wrld.pos.y + 0x100u, + .y = 0x22'3F8B'93C0p0, .z = 0x0p0, }, - .typ = bow_objtyp_sat, - .mass = 0x1p0, + .rot = { + .x = 0x0p0, + .y = 0x0p0, + .z = 0x0p0, + }, + .posvel = { + .x = 0x7652p0, + .y = 0x0p0, + .z = 0x0p0, + }, + .rotvel = { + .x = 0x0p0, + .y = 0x0p0, + .z = 0x1.31DB66BBp-15, + }, + .mass = 0x4'F0A9'9C58'8848'32A0'0000p0, + .wrldtyp = bow_wrld_rck, }; - wrld.vel.x = sqrt(bow_gravconst*star.mass/(wrld.pos.y - star.pos.y)); // orbital speed - sat.vel.x = wrld.vel.x + sqrt(bow_gravconst*wrld.mass/(sat.pos.y - wrld.pos.y)); // orbital speed + bow_obj * const ter = bow_addobj(&sysroot,&objtmp); for (zap_i04 i = 0x0u;;) { if (bow_gotintr) { bow_log("got interrupt"); @@ -55,40 +85,30 @@ bow_stat bow_loop(bow_playdat * playdatptr) { } if (glfwWindowShouldClose(bow_gfxdat.win)) break; // Calculate gravitations: - bow_grav(&star,&wrld); - bow_grav(&star,&sat); - bow_grav(&wrld,&star); - bow_grav(&wrld,&sat); - bow_grav(&sat, &star); - bow_grav(&sat, &wrld); + bow_gravobjs(&sysroot); // Move objects: - bow_mv(&star); - bow_mv(&wrld); - bow_mv(&sat); + bow_mvobjs(sysroot.objs); // Plot objects: { - constexpr double frm = 0x4'0000p0; - zap_i04 const starposx = (zap_i04)((star.pos.x + frm / 0x2p0) / frm * 0xFFFp0); - zap_i04 const starposy = (zap_i04)((-star.pos.y + frm / 0x2p0) / frm * 0xFFFp0); - zap_i04 const wrldposx = (zap_i04)((wrld.pos.x + frm / 0x2p0) / frm * 0xFFFp0); - zap_i04 const wrldposy = (zap_i04)((-wrld.pos.y + frm / 0x2p0) / frm * 0xFFFp0); - zap_i04 const satposx = (zap_i04)((sat.pos.x + frm / 0x2p0) / frm * 0xFFFp0); - zap_i04 const satposy = (zap_i04)((-sat.pos.y + frm / 0x2p0) / frm * 0xFFFp0); - if ((starposx <= 0xFFFu) && (starposy <= 0xFFFu) && (wrldposx <= 0xFFFu) && (wrldposy <= 0xFFFu) && (satposx <= 0xFFFu) && (satposy <= 0xFFFu)) { - zap_sz const starpos = (starposy * 0xFFFu + starposx) * 0x3u; - zap_sz const wrldpos = (wrldposy * 0xFFFu + wrldposx) * 0x3u; - zap_sz const satpos = (satposy * 0xFFFu + satposx) * 0x3u; - if (img[starpos + 0x0u] <= 0xFEu) img[starpos + 0x0u] += 0x1u; - if (img[wrldpos + 0x1u] <= 0xFEu) img[wrldpos + 0x1u] += 0x1u; - if (img[satpos + 0x2u] <= 0xFEu) img[satpos + 0x2u] += 0x1u; + constexpr double frm = 0x22'3F8B'93C0p0*0x3p0; + zap_i04 const solposx = (zap_i04)(( sol->pos.x+frm/0x2p0)/frm*0xFFFp0); + zap_i04 const solposy = (zap_i04)((-sol->pos.y+frm/0x2p0)/frm*0xFFFp0); + zap_i04 const terposx = (zap_i04)(( ter->pos.x+frm/0x2p0)/frm*0xFFFp0); + zap_i04 const terposy = (zap_i04)((-ter->pos.y+frm/0x2p0)/frm*0xFFFp0); + if ((solposx <= 0xFFFu) && (solposy <= 0xFFFu) && (terposx <= 0xFFFu) && (terposy <= 0xFFFu)) { + zap_sz const solpos = (solposy*0xFFFu+solposx)*0x3u; + zap_sz const terpos = (terposy*0xFFFu+terposx)*0x3u; + img[solpos+0x0u] = 0xFFu; + img[terpos+0x1u] = 0xFFu; } } // Check tick number: - if (i++ == 0xFFFFFu) break; + if (i++ == 0x1E18557u * bow_tmmod) break; // One Gregorian year } + bow_freeobjs(&sysroot); { zap_i8 * enc; - zap_sz const enclen = WebPEncodeLosslessRGB((void *)img,0xFFFu,0xFFFu,0xFFFu * 0x3u,&enc); + zap_sz const enclen = WebPEncodeLosslessRGB((void *)img,0xFFFu,0xFFFu,0xFFFu*0x3u,&enc); flux_fil * imgfil; flux_err err = flux_mkfil(&imgfil,"img.webp",0644u); if (err == flux_err_exist) { diff --git a/bowshock/source/bs/quit.c b/bowshock/source/bs/quit.c index bb28b1f..0e7f4ae 100644 --- a/bowshock/source/bs/quit.c +++ b/bowshock/source/bs/quit.c @@ -4,6 +4,7 @@ #include <bow/info.h> #include <GLFW/glfw3.h> +#include <stddef.h> #include <stdlib.h> void bow_quit(bow_stat const stat) { @@ -12,6 +13,8 @@ void bow_quit(bow_stat const stat) { glfwTerminate(); int sysstat; switch (stat) { + default: + unreachable(); case bow_stat_err: sysstat = EXIT_FAILURE; break; diff --git a/bowshock/source/gfx/initgfx.c b/bowshock/source/gfx/initgfx.c index 23576e5..3ecbcc3 100644 --- a/bowshock/source/gfx/initgfx.c +++ b/bowshock/source/gfx/initgfx.c @@ -14,7 +14,7 @@ void bow_initgfx(void) { } glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR,0x3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR,0x0); - GLFWwindow * win = glfwCreateWindow(0x300,0x200,"Bowshock",nullptr,nullptr); + GLFWwindow * win = glfwCreateWindow(0x300,0x200,"Bowshock",glfwGetPrimaryMonitor(),nullptr); if (win == nullptr) { bow_logerr("unable to open window"); bow_quit(bow_stat_err); diff --git a/bowshock/source/info/objtypstr.c b/bowshock/source/info/objtypstr.c new file mode 100644 index 0000000..719634a --- /dev/null +++ b/bowshock/source/info/objtypstr.c @@ -0,0 +1,35 @@ +#define bow_sym "objtypstr" + +#include <bow/info.h> + +#include <stddef.h> + +char const * bow_objtypstr(bow_objtyp const typ) { + char const * str; + switch (typ) { + default: + unreachable(); + case bow_objtyp_can: + str = "canister"; + break; + case bow_objtyp_play: + str = "player"; + break; + case bow_objtyp_sat: + str = "satellite"; + break; + case bow_objtyp_ship: + str = "ship"; + break; + case bow_objtyp_star: + str = "star"; + break; + case bow_objtyp_station: + str = "station"; + break; + case bow_objtyp_wrld: + str = "world"; + break; + } + return str; +} diff --git a/bowshock/source/lgc/addobj.c b/bowshock/source/lgc/addobj.c new file mode 100644 index 0000000..375fcfc --- /dev/null +++ b/bowshock/source/lgc/addobj.c @@ -0,0 +1,20 @@ +#define bow_sym "addobj" + +#include <bow/info.h> +#include <bow/lgc.h> + +#include <stdlib.h> +#include <zap/mem.h> + +bow_obj * bow_addobj(bow_objroot * const root,bow_obj const * const objval) { + bow_dbglog("adding object of type %s",bow_objtypstr(objval->typ)); + bow_obj * const obj = malloc(sizeof (bow_obj)); + if (obj == nullptr) { + bow_dbglog("unable to allocate memory for object"); + bow_quit(bow_stat_err); + } + zap_cp(obj,objval,sizeof (bow_obj)); + obj->next = root->objs; + root->objs = obj; + return obj; +} diff --git a/bowshock/source/lgc/freeobjs.c b/bowshock/source/lgc/freeobjs.c new file mode 100644 index 0000000..66b3435 --- /dev/null +++ b/bowshock/source/lgc/freeobjs.c @@ -0,0 +1,19 @@ +#define bow_sym "freeobjs" + +#include <bow/info.h> +#include <bow/lgc.h> + +#include <stdlib.h> +#include <zap/mem.h> + +void bow_freeobjs(bow_objroot const * const root) { + bow_dbglog("freeing objects"); + bow_obj * obj = root->objs; + bow_obj * next; + while (obj != nullptr) { + bow_dbglog("freeing object of type %s",bow_objtypstr(obj->typ)); + next = obj->next; + free(obj); + obj = next; + } +} diff --git a/bowshock/source/lgc/grav.c b/bowshock/source/lgc/grav.c index c32b418..848aabf 100644 --- a/bowshock/source/lgc/grav.c +++ b/bowshock/source/lgc/grav.c @@ -5,23 +5,42 @@ #include <math.h> #include <zap/mem.h> -void bow_grav(bow_obj * objptr,bow_obj const * parptr) { - bow_obj obj; - bow_obj par; - zap_cp(&obj,objptr,sizeof (obj)); - zap_cp(&par,parptr,sizeof (par)); - 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(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); - double const vx = cos(angy)*acc; - double const vy = sin(angy)*acc; - double const vz = sin(angz)*acc; - obj.vel.x += vx; - obj.vel.y += vy; - obj.vel.z += vz; - zap_cp(objptr,&obj,sizeof (obj)); +void bow_grav(bow_obj * obj0ptr,bow_obj * obj1ptr) { + bow_obj obj0; + bow_obj obj1; + zap_cp(&obj0,obj0ptr,sizeof (obj0)); + zap_cp(&obj1,obj1ptr,sizeof (obj1)); + double const distx = obj1.pos.x-obj0.pos.x; + double const disty = obj1.pos.y-obj0.pos.y; + double const distz = obj1.pos.z-obj0.pos.z; + double const dist = sqrt(distx *distx+disty*disty+distz*distz); + double const angy = atan2(disty,distx); + double const angz = atan2(distz,distx); + double acc0 = bow_gravconst/pow(dist,2.0); + double const acc1 = acc0*obj0.mass; // This is negative. + acc0 *= obj1.mass; + double vx0 = cos(angy); + double vy0 = sin(angy); + double vz0 = sin(angz); + double const vx1 = vx0*acc1; + double const vy1 = vy0*acc1; + double const vz1 = vz0*acc1; + vx0 *= acc0; + vy0 *= acc0; + vz0 *= acc0; + obj0.posvel.x += vx0; + obj0.posvel.y += vy0; + obj0.posvel.z += vz0; + obj1.posvel.x -= vx1; + obj1.posvel.y -= vy1; + obj1.posvel.z -= vz1; + zap_cp(obj0ptr,&obj0,sizeof (obj0)); + zap_cp(obj1ptr,&obj1,sizeof (obj1)); +} + +void bow_gravobjs(bow_objroot const * const root) { + for (bow_obj * obj0 = root->objs;obj0 != nullptr;obj0 = obj0->next) + for (bow_obj * obj1 = obj0->next;obj1 != nullptr;obj1 = obj1->next) { + bow_grav(obj0,obj1); + } } diff --git a/bowshock/source/lgc/mv.c b/bowshock/source/lgc/mv.c index 5c8fcc0..175b076 100644 --- a/bowshock/source/lgc/mv.c +++ b/bowshock/source/lgc/mv.c @@ -8,8 +8,16 @@ void bow_mv(bow_obj * objptr) { bow_obj obj; zap_cp(&obj,objptr,sizeof (obj)); - obj.pos.x += obj.vel.x; - obj.pos.y += obj.vel.y; - obj.pos.z += obj.vel.z; + obj.pos.x += obj.posvel.x; + obj.pos.y += obj.posvel.y; + obj.pos.z += obj.posvel.z; + obj.rot.x += obj.rotvel.x; + obj.rot.y += obj.rotvel.y; + obj.rot.z += obj.rotvel.z; zap_cp(objptr,&obj,sizeof (obj)); } + +void bow_mvobjs(bow_obj * obj) { + for (;obj != nullptr;obj = obj->next) + bow_mv(obj); +} diff --git a/bowshock/source/sav/cont.c b/bowshock/source/sav/cont.c index 93e475c..3eb1580 100644 --- a/bowshock/source/sav/cont.c +++ b/bowshock/source/sav/cont.c @@ -1,21 +1,42 @@ -#define bow_sym "sav" +#define bow_sym "cont" #include <bow/sav.h> #include <flux/io.h> +#include <inttypes.h> #include <zap/mem.h> +static void bow_decsav(bow_savdat * buf,zap_i8 * dat) { + dat = zap_cp(&buf->fmtver, dat,0x8u).src; + dat = zap_cp(&buf->cmdrnm, dat,bow_cmdrnmlen).src; + dat = zap_cp(&buf->tm, dat,0x8u).src; + dat = zap_cp(&buf->sysid, dat,0x8u).src; + dat = zap_cp(&buf->shiptyp, dat,0x1u).src; + dat = zap_cp(&buf->shipposx, dat,0x8u).src; + dat = zap_cp(&buf->shipposy, dat,0x8u).src; + dat = zap_cp(&buf->shipposz, dat,0x8u).src; + dat = zap_cp(&buf->shiprotx, dat,0x8u).src; + dat = zap_cp(&buf->shiproty, dat,0x8u).src; + dat = zap_cp(&buf->shiprotz, dat,0x8u).src; + dat = zap_cp(&buf->shipposvelx,dat,0x8u).src; + dat = zap_cp(&buf->shipposvely,dat,0x8u).src; + dat = zap_cp(&buf->shipposvelz,dat,0x8u).src; + dat = zap_cp(&buf->shiprotvelx,dat,0x8u).src; + dat = zap_cp(&buf->shiprotvely,dat,0x8u).src; + dat = zap_cp(&buf->shiprotvelz,dat,0x8u).src; +} + 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) { + if (err) { 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) { + zap_i8 rawdat[bow_savlen]; + err = flux_rd(rawdat,fil,bow_savlen,nullptr); + if (err) { flux_cl(fil); if (err == flux_err_eof) { bow_logerr("corrupt save file at \"%s\"",pth); @@ -24,17 +45,32 @@ void bow_cont(char const * const pth,bow_playdat * const playdatptr) { goto new; } flux_cl(fil); - if (dat.fmtver != bow_savfmtver) { - bow_logerr("invalid format of save file at \"%s\"",pth); + bow_savdat dat; + bow_decsav(&dat,rawdat); + if (dat.fmtver != bow_savver) { + bow_logerr("invalid format (%" PRIX64 " of save file at \"%s\"",dat.fmtver,pth); + goto new; + } + if (dat.shiptyp > (zap_i8)bow_ship_ursa) { + bow_logerr("invalid ship type (%" PRIX8 ")",dat.shiptyp); goto new; } bow_playdat playdat = { - .sysid = dat.sysid, - .tm = dat.tm, - .ship.shiptyp = dat.shiptyp, - .ship.pos = dat.shippos, - .ship.rot = dat.shiprot, - .ship.vel = dat.shipvel, + .tm = dat.tm, + .sysid = dat.sysid, + .ship.shiptyp = (bow_ship)dat.shiptyp, + .ship.pos.x = dat.shipposx, + .ship.pos.y = dat.shipposy, + .ship.pos.z = dat.shipposz, + .ship.rot.x = dat.shiprotx, + .ship.rot.y = dat.shiproty, + .ship.rot.z = dat.shiprotz, + .ship.posvel.x = dat.shipposvelx, + .ship.posvel.y = dat.shipposvely, + .ship.posvel.z = dat.shipposvelz, + .ship.rotvel.x = dat.shiprotvelx, + .ship.rotvel.y = dat.shiprotvely, + .ship.rotvel.z = dat.shiprotvelz, }; zap_cp(playdat.nm,dat.cmdrnm,bow_cmdrnmlen); playdat.nm[bow_cmdrnmlen] = '\x0'; @@ -51,7 +87,17 @@ new: .y = 0x0p0, .z = 0x0p0, }, - .vel = { + .rot = { + .x = 0x0p0, + .y = 0x0p0, + .z = 0x0p0, + }, + .posvel = { + .x = 0x0p0, + .y = 0x0p0, + .z = 0x0p0, + }, + .rotvel = { .x = 0x0p0, .y = 0x0p0, .z = 0x0p0, diff --git a/bowshock/source/sav/sav.c b/bowshock/source/sav/sav.c index 53eec68..451522e 100644 --- a/bowshock/source/sav/sav.c +++ b/bowshock/source/sav/sav.c @@ -5,33 +5,43 @@ #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); +static void bow_encsav(zap_i8 * buf,bow_playdat const * const playdat) { + buf = zap_cp(buf,(zap_i04[0x1u]) {bow_savver},0x8u).dest; // fmtver + buf = zap_cp(buf,playdat->nm, bow_cmdrnmlen).dest; // cmdrnm + buf = zap_cp(buf,&playdat->tm, 0x8u).dest; // tm + buf = zap_cp(buf,&playdat->sysid, 0x8u).dest; // sysid + buf = zap_cp(buf,&playdat->ship.shiptyp, 0x1u).dest; // shiptyp + buf = zap_cp(buf,&playdat->ship.pos.x, 0x8u).dest; // shipposx + buf = zap_cp(buf,&playdat->ship.pos.y, 0x8u).dest; // shipposy + buf = zap_cp(buf,&playdat->ship.pos.z, 0x8u).dest; // shipposz + buf = zap_cp(buf,&playdat->ship.rot.x, 0x8u).dest; // shiprotx + buf = zap_cp(buf,&playdat->ship.rot.y, 0x8u).dest; // shiproty + buf = zap_cp(buf,&playdat->ship.rot.z, 0x8u).dest; // shiprotz + buf = zap_cp(buf,&playdat->ship.posvel.x, 0x8u).dest; // shipposvelx + buf = zap_cp(buf,&playdat->ship.posvel.y, 0x8u).dest; // shipposvely + buf = zap_cp(buf,&playdat->ship.posvel.z, 0x8u).dest; // shipposvelz + buf = zap_cp(buf,&playdat->ship.rotvel.x, 0x8u).dest; // shiprotvelx + buf = zap_cp(buf,&playdat->ship.rotvel.y, 0x8u).dest; // shiprotvely + zap_cp(buf,&playdat->ship.rotvel.z, 0x8u); // shiprotvelz +} + +void bow_sav(char const * const pth,bow_playdat const * const playdat) { + bow_log("saving commander %s at \"%s\"",playdat->nm,pth); flux_fil * fil; flux_err err = flux_mkfil(&fil,pth,0644); - if (err != flux_err_ok) { + if (err) { if (err != flux_err_exist) { 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) { + if (err) { 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, - .tm = playdat.tm, - .shiptyp = playdat.ship.shiptyp, - .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)); + zap_i8 dat[bow_savlen]; + bow_encsav(dat,playdat); + flux_wr(fil,dat,bow_savlen); flux_cl(fil); } |