summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore9
-rw-r--r--CHANGELOG.txt31
-rw-r--r--CMakeLists.txt67
-rw-r--r--CREDITS.txt11
-rw-r--r--README.txt64
-rw-r--r--bowshock/CMakeLists.txt123
-rw-r--r--bowshock/GNUmakefile104
-rw-r--r--bowshock/include/bow/bs.h170
-rw-r--r--bowshock/include/bow/c2x.h43
-rw-r--r--bowshock/include/bow/gfx.h18
-rw-r--r--bowshock/include/bow/init.h34
-rw-r--r--bowshock/include/bow/lgc.h108
-rw-r--r--bowshock/include/bow/run.h31
-rw-r--r--bowshock/include/bow/sav.h59
-rw-r--r--bowshock/shader/main.frag.glsl7
-rw-r--r--bowshock/shader/main.vert.glsl7
-rw-r--r--bowshock/source/bs/chkparams.c33
-rw-r--r--bowshock/source/bs/getsavpth.c37
-rw-r--r--bowshock/source/bs/init.c49
-rw-r--r--bowshock/source/bs/initsig.c21
-rw-r--r--bowshock/source/bs/loop.c77
-rw-r--r--bowshock/source/bs/objTypStr.c (renamed from bowshock/source/lgc/objtypstr.c)19
-rw-r--r--bowshock/source/bs/rnd.c2
-rw-r--r--bowshock/source/gfx/drw.c26
-rw-r--r--bowshock/source/gfx/initgfx.c40
-rw-r--r--bowshock/source/init/chkParams.c40
-rw-r--r--bowshock/source/init/compShd.c97
-rw-r--r--bowshock/source/init/compShdProg.c36
-rw-r--r--bowshock/source/init/cred.c43
-rw-r--r--bowshock/source/init/getQuot.c (renamed from bowshock/source/bs/getquot.c)12
-rw-r--r--bowshock/source/init/getSavPth.c40
-rw-r--r--bowshock/source/init/help.c (renamed from bowshock/source/bs/help.c)7
-rw-r--r--bowshock/source/init/init.c56
-rw-r--r--bowshock/source/init/initGfx.c50
-rw-r--r--bowshock/source/init/initRnd.c (renamed from bowshock/source/bs/initrnd.c)7
-rw-r--r--bowshock/source/init/initSig.c23
-rw-r--r--bowshock/source/init/priQuot.c22
-rw-r--r--bowshock/source/lgc/grav.c34
-rw-r--r--bowshock/source/lgc/mv.c14
-rw-r--r--bowshock/source/lgc/shipMass.c10
-rw-r--r--bowshock/source/lgc/shipmass.c7
-rw-r--r--bowshock/source/lgc/sim.c7
-rw-r--r--bowshock/source/run/abrt.c (renamed from bowshock/source/bs/abrt.c)3
-rw-r--r--bowshock/source/run/addObj.c (renamed from bowshock/source/lgc/addobj.c)12
-rw-r--r--bowshock/source/run/freeObjs.c (renamed from bowshock/source/lgc/freeobjs.c)8
-rw-r--r--bowshock/source/run/genSys.c (renamed from bowshock/source/lgc/gensys.c)31
-rw-r--r--bowshock/source/run/intro.c (renamed from bowshock/source/bs/intro.c)46
-rw-r--r--bowshock/source/run/loop.c117
-rw-r--r--bowshock/source/run/pollEvts.c18
-rw-r--r--bowshock/source/run/quit.c (renamed from bowshock/source/bs/quit.c)14
-rw-r--r--bowshock/source/sav/cont.c109
-rw-r--r--bowshock/source/sav/decSav.c25
-rw-r--r--bowshock/source/sav/encSav.c25
-rw-r--r--bowshock/source/sav/genDat.c (renamed from bowshock/source/sav/gendat.c)12
-rw-r--r--bowshock/source/sav/new.c (renamed from bowshock/source/sav/rstart.c)22
-rw-r--r--bowshock/source/sav/sav.c48
-rwxr-xr-xextractGlad.sh21
-rw-r--r--glad.CMakeLists.txt25
-rwxr-xr-xinstall.sh71
-rwxr-xr-xvalidateShaders.py33
60 files changed, 1539 insertions, 796 deletions
diff --git a/.gitignore b/.gitignore
index ea84b71..b7109f3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,9 @@
/assets
-*.elf
-*.exe
-*.o
+/bindir
+/build
+/datdir
+/glad
+*.tar
+*.zip
*.zst
vgcore.*
diff --git a/CHANGELOG.txt b/CHANGELOG.txt
index 1cbfafd..98f18a5 100644
--- a/CHANGELOG.txt
+++ b/CHANGELOG.txt
@@ -1,3 +1,34 @@
+# 0.A.0
+
+* Remove satellite object type;
+* Fix viewport size being too small on some devices;
+* Update mass unit;
+* Add macros for branch prediction;
+* Add new modules 'init' and 'run';
+* Remove module 'gfx';
+* Add more ship types;
+* Use OpenGL 4.0;
+* Use GLAD;
+* Specify OpenGL profile;
+* Update code style;
+* Update gitignore;
+* Update naming convention;
+* Add more station types;
+* Create script for validating shaders;
+* Add install script;
+* Add script for extracting glad;
+* Add launch option 'credits';
+* Make code more modular;
+* Add readme;
+* Update credits;
+* Switch back to CMake;
+* Add minimal MSVC support;
+* Specify underlying type for enumerations;
+* Add more quotes;
+* Rename launch option 'restart' to 'new';
+* Add assumption macro;
+* Improve precision of gravitational constant;
+
# 0.9.0
* Fix compilation warning;
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..19d3679
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,67 @@
+cmake_minimum_required(VERSION 3.21)
+
+project(
+ bowshock
+
+ VERSION 0.10.0
+ HOMEPAGE_URL "https://mandelbrot.dk/bowshock"
+ LANGUAGES C
+)
+
+function(target_enable_warnings TARGET)
+ if("${CMAKE_C_COMPILER_ID}" MATCHES "Clang|GNU")
+ target_compile_options(
+ ${TARGET} PRIVATE
+
+ -Wall
+ -Wextra
+ )
+ elseif("${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC")
+ target_compile_options(
+ ${TARGET} PRIVATE
+
+ /W4
+ )
+ endif()
+endfunction()
+
+function(target_enable_optimisations TARGET)
+ if("${CMAKE_C_COMPILER_ID}" MATCHES "Clang|GNU")
+ if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
+ target_compile_options(
+ ${TARGET} PRIVATE
+
+ -Og
+ )
+ else()
+ target_compile_options(
+ ${TARGET} PRIVATE
+
+ -Ofast
+ )
+ endif()
+ elseif("${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC")
+ target_compile_options(
+ ${TARGET} PRIVATE
+
+ /O2
+ )
+
+ if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
+ target_compile_options(
+ ${TARGET} PRIVATE
+
+ /Zo
+ )
+ endif()
+ endif()
+endfunction()
+
+if("${CMAKE_C_COMPILER_ID}" MATCHES "Clang|GNU")
+ add_compile_options(
+ -fdiagnostics-color=always
+ )
+endif()
+
+add_subdirectory(bowshock)
+add_subdirectory(glad)
diff --git a/CREDITS.txt b/CREDITS.txt
index 47fb90f..f40cb16 100644
--- a/CREDITS.txt
+++ b/CREDITS.txt
@@ -1,10 +1,13 @@
BOWSHOCK
-COPYRIGHT
+COPYRIGHT:
2022-2023 Gabriel Jensen
-LEAD DESIGN
-- Gabriel Jensen
+DESIGN
+ Gabriel Jensen
ARTWORK
-- Gabriel Jensen
+ Gabriel Jensen
+
+SOFTWARE DEVELOPMENT
+ Gabriel Jensen
diff --git a/README.txt b/README.txt
new file mode 100644
index 0000000..572b019
--- /dev/null
+++ b/README.txt
@@ -0,0 +1,64 @@
+BOWSHOCK
+
+# CHANGELOG
+
+Read: "CHANGELOG.txt"
+
+# COMPILATION
+
+Bowshock uses CMake as its build system. The standard option CMAKE_-
+BUILD_TYPE may be set to either "Release" or "Debug", depending on the
+build type.
+
+The program is written in C2x, and a conforming compiler is therefore
+required. It has been tested to work with GCC 12.2 and Clang 15.0, but
+the option BOW_C2X_COMPATIBILITY may have to be set to "true" when
+invoking CMake.
+
+Before compilation, an appropriate GLAD loader must be downloaded from
+a web instance. I use the one on dav1d.de, with the following settings:
+
+<https://glad.dav1d.de/#language=c&specification=gl&api=gl%3D4.0&api=gles1%3Dnone&api=gles2%3Dnone&api=glsc2%3Dnone&profile=core&loader=on>
+
+The script "extractGlad.sh" will extract "glad.zip" (or any other ar-
+chive - if specified) to "glad". It also copies a CMAKE lists file to
+the directory, and CMake will automatically include this and build
+GLAD.
+
+Before running - however - the data directory must be installed. This
+can be done via the installation script "install.sh":
+
+./install.sh data [data directory]
+
+## DEVELOPMENT
+
+The commands I use for development are:
+
+clear && \
+rm -fr build && \
+rm -fr bindir && \
+rm -fr datdir && \
+./validateShaders.py && \
+./extractGlad.sh && \
+cmake -Bbuild -DBOW_DATA_DIRECTORY="${PWD}/datdir" -DCMAKE_BUILD_TYPE=Debug . && \
+cmake --build build && \
+./install.sh data "${PWD}/datdir" && \
+build/bowshock/bowshock --skip
+
+## SHADER VALIDATION
+
+The shaders at bowshock/shader may be validated using the Python-
+script "validateShaders.py". If the shaders contain errors, and these
+are not fixed before installation, the program will fail to compile
+them during run-time, but the errors will not be diagnosed.
+
+## INSTALLATION
+
+The script "install.sh" will install the executable, the assets, the
+shaders... to the specified directories:
+
+./install.sh [build directory] [binary directory] [data directory]
+
+# CREDITS
+
+Read: "CREDITS.txt"
diff --git a/bowshock/CMakeLists.txt b/bowshock/CMakeLists.txt
new file mode 100644
index 0000000..d3a5f50
--- /dev/null
+++ b/bowshock/CMakeLists.txt
@@ -0,0 +1,123 @@
+cmake_minimum_required(VERSION 3.21)
+
+option(BOW_DATA_DIRECTORY "" "")
+option(BOW_C2X_COMPATIBILITY "Predefined C2x macros for older compilers." FALSE)
+
+if("${BOW_DATA_DIRECTORY}" STREQUAL "")
+ message(FATAL_ERROR "Data directory (BOW_DATA_DIRECTORY) not specified")
+endif()
+
+set(CMAKE_C_STANDARD 23)
+
+add_executable(
+ bowshock
+
+ "source/bs/objTypStr.c"
+ "source/bs/rnd.c"
+
+ "source/init/chkParams.c"
+ "source/init/compShd.c"
+ "source/init/compShdProg.c"
+ "source/init/cred.c"
+ "source/init/getQuot.c"
+ "source/init/getSavPth.c"
+ "source/init/help.c"
+ "source/init/init.c"
+ "source/init/initGfx.c"
+ "source/init/initRnd.c"
+ "source/init/initSig.c"
+ "source/init/priQuot.c"
+
+ "source/lgc/grav.c"
+ "source/lgc/mv.c"
+ "source/lgc/shipMass.c"
+ "source/lgc/sim.c"
+
+ "source/run/abrt.c"
+ "source/run/addObj.c"
+ "source/run/freeObjs.c"
+ "source/run/genSys.c"
+ "source/run/intro.c"
+ "source/run/loop.c"
+ "source/run/pollEvts.c"
+ "source/run/quit.c"
+
+ "source/sav/genDat.c"
+ "source/sav/cont.c"
+ "source/sav/decSav.c"
+ "source/sav/encSav.c"
+ "source/sav/new.c"
+ "source/sav/sav.c"
+)
+
+add_dependencies(
+ bowshock
+
+ glad
+)
+
+target_enable_warnings(bowshock)
+
+target_enable_optimisations(bowshock)
+
+target_include_directories(
+ bowshock PRIVATE
+
+ "include"
+)
+
+target_link_libraries(
+ bowshock PRIVATE
+
+ flux
+ glad
+ glfw
+ m
+ zap
+)
+
+target_compile_definitions(
+ bowshock PRIVATE
+
+ _POSIX_C_SOURCE=200112l
+ GLFW_INCLUDE_NONE
+ bow_datDir="/home/delta/Repositories/bowshock/datdir"
+)
+
+if(${BOW_C2X_COMPATIBILITY})
+ target_compile_definitions(
+ bowshock PRIVATE
+
+ bow_c2xCompat
+ )
+endif()
+
+if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
+ target_compile_definitions(
+ bowshock PRIVATE
+
+ bow_dbg
+ )
+endif()
+
+if("${CMAKE_C_COMPILER_ID}" MATCHES "Clang|GNU")
+ target_compile_options(
+ bowshock PRIVATE
+
+ -Wmissing-prototypes
+ -Wpedantic
+ -fdiagnostics-color=always
+ -g
+ )
+endif()
+
+if("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang")
+ target_compile_options(
+ bowshock PRIVATE
+
+ -Wno-fixed-enum-extension
+ -Wno-gnu-folding-constant
+ -Wno-gnu-empty-initializer
+ -Wno-gnu-zero-variadic-macro-arguments
+ )
+endif()
diff --git a/bowshock/GNUmakefile b/bowshock/GNUmakefile
deleted file mode 100644
index 3768123..0000000
--- a/bowshock/GNUmakefile
+++ /dev/null
@@ -1,104 +0,0 @@
-# Copyright 2022-2023 Gabriel Jensen.
-
-LD = $(CC)
-
-CFLAGS := \
- -Iinclude \
- -Wall \
- -Wextra \
- -Wmissing-prototypes \
- -Wpedantic \
- -Wno-attributes \
- -g \
- -pipe \
- -std=gnu2x
-
-ifeq "$(CC)" "clang"
-CFLAGS := \
- $(CFLAGS) \
- -Wno-gnu-folding-constant \
- -Wno-gnu-empty-initializer \
- -Wno-gnu-zero-variadic-macro-arguments
-endif
-
-ifeq "$(c2xcompat)" "true"
-CFLAGS := \
- $(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) \
- -D"bow_dbg=true" \
- -Og
-else
-CFLAGS := \
- $(CFLAGS) \
- -D"_FORTIFY_SOURCE=2" \
- -DNDEBUG \
- -Ofast
-endif
-
-OBJS := \
- source/bs/abrt.o \
- source/bs/chkparams.o \
- source/bs/getquot.o \
- source/bs/getsavpth.o \
- source/bs/help.o \
- source/bs/init.o \
- source/bs/initrnd.o \
- source/bs/initsig.o \
- source/bs/intro.o \
- source/bs/loop.o \
- source/bs/quit.o \
- source/bs/rnd.o \
- source/gfx/drw.o \
- source/gfx/initgfx.o \
- source/lgc/addobj.o \
- source/lgc/freeobjs.o \
- source/lgc/gensys.o \
- source/lgc/grav.o \
- source/lgc/mv.o \
- source/lgc/objtypstr.o \
- source/lgc/shipmass.o \
- source/lgc/sim.o \
- source/sav/gendat.o \
- source/sav/cont.o \
- source/sav/rstart.o \
- source/sav/sav.o
-
-LDLIBS := \
- -lGL \
- -lflux \
- -lglfw \
- -lm \
- -lzap
-
-BIN := bowshock.elf
-
-HDRS := \
- include/bow/bs.h \
- include/bow/gfx.h \
- include/bow/lgc.h \
- include/bow/sav.h
-
-.PHONY: clean purge
-
-$(BIN): $(OBJS)
- $(LD) -o$(@) $(^) $(LDLIBS)
-
-$(OBJS): $(HDRS)
-
-clean:
- $(RM) $(OBJS)
-
-purge: clean
- $(RM) $(BIN)
diff --git a/bowshock/include/bow/bs.h b/bowshock/include/bow/bs.h
index 22f3aec..7cfbb5c 100644
--- a/bowshock/include/bow/bs.h
+++ b/bowshock/include/bow/bs.h
@@ -2,25 +2,36 @@
#pragma once
-#define constexpr static const
+#ifdef bow_c2xCompat
+#include <bow/c2x.h>
+#endif
-#define _POSIX_C_SOURCE 200112l
+#ifndef bow_datDir
+#error Data directory not specified!
+#endif
-#if __STDC_VERSION__ <= 201710
-#error ISO/IEC 9899:2023 is required!
+#if defined(__GNUC__) || defined(__clang__)
+#define likely( expr) if (__builtin_expect((bool)(expr),true))
+#define unlikely(expr) if (__builtin_expect((bool)(expr),false))
+#else
+#define likely( expr) if ((expr))
+#define unlikely(expr) if ((expr))
#endif
-//#if __STDC_IEC_60559_BFP__ < 202311
-//#error ISO/IEC 60559:2020 is required!
-//#endif
+#if defined(__clang__)
+#define assume(expr) ((void)__builtin_assume((expr)))
+#elifdef (_MSC_VER)
+#define assume(expr) ((void)__assume((expr)))
+#else
+#define assume(expr) ((void)0x0u)
+#endif
-#include <limits.h>
-#include <signal.h>
#include <stdio.h>
-#include <zap/bs.h>
+#include <zap/bs.h> // This header is guaranteed to be included.
-static_assert(CHAR_BIT == 0x8,"Bytes must contain exactly eight bits.");
+static_assert(zap_bytelen == 0x8u,"Bytes must contain exactly eight bits.");
+static_assert(sizeof (zap_i8) == 0x1u);
static_assert(sizeof (zap_i01) == 0x2u);
static_assert(sizeof (zap_i02) == 0x4u);
static_assert(sizeof (zap_i04) == 0x8u);
@@ -32,23 +43,21 @@ static_assert(sizeof (double) == 0x8u);
#define bow_log(msg,...) bow_rawlog("\x1B[1m%s\x1B[0m: " msg "\n",__func__ __VA_OPT__(,) __VA_ARGS__)
-#define bow_logerr(msg,...) bow_log("\x1B[38;5;197m[ERROR]\x1B[0m " msg __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__)
+#ifdef bow_dbg
+#define bow_dbgLog(msg,...) bow_log(msg __VA_OPT__ (,) __VA_ARGS__)
#else
-#define bow_dbglog(msg,...) ((void)0x0u)
+#define bow_dbgLog(msg,...) ((void)0x0u)
#endif
-#define bow_logxyz(xyz) bow_dbglog("%.03f %.03f %.03f",(xyz).x,(xyz).y,(xyz).z)
+#define bow_logXyz(xyz) bow_dbgLog("%.03f %.03f %.03f",(xyz).x,(xyz).y,(xyz).z)
-constexpr zap_i04 bow_vermaj = 0x0u;
-constexpr zap_i04 bow_vermin = 0x9u;
-constexpr zap_i04 bow_verpat = 0x0u;
+#define bow_setStrLen(ptr,len,str) ((void)(ptr = str,len = sizeof (str) - 0x1u))
-#define bow_cmdrnmlen ((zap_sz)0xEu)
+#define bow_cmdrNmLen ((zap_sz)0xEu)
-typedef enum {
+typedef enum : zap_i8 {
bow_stat_ok = 0x0u,
bow_stat_err = 0x1u,
} bow_stat;
@@ -59,40 +68,97 @@ typedef struct {
double z;
} bow_xyz;
-typedef struct bow_impl_obj bow_obj;
-
-typedef struct bow_impl_objroot bow_objroot;
-
-typedef struct bow_impl_playdat bow_playdat;
-
-typedef struct bow_impl_gfxdat bow_gfxdat;
+typedef enum : zap_i8 {
+ bow_objTyp_can, // canister
+ bow_objTyp_pl, // player
+ bow_objTyp_ship, // ship
+ bow_objTyp_star, // star
+ bow_objTyp_station, // station
+ bow_objTyp_wrld, // world (planet/moon)
+} bow_objTyp;
+
+typedef enum : zap_i8 {
+ 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 : zap_i8 {
+ bow_ship_aq, // aquila
+ bow_ship_cas, // cassiopeia
+ bow_ship_cent, // centaurus
+ bow_ship_cov, // corvus
+ bow_ship_cur, // cursor
+ bow_ship_eri, // eridanus
+ bow_ship_fal, // falco
+ bow_ship_lyra, // lyra
+ bow_ship_tau, // taurus
+ bow_ship_ursa, // ursa
+ bow_ship_vip, // vipera
+ // Remember bow_maxShipId
+} bow_ship;
+
+typedef enum : zap_i8 {
+ bow_star_a, // main sequence
+ bow_star_b, // main sequence
+ bow_star_c, // carbon
+ bow_star_f, // main sequence
+ bow_star_g, // main sequence
+ bow_star_k, // main sequence
+ bow_star_l, // brown dwarf
+ bow_star_m, // main sequence
+ bow_star_n, // neutron star
+ bow_star_o, // main sequence
+ bow_star_s, // carbon
+ bow_star_t, // brown dwarf
+ bow_star_w, // worm hole
+ bow_star_x, // black hole
+ bow_star_y, // brown dwarf
+ bow_star_z, // white hole
+} bow_star;
+
+typedef enum : zap_i8 {
+ bow_station_glob, // globus
+ bow_station_orb, // orbis
+} bow_station;
+
+typedef struct bow_implObj bow_obj;
+
+struct bow_implObj {
+ bow_objTyp typ;
+ bow_xyz pos; // astronomical units
+ bow_xyz rot; // radians
+ bow_xyz posVel; // astronomical units per second
+ bow_xyz rotVel; // radians per second
+ double mass; // kilograms
+ union {
+ bow_wrld wrldTyp;
+ bow_ship shipTyp;
+ bow_star starTyp;
+ bow_station stationTyp;
+ };
+ bow_obj * next;
+};
typedef struct {
- char const * savpth;
- bool hassavpth:0x1u;
- bool rstart:0x1u;
- bool skip:0x1u;
-} bow_termopts;
-
-extern sig_atomic_t volatile bow_gotintr;
+ bow_obj * objs;
+} bow_objRoot;
-zap_i04 bow_rnd(void);
-
-char const * bow_getsavpth(void);
-bool bow_getquot( char const * * quot,char const * * src,zap_i8 id);
-
-void bow_loop(bow_gfxdat * gfxdat,bow_playdat * playdat);
-
-[[noreturn]] void bow_help(char const * prognm);
-
-void bow_chkparams(bow_termopts * opts,int argc,char const * const * argv);
-
-void bow_initrnd(void);
-void bow_initsig(void);
+typedef struct {
+ char nm[bow_cmdrNmLen+0x1u];
+ zap_i04 tm;
+ zap_i04 sysId;
+ bow_obj ship;
+ float zoom;
+} bow_plDat;
-bool bow_intro(bow_gfxdat * gfxdat);
+constexpr zap_i04 bow_verMaj = 0x0u;
+constexpr zap_i04 bow_verMin = 0xAu;
+constexpr zap_i04 bow_verPat = 0x0u;
-[[noreturn]] void bow_init(int argc,char const * const * argv);
+char const * bow_objTypStr(bow_objTyp typ);
-[[noreturn]] void bow_abrt(void);
-[[noreturn]] void bow_quit(bow_gfxdat * gfxdat,bow_stat stat);
+zap_i04 bow_rnd(void);
diff --git a/bowshock/include/bow/c2x.h b/bowshock/include/bow/c2x.h
new file mode 100644
index 0000000..43d5b97
--- /dev/null
+++ b/bowshock/include/bow/c2x.h
@@ -0,0 +1,43 @@
+// Copyright 2022-2023 Gabriel Jensen.
+
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC system_header
+#elifdef _MSC_VER
+#pragma system_header
+#endif
+
+#undef bool
+#undef constexpr
+#undef false
+#undef nullptr
+#undef reproducible
+#undef static_assert
+#undef thread_safe
+#undef typeof
+#undef true
+#undef unreachable
+#undef unsequenced
+
+#define bool _Bool
+#define constexpr static const
+#define false ((bool)+0x0u)
+#define nullptr ((void *)0x0u)
+#define static_assert _Static_assert
+#define thread_safe _Thread_safe
+#define typeof __typeof__
+#define true ((bool)+0x1u)
+
+#if defined(__GNUC__) || defined(__clang__)
+#define unreachable ((void)__builtin_unreachable())
+#elifdef __MSC_VER
+#define unreachable ((void)__assume(false))
+#else
+#define unreachable ((void)0x0u)
+#endif
+
+#if __GNUC__
+#define reproducible gnu::const
+#define unsequenced gnu::pure
+#endif
diff --git a/bowshock/include/bow/gfx.h b/bowshock/include/bow/gfx.h
deleted file mode 100644
index 2c19950..0000000
--- a/bowshock/include/bow/gfx.h
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2022-2023 Gabriel Jensen.
-
-#pragma once
-
-#include <bow/bs.h>
-
-#include <GLFW/glfw3.h>
-
-struct bow_impl_gfxdat {
- GLFWwindow * win;
- int frmw;
- int frmh;
- float zoom;
-};
-
-void bow_initgfx(bow_gfxdat * dat);
-
-void bow_drw(bow_gfxdat * gfxdat,bow_objroot * sys,bow_objroot * objs,float zoom);
diff --git a/bowshock/include/bow/init.h b/bowshock/include/bow/init.h
new file mode 100644
index 0000000..c79aa3f
--- /dev/null
+++ b/bowshock/include/bow/init.h
@@ -0,0 +1,34 @@
+// Copyright 2022-2023 Gabriel Jensen.
+
+#pragma once
+
+#include <bow/run.h>
+
+#include <glad/glad.h>
+
+typedef struct {
+ char const * savPth;
+ bool hasSavPth:0x1u;
+ bool newSav:0x1u;
+ bool skip:0x1u;
+} bow_termOpts;
+
+char const * bow_getSavPth(void);
+bool bow_getQuot( char const * * quot,char const * * src,zap_i8 id);
+
+void bow_priQuot(void);
+
+[[noreturn]] void bow_cred(void);
+[[noreturn]] void bow_help(char const * progNm);
+
+void bow_chkParams(bow_termOpts * opts,int argc,char const * const * argv);
+
+bool bow_compShd(GLuint * refPtr,char const * nm,GLenum typ);
+
+void bow_compShdProg(GLuint * shdProg,char const * nm);
+
+void bow_initGfx(bow_gfxDat * dat);
+void bow_initRnd(void);
+void bow_initSig(void);
+
+[[noreturn]] void bow_init(int argc,char const * const * argv);
diff --git a/bowshock/include/bow/lgc.h b/bowshock/include/bow/lgc.h
index 6cbca87..136a2ca 100644
--- a/bowshock/include/bow/lgc.h
+++ b/bowshock/include/bow/lgc.h
@@ -4,107 +4,19 @@
#include <bow/bs.h>
-#include <zap/bs.h>
+constexpr double bow_distMod = 0x1.16A5D2D360000000p037; // distance modifier (1 astronomical unit)
+constexpr double bow_massMod = 0x1.91930A5E75F0C192p100; // mass modifier (1 solar mass)
+constexpr double bow_tmMod = 0x1.0000000000000000p012; // time modifier (1 second)
-typedef enum {
- bow_objtyp_can, // canister
- bow_objtyp_play, // player
- bow_objtyp_sat, // satellite (moon)
- bow_objtyp_ship, // ship
- bow_objtyp_star, // star
- bow_objtyp_station, // station
- bow_objtyp_wrld, // world (planet)
-} bow_objtyp;
+constexpr double bow_gravConstFac = (bow_massMod*(bow_tmMod*bow_tmMod))/((bow_distMod*bow_distMod*bow_distMod)); // inverse
-typedef enum {
- 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;
+constexpr double bow_gravConst = 0x1.258688101B4BB16Dp-34*bow_gravConstFac; // gravitational constant (s^2*m*t^2)
-typedef enum {
- bow_ship_aq, // aquila
- bow_ship_cas, // cassiopeia
- bow_ship_cent, // centaurus
- bow_ship_eri, // eridanus
- bow_ship_lyra, // lyra
- bow_ship_tau, // taurus
- bow_ship_ursa, // ursa
-} bow_ship;
+[[unsequenced]] double bow_shipMass(bow_ship id);
-typedef enum {
- bow_star_a, // main sequence
- bow_star_b, // main sequence
- bow_star_c, // carbon
- bow_star_f, // main sequence
- bow_star_g, // main sequence
- bow_star_k, // main sequence
- bow_star_l, // brown dwarf
- bow_star_m, // main sequence
- bow_star_n, // neutron star
- bow_star_o, // main sequence
- bow_star_s, // carbon
- bow_star_t, // brown dwarf
- bow_star_w, // worm hole
- bow_star_x, // black hole
- bow_star_y, // brown dwarf
- bow_star_z, // white hole
-} bow_star;
-
-typedef enum {
- bow_station_cor, // coriolis
-} bow_station;
-
-struct bow_impl_obj {
- bow_objtyp typ;
- bow_xyz pos; // astronomical units
- bow_xyz rot; // radians
- bow_xyz posvel; // astronomical units per second
- bow_xyz rotvel; // radians per second
- double mass; // kilograms
- union {
- bow_wrld wrldtyp;
- bow_ship shiptyp;
- bow_star startyp;
- bow_station stationtyp;
- };
- bow_obj * next;
-};
-
-struct bow_impl_objroot {
- bow_obj * objs;
-};
-
-struct bow_impl_playdat {
- char nm[bow_cmdrnmlen+0x1u];
- zap_i04 tm;
- zap_i04 sysid;
- bow_obj ship;
-};
-
-constexpr double bow_distmod = 0x1.16A5D2D3p37; // distance modifier (1 au)
-constexpr double bow_massmod = 0x1p0; // mass modifier
-constexpr double bow_tmmod = 0x1p12; // time modifier
-
-constexpr double bow_gravconstfac = (bow_massmod*(bow_tmmod*bow_tmmod))/((bow_distmod*bow_distmod*bow_distmod)); // inverse
-
-constexpr double bow_gravconst = 0x1.2589EFFFp-34*bow_gravconstfac; // gravitational constant (s^2*m*t^2)
-
-char const * bow_objtypstr(bow_objtyp typ);
-
-[[unsequenced]] double bow_shipmass(bow_ship id);
-
-void bow_gravsys( bow_objroot * sys);
-void bow_gravobjs(bow_objroot * sys,bow_objroot * objs);
+void bow_gravSys( bow_objRoot * sys);
+void bow_gravObjs(bow_objRoot * objs,bow_objRoot const * sys);
void bow_mv( bow_obj * obj);
-void bow_mvobjs( bow_objroot * root);
-
-void bow_sim(bow_objroot * sys,zap_i04 dur);
-
-bow_obj * bow_addobj( bow_objroot * root,bow_obj const * obj);
-void bow_freeobjs(bow_objroot * root);
+void bow_mvObjs( bow_objRoot * root);
-void bow_gensys(bow_objroot * sys,zap_i04 id,zap_i04 tm);
+void bow_sim(bow_objRoot * sys,zap_i04 dur);
diff --git a/bowshock/include/bow/run.h b/bowshock/include/bow/run.h
new file mode 100644
index 0000000..780563e
--- /dev/null
+++ b/bowshock/include/bow/run.h
@@ -0,0 +1,31 @@
+// Copyright 2022-2023 Gabriel Jensen.
+
+#pragma once
+
+#include <bow/bs.h>
+
+#include <GLFW/glfw3.h>
+#include <glad/glad.h>
+#include <signal.h>
+
+typedef struct {
+ GLFWwindow * win;
+ GLuint shdProg;
+} bow_gfxDat;
+
+extern sig_atomic_t volatile bow_gotIntr;
+
+[[noreturn]] void bow_abrt(void);
+[[noreturn]] void bow_quit(bow_gfxDat * gfxdat,bow_stat stat);
+
+bow_obj * bow_addObj( bow_objRoot * root,bow_obj const * obj);
+void bow_freeObjs(bow_objRoot * root);
+
+void bow_genSys(bow_objRoot * sys,zap_i04 id,zap_i04 tm);
+
+bool bow_pollEvts(bow_gfxDat * const gfxdat);
+
+void bow_drw(bow_gfxDat * gfxdat,bow_objRoot * sys,bow_objRoot * objs,float zoom);
+
+bool bow_intro(bow_gfxDat * gfxdat);
+void bow_loop( bow_gfxDat * gfxdat,bow_plDat * pldat);
diff --git a/bowshock/include/bow/sav.h b/bowshock/include/bow/sav.h
index 391f64f..7c850e2 100644
--- a/bowshock/include/bow/sav.h
+++ b/bowshock/include/bow/sav.h
@@ -4,11 +4,11 @@
#include <bow/bs.h>
-#include <zap/bs.h>
+#define bow_savLen ((zap_sz)((zap_sz)0x79u+(zap_sz)bow_cmdrNmLen))
-constexpr zap_i04 bow_savver = 0x6u;
+constexpr zap_i04 bow_savVer = 0x6u;
-#define bow_savlen ((zap_sz)((zap_sz)0x79u+(zap_sz)bow_cmdrnmlen))
+constexpr zap_i8 bow_maxShipId = bow_ship_vip;
/*
Save format:
@@ -34,28 +34,31 @@ constexpr zap_i04 bow_savver = 0x6u;
*/
typedef struct {
- zap_i04 fmtver;
- char cmdrnm[bow_cmdrnmlen];
- zap_i04 tm;
- zap_i04 sysid;
- 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_rstart(bow_playdat * dat);
-
-void bow_cont( bow_playdat * dat,char const * fil);
-void bow_gendat(bow_playdat * dat);
-
-void bow_sav(char const * fil,bow_playdat const * dat);
+ zap_i04 fmtVer;
+ char cmdrNm[bow_cmdrNmLen];
+ zap_i04 tm;
+ zap_i04 sysId;
+ 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_decSav(bow_savDat * buf,zap_i8 const * dat);
+void bow_encSav(zap_i8 * buf,bow_plDat const * dat);
+
+void bow_new(bow_plDat * dat);
+
+void bow_cont( bow_plDat * dat,char const * fil);
+void bow_genDat(bow_plDat * dat);
+
+void bow_sav(char const * fil,bow_plDat const * dat);
diff --git a/bowshock/shader/main.frag.glsl b/bowshock/shader/main.frag.glsl
new file mode 100644
index 0000000..d3ec746
--- /dev/null
+++ b/bowshock/shader/main.frag.glsl
@@ -0,0 +1,7 @@
+#version 400 core
+
+out vec4 col;
+
+void main() {
+ col = vec4(0.7137f,0.0941f,0.2000f,1.0f);
+}
diff --git a/bowshock/shader/main.vert.glsl b/bowshock/shader/main.vert.glsl
new file mode 100644
index 0000000..0bbefa9
--- /dev/null
+++ b/bowshock/shader/main.vert.glsl
@@ -0,0 +1,7 @@
+#version 400 core
+
+in vec3 pos;
+
+void main() {
+ gl_Position = vec4(pos.x,pos.y,pos.z,1.0f);
+}
diff --git a/bowshock/source/bs/chkparams.c b/bowshock/source/bs/chkparams.c
deleted file mode 100644
index 2926cae..0000000
--- a/bowshock/source/bs/chkparams.c
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2022-2023 Gabriel Jensen.
-
-#include <bow/bs.h>
-
-#include <zap/mem.h>
-#include <zap/str.h>
-
-void bow_chkparams(bow_termopts * const optsptr,int const argc,char const * const * argv) {
- char const * const prognm = *argv;
- bow_termopts opts = {
- .hassavpth = false,
- .rstart = false,
- .skip = false,
- };
- if (argc >= 0x2) {
- char const * const * const stop = (argv++)+(zap_sz)argc;
- for (;argv != stop;++argv) {
- char const * param = *argv;
- if (param[0x0u] == '-' && param[0x1u] == '-') {
- param += 0x2u;
- if (zap_streq(param,"help")) bow_help(prognm);
- else if (zap_streq(param,"restart")) opts.rstart = true;
- else if (zap_streq(param,"skip")) opts.skip = true;
- else bow_logerr("invalid parameter \"%s\"",param);
- continue;
- }
- // Else: Interpret it as a save path;
- opts.savpth = param;
- opts.hassavpth = true;
- }
- }
- zap_cp(optsptr,&opts,sizeof (opts));
-}
diff --git a/bowshock/source/bs/getsavpth.c b/bowshock/source/bs/getsavpth.c
deleted file mode 100644
index 173d904..0000000
--- a/bowshock/source/bs/getsavpth.c
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2022-2023 Gabriel Jensen.
-
-#include <bow/bs.h>
-
-#include <flux/stats.h>
-#include <stdlib.h>
-#include <zap/mem.h>
-#include <zap/str.h>
-
-#define bow_setstrlen(ptr,len,str) ((void)(ptr = str,len = sizeof (str)))
-
-char const * bow_getsavpth(void) {
- char const * hmdir = flux_hmdir();
- zap_sz hmdirlen;
- char const * filnm;
- zap_sz filnmlen;
- if (hmdir == nullptr) {
- bow_log("unable to get home directory");
- bow_setstrlen(hmdir,hmdirlen,"./");
- }
- else hmdirlen = zap_strlen(hmdir);
- bow_setstrlen(filnm,filnmlen,".save.bowshock");
- zap_sz pthsz = hmdirlen+filnmlen+0x2u;
- char * pth = malloc(pthsz);
- if (pth == nullptr) {
- bow_log("unable to allocate memory");
- bow_abrt();
- }
- zap_cp(pth,hmdir,hmdirlen);
- pth += hmdirlen;
- *pth++ = '/';
- zap_cp(pth,filnm,filnmlen);
- pth += filnmlen;
- *pth++ = '\x0';
- pth -= pthsz;
- return pth;
-}
diff --git a/bowshock/source/bs/init.c b/bowshock/source/bs/init.c
deleted file mode 100644
index 523eb35..0000000
--- a/bowshock/source/bs/init.c
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2022-2023 Gabriel Jensen.
-
-#include <bow/gfx.h>
-#include <bow/lgc.h>
-#include <bow/sav.h>
-
-#include <inttypes.h>
-#include <stdlib.h>
-#include <zap/str.h>
-
-void bow_init(int const argc,char const * const * const argv) {
- bow_termopts opts;
- bow_chkparams(&opts,argc,argv);
- bow_rawlog("\x1B[0m\x1B[1mBowshock\x1B[0m %" PRIXLEAST64 ".%" PRIXLEAST64 ".%" PRIXLEAST64 " \u2013 Copyright 2022\u20102023 \x1B[1mGabriel Jensen\x1B[0m.\n\n",bow_vermaj,bow_vermin,bow_verpat);
- bow_log("initialising");
- bow_dbglog("debug mode is enabled");
- bow_dbglog("angle unit: %f radians",0x1p0f);
- bow_dbglog("distance unit: %f metres",bow_distmod);
- bow_dbglog("mass unit: %f kilograms",bow_massmod);
- bow_dbglog("time unit: %f seconds",bow_tmmod);
- bow_gfxdat gfxdat;
- bow_initrnd();
- bow_initsig();
- bow_initgfx(&gfxdat);
- {
- zap_i8 const quotid = (zap_i8)bow_rnd() % 0x21u;
- char const * quot;
- char const * src;
- if (bow_getquot(&quot,&src,quotid)) {
- bow_logerr("invalid quote identifier (%" PRIXLEAST8 ")",quotid);
- bow_getquot(&quot,&src,0x0u);
- }
- bow_rawlog("\n%s\n\u2014 %s\n\n",quot,src);
- }
- if (opts.skip || !bow_intro(&gfxdat)) {
- if (!opts.hassavpth) opts.savpth = bow_getsavpth();
- bow_playdat playdat;
- if (opts.rstart) bow_rstart(&playdat);
- else bow_cont(&playdat,opts.savpth);
- bow_loop(&gfxdat,&playdat);
- bow_sav(opts.savpth,&playdat);
- if (!opts.hassavpth) free((char *)opts.savpth);
- }
- bow_quit(&gfxdat,bow_stat_ok);
-}
-
-int main(int const argc,char const * const * argv) {
- bow_init(argc,argv);
-}
diff --git a/bowshock/source/bs/initsig.c b/bowshock/source/bs/initsig.c
deleted file mode 100644
index 35ceb59..0000000
--- a/bowshock/source/bs/initsig.c
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2022-2023 Gabriel Jensen.
-
-#include <bow/bs.h>
-
-#include <signal.h>
-
-sig_atomic_t volatile bow_gotintr;
-
-static void bow_intrhandl(int const sig) {
- signal(sig,bow_intrhandl); // Ignore the return value.
- bow_gotintr = 0x1;
-}
-
-void bow_initsig(void) {
- bow_log("initialising signal handlers");
- bow_gotintr = 0x0;
- if (signal(SIGINT,bow_intrhandl) == SIG_ERR) {
- bow_log("unable to set signal handler");
- bow_abrt();
- }
-}
diff --git a/bowshock/source/bs/loop.c b/bowshock/source/bs/loop.c
deleted file mode 100644
index 0dcd02a..0000000
--- a/bowshock/source/bs/loop.c
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright 2022-2023 Gabriel Jensen.
-
-#include <bow/gfx.h>
-#include <bow/lgc.h>
-#include <bow/sav.h>
-
-#include <GLFW/glfw3.h>
-#include <flux/io.h>
-#include <inttypes.h>
-#include <math.h>
-#include <stdlib.h>
-#include <zap/mem.h>
-
-static void bow_scrllhandl(GLFWwindow * win,[[maybe_unused]] double const xoff,double const yoff) {
- bow_gfxdat * dat = glfwGetWindowUserPointer(win);
- dat->zoom *= powf(0x1.1p0f,0x0p0f-(float)yoff);
-}
-
-void bow_loop(bow_gfxdat * gfxdatptr,bow_playdat * playdatptr) {
- bow_log("entering main loop");
- bow_gfxdat gfxdat;
- bow_playdat playdat;
- zap_cp(&gfxdat, gfxdatptr, sizeof (gfxdat));
- zap_cp(&playdat,playdatptr,sizeof (playdat));
- glfwSetWindowUserPointer(gfxdat.win,&gfxdat);
- bow_objroot sysroot; // For stellar bodies.
- bow_objroot objroot = { // For miscellaneous objects (canisters, ships...).
- .objs = nullptr,
- };
- bow_gensys(&sysroot,playdat.sysid,playdat.tm);
- bow_obj objtmp = {
- .typ = bow_objtyp_can,
- .pos = {
- .x = 0x0p0,
- .y = -0x2p0,
- .z = 0x0p0,
- },
- .rot = {
- .x = 0x0p0,
- .y = 0x0p0,
- .z = 0x0p0,
- },
- .posvel = {
- .x = -0x1p-12,
- .y = 0x0p0,
- .z = 0x0p0,
- },
- .rotvel = {
- .x = 0x0p0,
- .y = 0x0p0,
- .z = 0x0p0,
- },
- .mass = 0x1p0,
- };
- bow_addobj(&objroot,&objtmp);
- glfwSetScrollCallback(gfxdat.win,bow_scrllhandl);
- for (;;++playdat.tm) {
- glfwPollEvents();
- if (bow_gotintr) {
- bow_log("got interrupt");
- glfwSetWindowShouldClose(gfxdat.win,GLFW_TRUE);
- }
- if (glfwWindowShouldClose(gfxdat.win)) break;
- // Calculate gravitations:
- bow_gravsys(&sysroot);
- bow_gravobjs(&sysroot,&objroot);
- // Move objects:
- bow_mvobjs(&sysroot);
- bow_mvobjs(&objroot);
- // Render:
- bow_drw(&gfxdat,&sysroot,&objroot,gfxdat.zoom);
- }
- glfwSetScrollCallback(gfxdat.win,nullptr);
- bow_freeobjs(&sysroot);
- zap_cp(gfxdatptr, &gfxdat, sizeof (gfxdat));
- zap_cp(playdatptr,&playdat,sizeof (playdat));
-}
diff --git a/bowshock/source/lgc/objtypstr.c b/bowshock/source/bs/objTypStr.c
index ae0a300..9093014 100644
--- a/bowshock/source/lgc/objtypstr.c
+++ b/bowshock/source/bs/objTypStr.c
@@ -2,30 +2,25 @@
#include <bow/lgc.h>
-#include <stddef.h>
-
-char const * bow_objtypstr(bow_objtyp const typ) {
+char const * bow_objTypStr(bow_objTyp const typ) {
char const * str;
switch (typ) {
- case bow_objtyp_can:
+ case bow_objTyp_can:
str = "canister";
break;
- case bow_objtyp_play:
+ case bow_objTyp_pl:
str = "player";
break;
- case bow_objtyp_sat:
- str = "satellite";
- break;
- case bow_objtyp_ship:
+ case bow_objTyp_ship:
str = "ship";
break;
- case bow_objtyp_star:
+ case bow_objTyp_star:
str = "star";
break;
- case bow_objtyp_station:
+ case bow_objTyp_station:
str = "station";
break;
- case bow_objtyp_wrld:
+ case bow_objTyp_wrld:
str = "world";
break;
}
diff --git a/bowshock/source/bs/rnd.c b/bowshock/source/bs/rnd.c
index 25e4932..f7728f0 100644
--- a/bowshock/source/bs/rnd.c
+++ b/bowshock/source/bs/rnd.c
@@ -3,7 +3,6 @@
#include <bow/bs.h>
#include <stdlib.h>
-#include <zap/bs.h>
static_assert(sizeof (int) == sizeof (zap_i02));
@@ -13,5 +12,6 @@ zap_i04 bow_rnd(void) {
zap_i02 const rnd0 = (zap_i02)rand();
zap_i02 const rnd1 = (zap_i02)rand();
zap_i04 const rnd = (zap_i04)rnd0 | (zap_i04)rnd1 >> 0x4u;
+
return rnd;
}
diff --git a/bowshock/source/gfx/drw.c b/bowshock/source/gfx/drw.c
deleted file mode 100644
index 2d45362..0000000
--- a/bowshock/source/gfx/drw.c
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2022-2023 Gabriel Jensen.
-
-#include <bow/gfx.h>
-#include <bow/lgc.h>
-
-#include <GLFW/glfw3.h>
-
-static void bow_drwobjs(bow_objroot * const root,float const zoom) {
- float const frm = 0x1p0*zoom;
- for (bow_obj * obj = root->objs;obj != nullptr;obj = obj->next) {
- GLfloat const posx = (GLfloat)obj->pos.x/frm;
- GLfloat const posy = (GLfloat)obj->pos.y/frm;
- GLfloat const posz = (GLfloat)obj->pos.z/frm;
- glVertex3f(posx,posy,posz);
- }
-}
-
-void bow_drw(bow_gfxdat * gfxdat,bow_objroot * const sys,bow_objroot * const objs,float const zoom) {
- glClear(GL_COLOR_BUFFER_BIT);
- glPointSize(0x2p0);
- glBegin(GL_POINTS);
- bow_drwobjs(sys,zoom);
- bow_drwobjs(objs,zoom);
- glEnd();
- glfwSwapBuffers(gfxdat->win);
-}
diff --git a/bowshock/source/gfx/initgfx.c b/bowshock/source/gfx/initgfx.c
deleted file mode 100644
index 6e228eb..0000000
--- a/bowshock/source/gfx/initgfx.c
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2022-2023 Gabriel Jensen.
-
-#include <bow/gfx.h>
-
-#include <GLFW/glfw3.h>
-#include <math.h>
-#include <zap/mem.h>
-
-void bow_initgfx(bow_gfxdat * const datptr) {
- bow_log("initialising graphics");
- bow_gfxdat dat;
- bow_dbglog("initialising glfw");
- if (!glfwInit()) {
- bow_logerr("unable to initialise glfw");
- bow_abrt();
- }
- bow_dbglog("initialising window");
- glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR,0x3);
- glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR,0x0);
- glfwWindowHint(GLFW_DECORATED, GLFW_FALSE);
- glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);
- GLFWwindow * win = glfwCreateWindow(0x400,0x240,"Bowshock",glfwGetPrimaryMonitor(),nullptr);
- if (win == nullptr) {
- bow_logerr("unable to open window");
- bow_abrt();
- }
- glfwMakeContextCurrent(win);
- int frmbufw;
- int frmbufh;
- glfwGetFramebufferSize(win,&frmbufw,&frmbufh);
- glViewport(0x0,0x0,frmbufw,frmbufh);
- glOrtho(-0x1p0,0x1p0,-0x1p0,0x1p0,0x0p0,0x0p0);
- glClearColor(0x0p0,0x0p0,0x0p0,0x1p0);
- glClear(GL_COLOR_BUFFER_BIT);
- glfwSwapBuffers(win);
- glfwSwapInterval(0x1);
- dat.win = win;
- dat.zoom = 0x4p0f;
- zap_cp(datptr,&dat,sizeof (dat));
-}
diff --git a/bowshock/source/init/chkParams.c b/bowshock/source/init/chkParams.c
new file mode 100644
index 0000000..839fd57
--- /dev/null
+++ b/bowshock/source/init/chkParams.c
@@ -0,0 +1,40 @@
+// Copyright 2022-2023 Gabriel Jensen.
+
+#include <bow/init.h>
+
+#include <zap/mem.h>
+#include <zap/str.h>
+
+void bow_chkParams(bow_termOpts * const optsptr,int const argc,char const * const * argv) {
+ char const * const progNm = *argv;
+
+ bow_termOpts opts = {
+ .hasSavPth = false,
+ .newSav = false,
+ .skip = false,
+ };
+
+ unlikely (argc >= 0x2) {
+ char const * const * const stop = (argv++)+(zap_sz)argc;
+
+ for (;argv != stop;++argv) {
+ char const * param = *argv;
+
+ if (param[0x0u] == '-' && param[0x1u] == '-') {
+ param += 0x2u;
+ if (zap_streq(param,"credits")) bow_cred();
+ else if (zap_streq(param,"help")) bow_help(progNm);
+ else if (zap_streq(param,"new")) opts.newSav = true;
+ else if (zap_streq(param,"skip")) opts.skip = true;
+ else bow_logErr("invalid parameter \"%s\"",param);
+ continue;
+ }
+
+ // Else: Interpret it as a save path.
+ opts.savPth = param;
+ opts.hasSavPth = true;
+ }
+ }
+
+ zap_cp(optsptr,&opts,sizeof (opts));
+}
diff --git a/bowshock/source/init/compShd.c b/bowshock/source/init/compShd.c
new file mode 100644
index 0000000..37131bb
--- /dev/null
+++ b/bowshock/source/init/compShd.c
@@ -0,0 +1,97 @@
+// Copyright 2022-2023 Gabriel Jensen.
+
+#include <bow/init.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <glad/glad.h>
+#include <zap/mem.h>
+#include <zap/str.h>
+
+#define bow_shdFilExt ("glsl")
+
+bool bow_compShd(GLuint * const refPtr,char const * const nm,GLenum const typ) {
+ char const * typStr;
+
+ char const * typExt;
+ zap_sz typExtLen;
+ switch (typ) {
+ default:
+ bow_logErr("bad shader type %lX",(unsigned long)typ);
+ bow_abrt();
+ case GL_FRAGMENT_SHADER:
+ bow_setStrLen(typExt,typExtLen,"frag");
+ typStr = "fragment";
+ break;
+ case GL_VERTEX_SHADER:
+ bow_setStrLen(typExt,typExtLen,"vert");
+ typStr = "vertex";
+ break;
+ }
+
+ char const * dir;
+ zap_sz dirLen;
+ bow_setStrLen(dir,dirLen,bow_datDir "/shaders");
+
+ zap_sz const nmLen = zap_strlen(nm);
+ zap_sz const pthLen = dirLen + 0x1u + nmLen + 0x1u + typExtLen + 0x1u + sizeof (bow_shdFilExt);
+
+ char * pth = malloc(pthLen + 0x1u);
+ if (pth == nullptr) {
+ bow_logErr("unable to allocate memory for shader source path");
+ bow_abrt();
+ }
+
+ pth = zap_cp(pth,dir,dirLen).dest;
+ *pth++ = '/';
+ pth = zap_cp(pth,nm,nmLen).dest;
+ *pth++ = '.';
+ pth = zap_cp(pth,typExt,typExtLen).dest;
+ *pth++ = '.';
+ pth = zap_cp(pth,bow_shdFilExt,sizeof (bow_shdFilExt)).dest;
+ *pth = '\x00';
+ pth -= pthLen;
+
+ bow_dbgLog("compiling %s shader at \"%s\"",typStr,pth);
+
+ FILE * fp = fopen(pth,"r");
+
+ free(pth);
+
+ if (fp == nullptr) {
+ bow_logErr("unable to open shader source");
+ return true;
+ }
+
+ fseek(fp,0x0,SEEK_END);
+ zap_sz const filsz = (zap_sz)ftell(fp);
+ rewind(fp);
+
+ static_assert(sizeof (GLchar) == sizeof (char));
+ GLchar * const src = malloc(filsz + 0x1u);
+
+ if (src == nullptr) {
+ bow_logErr("unable to allocate memory for shader source");
+ return true;
+ }
+
+ fread(src,sizeof (GLchar),filsz,fp);
+ fclose(fp);
+
+ src[filsz] = '\x00';
+
+ GLuint shdRef = glCreateShader(typ);
+ glShaderSource(shdRef,0x1,(GLchar const * const *)&src,nullptr);
+
+ free(src);
+
+ glCompileShader(shdRef);
+
+ GLint compStat;
+ glGetShaderiv(shdRef,GL_COMPILE_STATUS,&compStat);
+ unlikely (compStat == GL_FALSE) return true;
+
+ *refPtr = shdRef;
+
+ return false;
+}
diff --git a/bowshock/source/init/compShdProg.c b/bowshock/source/init/compShdProg.c
new file mode 100644
index 0000000..0112485
--- /dev/null
+++ b/bowshock/source/init/compShdProg.c
@@ -0,0 +1,36 @@
+// Copyright 2022-2023 Gabriel Jensen.
+
+#include <bow/init.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <glad/glad.h>
+#include <zap/mem.h>
+#include <zap/str.h>
+
+void bow_compShdProg(GLuint * const shdProgPtr,char const * const nm) {
+ bow_log("compiling shader program \"%s\"",nm);
+
+ GLuint vtxShd;
+ GLuint fragShd;
+
+ bool err = false;
+
+ err |= bow_compShd(&vtxShd, nm, GL_VERTEX_SHADER);
+ err |= bow_compShd(&fragShd,nm,GL_FRAGMENT_SHADER);
+
+ if (err) {
+ bow_logErr("unable to compile shaders");
+ bow_abrt();
+ }
+
+ GLuint shdProg = glCreateProgram();
+ glAttachShader(shdProg,vtxShd);
+ glAttachShader(shdProg,fragShd);
+ glLinkProgram(shdProg);
+
+ glDeleteShader(vtxShd);
+ glDeleteShader(fragShd);
+
+ *shdProgPtr = shdProg;
+}
diff --git a/bowshock/source/init/cred.c b/bowshock/source/init/cred.c
new file mode 100644
index 0000000..fac3ed3
--- /dev/null
+++ b/bowshock/source/init/cred.c
@@ -0,0 +1,43 @@
+// Copyright 2022-2023 Gabriel Jensen.
+
+#include <bow/init.h>
+
+#include <flux/io.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+void bow_cred(void) {
+ FILE * fp = fopen(bow_datDir "/CREDITS.txt","r");
+
+ fseek(fp,0x0,SEEK_END);
+ zap_sz const filsz = (zap_sz)ftell(fp);
+ rewind(fp);
+
+ char * cred = malloc(filsz + 0x3u);
+ char * const credstart = cred;
+
+ if (cred == nullptr) {
+ bow_logErr("unable to allocate memory");
+ exit(EXIT_FAILURE);
+ }
+
+ *cred++ = '\n';
+
+ cred += fread(cred,sizeof (char),filsz,fp);
+ fclose(fp);
+
+ *cred++ = '\n';
+ *cred++ = '\x00';
+
+ cred = credstart;
+
+ flux_err err = flux_wrstr(flux_defout,cred);
+
+ if (err) {
+ bow_logErr("unable to write to defout");
+ }
+
+ free(cred);
+
+ exit(EXIT_SUCCESS);
+}
diff --git a/bowshock/source/bs/getquot.c b/bowshock/source/init/getQuot.c
index 2f5bbe3..243990b 100644
--- a/bowshock/source/bs/getquot.c
+++ b/bowshock/source/init/getQuot.c
@@ -1,11 +1,12 @@
// Copyright 2022-2023 Gabriel Jensen.
-#include <bow/bs.h>
+#include <bow/init.h>
-bool bow_getquot(char const * * const quot,char const * * src,zap_i8 const id) {
+bool bow_getQuot(char const * * const quot,char const * * src,zap_i8 const id) {
switch (id) {
default:
return true;
+
case 0x0u:
*quot = "You gotta be heaven to see heaven.";
*src = "Jim Carrey";
@@ -135,9 +136,14 @@ bool bow_getquot(char const * * const quot,char const * * src,zap_i8 const id) {
*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.";
+ *quot = "I have always wished for my computer to be as easy to use as my telephone.\nMy wish has come true because I can no longer figure out how to use my telephone.";
*src = "Bjarne Stroustrup";
break;
+ case 0x21u:
+ *quot = "There is no mathematical sibstitute for philosophy.";
+ *src = "Saul Aaron Kripke";
+ break;
}
+
return false;
}
diff --git a/bowshock/source/init/getSavPth.c b/bowshock/source/init/getSavPth.c
new file mode 100644
index 0000000..88d5b30
--- /dev/null
+++ b/bowshock/source/init/getSavPth.c
@@ -0,0 +1,40 @@
+// Copyright 2022-2023 Gabriel Jensen.
+
+#include <bow/init.h>
+
+#include <flux/stats.h>
+#include <stdlib.h>
+#include <zap/mem.h>
+#include <zap/str.h>
+
+char const * bow_getSavPth(void) {
+ char const * hmDir = flux_hmdir();
+ char const * filNm;
+ zap_sz hmDirLen;
+ zap_sz filNmLen;
+
+ unlikely (hmDir == nullptr) {
+ bow_log("unable to get home directory");
+ bow_setStrLen(hmDir,hmDirLen,"./");
+ }
+ else hmDirLen = zap_strlen(hmDir);
+
+ bow_setStrLen(filNm,filNmLen,".save.bowshock");
+
+ zap_sz pthLen = hmDirLen+filNmLen+0x1u;
+ char * pth = malloc(pthLen + 0x1u);
+
+ unlikely (pth == nullptr) {
+ bow_log("unable to allocate memory");
+ bow_abrt();
+ }
+
+ pth = zap_cp(pth,hmDir,hmDirLen).dest;
+ *pth++ = '/';
+ pth = zap_cp(pth,filNm,filNmLen).dest;
+ *pth = '\x00';
+
+ pth -= pthLen;
+
+ return pth;
+}
diff --git a/bowshock/source/bs/help.c b/bowshock/source/init/help.c
index c362d20..6fa5b8d 100644
--- a/bowshock/source/bs/help.c
+++ b/bowshock/source/init/help.c
@@ -1,11 +1,11 @@
// Copyright 2022-2023 Gabriel Jensen.
-#include <bow/bs.h>
+#include <bow/init.h>
#include <inttypes.h>
#include <stdlib.h>
-void bow_help(char const * const prognm) {
+void bow_help(char const * const progNm) {
bow_rawlog(
"\n"
"bowshock %" PRIXLEAST64 ".%" PRIXLEAST64 ".%" PRIXLEAST64 "\n"
@@ -17,6 +17,7 @@ void bow_help(char const * const prognm) {
" --help Print help screen\n"
" --restart Generate default commander\n"
"\n",
- bow_vermaj,bow_vermin,bow_verpat,prognm);
+ bow_verMaj,bow_verMin,bow_verPat,progNm);
+
exit(EXIT_SUCCESS);
}
diff --git a/bowshock/source/init/init.c b/bowshock/source/init/init.c
new file mode 100644
index 0000000..be6f089
--- /dev/null
+++ b/bowshock/source/init/init.c
@@ -0,0 +1,56 @@
+// Copyright 2022-2023 Gabriel Jensen.
+
+#include <bow/init.h>
+#include <bow/lgc.h>
+#include <bow/run.h>
+#include <bow/sav.h>
+
+#include <inttypes.h>
+#include <stdlib.h>
+#include <zap/str.h>
+
+void bow_init(int const argc,char const * const * const argv) {
+ bow_termOpts opts;
+ bow_chkParams(&opts,argc,argv);
+
+ bow_priQuot();
+
+ bow_rawlog("\x1B[0m\x1B[1mBowshock\x1B[0m %" PRIXLEAST64 ".%" PRIXLEAST64 ".%" PRIXLEAST64 " \u2013 Copyright 2022\u20102023 \x1B[1mGabriel Jensen\x1B[0m.\n\n",bow_verMaj,bow_verMin,bow_verPat);
+
+ bow_log("initialising");
+
+ bow_dbgLog("debug mode is enabled");
+ bow_dbgLog("data directory at \"" bow_datDir "\"");
+ bow_dbgLog("angle unit: %.3f radians",0x1p0f);
+ bow_dbgLog("distance unit: %.3f metres",bow_distMod);
+ bow_dbgLog("mass unit: %.3f kilograms",bow_massMod);
+ bow_dbgLog("time unit: %.3f seconds",bow_tmMod);
+ bow_dbgLog("gravitational constant: %f (factor: %f))",bow_gravConst,bow_gravConstFac);
+
+ bow_gfxDat gfxdat;
+
+ bow_initRnd();
+ bow_initSig();
+ bow_initGfx(&gfxdat);
+
+ likely (opts.skip || !bow_intro(&gfxdat)) {
+ if (!opts.hasSavPth) opts.savPth = bow_getSavPth();
+
+ bow_plDat pldat;
+
+ if (opts.newSav) bow_new(&pldat);
+ else bow_cont(&pldat,opts.savPth);
+
+ bow_loop(&gfxdat,&pldat);
+
+ bow_sav(opts.savPth,&pldat);
+
+ if (!opts.hasSavPth) free((char *)opts.savPth);
+ }
+
+ bow_quit(&gfxdat,bow_stat_ok);
+}
+
+int main(int const argc,char const * const * argv) {
+ bow_init(argc,argv);
+}
diff --git a/bowshock/source/init/initGfx.c b/bowshock/source/init/initGfx.c
new file mode 100644
index 0000000..34a04f5
--- /dev/null
+++ b/bowshock/source/init/initGfx.c
@@ -0,0 +1,50 @@
+// Copyright 2022-2023 Gabriel Jensen.
+
+#include <bow/init.h>
+
+#include <GLFW/glfw3.h>
+#include <glad/glad.h>
+#include <math.h>
+#include <zap/mem.h>
+
+void bow_initGfx(bow_gfxDat * const datptr) {
+ bow_log("initialising graphics");
+
+ bow_gfxDat dat;
+
+ bow_dbgLog("initialising glfw");
+ unlikely (!glfwInit()) {
+ bow_logErr("unable to initialise glfw");
+ bow_abrt();
+ }
+
+ bow_dbgLog("initialising window");
+ glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR,0x4);
+ glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR,0x0);
+ glfwWindowHint(GLFW_DECORATED, GLFW_FALSE);
+ glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
+ glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);
+ glfwWindowHint(GLFW_SAMPLES, 0x8);
+ GLFWwindow * win = glfwCreateWindow(0x400,0x240,"Bowshock",glfwGetPrimaryMonitor(),nullptr);
+ unlikely (win == nullptr) {
+ bow_logErr("unable to open window");
+ bow_abrt();
+ }
+
+ bow_dbgLog("initialising context");
+ glfwMakeContextCurrent(win);
+ gladLoadGL();
+ glEnable(GL_MULTISAMPLE);
+ GLFWvidmode const * vidmd = glfwGetVideoMode(glfwGetPrimaryMonitor());
+ glViewport(0x0,0x0,vidmd->width,vidmd->height);
+ glClearColor(0x0p0,0x0p0,0x0p0,0x1p0);
+ glClear(GL_COLOR_BUFFER_BIT);
+ glfwSwapBuffers(win);
+ glfwSwapInterval(0x1);
+
+ bow_compShdProg(&dat.shdProg,"main");
+
+ dat.win = win;
+
+ zap_cp(datptr,&dat,sizeof (dat));
+}
diff --git a/bowshock/source/bs/initrnd.c b/bowshock/source/init/initRnd.c
index d877f3b..886adc3 100644
--- a/bowshock/source/bs/initrnd.c
+++ b/bowshock/source/init/initRnd.c
@@ -1,11 +1,12 @@
// Copyright 2022-2023 Gabriel Jensen.
-#include <bow/bs.h>
+#include <bow/init.h>
#include <stdlib.h>
#include <time.h>
-void bow_initrnd(void) {
- bow_log("initialising random generator");
+void bow_initRnd(void) {
+ bow_log("initialising random number generator");
+
srand((unsigned int)time(nullptr));
}
diff --git a/bowshock/source/init/initSig.c b/bowshock/source/init/initSig.c
new file mode 100644
index 0000000..87b694c
--- /dev/null
+++ b/bowshock/source/init/initSig.c
@@ -0,0 +1,23 @@
+// Copyright 2022-2023 Gabriel Jensen.
+
+#include <bow/init.h>
+
+#include <signal.h>
+
+sig_atomic_t volatile bow_gotIntr;
+
+static void bow_intrHand(int const sig) {
+ signal(sig,bow_intrHand); // Ignore the return value: We can't do anything (meaningful) about it anyways.
+ bow_gotIntr = 0x1;
+}
+
+void bow_initSig(void) {
+ bow_log("initialising signal handlers");
+
+ bow_gotIntr = 0x0;
+
+ unlikely (signal(SIGINT,bow_intrHand) == SIG_ERR) {
+ bow_log("unable to set signal handler");
+ bow_abrt();
+ }
+}
diff --git a/bowshock/source/init/priQuot.c b/bowshock/source/init/priQuot.c
new file mode 100644
index 0000000..bd23f2a
--- /dev/null
+++ b/bowshock/source/init/priQuot.c
@@ -0,0 +1,22 @@
+// Copyright 2022-2023 Gabriel Jensen.
+
+#include <bow/init.h>
+
+#include <inttypes.h>
+#include <time.h>
+#include <stdlib.h>
+
+void bow_priQuot(void) {
+ srand((unsigned int)time(nullptr));
+ zap_i8 const quotId = (zap_i8)rand() % 0x22u;
+
+ char const * quot;
+ char const * src;
+
+ unlikely (bow_getQuot(&quot,&src,quotId)) {
+ bow_logErr("invalid quote identifier (%" PRIXLEAST8 ")",quotId);
+ bow_getQuot(&quot,&src,0x0u);
+ }
+
+ bow_rawlog("\n%s\n\u2014 %s\n\n",quot,src);
+}
diff --git a/bowshock/source/lgc/grav.c b/bowshock/source/lgc/grav.c
index 7ef2106..3d80333 100644
--- a/bowshock/source/lgc/grav.c
+++ b/bowshock/source/lgc/grav.c
@@ -10,15 +10,19 @@ static void bow_grav1(bow_obj * obj,bow_obj * par) {
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 angy = atan2(disty,distx);
double const angz = atan2(distz,distx);
- double acc = par->mass/(dist*dist)*bow_gravconst;
+
+ double acc = par->mass/(dist*dist)*bow_gravConst;
+
double const vx = cos(angy)*acc;
double const vy = sin(angy)*acc;
double const vz = sin(angz)*acc;
- obj->posvel.x += vx;
- obj->posvel.y += vy;
- obj->posvel.z += vz;
+
+ obj->posVel.x += vx;
+ obj->posVel.y += vy;
+ obj->posVel.z += vz;
}
static void bow_grav2(bow_obj * obj0,bow_obj * obj1) {
@@ -26,11 +30,14 @@ static void bow_grav2(bow_obj * obj0,bow_obj * obj1) {
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/(dist*dist);
+
+ double acc0 = bow_gravConst/(dist*dist);
double const acc1 = acc0*obj0->mass; // This is negative.
acc0 *= obj1->mass;
+
double vx0 = cos(angy);
double vy0 = sin(angy);
double vz0 = sin(angz);
@@ -40,21 +47,22 @@ static void bow_grav2(bow_obj * obj0,bow_obj * obj1) {
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;
+
+ obj0->posVel.x += vx0;
+ obj0->posVel.y += vy0;
+ obj0->posVel.z += vz0;
+ obj1->posVel.x -= vx1;
+ obj1->posVel.y -= vy1;
+ obj1->posVel.z -= vz1;
}
-void bow_gravsys(bow_objroot * const sys) {
+void bow_gravSys(bow_objRoot * const sys) {
for (bow_obj * obj0 = sys->objs;obj0 != nullptr;obj0 = obj0->next)
for (bow_obj * obj1 = obj0->next;obj1 != nullptr;obj1 = obj1->next)
bow_grav2(obj0,obj1);
}
-void bow_gravobjs(bow_objroot * const sys,bow_objroot * const objs) {
+void bow_gravObjs(bow_objRoot * const objs,bow_objRoot const * const sys) {
for (bow_obj * obj = objs->objs;obj != nullptr;obj = obj->next)
for (bow_obj * par = sys->objs;par != nullptr;par = par->next)
bow_grav1(obj,par);
diff --git a/bowshock/source/lgc/mv.c b/bowshock/source/lgc/mv.c
index d83bbf9..ac27e4e 100644
--- a/bowshock/source/lgc/mv.c
+++ b/bowshock/source/lgc/mv.c
@@ -6,15 +6,15 @@
#include <zap/mem.h>
void bow_mv(bow_obj * obj) {
- 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;
+ 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;
}
-void bow_mvobjs(bow_objroot * root) {
+void bow_mvObjs(bow_objRoot * root) {
for (bow_obj * obj = root->objs;obj != nullptr;obj = obj->next)
bow_mv(obj);
}
diff --git a/bowshock/source/lgc/shipMass.c b/bowshock/source/lgc/shipMass.c
new file mode 100644
index 0000000..05f2e2b
--- /dev/null
+++ b/bowshock/source/lgc/shipMass.c
@@ -0,0 +1,10 @@
+// Copyright 2022-2023 Gabriel Jensen.
+
+#include <bow/lgc.h>
+
+double bow_shipMass([[maybe_unused]] bow_ship const id) {
+ double mass = 0x100p0;
+ mass /= bow_massMod;
+
+ return mass;
+}
diff --git a/bowshock/source/lgc/shipmass.c b/bowshock/source/lgc/shipmass.c
deleted file mode 100644
index 0b5f768..0000000
--- a/bowshock/source/lgc/shipmass.c
+++ /dev/null
@@ -1,7 +0,0 @@
-// Copyright 2022-2023 Gabriel Jensen.
-
-#include <bow/lgc.h>
-
-double bow_shipmass([[maybe_unused]] bow_ship const id) {
- return 0x100p0;
-}
diff --git a/bowshock/source/lgc/sim.c b/bowshock/source/lgc/sim.c
index 69a61e4..86327f2 100644
--- a/bowshock/source/lgc/sim.c
+++ b/bowshock/source/lgc/sim.c
@@ -4,10 +4,11 @@
#include <inttypes.h>
-void bow_sim(bow_objroot * const sys,zap_i04 const dur) {
+void bow_sim(bow_objRoot * const sys,zap_i04 const dur) {
bow_log("simulating for (%" PRIXLEAST64 ") time units",dur);
+
for (zap_i04 i = 0x0u;i <= dur;++i) {
- bow_gravsys(sys);
- bow_mvobjs(sys);
+ bow_gravSys(sys);
+ bow_mvObjs(sys);
}
}
diff --git a/bowshock/source/bs/abrt.c b/bowshock/source/run/abrt.c
index 768e403..29a3102 100644
--- a/bowshock/source/bs/abrt.c
+++ b/bowshock/source/run/abrt.c
@@ -1,10 +1,11 @@
// Copyright 2022-2023 Gabriel Jensen.
-#include <bow/bs.h>
+#include <bow/run.h>
#include <stdlib.h>
void bow_abrt(void) {
bow_log("aborting");
+
abort();
}
diff --git a/bowshock/source/lgc/addobj.c b/bowshock/source/run/addObj.c
index 11f4e60..f7d25ae 100644
--- a/bowshock/source/lgc/addobj.c
+++ b/bowshock/source/run/addObj.c
@@ -1,19 +1,21 @@
// Copyright 2022-2023 Gabriel Jensen.
-#include <bow/lgc.h>
+#include <bow/run.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 * 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_logerr("unable to allocate memory for object");
+ unlikely (obj == nullptr) {
+ bow_logErr("unable to allocate memory for object");
bow_abrt();
}
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/run/freeObjs.c
index 18fd356..0a8ecd0 100644
--- a/bowshock/source/lgc/freeobjs.c
+++ b/bowshock/source/run/freeObjs.c
@@ -1,16 +1,16 @@
// Copyright 2022-2023 Gabriel Jensen.
-#include <bow/lgc.h>
+#include <bow/run.h>
#include <stdlib.h>
#include <zap/mem.h>
-void bow_freeobjs(bow_objroot * const root) {
- bow_dbglog("freeing objects");
+void bow_freeObjs(bow_objRoot * const root) {
+ bow_dbgLog("freeing objects");
bow_obj * obj;
bow_obj * next;
for (obj = root->objs;obj != nullptr;obj = next) {
- bow_dbglog("freeing object of type %s",bow_objtypstr(obj->typ));
+ bow_dbgLog("freeing object of type %s",bow_objTypStr(obj->typ));
next = obj->next;
free(obj);
}
diff --git a/bowshock/source/lgc/gensys.c b/bowshock/source/run/genSys.c
index 9f3f226..e8161a3 100644
--- a/bowshock/source/lgc/gensys.c
+++ b/bowshock/source/run/genSys.c
@@ -1,15 +1,17 @@
// Copyright 2022-2023 Gabriel Jensen.
#include <bow/lgc.h>
+#include <bow/run.h>
#include <inttypes.h>
-void bow_gensys(bow_objroot * const sys,zap_i04 const id,zap_i04 const tm) {
+void bow_genSys(bow_objRoot * const sys,zap_i04 const id,zap_i04 const tm) {
bow_log("generating system (%" PRIXLEAST64 ")",id);
+
sys->objs = nullptr;
bow_obj objtmp;
objtmp = (bow_obj) {
- .typ = bow_objtyp_star,
+ .typ = bow_objTyp_star,
.pos = {
.x = 0x0p0,
.y = 0x0p0,
@@ -20,23 +22,23 @@ void bow_gensys(bow_objroot * const sys,zap_i04 const id,zap_i04 const tm) {
.y = 0x0p0,
.z = 0x0p0,
},
- .posvel = {
+ .posVel = {
.x = 0x0p0,
.y = 0x0p0,
.z = 0x0p0,
},
- .rotvel = {
+ .rotVel = {
.x = 0x0p0,
.y = 0x0p0,
.z = 0x0p0,
},
- .mass = 0x19'1930'A5E7'5F0C'1918'1400'0000p0,
- .startyp = bow_star_g,
+ .mass = 0x1p0,
+ .starTyp = bow_star_g,
// next will be overwritten anyways.
};
- bow_addobj(sys,&objtmp);
+ bow_addObj(sys,&objtmp);
objtmp = (bow_obj) {
- .typ = bow_objtyp_wrld,
+ .typ = bow_objTyp_wrld,
.pos = {
.x = 0x0p0,
.y = 0x1.F76F144Dp-1,
@@ -47,19 +49,20 @@ void bow_gensys(bow_objroot * const sys,zap_i04 const id,zap_i04 const tm) {
.y = 0x0p0,
.z = 0x0p0,
},
- .posvel = {
- .x = 0x1.B2D06FF3p-23*bow_tmmod,
+ .posVel = {
+ .x = 0x1.B2D06FF3p-23*bow_tmMod,
.y = 0x0p0,
.z = 0x0p0,
},
- .rotvel = {
+ .rotVel = {
.x = 0x0p0,
.y = 0x0p0,
.z = 0x1.31DB66BBp-15,
},
- .mass = 0x4'F0A9'9C58'8848'32A0'0000p0,
- .wrldtyp = bow_wrld_rck,
+ .mass = 0x1.931AFC649369998Fp-19,
+ .wrldTyp = bow_wrld_rck,
};
- bow_addobj(sys,&objtmp);
+ bow_addObj(sys,&objtmp);
+
bow_sim(sys,tm);
}
diff --git a/bowshock/source/bs/intro.c b/bowshock/source/run/intro.c
index 8032405..a8caee2 100644
--- a/bowshock/source/bs/intro.c
+++ b/bowshock/source/run/intro.c
@@ -1,51 +1,51 @@
// Copyright 2022-2023 Gabriel Jensen.
-#include <bow/gfx.h>
-#include <bow/lgc.h>
+#include <bow/run.h>
#include <GLFW/glfw3.h>
#include <zap/mem.h>
-bool bow_intro(bow_gfxdat * const gfxdatptr) {
+bool bow_intro(bow_gfxDat * const gfxdatptr) {
bow_log("starting intro");
- bow_gfxdat gfxdat;
+
+ bow_gfxDat gfxdat;
zap_cp(&gfxdat,gfxdatptr,sizeof (gfxdat));
+
bool quit = false;
GLfloat const bowr = 0x1.6D6D6D6Ep-1;
GLfloat const bowg = 0x1.81818182p-4;
GLfloat const bowb = 0x1.9999999Ap-3;
- glClearColor(bowr,bowg,bowb,0x1p0);
- glClear(GL_COLOR_BUFFER_BIT);
- glfwSwapBuffers(gfxdat.win);
+
glfwSetTime(0x0p0);
for (double dur = 0x0p0;dur <= 0x3p0;dur = glfwGetTime()) {
- glfwPollEvents();
- if (bow_gotintr) {
- bow_log("got interrupt");
- glfwSetWindowShouldClose(gfxdat.win,GLFW_TRUE);
- }
- if (glfwWindowShouldClose(gfxdat.win)) break;
+ unlikely (bow_pollEvts(&gfxdat)) break;
+
+ glClearColor(bowr,bowg,bowb,0x1p0);
+ glClear(GL_COLOR_BUFFER_BIT);
+ glfwSwapBuffers(gfxdat.win);
}
+
double const fadedur = 0x1p0;
glfwSetTime(0x0p0);
for (double fac = 0x0p0;fac <= fadedur;fac = glfwGetTime()) {
- glfwPollEvents();
- if (bow_gotintr) {
- bow_log("got interrupt");
- glfwSetWindowShouldClose(gfxdat.win,GLFW_TRUE);
- }
- if (glfwWindowShouldClose(gfxdat.win)) break;
- GLfloat const r = bowr-fac/fadedur;
- GLfloat const g = bowg-fac/fadedur;
- GLfloat const b = bowb-fac/fadedur;
+ unlikely (bow_pollEvts(&gfxdat)) break;
+
+ GLfloat const r = bowr*(0x1p0f-fac/fadedur);
+ GLfloat const g = bowg*(0x1p0f-fac/fadedur);
+ GLfloat const b = bowb*(0x1p0f-fac/fadedur);
+
glClearColor(r,g,b,0x1p0);
glClear(GL_COLOR_BUFFER_BIT);
glfwSwapBuffers(gfxdat.win);
}
+
glClearColor(0x0p0,0x0p0,0x0p0,0x1p0);
glClear(GL_COLOR_BUFFER_BIT);
glfwSwapBuffers(gfxdat.win);
- if (glfwWindowShouldClose(gfxdat.win)) quit = true;
+
+ unlikely (glfwWindowShouldClose(gfxdat.win)) quit = true;
+
zap_cp(gfxdatptr,&gfxdat,sizeof (gfxdat));
+
return quit;
}
diff --git a/bowshock/source/run/loop.c b/bowshock/source/run/loop.c
new file mode 100644
index 0000000..88008a9
--- /dev/null
+++ b/bowshock/source/run/loop.c
@@ -0,0 +1,117 @@
+// Copyright 2022-2023 Gabriel Jensen.
+
+#include <bow/lgc.h>
+#include <bow/run.h>
+
+#include <GLFW/glfw3.h>
+#include <glad/glad.h>
+#include <math.h>
+#include <zap/mem.h>
+
+static void bow_scrlHand(GLFWwindow * win,[[maybe_unused]] double const xoff,double const yoff) {
+ bow_plDat * dat = glfwGetWindowUserPointer(win);
+ dat->zoom *= powf(0x1.1p0f,0x0p0f-(float)yoff);
+}
+
+void bow_loop(bow_gfxDat * gfxDatPtr,bow_plDat * plDatPtr) {
+ bow_log("entering main loop");
+
+ bow_gfxDat gfxDat;
+ bow_plDat plDat;
+ zap_cp(&gfxDat, gfxDatPtr, sizeof (gfxDat));
+ zap_cp(&plDat,plDatPtr,sizeof (plDat));
+
+ GLfloat vtx[] = {
+ -0x1.0000p0f,+0x1.0000p0f,0x0p0f,
+ +0x1.0000p0f,+0x1.0000p0f,0x0p0f,
+ +0x0.0000p0f,+0x0.0000p0f,0x0p0f,
+ };
+
+ GLuint vao;
+ GLuint vbo;
+ glGenVertexArrays(0x1,&vao);
+ glGenBuffers(0x1,&vbo);
+
+ glBindVertexArray(vao);
+
+ glBindBuffer(GL_ARRAY_BUFFER,vbo);
+ glBufferData(GL_ARRAY_BUFFER,sizeof (vtx),vtx,GL_STREAM_DRAW);
+
+ glVertexAttribPointer(0x0,0x3,GL_FLOAT,GL_FALSE,0x3 * sizeof (GLfloat),nullptr);
+ glEnableVertexAttribArray(0x0);
+
+ bow_objRoot sysRoot; // For stellar bodies.
+ bow_objRoot objRoot = { // For miscellaneous objects (canisters, ships...).
+ .objs = nullptr,
+ };
+
+ bow_genSys(&sysRoot,plDat.sysId,plDat.tm);
+
+ bow_obj objTmp = {
+ .typ = bow_objTyp_can,
+ .pos = {
+ .x = 0x0p0,
+ .y = -0x2p0,
+ .z = 0x0p0,
+ },
+ .rot = {
+ .x = 0x0p0,
+ .y = 0x0p0,
+ .z = 0x0p0,
+ },
+ .posVel = {
+ .x = -0x1p-12,
+ .y = 0x0p0,
+ .z = 0x0p0,
+ },
+ .rotVel = {
+ .x = 0x0p0,
+ .y = 0x0p0,
+ .z = 0x0p0,
+ },
+ .mass = 0x1p0,
+ };
+ bow_addObj(&objRoot,&objTmp);
+
+ glfwSetWindowUserPointer(gfxDat.win,&plDat);
+ glfwSetScrollCallback(gfxDat.win,bow_scrlHand);
+
+ for (;;++plDat.tm) {
+ unlikely (bow_pollEvts(&gfxDat)) break;
+
+ bow_gravSys(&sysRoot);
+ bow_gravObjs(&objRoot,&sysRoot);
+
+ bow_mvObjs(&sysRoot);
+ bow_mvObjs(&objRoot);
+
+ GLfloat const frm = 0x1p0*plDat.zoom;
+
+ vtx[0x0u] = (GLfloat)sysRoot.objs->next->pos.x/frm;
+ vtx[0x1u] = (GLfloat)sysRoot.objs->next->pos.y/frm;
+ vtx[0x3u] = (GLfloat)sysRoot.objs->pos.x/frm;
+ vtx[0x4u] = (GLfloat)sysRoot.objs->pos.y/frm;
+ vtx[0x6u] = (GLfloat)objRoot.objs->pos.x/frm;
+ vtx[0x7u] = (GLfloat)objRoot.objs->pos.y/frm;
+
+ glClearColor(0x0p0f,0x0p0f,0x0p0f,1.0f);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ glBindBuffer(GL_ARRAY_BUFFER,vbo);
+ glBufferSubData(GL_ARRAY_BUFFER,0x0,sizeof (vtx),vtx);
+
+ glUseProgram(gfxDat.shdProg);
+ glBindVertexArray(vao);
+ glDrawArrays(GL_TRIANGLES,0x0,0x3 * 0x1);
+
+ glfwSwapBuffers(gfxDat.win);
+ }
+
+ glfwSetScrollCallback(gfxDat.win,nullptr);
+
+ glDeleteVertexArrays(0x1,&vao);
+ glDeleteBuffers(0x1,&vbo);
+
+ zap_cp(gfxDatPtr,&gfxDat,sizeof (gfxDat));
+ zap_cp(plDatPtr, &plDat, sizeof (plDat));
+}
diff --git a/bowshock/source/run/pollEvts.c b/bowshock/source/run/pollEvts.c
new file mode 100644
index 0000000..3444ceb
--- /dev/null
+++ b/bowshock/source/run/pollEvts.c
@@ -0,0 +1,18 @@
+// Copyright 2022-2023 Gabriel Jensen.
+
+#include <bow/run.h>
+
+#include <GLFW/glfw3.h>
+
+bool bow_pollEvts(bow_gfxDat * const gfxdat) {
+ glfwPollEvents();
+
+ unlikely (bow_gotIntr) {
+ bow_log("got interrupt");
+ glfwSetWindowShouldClose(gfxdat->win,GLFW_TRUE);
+
+ }
+ unlikely (glfwWindowShouldClose(gfxdat->win)) return true;
+
+ return false;
+}
diff --git a/bowshock/source/bs/quit.c b/bowshock/source/run/quit.c
index 925b99c..e8ee8a2 100644
--- a/bowshock/source/bs/quit.c
+++ b/bowshock/source/run/quit.c
@@ -1,19 +1,22 @@
// Copyright 2022-2023 Gabriel Jensen.
-#include <bow/gfx.h>
-#include <bow/lgc.h>
+#include <bow/run.h>
#include <GLFW/glfw3.h>
-#include <stddef.h>
#include <stdlib.h>
#include <zap/mem.h>
-void bow_quit(bow_gfxdat * gfxdatptr,bow_stat const stat) {
+void bow_quit(bow_gfxDat * gfxdatptr,bow_stat const stat) {
bow_log("quitting");
- bow_gfxdat gfxdat;
+
+ bow_gfxDat gfxdat;
zap_cp(&gfxdat,gfxdatptr,sizeof (gfxdat));
+
+ glDeleteProgram(gfxdat.shdProg);
+
glfwDestroyWindow(gfxdat.win);
glfwTerminate();
+
int sysstat;
switch (stat) {
case bow_stat_err:
@@ -23,6 +26,7 @@ void bow_quit(bow_gfxdat * gfxdatptr,bow_stat const stat) {
sysstat = EXIT_SUCCESS;
break;
}
+
bow_log("goodbye");
bow_log("exiting with code %i",sysstat);
exit(sysstat);
diff --git a/bowshock/source/sav/cont.c b/bowshock/source/sav/cont.c
index b12d914..137d2ef 100644
--- a/bowshock/source/sav/cont.c
+++ b/bowshock/source/sav/cont.c
@@ -1,82 +1,79 @@
// Copyright 2022-2023 Gabriel Jensen.
-#include <bow/lgc.h>
#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(bow_playdat * const playdatptr,char const * const pth) {
+void bow_cont(bow_plDat * const pldatptr,char const * const pth) {
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) {
- bow_logerr("unable to open save file \"%s\"",pth);
+
+ unlikely (err) {
+ bow_logErr("unable to open save file \"%s\"",pth);
goto new;
}
- zap_i8 rawdat[bow_savlen];
- err = flux_rd(rawdat,fil,bow_savlen,nullptr);
- if (err) {
+
+ zap_i8 rawdat[bow_savLen];
+ err = flux_rd(rawdat,fil,bow_savLen,nullptr);
+
+ unlikely (err) {
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);
+
+ 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);
- 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);
+
+ bow_savDat dat;
+
+ bow_decSav(&dat,rawdat);
+
+ unlikely (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);
+ unlikely (dat.shipTyp > bow_maxShipId) {
+ bow_logErr("invalid ship type (%" PRIX8 ")",dat.shipTyp);
+
goto new;
}
- bow_playdat playdat = {
+
+ bow_plDat pldat = {
.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,
+ .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';
- bow_log("welcome back, commander %s",playdat.nm);
- bow_gendat(&playdat);
- zap_cp(playdatptr,&playdat,sizeof (playdat));
+ zap_cp(pldat.nm,dat.cmdrNm,bow_cmdrNmLen);
+ pldat.nm[bow_cmdrNmLen] = '\x00';
+
+ bow_log("welcome back, commander %s",pldat.nm);
+
+ bow_genDat(&pldat);
+
+ zap_cp(pldatptr,&pldat,sizeof (pldat));
+
return;
+
new:
- bow_rstart(playdatptr);
+ bow_new(pldatptr);
}
diff --git a/bowshock/source/sav/decSav.c b/bowshock/source/sav/decSav.c
new file mode 100644
index 0000000..a4e25a6
--- /dev/null
+++ b/bowshock/source/sav/decSav.c
@@ -0,0 +1,25 @@
+// Copyright 2022-2023 Gabriel Jensen.
+
+#include <bow/sav.h>
+
+#include <zap/mem.h>
+
+void bow_decSav(bow_savDat * buf,zap_i8 const * 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;
+ zap_cp(&buf->shipRotVelZ,dat,0x8u);
+}
diff --git a/bowshock/source/sav/encSav.c b/bowshock/source/sav/encSav.c
new file mode 100644
index 0000000..ca7081c
--- /dev/null
+++ b/bowshock/source/sav/encSav.c
@@ -0,0 +1,25 @@
+// Copyright 2022-2023 Gabriel Jensen.
+
+#include <bow/sav.h>
+
+#include <zap/mem.h>
+
+void bow_encSav(zap_i8 * buf,bow_plDat const * const dat) {
+ buf = zap_cp(buf,(zap_i04[0x1u]) {bow_savVer},0x8u).dest; // fmtver
+ buf = zap_cp(buf,dat->nm, bow_cmdrNmLen).dest; // cmdrnm
+ buf = zap_cp(buf,&dat->tm, 0x8u).dest; // tm
+ buf = zap_cp(buf,&dat->sysId, 0x8u).dest; // sysId
+ buf = zap_cp(buf,&dat->ship.shipTyp, 0x1u).dest; // shipTyp
+ buf = zap_cp(buf,&dat->ship.pos.x, 0x8u).dest; // shipposx
+ buf = zap_cp(buf,&dat->ship.pos.y, 0x8u).dest; // shipposy
+ buf = zap_cp(buf,&dat->ship.pos.z, 0x8u).dest; // shipposz
+ buf = zap_cp(buf,&dat->ship.rot.x, 0x8u).dest; // shiprotx
+ buf = zap_cp(buf,&dat->ship.rot.y, 0x8u).dest; // shiproty
+ buf = zap_cp(buf,&dat->ship.rot.z, 0x8u).dest; // shiprotz
+ buf = zap_cp(buf,&dat->ship.posVel.x, 0x8u).dest; // shipposVelx
+ buf = zap_cp(buf,&dat->ship.posVel.y, 0x8u).dest; // shipposVely
+ buf = zap_cp(buf,&dat->ship.posVel.z, 0x8u).dest; // shipposVelz
+ buf = zap_cp(buf,&dat->ship.rotVel.x, 0x8u).dest; // shiprotVelx
+ buf = zap_cp(buf,&dat->ship.rotVel.y, 0x8u).dest; // shiprotVely
+ zap_cp(buf,&dat->ship.rotVel.z, 0x8u); // shiprotVelz
+}
diff --git a/bowshock/source/sav/gendat.c b/bowshock/source/sav/genDat.c
index 6711301..0b6810f 100644
--- a/bowshock/source/sav/gendat.c
+++ b/bowshock/source/sav/genDat.c
@@ -7,11 +7,15 @@
#include <string.h>
-void bow_gendat(bow_playdat * const datptr) {
+void bow_genDat(bow_plDat * const datptr) {
bow_log("generating player data");
- bow_playdat dat;
+
+ bow_plDat dat;
zap_cp(&dat,datptr,sizeof (dat));
- dat.ship.typ = bow_objtyp_ship;
- dat.ship.mass = bow_shipmass(dat.ship.shiptyp);
+
+ dat.ship.typ = bow_objTyp_ship;
+ dat.ship.mass = bow_shipMass(dat.ship.shipTyp);
+ dat.zoom = 0x4p0;
+
zap_cp(datptr,&dat,sizeof (dat));
}
diff --git a/bowshock/source/sav/rstart.c b/bowshock/source/sav/new.c
index 70b7bef..371cd07 100644
--- a/bowshock/source/sav/rstart.c
+++ b/bowshock/source/sav/new.c
@@ -1,15 +1,15 @@
// Copyright 2022-2023 Gabriel Jensen.
-#include <bow/lgc.h>
#include <bow/sav.h>
#include <zap/mem.h>
-void bow_rstart(bow_playdat * const datptr) {
- bow_log("restarting save");
- bow_playdat dat = {
- .nm = "Caelum\x0\x0\x0\x0\x0\x0\x0\x0\x0",
- .sysid = 0x45u,
+void bow_new(bow_plDat * const datptr) {
+ bow_log("generating new save file");
+
+ bow_plDat dat = {
+ .nm = "Caelum\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ .sysId = 0x45u,
.tm = 0x0u, // 256 julian years after the Unix Epoch.
.ship = {
.pos = {
@@ -22,20 +22,22 @@ void bow_rstart(bow_playdat * const datptr) {
.y = 0x0p0,
.z = 0x0p0,
},
- .posvel = {
+ .posVel = {
.x = 0x0p0,
.y = 0x0p0,
.z = 0x0p0,
},
- .rotvel = {
+ .rotVel = {
.x = 0x0p0,
.y = 0x0p0,
.z = 0x0p0,
},
- .shiptyp = bow_ship_aq,
+ .shipTyp = bow_ship_aq,
},
};
+ bow_genDat(&dat);
+
bow_log("welcome, commander %s",dat.nm);
- bow_gendat(&dat);
+
zap_cp(datptr,&dat,sizeof (dat));
}
diff --git a/bowshock/source/sav/sav.c b/bowshock/source/sav/sav.c
index c99fecf..1d99864 100644
--- a/bowshock/source/sav/sav.c
+++ b/bowshock/source/sav/sav.c
@@ -1,48 +1,32 @@
// Copyright 2022-2023 Gabriel Jensen.
-#include <bow/lgc.h>
+#include <bow/run.h>
#include <bow/sav.h>
#include <flux/io.h>
-#include <zap/mem.h>
-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);
+void bow_sav(char const * const pth,bow_plDat const * const plDat) {
+ bow_log("saving commander %s at \"%s\"",plDat->nm,pth);
+
flux_fil * fil;
flux_err err = flux_mkfil(&fil,pth,0644);
- if (err) {
- if (err != flux_err_exist) {
- bow_logerr("unable to open save file \"%s\"",pth);
+
+ unlikely (err) {
+ unlikely (err != flux_err_exist) {
+ bow_logErr("unable to open save file \"%s\"",pth);
bow_abrt();
}
+
err = flux_op(&fil,pth,flux_md_wr,flux_disc);
- if (err) {
- bow_logerr("unable to create save file \"%s\"",pth);
+ unlikely (err) {
+ bow_logErr("unable to create save file \"%s\"",pth);
bow_abrt();
}
}
- zap_i8 dat[bow_savlen];
- bow_encsav(dat,playdat);
- flux_wr(fil,dat,bow_savlen);
+
+ zap_i8 dat[bow_savLen];
+ bow_encSav(dat,plDat);
+
+ flux_wr(fil,dat,bow_savLen);
flux_cl(fil);
}
diff --git a/extractGlad.sh b/extractGlad.sh
new file mode 100755
index 0000000..4a3aa79
--- /dev/null
+++ b/extractGlad.sh
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+echo extracting GLAD...
+
+if ! [ -z "${1}" ]
+then
+ archive="${1}"
+else
+ archive="glad.zip"
+fi
+
+if ! [ -e "${archive}" ]
+then
+ echo "failure: unable to access file \"${archive}\""
+ exit 1
+fi
+
+unzip -od"glad" "${archive}"
+cp -v "glad.CMakeLists.txt" "glad/CMakeLists.txt"
+
+echo success
diff --git a/glad.CMakeLists.txt b/glad.CMakeLists.txt
new file mode 100644
index 0000000..b77ab48
--- /dev/null
+++ b/glad.CMakeLists.txt
@@ -0,0 +1,25 @@
+cmake_minimum_required(VERSION 3.19)
+
+set(CMAKE_C_STANDARD 99)
+
+add_library(
+ glad STATIC
+
+ "src/glad.c"
+)
+
+target_enable_optimisations(glad)
+
+target_include_directories(
+ glad PUBLIC
+
+ "include"
+)
+
+if("${CMAKE_C_COMPILER_ID}" MATCHES "Clang|GNU")
+ target_compile_options(
+ glad PRIVATE
+
+ -g
+ )
+endif()
diff --git a/install.sh b/install.sh
new file mode 100755
index 0000000..2727a86
--- /dev/null
+++ b/install.sh
@@ -0,0 +1,71 @@
+#!/bin/sh
+
+installBinary() {
+ builddir="${1}"
+ bindir="${2}"
+
+ mkdir -pvm755 "${bindir}"
+
+ install -vm755 "${builddir}/bowshock/bowshock" "${bindir}"/bowshock
+}
+
+installData() {
+ srcdir="${1}"
+ datdir="${2}"
+
+ mkdir -pvm755 "${datdir}/shaders"
+
+ install -vm644 "${srcdir}/CHANGELOG.txt" "${datdir}"
+ install -vm644 "${srcdir}/CREDITS.txt" "${datdir}"
+ install -vm644 "${srcdir}/bowshock/shader/"*".glsl" "${datdir}/shaders"
+}
+
+if [ "${1}" == "data" ]
+then
+ echo installing data...
+
+ if [ -z "${2}" ]
+ then
+ echo failure: data directory is not set
+ exit 2
+ fi
+
+ srcdir="${PWD}"
+ datdir="${2}"
+
+ installData "${srcdir}" "${datdir}"
+
+ echo done
+
+ exit 0
+fi
+
+echo installing all...
+
+if [ -z "${1}" ]
+then
+ echo failure: build directory is not set
+ exit 3
+fi
+
+if [ -z "${2}" ]
+then
+ echo failure: binary directory is not set
+ exit 2
+fi
+
+if [ -z "${3}" ]
+then
+ echo failure: data directory is not set
+ exit 1
+fi
+
+srcdir="${PWD}"
+builddir="${1}"
+bindir="${2}"
+datdir="${3}"
+
+installBinary "${builddir}" "${bindir}"
+installData "${srcdir}" "${datdir}"
+
+echo done
diff --git a/validateShaders.py b/validateShaders.py
new file mode 100755
index 0000000..d0b9c51
--- /dev/null
+++ b/validateShaders.py
@@ -0,0 +1,33 @@
+#!/usr/bin/env python
+
+from subprocess import PIPE,run
+
+def validate(pth:str):
+ print("validating \"",pth,"\"... ",end='',sep='')
+
+ pth = "bowshock/shader/" + pth + ".glsl"
+ prog = "glslangValidator"
+
+ stat = run([prog,pth],stdout=PIPE)
+
+ ret = stat.returncode
+ if ret != 0x0:
+ print("\x1B[38;5;161merror\x1B[0m")
+ print()
+ print(stat.stdout.decode("utf-8"))
+ quit(0x1)
+
+ print("\x1B[38;5;77mokay\x1B[0m")
+
+if __name__ == "__main__":
+ print("validating shaders...")
+
+ shaders = [
+ "main.frag",
+ "main.vert",
+ ]
+
+ for shader in shaders:
+ validate(shader)
+
+ print("success")