summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.txt14
-rw-r--r--CREDITS.txt1
-rw-r--r--bowshock/GNUmakefile56
-rw-r--r--bowshock/include/bow/bs.h63
-rw-r--r--bowshock/include/bow/gfx.h5
-rw-r--r--bowshock/include/bow/info.h7
-rw-r--r--bowshock/include/bow/lgc.h20
-rw-r--r--bowshock/include/bow/sav.h49
-rw-r--r--bowshock/source/bs/init.c24
-rw-r--r--bowshock/source/bs/initdat.c2
-rw-r--r--bowshock/source/bs/loop.c104
-rw-r--r--bowshock/source/bs/quit.c3
-rw-r--r--bowshock/source/gfx/initgfx.c2
-rw-r--r--bowshock/source/info/objtypstr.c35
-rw-r--r--bowshock/source/lgc/addobj.c20
-rw-r--r--bowshock/source/lgc/freeobjs.c19
-rw-r--r--bowshock/source/lgc/grav.c57
-rw-r--r--bowshock/source/lgc/mv.c14
-rw-r--r--bowshock/source/sav/cont.c74
-rw-r--r--bowshock/source/sav/sav.c44
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(&quot,&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);
}