summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.txt12
-rw-r--r--CMakeLists.txt59
-rw-r--r--README.txt16
-rw-r--r--bowshock/CMakeLists.txt117
-rw-r--r--bowshock/include/bow/bs.h164
-rw-r--r--bowshock/include/bow/bs.hxx146
-rw-r--r--bowshock/include/bow/c2x.h43
-rw-r--r--bowshock/include/bow/init.h34
-rw-r--r--bowshock/include/bow/init.hxx63
-rw-r--r--bowshock/include/bow/lgc.h22
-rw-r--r--bowshock/include/bow/lgc.hxx23
-rw-r--r--bowshock/include/bow/run.h31
-rw-r--r--bowshock/include/bow/run.hxx14
-rw-r--r--bowshock/include/bow/sav.h64
-rw-r--r--bowshock/include/bow/sav.hxx67
-rw-r--r--bowshock/shader/main.frag.glsl2
-rw-r--r--bowshock/shader/main.vert.glsl4
-rw-r--r--bowshock/source/bs/objTypStr.cxx (renamed from bowshock/source/bs/objTypStr.c)18
-rw-r--r--bowshock/source/bs/rnd.c17
-rw-r--r--bowshock/source/bs/rnd.cxx17
-rw-r--r--bowshock/source/init/bow/bow.cxx20
-rw-r--r--bowshock/source/init/bow/chkParams.cxx38
-rw-r--r--bowshock/source/init/bow/compShd.cxx80
-rw-r--r--bowshock/source/init/bow/compShdProg.cxx34
-rw-r--r--bowshock/source/init/bow/cred.cxx43
-rw-r--r--bowshock/source/init/bow/getQuot.cxx (renamed from bowshock/source/init/getQuot.c)20
-rw-r--r--bowshock/source/init/bow/getSavPth.cxx36
-rw-r--r--bowshock/source/init/bow/help.cxx25
-rw-r--r--bowshock/source/init/bow/init.cxx44
-rw-r--r--bowshock/source/init/bow/initGfx.cxx42
-rw-r--r--bowshock/source/init/bow/initRnd.cxx12
-rw-r--r--bowshock/source/init/bow/initSig.cxx25
-rw-r--r--bowshock/source/init/bow/intro.cxx (renamed from bowshock/source/run/intro.c)30
-rw-r--r--bowshock/source/init/bow/loop.cxx (renamed from bowshock/source/run/loop.c)62
-rw-r--r--bowshock/source/init/bow/pollEvts.cxx18
-rw-r--r--bowshock/source/init/bow/priQuot.cxx19
-rw-r--r--bowshock/source/init/bow/quit.cxx29
-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/getSavPth.c40
-rw-r--r--bowshock/source/init/help.c23
-rw-r--r--bowshock/source/init/init.c56
-rw-r--r--bowshock/source/init/initGfx.c50
-rw-r--r--bowshock/source/init/initRnd.c12
-rw-r--r--bowshock/source/init/initSig.c23
-rw-r--r--bowshock/source/init/priQuot.c22
-rw-r--r--bowshock/source/lgc/grav.c69
-rw-r--r--bowshock/source/lgc/grav.cxx75
-rw-r--r--bowshock/source/lgc/mv.c20
-rw-r--r--bowshock/source/lgc/mv.cxx18
-rw-r--r--bowshock/source/lgc/shipMass.c10
-rw-r--r--bowshock/source/lgc/shipMass.cxx10
-rw-r--r--bowshock/source/lgc/sim.c14
-rw-r--r--bowshock/source/lgc/sim.cxx16
-rw-r--r--bowshock/source/run/abrt.c11
-rw-r--r--bowshock/source/run/abrt.cxx11
-rw-r--r--bowshock/source/run/addObj.c21
-rw-r--r--bowshock/source/run/addObj.cxx16
-rw-r--r--bowshock/source/run/freeObjs.c17
-rw-r--r--bowshock/source/run/freeObjs.cxx16
-rw-r--r--bowshock/source/run/genSys.cxx (renamed from bowshock/source/run/genSys.c)34
-rw-r--r--bowshock/source/run/pollEvts.c18
-rw-r--r--bowshock/source/run/quit.c33
-rw-r--r--bowshock/source/sav/cont.c79
-rw-r--r--bowshock/source/sav/cont.cxx83
-rw-r--r--bowshock/source/sav/decSav.c25
-rw-r--r--bowshock/source/sav/decSav.cxx29
-rw-r--r--bowshock/source/sav/encSav.c25
-rw-r--r--bowshock/source/sav/encSav.cxx29
-rw-r--r--bowshock/source/sav/genDat.c21
-rw-r--r--bowshock/source/sav/genDat.cxx12
-rw-r--r--bowshock/source/sav/newSav.cxx (renamed from bowshock/source/sav/new.c)18
-rw-r--r--bowshock/source/sav/sav.c32
-rw-r--r--bowshock/source/sav/sav.cxx54
-rw-r--r--glad.CMakeLists.txt13
77 files changed, 1338 insertions, 1443 deletions
diff --git a/CHANGELOG.txt b/CHANGELOG.txt
index 98f18a5..6d51283 100644
--- a/CHANGELOG.txt
+++ b/CHANGELOG.txt
@@ -1,3 +1,15 @@
+# 0.B.0
+
+* Use generator expressions in CMake;
+* Use OpenGL 4.1;
+* Migrate to C++;
+* Implement main program as a class;
+* Use exceptions;
+* Use references;
+* Update readme;
+* Add more quotes;
+* Fix launch options not being listed on the help print;
+
# 0.A.0
* Remove satellite object type;
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 19d3679..3a2b650 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -3,65 +3,10 @@ cmake_minimum_required(VERSION 3.21)
project(
bowshock
- VERSION 0.10.0
+ VERSION 0.11.0
HOMEPAGE_URL "https://mandelbrot.dk/bowshock"
- LANGUAGES C
+ LANGUAGES C CXX
)
-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/README.txt b/README.txt
index 572b019..01ea541 100644
--- a/README.txt
+++ b/README.txt
@@ -12,7 +12,7 @@ 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
+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
@@ -32,18 +32,20 @@ can be done via the installation script "install.sh":
## DEVELOPMENT
-The commands I use for development are:
+To initialise the environment, I use the following commands:
-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
+./install.sh data "${PWD}/datdir"
+
+... and from there just use the following to rebuild the project:
+
+clear && \
+./validateShaders.py && \
+cmake --build build && build/bowshock/bowshock --skip
## SHADER VALIDATION
diff --git a/bowshock/CMakeLists.txt b/bowshock/CMakeLists.txt
index d3a5f50..13b62e2 100644
--- a/bowshock/CMakeLists.txt
+++ b/bowshock/CMakeLists.txt
@@ -1,53 +1,53 @@
cmake_minimum_required(VERSION 3.21)
-option(BOW_DATA_DIRECTORY "" "")
-option(BOW_C2X_COMPATIBILITY "Predefined C2x macros for older compilers." FALSE)
+option(BOW_DATA_DIRECTORY "Directory for storing run-time data (assets, shaders...)." "")
if("${BOW_DATA_DIRECTORY}" STREQUAL "")
message(FATAL_ERROR "Data directory (BOW_DATA_DIRECTORY) not specified")
endif()
-set(CMAKE_C_STANDARD 23)
+set(CMAKE_CXX_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"
+ "source/bs/objTypStr.cxx"
+ "source/bs/rnd.cxx"
+
+ "source/init/bow/bow.cxx"
+ "source/init/bow/chkParams.cxx"
+ "source/init/bow/compShd.cxx"
+ "source/init/bow/compShdProg.cxx"
+ "source/init/bow/cred.cxx"
+ "source/init/bow/getQuot.cxx"
+ "source/init/bow/getSavPth.cxx"
+ "source/init/bow/help.cxx"
+ "source/init/bow/init.cxx"
+ "source/init/bow/initGfx.cxx"
+ "source/init/bow/initRnd.cxx"
+ "source/init/bow/initSig.cxx"
+ "source/init/bow/intro.cxx"
+ "source/init/bow/loop.cxx"
+ "source/init/bow/pollEvts.cxx"
+ "source/init/bow/priQuot.cxx"
+ "source/init/bow/quit.cxx"
+
+ "source/lgc/grav.cxx"
+ "source/lgc/mv.cxx"
+ "source/lgc/shipMass.cxx"
+ "source/lgc/sim.cxx"
+
+ "source/run/abrt.cxx"
+ "source/run/addObj.cxx"
+ "source/run/freeObjs.cxx"
+ "source/run/genSys.cxx"
+
+ "source/sav/genDat.cxx"
+ "source/sav/cont.cxx"
+ "source/sav/decSav.cxx"
+ "source/sav/encSav.cxx"
+ "source/sav/newSav.cxx"
+ "source/sav/sav.cxx"
)
add_dependencies(
@@ -56,10 +56,6 @@ add_dependencies(
glad
)
-target_enable_warnings(bowshock)
-
-target_enable_optimisations(bowshock)
-
target_include_directories(
bowshock PRIVATE
@@ -82,42 +78,27 @@ target_compile_definitions(
_POSIX_C_SOURCE=200112l
GLFW_INCLUDE_NONE
bow_datDir="/home/delta/Repositories/bowshock/datdir"
+ bow_dbg=$<IF:$<STREQUAL:"${CMAKE_BUILD_TYPE}","Debug">,true,false>
)
-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")
+if("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang|GNU")
target_compile_options(
bowshock PRIVATE
+ $<IF:$<STREQUAL:"${CMAKE_BUILD_TYPE}","Debug">,-Og,-Ofast>
+ -Wall
+ -Wextra
-Wmissing-prototypes
-Wpedantic
-fdiagnostics-color=always
-g
)
-endif()
-
-if("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang")
+elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
target_compile_options(
bowshock PRIVATE
- -Wno-fixed-enum-extension
- -Wno-gnu-folding-constant
- -Wno-gnu-empty-initializer
- -Wno-gnu-zero-variadic-macro-arguments
- )
+ /O2
+ /W4
+ $<IF:$<STREQUAL:"${CMAKE_BUILD_TYPE}","Debug">,/Zo>
+ )
endif()
diff --git a/bowshock/include/bow/bs.h b/bowshock/include/bow/bs.h
deleted file mode 100644
index 7cfbb5c..0000000
--- a/bowshock/include/bow/bs.h
+++ /dev/null
@@ -1,164 +0,0 @@
-// Copyright 2022-2023 Gabriel Jensen.
-
-#pragma once
-
-#ifdef bow_c2xCompat
-#include <bow/c2x.h>
-#endif
-
-#ifndef bow_datDir
-#error Data directory not specified!
-#endif
-
-#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 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 <stdio.h>
-#include <zap/bs.h> // This header is guaranteed to be included.
-
-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);
-
-static_assert(sizeof (float) == 0x4u);
-static_assert(sizeof (double) == 0x8u);
-
-#define bow_rawlog(msg,...) fprintf(stderr,msg __VA_OPT__(,) __VA_ARGS__)
-
-#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__)
-
-#ifdef bow_dbg
-#define bow_dbgLog(msg,...) bow_log(msg __VA_OPT__ (,) __VA_ARGS__)
-#else
-#define bow_dbgLog(msg,...) ((void)0x0u)
-#endif
-
-#define bow_logXyz(xyz) bow_dbgLog("%.03f %.03f %.03f",(xyz).x,(xyz).y,(xyz).z)
-
-#define bow_setStrLen(ptr,len,str) ((void)(ptr = str,len = sizeof (str) - 0x1u))
-
-#define bow_cmdrNmLen ((zap_sz)0xEu)
-
-typedef enum : zap_i8 {
- bow_stat_ok = 0x0u,
- bow_stat_err = 0x1u,
-} bow_stat;
-
-typedef struct {
- double x;
- double y;
- double z;
-} bow_xyz;
-
-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 {
- bow_obj * objs;
-} bow_objRoot;
-
-typedef struct {
- char nm[bow_cmdrNmLen+0x1u];
- zap_i04 tm;
- zap_i04 sysId;
- bow_obj ship;
- float zoom;
-} bow_plDat;
-
-constexpr zap_i04 bow_verMaj = 0x0u;
-constexpr zap_i04 bow_verMin = 0xAu;
-constexpr zap_i04 bow_verPat = 0x0u;
-
-char const * bow_objTypStr(bow_objTyp typ);
-
-zap_i04 bow_rnd(void);
diff --git a/bowshock/include/bow/bs.hxx b/bowshock/include/bow/bs.hxx
new file mode 100644
index 0000000..bb867fb
--- /dev/null
+++ b/bowshock/include/bow/bs.hxx
@@ -0,0 +1,146 @@
+// Copyright 2022-2023 Gabriel Jensen.
+
+#pragma once
+
+// flux is retarded and uses compound literals - even for C++. We override this nonsense with some value initialisations.
+#include <flux/io.h>
+#undef flux_disc
+#undef flux_keep
+#define flux_disc (::flux_priv_disc {._disc = true,})
+#define flux_keep (::flux_priv_disc {._disc = false,})
+// Note: flux will recieve better (C++) support in the future.
+
+#ifndef bow_datDir
+#error Data directory not specified!
+#endif
+
+#include <cstdio>
+#include <zap/bs.hh> // We guarantee that this header is included.
+
+static_assert(::zap::bytelen == 0x8u,"Bytes must contain exactly eight bits.");
+
+#define bow_logRaw(msg,...) fprintf(stderr,msg __VA_OPT__(,) __VA_ARGS__)
+
+#define bow_log(msg,...) bow_logRaw("\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__)
+
+#if bow_dbg
+#define bow_logDbg(msg,...) bow_log(msg __VA_OPT__ (,) __VA_ARGS__)
+#else
+#define bow_logDbg(msg,...) ((void)0x0u)
+#endif
+
+#define bow_logXyz(xyz) bow_logDbg("%s: %.03f %.03f %.03f",#xyz,(xyz).x,(xyz).y,(xyz).z)
+
+#define bow_setStrLen(ptr,len,str) ((void)(ptr = str,len = sizeof (str) - 0x1u))
+
+namespace bow {
+ constexpr bool dbg = bow_dbg;
+
+ constexpr ::zap::sz cmdrNmLen = 0xEu;
+
+ enum struct stat : ::zap::i8 {
+ ok = 0x0u,
+ err = 0x1u,
+ };
+
+ enum struct objTyp : ::zap::i8 {
+ can, // canister
+ pl, // player
+ ship, // ship
+ star, // star
+ station, // station
+ wrld, // world (planet/moon)
+ };
+
+ enum struct wrld : ::zap::i8 {
+ amm, // ammonium world
+ gas, // gas giant
+ ice, // icy world
+ rck, // rocky world
+ lav, // lava world
+ wat, // water world
+ };
+
+ enum struct ship : ::zap::i8 {
+ aq, // aquila
+ cas, // cassiopeia
+ cent, // centaurus
+ cov, // corvus
+ cur, // cursor
+ eri, // eridanus
+ fal, // falco
+ lyra, // lyra
+ tau, // taurus
+ ursa, // ursa
+ vip, // vipera
+ // Remember maxShipId in sav
+ };
+
+ enum struct star : ::zap::i8 {
+ a, // main sequence
+ b, // main sequence
+ c, // carbon
+ f, // main sequence
+ g, // main sequence
+ k, // main sequence
+ l, // brown dwarf
+ m, // main sequence
+ n, // neutron star
+ o, // main sequence
+ s, // carbon
+ t, // brown dwarf
+ w, // worm hole
+ x, // black hole
+ y, // brown dwarf
+ z, // white hole
+ };
+
+ enum struct station : ::zap::i8 {
+ station_glob, // globus
+ station_orb, // orbis
+ };
+
+ struct xyz {
+ double x;
+ double y;
+ double z;
+ };
+
+ struct obj {
+ ::bow::objTyp typ;
+ union {
+ ::bow::wrld wrldTyp;
+ ::bow::ship shipTyp;
+ ::bow::star starTyp;
+ ::bow::station stationTyp;
+ };
+ ::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
+ ::bow::obj * next;
+ };
+
+ struct objRoot {
+ ::bow::obj * objs;
+ };
+
+ struct plDat {
+ char nm[::bow::cmdrNmLen+0x1u];
+ ::zap::i04 tm;
+ ::zap::i04 sysId;
+ ::bow::obj ship;
+ float zoom;
+ };
+
+ constexpr ::zap::i04 verMaj = 0x0u;
+ constexpr ::zap::i04 verMin = 0xBu;
+ constexpr ::zap::i04 verPat = 0x0u;
+
+ char const * objTypStr(::bow::objTyp typ) noexcept;
+
+ ::zap::i04 rnd() noexcept;
+}
diff --git a/bowshock/include/bow/c2x.h b/bowshock/include/bow/c2x.h
deleted file mode 100644
index 43d5b97..0000000
--- a/bowshock/include/bow/c2x.h
+++ /dev/null
@@ -1,43 +0,0 @@
-// 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/init.h b/bowshock/include/bow/init.h
deleted file mode 100644
index c79aa3f..0000000
--- a/bowshock/include/bow/init.h
+++ /dev/null
@@ -1,34 +0,0 @@
-// 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/init.hxx b/bowshock/include/bow/init.hxx
new file mode 100644
index 0000000..2dea576
--- /dev/null
+++ b/bowshock/include/bow/init.hxx
@@ -0,0 +1,63 @@
+// Copyright 2022-2023 Gabriel Jensen.
+
+#pragma once
+
+#include <bow/run.hxx>
+
+#include <GLFW/glfw3.h>
+#include <csignal>
+#include <glad/glad.h>
+
+namespace bow {
+ constexpr char const shdFilExt[] = "glsl";
+
+ struct gfxDat {
+ ::GLFWwindow * win;
+ GLuint shdProg;
+ };
+
+ struct termOpts {
+ char const * savPth;
+ bool hasSavPth:0x1u;
+ bool newSav:0x1u;
+ bool skip:0x1u;
+ };
+
+ class bow {
+ public:
+ bow( int argc,char const * const * argv) noexcept;
+ [[noreturn]] ~bow() noexcept;
+
+ private:
+ ::bow::plDat plDat;
+ ::bow::gfxDat gfxDat;
+
+ char const * getSavPth() noexcept;
+ void getQuot( char const * * quot,char const * * src,::zap::i8 id) noexcept;
+
+ void priQuot() noexcept;
+
+ [[noreturn]] void cred() noexcept;
+ [[noreturn]] void help(char const * progNm) noexcept;
+
+ void chkParams(termOpts & opts,int argc,char const * const * argv) noexcept;
+
+ void compShd( GLuint & shd, char const * nm,GLenum typ);
+ void compShdProg(GLuint & shdProg,char const * nm) noexcept;
+
+ void initGfx() noexcept;
+ void initRnd() noexcept;
+ void initSig() noexcept;
+
+ void init(int argc,char const * const * argv) noexcept;
+
+ bool pollEvts() noexcept;
+
+ bool intro() noexcept;
+ void loop() noexcept;
+
+ [[noreturn]] void quit(::bow::stat stat) noexcept;
+ };
+
+ extern ::std::sig_atomic_t volatile gotIntr;
+}
diff --git a/bowshock/include/bow/lgc.h b/bowshock/include/bow/lgc.h
deleted file mode 100644
index 136a2ca..0000000
--- a/bowshock/include/bow/lgc.h
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2022-2023 Gabriel Jensen.
-
-#pragma once
-
-#include <bow/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)
-
-constexpr double bow_gravConstFac = (bow_massMod*(bow_tmMod*bow_tmMod))/((bow_distMod*bow_distMod*bow_distMod)); // inverse
-
-constexpr double bow_gravConst = 0x1.258688101B4BB16Dp-34*bow_gravConstFac; // gravitational constant (s^2*m*t^2)
-
-[[unsequenced]] double bow_shipMass(bow_ship id);
-
-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);
diff --git a/bowshock/include/bow/lgc.hxx b/bowshock/include/bow/lgc.hxx
new file mode 100644
index 0000000..3646153
--- /dev/null
+++ b/bowshock/include/bow/lgc.hxx
@@ -0,0 +1,23 @@
+// Copyright 2022-2023 Gabriel Jensen.
+
+#pragma once
+
+#include <bow/bs.hxx>
+
+namespace bow {
+ constexpr double distMod = 0x1.16A5D2D360000000p037; // distance modifier (1 astronomical unit)
+ constexpr double massMod = 0x1.91930A5E75F0C192p100; // mass modifier (1 solar mass)
+ constexpr double tmMod = 0x1.0000000000000000p012; // time modifier (1 second)
+
+ constexpr double gravConstFac = (::bow::massMod*(::bow::tmMod*::bow::tmMod))/((::bow::distMod*::bow::distMod*::bow::distMod)); // inverse
+
+ constexpr double gravConst = 0x1.258688101B4BB16Dp-34*::bow::gravConstFac; // gravitational constant (s^2*m*t^2)
+
+ zap_attr_unseq double shipMass(::bow::ship id) noexcept;
+
+ void grav(::bow::objRoot & sys) noexcept;
+ void grav(::bow::objRoot & objs,::bow::objRoot const & sys) noexcept;
+ void mv( ::bow::objRoot & root) noexcept;
+
+ void sim(::bow::objRoot & sys,::zap::i04 dur) noexcept;
+}
diff --git a/bowshock/include/bow/run.h b/bowshock/include/bow/run.h
deleted file mode 100644
index 780563e..0000000
--- a/bowshock/include/bow/run.h
+++ /dev/null
@@ -1,31 +0,0 @@
-// 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/run.hxx b/bowshock/include/bow/run.hxx
new file mode 100644
index 0000000..f341df1
--- /dev/null
+++ b/bowshock/include/bow/run.hxx
@@ -0,0 +1,14 @@
+// Copyright 2022-2023 Gabriel Jensen.
+
+#pragma once
+
+#include <bow/bs.hxx>
+
+namespace bow {
+ [[noreturn]] void abrt() noexcept;
+
+ void addObj( ::bow::objRoot & root,::bow::obj const & obj);
+ void freeObjs(::bow::objRoot const & root) noexcept;
+
+ void genSys(::bow::objRoot & sys,::zap::i04 id,::zap::i04 tm);
+}
diff --git a/bowshock/include/bow/sav.h b/bowshock/include/bow/sav.h
deleted file mode 100644
index 7c850e2..0000000
--- a/bowshock/include/bow/sav.h
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright 2022-2023 Gabriel Jensen.
-
-#pragma once
-
-#include <bow/bs.h>
-
-#define bow_savLen ((zap_sz)((zap_sz)0x79u+(zap_sz)bow_cmdrNmLen))
-
-constexpr zap_i04 bow_savVer = 0x6u;
-
-constexpr zap_i8 bow_maxShipId = bow_ship_vip;
-
-/*
- 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;
- 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/include/bow/sav.hxx b/bowshock/include/bow/sav.hxx
new file mode 100644
index 0000000..41ae867
--- /dev/null
+++ b/bowshock/include/bow/sav.hxx
@@ -0,0 +1,67 @@
+// Copyright 2022-2023 Gabriel Jensen.
+
+#pragma once
+
+#include <bow/bs.hxx>
+
+namespace bow {
+ constexpr ::zap::i04 savVer = 0x6u;
+
+ constexpr ::zap::sz savLen = 0x79u+::bow::cmdrNmLen;
+
+ constexpr ::zap::i8 maxShipId = static_cast<::zap::i8>(::bow::ship::vip);
+
+ /*
+ Save format:
+
+ offset: id: size [bytes]: format:
+
+ 0x00 fmtver 8 unsigned
+ 0x08 cmdrnm E UTF-8
+ 0x16 tm 8 unsigned
+ 0x1E sysid 8 unsigned
+ 0x1F shiptyp 1 unsigned
+ 0x27 shipposx 8 binary64
+ 0x2F shipposy 8 binary64
+ 0x37 shipposz 8 binary64
+ 0x3F shiprotx 8 binary64
+ 0x47 shiproty 8 binary64
+ 0x4F shiprotz 8 binary64
+ 0x57 shipposvelx 8 binary64
+ 0x5F shipposvely 8 binary64
+ 0x67 shipposvelz 8 binary64
+ 0x6F shiprotvelx 8 binary64
+ 0x77 shiprotvely 8 binary64
+ 0x7F shiprotvelz 8 binary64
+ */
+
+ struct savDat {
+ ::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;
+ };
+
+ void decSav(::bow::savDat & buf,::zap::i8 const * dat) noexcept;
+ void encSav(::zap::i8 * buf,::bow::savDat const & dat) noexcept;
+
+ void newSav(::bow::plDat & dat) noexcept;
+
+ void cont( ::bow::plDat & dat,char const * fil) noexcept;
+ void genDat(::bow::plDat & dat) noexcept;
+
+ void sav(char const * fil,::bow::plDat const & dat) noexcept;
+}
diff --git a/bowshock/shader/main.frag.glsl b/bowshock/shader/main.frag.glsl
index d3ec746..08d14db 100644
--- a/bowshock/shader/main.frag.glsl
+++ b/bowshock/shader/main.frag.glsl
@@ -1,4 +1,4 @@
-#version 400 core
+#version 410 core
out vec4 col;
diff --git a/bowshock/shader/main.vert.glsl b/bowshock/shader/main.vert.glsl
index 0bbefa9..b4f862a 100644
--- a/bowshock/shader/main.vert.glsl
+++ b/bowshock/shader/main.vert.glsl
@@ -1,6 +1,6 @@
-#version 400 core
+#version 410 core
-in vec3 pos;
+layout (location = 0x0) in vec3 pos;
void main() {
gl_Position = vec4(pos.x,pos.y,pos.z,1.0f);
diff --git a/bowshock/source/bs/objTypStr.c b/bowshock/source/bs/objTypStr.cxx
index 9093014..d70c9f5 100644
--- a/bowshock/source/bs/objTypStr.c
+++ b/bowshock/source/bs/objTypStr.cxx
@@ -1,28 +1,30 @@
// Copyright 2022-2023 Gabriel Jensen.
-#include <bow/lgc.h>
+#include <bow/lgc.hxx>
-char const * bow_objTypStr(bow_objTyp const typ) {
+char const * ::bow::objTypStr(::bow::objTyp const typ) noexcept {
char const * str;
+
switch (typ) {
- case bow_objTyp_can:
+ case ::bow::objTyp::can:
str = "canister";
break;
- case bow_objTyp_pl:
+ case ::bow::objTyp::pl:
str = "player";
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;
}
+
return str;
}
diff --git a/bowshock/source/bs/rnd.c b/bowshock/source/bs/rnd.c
deleted file mode 100644
index f7728f0..0000000
--- a/bowshock/source/bs/rnd.c
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2022-2023 Gabriel Jensen.
-
-#include <bow/bs.h>
-
-#include <stdlib.h>
-
-static_assert(sizeof (int) == sizeof (zap_i02));
-
-static_assert(RAND_MAX == zap_maxvali);
-
-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/bs/rnd.cxx b/bowshock/source/bs/rnd.cxx
new file mode 100644
index 0000000..32b1b0e
--- /dev/null
+++ b/bowshock/source/bs/rnd.cxx
@@ -0,0 +1,17 @@
+// Copyright 2022-2023 Gabriel Jensen.
+
+#include <bow/bs.hxx>
+
+#include <cstdlib>
+
+static_assert(sizeof (int) == sizeof (::zap::i02));
+
+static_assert(RAND_MAX == ::zap::maxval<int>);
+
+unsigned long ::bow::rnd() noexcept {
+ ::zap::i02 const rnd0 = (::zap::i02)::std::rand();
+ ::zap::i02 const rnd1 = (::zap::i02)::std::rand();
+ ::zap::i04 const rnd = (::zap::i04)rnd0 | (::zap::i04)rnd1 >> 0x4u;
+
+ return rnd;
+}
diff --git a/bowshock/source/init/bow/bow.cxx b/bowshock/source/init/bow/bow.cxx
new file mode 100644
index 0000000..61d2820
--- /dev/null
+++ b/bowshock/source/init/bow/bow.cxx
@@ -0,0 +1,20 @@
+// Copyright 2022-2023 Gabriel Jensen.
+
+#include <bow/init.hxx>
+#include <bow/lgc.hxx>
+#include <bow/run.hxx>
+#include <bow/sav.hxx>
+
+#include <cinttypes>
+
+::bow::bow::bow(int const argc,char const * const * const argv) noexcept {
+ init(argc,argv);
+}
+
+::bow::bow::~bow() noexcept {
+ quit(::bow::stat::ok);
+}
+
+int main(int const argc,char const * const * argv) {
+ ::bow::bow bow = {argc,argv};
+}
diff --git a/bowshock/source/init/bow/chkParams.cxx b/bowshock/source/init/bow/chkParams.cxx
new file mode 100644
index 0000000..eb49e5d
--- /dev/null
+++ b/bowshock/source/init/bow/chkParams.cxx
@@ -0,0 +1,38 @@
+// Copyright 2022-2023 Gabriel Jensen.
+
+#include <bow/init.hxx>
+
+#include <zap/mem.hh>
+#include <zap/str.hh>
+
+void ::bow::bow::chkParams(::bow::termOpts & opts,int const argc,char const * const * argv) noexcept {
+ char const * const progNm = *argv;
+
+ opts = ::bow::termOpts {
+ .hasSavPth = false,
+ .newSav = false,
+ .skip = false,
+ };
+
+ if (argc >= 0x2) [[unlikely]] {
+ 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")) cred();
+ else if (::zap::streq(param,"help")) 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;
+ }
+ }
+}
diff --git a/bowshock/source/init/bow/compShd.cxx b/bowshock/source/init/bow/compShd.cxx
new file mode 100644
index 0000000..eeba260
--- /dev/null
+++ b/bowshock/source/init/bow/compShd.cxx
@@ -0,0 +1,80 @@
+// Copyright 2022-2023 Gabriel Jensen.
+
+#include <bow/init.hxx>
+
+#include <cstdio>
+#include <cstdlib>
+#include <glad/glad.h>
+#include <stdexcept>
+#include <zap/mem.hh>
+#include <zap/str.hh>
+
+void ::bow::bow::compShd(GLuint & shd,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",static_cast<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 = new char[pthLen + 0x1u];
+
+ 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_logDbg("compiling %s shader at \"%s\"",typStr,pth);
+
+ FILE * fp = ::std::fopen(pth,"r");
+
+ delete[] pth;
+
+ if (fp == nullptr) {throw ::std::runtime_error {"unable to open shader source"};}
+
+ ::std::fseek(fp,0x0,SEEK_END);
+ ::zap::sz const filsz = static_cast<::zap::sz>(ftell(fp));
+ ::std::rewind(fp);
+
+ static_assert(sizeof (GLchar) == sizeof (char));
+ GLchar * const src = new GLchar[filsz + 0x1u];
+
+ ::std::fread(src,sizeof (GLchar),filsz,fp);
+ ::std::fclose(fp);
+
+ src[filsz] = '\x00';
+
+ shd = glCreateShader(typ);
+ glShaderSource(shd,0x1,(GLchar const * const *)&src,nullptr);
+
+ delete[] src;
+
+ glCompileShader(shd);
+
+ GLint compStat;
+ glGetShaderiv(shd,GL_COMPILE_STATUS,&compStat);
+ if (compStat == GL_FALSE) [[unlikely]] {throw ::std::runtime_error {"unable to compile shader"};}
+}
diff --git a/bowshock/source/init/bow/compShdProg.cxx b/bowshock/source/init/bow/compShdProg.cxx
new file mode 100644
index 0000000..43bd7e5
--- /dev/null
+++ b/bowshock/source/init/bow/compShdProg.cxx
@@ -0,0 +1,34 @@
+// Copyright 2022-2023 Gabriel Jensen.
+
+#include <bow/init.hxx>
+
+#include <glad/glad.h>
+#include <stdexcept>
+
+void ::bow::bow::compShdProg(GLuint & shdProg,char const * const nm) noexcept {
+ bow_log("compiling shader program \"%s\"",nm);
+
+ GLuint vtxShd;
+ GLuint fragShd;
+
+ try {
+ compShd(vtxShd, nm, GL_VERTEX_SHADER);
+ compShd(fragShd,nm,GL_FRAGMENT_SHADER);
+ }
+ catch (::std::runtime_error const & e) {
+ bow_logErr("%s",e.what());
+ ::bow::abrt();
+ }
+ catch (::std::bad_alloc const & e) {
+ bow_logErr("unable to allocate memory for shader data");
+ ::bow::abrt();
+ }
+
+ shdProg = glCreateProgram();
+ glAttachShader(shdProg,vtxShd);
+ glAttachShader(shdProg,fragShd);
+ glLinkProgram(shdProg);
+
+ glDeleteShader(vtxShd);
+ glDeleteShader(fragShd);
+}
diff --git a/bowshock/source/init/bow/cred.cxx b/bowshock/source/init/bow/cred.cxx
new file mode 100644
index 0000000..905ddd1
--- /dev/null
+++ b/bowshock/source/init/bow/cred.cxx
@@ -0,0 +1,43 @@
+// Copyright 2022-2023 Gabriel Jensen.
+
+#include <bow/init.hxx>
+
+#include <flux/io.h>
+#include <cstdio>
+#include <cstdlib>
+
+void ::bow::bow::cred() noexcept {
+ FILE * fp = ::std::fopen(bow_datDir "/CREDITS.txt","r");
+
+ ::std::fseek(fp,0x0,SEEK_END);
+ ::zap::sz const filsz = (::zap::sz)ftell(fp);
+ ::std::rewind(fp);
+
+ char * cred = new char[filsz + 0x3u];
+ char * const credstart = cred;
+
+ if (cred == nullptr) {
+ bow_logErr("unable to allocate memory");
+ ::std::exit(EXIT_FAILURE);
+ }
+
+ *cred++ = '\n';
+
+ cred += ::std::fread(cred,sizeof (char),filsz,fp);
+ ::std::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");
+ }
+
+ delete[] cred;
+
+ ::std::exit(EXIT_SUCCESS);
+}
diff --git a/bowshock/source/init/getQuot.c b/bowshock/source/init/bow/getQuot.cxx
index 243990b..8749310 100644
--- a/bowshock/source/init/getQuot.c
+++ b/bowshock/source/init/bow/getQuot.cxx
@@ -1,12 +1,14 @@
// Copyright 2022-2023 Gabriel Jensen.
-#include <bow/init.h>
+#include <bow/init.hxx>
-bool bow_getQuot(char const * * const quot,char const * * src,zap_i8 const id) {
+#include <cinttypes>
+
+void ::bow::bow::getQuot(char const * * const quot,char const * * src,::zap::i8 const id) noexcept {
switch (id) {
default:
- return true;
-
+ bow_logErr("invalid quote identifier (%" PRIX8 ")",id);
+ [[fallthrough]];
case 0x0u:
*quot = "You gotta be heaven to see heaven.";
*src = "Jim Carrey";
@@ -143,7 +145,13 @@ bool bow_getQuot(char const * * const quot,char const * * src,zap_i8 const id) {
*quot = "There is no mathematical sibstitute for philosophy.";
*src = "Saul Aaron Kripke";
break;
+ case 0x22u:
+ *quot = "Biology is engineering.";
+ *src = "Daniel Clement Dennett III";
+ break;
+ case 0x23u:
+ *quot = "The universe is under no obligation to make sense to you.";
+ *src = "Neil deGrasse Tyson";
+ break;
}
-
- return false;
}
diff --git a/bowshock/source/init/bow/getSavPth.cxx b/bowshock/source/init/bow/getSavPth.cxx
new file mode 100644
index 0000000..ad0e6e1
--- /dev/null
+++ b/bowshock/source/init/bow/getSavPth.cxx
@@ -0,0 +1,36 @@
+// Copyright 2022-2023 Gabriel Jensen.
+
+#include <bow/init.hxx>
+
+#include <cstdlib>
+#include <flux/stats.h>
+#include <zap/mem.hh>
+#include <zap/str.hh>
+
+char const * ::bow::bow::getSavPth() noexcept {
+ char const * hmDir = ::flux_hmdir();
+ char const * filNm;
+ ::zap::sz hmDirLen;
+ ::zap::sz filNmLen;
+
+ if (hmDir == nullptr) [[unlikely]] {
+ bow_log("unable to get home directory, using current directory");
+ bow_setStrLen(hmDir,hmDirLen,"./");
+ }
+ else hmDirLen = ::zap::strlen(hmDir);
+
+ bow_setStrLen(filNm,filNmLen,".save.bowshock");
+
+ ::zap::sz pthLen = hmDirLen+filNmLen+0x1u;
+
+ char * pth = new char[pthLen + 0x1u];
+
+ pth = ::zap::bytecp(pth,hmDir,hmDirLen).dest;
+ *pth++ = '/';
+ pth = ::zap::bytecp(pth,filNm,filNmLen).dest;
+ *pth = '\x00';
+
+ pth -= pthLen;
+
+ return pth;
+}
diff --git a/bowshock/source/init/bow/help.cxx b/bowshock/source/init/bow/help.cxx
new file mode 100644
index 0000000..f216ed3
--- /dev/null
+++ b/bowshock/source/init/bow/help.cxx
@@ -0,0 +1,25 @@
+// Copyright 2022-2023 Gabriel Jensen.
+
+#include <bow/init.hxx>
+
+#include <cinttypes>
+#include <cstdlib>
+
+void ::bow::bow::help(char const * const progNm) noexcept {
+ bow_logRaw(
+ "\n"
+ "\x1B[1mBowshock\x1B[0m %" PRIX64 ".%" PRIX64 ".%" PRIX64 "\n"
+ "Copyright 2022-2023 Gabriel Jensen.\n"
+ "\n"
+ "Usage: \"%s\" <options> [savefile]\n"
+ "\n"
+ "Options:\n"
+ " --credits Print the game \x1B[1mcredits\x1B[0m\n"
+ " --help Print \x1B[1mhelp\x1B[0m screen\n"
+ " --new Start a \x1B[1mnew\x1B[0m save file\n"
+ " --skip \x1B[1mSkip\x1B[0m the intro\n"
+ "\n",
+ ::bow::verMaj,::bow::verMin,::bow::verPat,progNm);
+
+ ::std::exit(EXIT_SUCCESS);
+}
diff --git a/bowshock/source/init/bow/init.cxx b/bowshock/source/init/bow/init.cxx
new file mode 100644
index 0000000..ffb1083
--- /dev/null
+++ b/bowshock/source/init/bow/init.cxx
@@ -0,0 +1,44 @@
+// Copyright 2022-2023 Gabriel Jensen.
+
+#include <bow/init.hxx>
+#include <bow/lgc.hxx>
+#include <bow/run.hxx>
+#include <bow/sav.hxx>
+
+#include <cinttypes>
+
+void ::bow::bow::init(int const argc,char const * const * const argv) noexcept {
+ ::bow::termOpts opts;
+ chkParams(opts,argc,argv);
+
+ priQuot();
+
+ bow_logRaw("\x1B[0m\x1B[1mBowshock\x1B[0m %" PRIX64 ".%" PRIX64 ".%" PRIX64 " \u2013 Copyright 2022\u20102023 \x1B[1mGabriel Jensen\x1B[0m.\n\n",::bow::verMaj,::bow::verMin,::bow::verPat);
+
+ bow_log("initialising");
+
+ bow_logDbg("debug mode is enabled");
+ bow_logDbg("data directory at \"" bow_datDir "\"");
+ bow_logDbg("angle unit: %.3f radians",0x1p0f);
+ bow_logDbg("distance unit: %.3f metres",::bow::distMod);
+ bow_logDbg("mass unit: %.3f kilograms",::bow::massMod);
+ bow_logDbg("time unit: %.3f seconds",::bow::tmMod);
+ bow_logDbg("gravitational constant: %f (factor: %f))",::bow::gravConst,::bow::gravConstFac);
+
+ initRnd();
+ initSig();
+ initGfx();
+
+ if (opts.skip || !intro()) [[likely]] {
+ if (!opts.hasSavPth) {opts.savPth = getSavPth();}
+
+ if (opts.newSav) ::bow::newSav(plDat);
+ else ::bow::cont(plDat,opts.savPth);
+
+ loop();
+
+ ::bow::sav(opts.savPth,plDat);
+
+ if (!opts.hasSavPth) delete[] const_cast<char *>(opts.savPth);
+ }
+}
diff --git a/bowshock/source/init/bow/initGfx.cxx b/bowshock/source/init/bow/initGfx.cxx
new file mode 100644
index 0000000..11efdeb
--- /dev/null
+++ b/bowshock/source/init/bow/initGfx.cxx
@@ -0,0 +1,42 @@
+// Copyright 2022-2023 Gabriel Jensen.
+
+#include <bow/init.hxx>
+
+#include <GLFW/glfw3.h>
+#include <glad/glad.h>
+
+void ::bow::bow::initGfx() noexcept {
+ bow_log("initialising graphics");
+
+ bow_logDbg("initialising glfw");
+ if (!::glfwInit()) [[unlikely]] {
+ bow_logErr("unable to initialise glfw");
+ ::bow::abrt();
+ }
+
+ bow_logDbg("initialising window");
+ ::glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR,0x4);
+ ::glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR,0x1);
+ ::glfwWindowHint(GLFW_DECORATED, GLFW_FALSE);
+ ::glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
+ ::glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);
+ ::glfwWindowHint(GLFW_SAMPLES, 0x8);
+ gfxDat.win = ::glfwCreateWindow(0x400,0x240,"Bowshock",::glfwGetPrimaryMonitor(),nullptr);
+ if (gfxDat.win == nullptr) [[unlikely]] {
+ bow_logErr("unable to open window");
+ ::bow::abrt();
+ }
+
+ bow_logDbg("initialising context");
+ ::glfwMakeContextCurrent(gfxDat.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(gfxDat.win);
+ ::glfwSwapInterval(0x1);
+
+ compShdProg(gfxDat.shdProg,"main");
+}
diff --git a/bowshock/source/init/bow/initRnd.cxx b/bowshock/source/init/bow/initRnd.cxx
new file mode 100644
index 0000000..369a68a
--- /dev/null
+++ b/bowshock/source/init/bow/initRnd.cxx
@@ -0,0 +1,12 @@
+// Copyright 2022-2023 Gabriel Jensen.
+
+#include <bow/init.hxx>
+
+#include <cstdlib>
+#include <ctime>
+
+void ::bow::bow::initRnd() noexcept {
+ bow_log("initialising random number generator");
+
+ ::std::srand(static_cast<unsigned int>(::std::time(nullptr)));
+}
diff --git a/bowshock/source/init/bow/initSig.cxx b/bowshock/source/init/bow/initSig.cxx
new file mode 100644
index 0000000..aef0424
--- /dev/null
+++ b/bowshock/source/init/bow/initSig.cxx
@@ -0,0 +1,25 @@
+// Copyright 2022-2023 Gabriel Jensen.
+
+#include <bow/init.hxx>
+
+#include <csignal>
+
+::std::sig_atomic_t volatile ::bow::gotIntr;
+
+namespace bow {
+ static void intrHand(int const sig) {
+ ::std::signal(sig,::bow::intrHand); // Ignore the return value: We can't do anything (meaningful) about it anyways.
+ ::bow::gotIntr = 0x1;
+ }
+}
+
+void ::bow::bow::initSig() noexcept {
+ bow_log("initialising signal handlers");
+
+ ::bow::gotIntr = 0x0;
+
+ if (::std::signal(SIGINT,::bow::intrHand) == SIG_ERR) [[unlikely]] {
+ bow_log("unable to set signal handler");
+ ::bow::abrt();
+ }
+}
diff --git a/bowshock/source/run/intro.c b/bowshock/source/init/bow/intro.cxx
index a8caee2..9d2d8c3 100644
--- a/bowshock/source/run/intro.c
+++ b/bowshock/source/init/bow/intro.cxx
@@ -1,34 +1,30 @@
// Copyright 2022-2023 Gabriel Jensen.
-#include <bow/run.h>
+#include <bow/init.hxx>
#include <GLFW/glfw3.h>
-#include <zap/mem.h>
-bool bow_intro(bow_gfxDat * const gfxdatptr) {
+bool ::bow::bow::intro() noexcept {
bow_log("starting intro");
- 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;
- glfwSetTime(0x0p0);
- for (double dur = 0x0p0;dur <= 0x3p0;dur = glfwGetTime()) {
- unlikely (bow_pollEvts(&gfxdat)) break;
+ ::glfwSetTime(0x0p0);
+ for (double dur = 0x0p0;dur <= 0x3p0;dur = ::glfwGetTime()) {
+ if (pollEvts()) [[unlikely]] break;
glClearColor(bowr,bowg,bowb,0x1p0);
glClear(GL_COLOR_BUFFER_BIT);
- glfwSwapBuffers(gfxdat.win);
+ ::glfwSwapBuffers(gfxDat.win);
}
double const fadedur = 0x1p0;
- glfwSetTime(0x0p0);
- for (double fac = 0x0p0;fac <= fadedur;fac = glfwGetTime()) {
- unlikely (bow_pollEvts(&gfxdat)) break;
+ ::glfwSetTime(0x0p0);
+ for (double fac = 0x0p0;fac <= fadedur;fac = ::glfwGetTime()) {
+ if (pollEvts()) [[unlikely]] break;
GLfloat const r = bowr*(0x1p0f-fac/fadedur);
GLfloat const g = bowg*(0x1p0f-fac/fadedur);
@@ -36,16 +32,14 @@ bool bow_intro(bow_gfxDat * const gfxdatptr) {
glClearColor(r,g,b,0x1p0);
glClear(GL_COLOR_BUFFER_BIT);
- glfwSwapBuffers(gfxdat.win);
+ ::glfwSwapBuffers(gfxDat.win);
}
glClearColor(0x0p0,0x0p0,0x0p0,0x1p0);
glClear(GL_COLOR_BUFFER_BIT);
- glfwSwapBuffers(gfxdat.win);
-
- unlikely (glfwWindowShouldClose(gfxdat.win)) quit = true;
+ ::glfwSwapBuffers(gfxDat.win);
- zap_cp(gfxdatptr,&gfxdat,sizeof (gfxdat));
+ if (::glfwWindowShouldClose(gfxDat.win)) [[unlikely]] quit = true;
return quit;
}
diff --git a/bowshock/source/run/loop.c b/bowshock/source/init/bow/loop.cxx
index 88008a9..8a963e4 100644
--- a/bowshock/source/run/loop.c
+++ b/bowshock/source/init/bow/loop.cxx
@@ -1,26 +1,16 @@
// Copyright 2022-2023 Gabriel Jensen.
-#include <bow/lgc.h>
-#include <bow/run.h>
+#include <bow/init.hxx>
+#include <bow/lgc.hxx>
#include <GLFW/glfw3.h>
+#include <cmath>
#include <glad/glad.h>
-#include <math.h>
-#include <zap/mem.h>
+#include <stdexcept>
-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) {
+void ::bow::bow::loop() noexcept {
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,
@@ -40,15 +30,19 @@ void bow_loop(bow_gfxDat * gfxDatPtr,bow_plDat * plDatPtr) {
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...).
+ ::bow::objRoot sysRoot; // For stellar bodies.
+ ::bow::objRoot objRoot = { // For miscellaneous objects (canisters, ships...).
.objs = nullptr,
};
- bow_genSys(&sysRoot,plDat.sysId,plDat.tm);
+ try {::bow::genSys(sysRoot,plDat.sysId,plDat.tm);}
+ catch (::std::bad_alloc const & e) {
+ bow_logErr("unable to allocate memory for object");
+ ::bow::abrt();
+ }
- bow_obj objTmp = {
- .typ = bow_objTyp_can,
+ ::bow::obj objTmp = {
+ .typ = ::bow::objTyp::can,
.pos = {
.x = 0x0p0,
.y = -0x2p0,
@@ -71,19 +65,24 @@ void bow_loop(bow_gfxDat * gfxDatPtr,bow_plDat * plDatPtr) {
},
.mass = 0x1p0,
};
- bow_addObj(&objRoot,&objTmp);
+ ::bow::addObj(objRoot,objTmp);
- glfwSetWindowUserPointer(gfxDat.win,&plDat);
- glfwSetScrollCallback(gfxDat.win,bow_scrlHand);
+ auto const scrlHand = [](::GLFWwindow * const win,[[maybe_unused]] double const xoff,double const yoff) -> void {
+ ::bow::plDat * dat = static_cast<::bow::plDat *>(::glfwGetWindowUserPointer(win));
+ dat->zoom *= ::std::pow(0x1.04p0f,0x0p0f-static_cast<float>(yoff));
+ };
+
+ ::glfwSetWindowUserPointer(gfxDat.win,&plDat);
+ ::glfwSetScrollCallback(gfxDat.win,scrlHand);
for (;;++plDat.tm) {
- unlikely (bow_pollEvts(&gfxDat)) break;
+ if (pollEvts()) [[unlikely]] break;
- bow_gravSys(&sysRoot);
- bow_gravObjs(&objRoot,&sysRoot);
+ ::bow::grav(sysRoot);
+ ::bow::grav(objRoot,sysRoot);
- bow_mvObjs(&sysRoot);
- bow_mvObjs(&objRoot);
+ ::bow::mv(sysRoot);
+ ::bow::mv(objRoot);
GLfloat const frm = 0x1p0*plDat.zoom;
@@ -104,14 +103,11 @@ void bow_loop(bow_gfxDat * gfxDatPtr,bow_plDat * plDatPtr) {
glBindVertexArray(vao);
glDrawArrays(GL_TRIANGLES,0x0,0x3 * 0x1);
- glfwSwapBuffers(gfxDat.win);
+ ::glfwSwapBuffers(gfxDat.win);
}
- glfwSetScrollCallback(gfxDat.win,nullptr);
+ ::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/init/bow/pollEvts.cxx b/bowshock/source/init/bow/pollEvts.cxx
new file mode 100644
index 0000000..063a68e
--- /dev/null
+++ b/bowshock/source/init/bow/pollEvts.cxx
@@ -0,0 +1,18 @@
+// Copyright 2022-2023 Gabriel Jensen.
+
+#include <bow/init.hxx>
+
+#include <GLFW/glfw3.h>
+
+bool ::bow::bow::pollEvts() noexcept {
+ ::glfwPollEvents();
+
+ if (::bow::gotIntr) [[unlikely]] {
+ bow_log("got interrupt");
+ ::glfwSetWindowShouldClose(gfxDat.win,GLFW_TRUE);
+
+ }
+ if (::glfwWindowShouldClose(gfxDat.win)) [[unlikely]] return true;
+
+ return false;
+}
diff --git a/bowshock/source/init/bow/priQuot.cxx b/bowshock/source/init/bow/priQuot.cxx
new file mode 100644
index 0000000..51a2f20
--- /dev/null
+++ b/bowshock/source/init/bow/priQuot.cxx
@@ -0,0 +1,19 @@
+// Copyright 2022-2023 Gabriel Jensen.
+
+#include <bow/init.hxx>
+
+#include <cinttypes>
+#include <ctime>
+#include <cstdlib>
+
+void ::bow::bow::priQuot() noexcept {
+ ::std::srand(static_cast<unsigned int>(::std::time(nullptr)));
+ ::zap::i8 const quotId = (::zap::i8)rand() % 0x24u;
+
+ char const * quot;
+ char const * src;
+ getQuot(&quot,&src,quotId);
+
+ if (src == nullptr) {bow_logRaw("%s\n",quot);}
+ else {bow_logRaw("\n%s\n\u2014 %s\n\n",quot,src);}
+}
diff --git a/bowshock/source/init/bow/quit.cxx b/bowshock/source/init/bow/quit.cxx
new file mode 100644
index 0000000..50c71ea
--- /dev/null
+++ b/bowshock/source/init/bow/quit.cxx
@@ -0,0 +1,29 @@
+// Copyright 2022-2023 Gabriel Jensen.
+
+#include <bow/init.hxx>
+
+#include <cstdlib>
+#include <GLFW/glfw3.h>
+
+void ::bow::bow::quit(::bow::stat const stat) noexcept {
+ bow_log("quitting");
+
+ glDeleteProgram(gfxDat.shdProg);
+
+ ::glfwDestroyWindow(gfxDat.win);
+ ::glfwTerminate();
+
+ int sysstat;
+ switch (stat) {
+ case ::bow::stat::err:
+ sysstat = EXIT_FAILURE;
+ break;
+ case ::bow::stat::ok:
+ sysstat = EXIT_SUCCESS;
+ break;
+ }
+
+ bow_log("goodbye");
+ bow_log("exiting with code %i",sysstat);
+ ::std::exit(sysstat);
+}
diff --git a/bowshock/source/init/chkParams.c b/bowshock/source/init/chkParams.c
deleted file mode 100644
index 839fd57..0000000
--- a/bowshock/source/init/chkParams.c
+++ /dev/null
@@ -1,40 +0,0 @@
-// 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
deleted file mode 100644
index 37131bb..0000000
--- a/bowshock/source/init/compShd.c
+++ /dev/null
@@ -1,97 +0,0 @@
-// 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
deleted file mode 100644
index 0112485..0000000
--- a/bowshock/source/init/compShdProg.c
+++ /dev/null
@@ -1,36 +0,0 @@
-// 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
deleted file mode 100644
index fac3ed3..0000000
--- a/bowshock/source/init/cred.c
+++ /dev/null
@@ -1,43 +0,0 @@
-// 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/init/getSavPth.c b/bowshock/source/init/getSavPth.c
deleted file mode 100644
index 88d5b30..0000000
--- a/bowshock/source/init/getSavPth.c
+++ /dev/null
@@ -1,40 +0,0 @@
-// 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/init/help.c b/bowshock/source/init/help.c
deleted file mode 100644
index 6fa5b8d..0000000
--- a/bowshock/source/init/help.c
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2022-2023 Gabriel Jensen.
-
-#include <bow/init.h>
-
-#include <inttypes.h>
-#include <stdlib.h>
-
-void bow_help(char const * const progNm) {
- bow_rawlog(
- "\n"
- "bowshock %" PRIXLEAST64 ".%" PRIXLEAST64 ".%" PRIXLEAST64 "\n"
- "Copyright 2022-2023 Gabriel Jensen.\n"
- "\n"
- "Usage: %s <options> [savefile]\n"
- "\n"
- "Options:\n"
- " --help Print help screen\n"
- " --restart Generate default commander\n"
- "\n",
- bow_verMaj,bow_verMin,bow_verPat,progNm);
-
- exit(EXIT_SUCCESS);
-}
diff --git a/bowshock/source/init/init.c b/bowshock/source/init/init.c
deleted file mode 100644
index be6f089..0000000
--- a/bowshock/source/init/init.c
+++ /dev/null
@@ -1,56 +0,0 @@
-// 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
deleted file mode 100644
index 34a04f5..0000000
--- a/bowshock/source/init/initGfx.c
+++ /dev/null
@@ -1,50 +0,0 @@
-// 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/init/initRnd.c b/bowshock/source/init/initRnd.c
deleted file mode 100644
index 886adc3..0000000
--- a/bowshock/source/init/initRnd.c
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright 2022-2023 Gabriel Jensen.
-
-#include <bow/init.h>
-
-#include <stdlib.h>
-#include <time.h>
-
-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
deleted file mode 100644
index 87b694c..0000000
--- a/bowshock/source/init/initSig.c
+++ /dev/null
@@ -1,23 +0,0 @@
-// 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
deleted file mode 100644
index bd23f2a..0000000
--- a/bowshock/source/init/priQuot.c
+++ /dev/null
@@ -1,22 +0,0 @@
-// 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
deleted file mode 100644
index 3d80333..0000000
--- a/bowshock/source/lgc/grav.c
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright 2022-2023 Gabriel Jensen.
-
-#include <bow/lgc.h>
-
-#include <math.h>
-#include <zap/mem.h>
-
-static void bow_grav1(bow_obj * obj,bow_obj * 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 angy = atan2(disty,distx);
- double const angz = atan2(distz,distx);
-
- 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;
-}
-
-static void bow_grav2(bow_obj * obj0,bow_obj * 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/(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);
- 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;
-}
-
-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 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/grav.cxx b/bowshock/source/lgc/grav.cxx
new file mode 100644
index 0000000..3896756
--- /dev/null
+++ b/bowshock/source/lgc/grav.cxx
@@ -0,0 +1,75 @@
+// Copyright 2022-2023 Gabriel Jensen.
+
+#include <bow/lgc.hxx>
+
+#include <cmath>
+
+namespace bow {
+ static void grav1(::bow::obj & obj,::bow::obj const & par) noexcept {
+ 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 = ::std::sqrt(distx*distx+disty*disty+distz*distz);
+
+ double const angy = ::std::atan2(disty,distx);
+ double const angz = ::std::atan2(distz,distx);
+
+ double acc = par.mass/(dist*dist)*::bow::gravConst;
+
+ double const vx = ::std::cos(angy)*acc;
+ double const vy = ::std::sin(angy)*acc;
+ double const vz = ::std::sin(angz)*acc;
+
+ obj.posVel.x += vx;
+ obj.posVel.y += vy;
+ obj.posVel.z += vz;
+ }
+
+ static void grav2(::bow::obj & obj0,::bow::obj & obj1) noexcept {
+ 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 = ::std::sqrt(distx*distx+disty*disty+distz*distz);
+
+ double const angy = ::std::atan2(disty,distx);
+ double const angz = ::std::atan2(distz,distx);
+
+ double acc0 = ::bow::gravConst/(dist*dist);
+ double const acc1 = acc0*obj0.mass; // This is negative.
+ acc0 *= obj1.mass;
+
+ double vx0 = ::std::cos(angy);
+ double vy0 = ::std::sin(angy);
+ double vz0 = ::std::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;
+ }
+}
+
+void ::bow::grav(::bow::objRoot & sys) noexcept {
+ 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::grav(::bow::objRoot & objs,::bow::objRoot const & sys) noexcept {
+ 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
deleted file mode 100644
index ac27e4e..0000000
--- a/bowshock/source/lgc/mv.c
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2022-2023 Gabriel Jensen.
-
-#include <bow/lgc.h>
-
-#include <math.h>
-#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;
-}
-
-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/mv.cxx b/bowshock/source/lgc/mv.cxx
new file mode 100644
index 0000000..b54a0af
--- /dev/null
+++ b/bowshock/source/lgc/mv.cxx
@@ -0,0 +1,18 @@
+// Copyright 2022-2023 Gabriel Jensen.
+
+#include <bow/lgc.hxx>
+
+void ::bow::mv(::bow::objRoot & root) noexcept {
+ auto const 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;
+ };
+
+ for (::bow::obj * obj = root.objs;obj != nullptr;obj = obj->next) {
+ mv(*obj);
+ }
+}
diff --git a/bowshock/source/lgc/shipMass.c b/bowshock/source/lgc/shipMass.c
deleted file mode 100644
index 05f2e2b..0000000
--- a/bowshock/source/lgc/shipMass.c
+++ /dev/null
@@ -1,10 +0,0 @@
-// 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.cxx b/bowshock/source/lgc/shipMass.cxx
new file mode 100644
index 0000000..e95140b
--- /dev/null
+++ b/bowshock/source/lgc/shipMass.cxx
@@ -0,0 +1,10 @@
+// Copyright 2022-2023 Gabriel Jensen.
+
+#include <bow/lgc.hxx>
+
+double ::bow::shipMass([[maybe_unused]] ::bow::ship const id) noexcept {
+ double mass = 0x100p0;
+ mass /= ::bow::massMod;
+
+ return mass;
+}
diff --git a/bowshock/source/lgc/sim.c b/bowshock/source/lgc/sim.c
deleted file mode 100644
index 86327f2..0000000
--- a/bowshock/source/lgc/sim.c
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2022-2023 Gabriel Jensen.
-
-#include <bow/lgc.h>
-
-#include <inttypes.h>
-
-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);
- }
-}
diff --git a/bowshock/source/lgc/sim.cxx b/bowshock/source/lgc/sim.cxx
new file mode 100644
index 0000000..596b0c9
--- /dev/null
+++ b/bowshock/source/lgc/sim.cxx
@@ -0,0 +1,16 @@
+// Copyright 2022-2023 Gabriel Jensen.
+
+#include <bow/lgc.hxx>
+
+#include <bow/run.hxx>
+
+#include <cinttypes>
+
+void ::bow::sim(::bow::objRoot & sys,::zap::i04 const dur) noexcept {
+ bow_log("simulating for (%" PRIX64 ") time units",dur);
+
+ for (::zap::i04 i = 0x0u;i <= dur;++i) {
+ ::bow::grav(sys);
+ ::bow::mv(sys);
+ }
+}
diff --git a/bowshock/source/run/abrt.c b/bowshock/source/run/abrt.c
deleted file mode 100644
index 29a3102..0000000
--- a/bowshock/source/run/abrt.c
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2022-2023 Gabriel Jensen.
-
-#include <bow/run.h>
-
-#include <stdlib.h>
-
-void bow_abrt(void) {
- bow_log("aborting");
-
- abort();
-}
diff --git a/bowshock/source/run/abrt.cxx b/bowshock/source/run/abrt.cxx
new file mode 100644
index 0000000..80ceb4b
--- /dev/null
+++ b/bowshock/source/run/abrt.cxx
@@ -0,0 +1,11 @@
+// Copyright 2022-2023 Gabriel Jensen.
+
+#include <bow/run.hxx>
+
+#include <cstdlib>
+
+void ::bow::abrt() noexcept {
+ bow_log("\x1B[38;5;197maborting\x1B[0m");
+
+ ::std::abort();
+}
diff --git a/bowshock/source/run/addObj.c b/bowshock/source/run/addObj.c
deleted file mode 100644
index f7d25ae..0000000
--- a/bowshock/source/run/addObj.c
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2022-2023 Gabriel Jensen.
-
-#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 * const obj = malloc(sizeof (bow_obj));
- 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/run/addObj.cxx b/bowshock/source/run/addObj.cxx
new file mode 100644
index 0000000..54732db
--- /dev/null
+++ b/bowshock/source/run/addObj.cxx
@@ -0,0 +1,16 @@
+// Copyright 2022-2023 Gabriel Jensen.
+
+#include <bow/run.hxx>
+
+#include <cstdlib>
+#include <zap/mem.hh>
+
+void ::bow::addObj(::bow::objRoot & root,::bow::obj const & objVal) {
+ bow_logDbg("adding object of type %s",::bow::objTypStr(objVal.typ));
+
+ ::bow::obj * const obj = new ::bow::obj;
+ ::zap::bytecp(obj,&objVal,sizeof (objVal));
+
+ obj->next = root.objs;
+ root.objs = obj;
+}
diff --git a/bowshock/source/run/freeObjs.c b/bowshock/source/run/freeObjs.c
deleted file mode 100644
index 0a8ecd0..0000000
--- a/bowshock/source/run/freeObjs.c
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2022-2023 Gabriel Jensen.
-
-#include <bow/run.h>
-
-#include <stdlib.h>
-#include <zap/mem.h>
-
-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));
- next = obj->next;
- free(obj);
- }
-}
diff --git a/bowshock/source/run/freeObjs.cxx b/bowshock/source/run/freeObjs.cxx
new file mode 100644
index 0000000..7843aca
--- /dev/null
+++ b/bowshock/source/run/freeObjs.cxx
@@ -0,0 +1,16 @@
+// Copyright 2022-2023 Gabriel Jensen.
+
+#include <bow/run.hxx>
+
+void ::bow::freeObjs(::bow::objRoot const & root) noexcept {
+ bow_logDbg("freeing objects");
+
+ ::bow::obj * obj;
+ ::bow::obj * next;
+ for (obj = root.objs;obj != nullptr;obj = next) {
+ bow_logDbg("freeing object of type %s",::bow::objTypStr(obj->typ));
+
+ next = obj->next;
+ delete obj;
+ }
+}
diff --git a/bowshock/source/run/genSys.c b/bowshock/source/run/genSys.cxx
index e8161a3..7f6f922 100644
--- a/bowshock/source/run/genSys.c
+++ b/bowshock/source/run/genSys.cxx
@@ -1,17 +1,18 @@
// Copyright 2022-2023 Gabriel Jensen.
-#include <bow/lgc.h>
-#include <bow/run.h>
+#include <bow/lgc.hxx>
+#include <bow/run.hxx>
-#include <inttypes.h>
+#include <cinttypes>
-void bow_genSys(bow_objRoot * const sys,zap_i04 const id,zap_i04 const tm) {
+void ::bow::genSys(::bow::objRoot & 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,
+ sys.objs = nullptr;
+ ::bow::obj objTmp;
+ objTmp = {
+ .typ = ::bow::objTyp::star,
+ .starTyp = ::bow::star::g,
.pos = {
.x = 0x0p0,
.y = 0x0p0,
@@ -33,12 +34,12 @@ void bow_genSys(bow_objRoot * const sys,zap_i04 const id,zap_i04 const tm) {
.z = 0x0p0,
},
.mass = 0x1p0,
- .starTyp = bow_star_g,
// next will be overwritten anyways.
};
- bow_addObj(sys,&objtmp);
- objtmp = (bow_obj) {
- .typ = bow_objTyp_wrld,
+ ::bow::addObj(sys,objTmp);
+ objTmp = {
+ .typ = ::bow::objTyp::wrld,
+ .wrldTyp = ::bow::wrld::rck,
.pos = {
.x = 0x0p0,
.y = 0x1.F76F144Dp-1,
@@ -50,7 +51,7 @@ void bow_genSys(bow_objRoot * const sys,zap_i04 const id,zap_i04 const tm) {
.z = 0x0p0,
},
.posVel = {
- .x = 0x1.B2D06FF3p-23*bow_tmMod,
+ .x = 0x1.B2D06FF3p-23*::bow::tmMod,
.y = 0x0p0,
.z = 0x0p0,
},
@@ -60,9 +61,8 @@ void bow_genSys(bow_objRoot * const sys,zap_i04 const id,zap_i04 const tm) {
.z = 0x1.31DB66BBp-15,
},
.mass = 0x1.931AFC649369998Fp-19,
- .wrldTyp = bow_wrld_rck,
};
- bow_addObj(sys,&objtmp);
-
- bow_sim(sys,tm);
+ ::bow::addObj(sys,objTmp);
+
+ ::bow::sim(sys,tm);
}
diff --git a/bowshock/source/run/pollEvts.c b/bowshock/source/run/pollEvts.c
deleted file mode 100644
index 3444ceb..0000000
--- a/bowshock/source/run/pollEvts.c
+++ /dev/null
@@ -1,18 +0,0 @@
-// 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/run/quit.c b/bowshock/source/run/quit.c
deleted file mode 100644
index e8ee8a2..0000000
--- a/bowshock/source/run/quit.c
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2022-2023 Gabriel Jensen.
-
-#include <bow/run.h>
-
-#include <GLFW/glfw3.h>
-#include <stdlib.h>
-#include <zap/mem.h>
-
-void bow_quit(bow_gfxDat * gfxdatptr,bow_stat const stat) {
- bow_log("quitting");
-
- bow_gfxDat gfxdat;
- zap_cp(&gfxdat,gfxdatptr,sizeof (gfxdat));
-
- glDeleteProgram(gfxdat.shdProg);
-
- glfwDestroyWindow(gfxdat.win);
- glfwTerminate();
-
- int sysstat;
- switch (stat) {
- case bow_stat_err:
- sysstat = EXIT_FAILURE;
- break;
- case bow_stat_ok:
- 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
deleted file mode 100644
index 137d2ef..0000000
--- a/bowshock/source/sav/cont.c
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright 2022-2023 Gabriel Jensen.
-
-#include <bow/sav.h>
-
-#include <flux/io.h>
-#include <inttypes.h>
-#include <zap/mem.h>
-
-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);
-
- 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);
-
- 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);
-
- goto new;
- }
-
- flux_cl(fil);
-
- 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;
- }
- unlikely (dat.shipTyp > bow_maxShipId) {
- bow_logErr("invalid ship type (%" PRIX8 ")",dat.shipTyp);
-
- goto new;
- }
-
- 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,
- };
- 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_new(pldatptr);
-}
diff --git a/bowshock/source/sav/cont.cxx b/bowshock/source/sav/cont.cxx
new file mode 100644
index 0000000..9132586
--- /dev/null
+++ b/bowshock/source/sav/cont.cxx
@@ -0,0 +1,83 @@
+// Copyright 2022-2023 Gabriel Jensen.
+
+#include <bow/sav.hxx>
+
+#include <cinttypes>
+#include <flux/io.h>
+#include <zap/mem.hh>
+
+void ::bow::cont(::bow::plDat & plDat,char const * const pth) noexcept {
+ 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) [[unlikely]] {
+ bow_logErr("unable to open save file \"%s\"",pth);
+
+ return ::bow::newSav(plDat);
+ }
+
+ ::zap::i8 rawDat[::bow::savLen];
+ err = ::flux_rd(rawDat,fil,::bow::savLen,nullptr);
+
+ if (err) [[unlikely]] {
+ ::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);
+
+ return ::bow::newSav(plDat);
+ }
+
+ ::flux_cl(fil);
+
+ ::bow::savDat dat;
+
+ ::bow::decSav(dat,rawDat);
+
+ if (dat.fmtVer != ::bow::savVer) [[unlikely]] {
+ bow_logErr("invalid format (%" PRIX64 " of save file at \"%s\"",dat.fmtVer,pth);
+
+ return ::bow::newSav(plDat);
+ }
+ if (dat.shipTyp > ::bow::maxShipId) [[unlikely]] {
+ bow_logErr("invalid ship type (%" PRIX8 ")",dat.shipTyp);
+
+ return ::bow::newSav(plDat);
+ }
+
+ plDat = ::bow::plDat {
+ .tm = dat.tm,
+ .sysId = dat.sysId,
+ .ship = {
+ .shipTyp = (::bow::ship)dat.shipTyp,
+ .pos = {
+ .x = dat.shipPosX,
+ .y = dat.shipPosY,
+ .z = dat.shipPosZ,
+ },
+ .rot = {
+ .x = dat.shipRotX,
+ .y = dat.shipRotY,
+ .z = dat.shipRotZ,
+ },
+ .posVel = {
+ .x = dat.shipPosVelX,
+ .y = dat.shipPosVelY,
+ .z = dat.shipPosVelZ,
+ },
+ .rotVel = {
+ .x = dat.shipRotVelX,
+ .y = dat.shipRotVelY,
+ .z = dat.shipRotVelZ,
+ },
+ },
+ };
+ ::zap::cp(plDat.nm,dat.cmdrNm,::bow::cmdrNmLen);
+ plDat.nm[::bow::cmdrNmLen] = '\x00';
+
+ ::bow::genDat(plDat);
+
+ bow_log("welcome back, commander %s",plDat.nm);
+}
diff --git a/bowshock/source/sav/decSav.c b/bowshock/source/sav/decSav.c
deleted file mode 100644
index a4e25a6..0000000
--- a/bowshock/source/sav/decSav.c
+++ /dev/null
@@ -1,25 +0,0 @@
-// 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/decSav.cxx b/bowshock/source/sav/decSav.cxx
new file mode 100644
index 0000000..983dd3a
--- /dev/null
+++ b/bowshock/source/sav/decSav.cxx
@@ -0,0 +1,29 @@
+// Copyright 2022-2023 Gabriel Jensen.
+
+#include <bow/sav.hxx>
+
+#include <zap/mem.hh>
+
+void ::bow::decSav(::bow::savDat & buf,::zap::i8 const * dat) noexcept {
+ auto const decVal = [&dat]<typename typ>(typ & buf) {
+ dat = ::zap::bytecp(&buf,dat,sizeof (buf)).src;
+ };
+
+ decVal(buf.fmtVer); // fmtver
+ decVal(buf.cmdrNm); // cmdrnm
+ decVal(buf.tm); // tm
+ decVal(buf.sysId); // sysId
+ decVal(buf.shipTyp); // shipTyp
+ decVal(buf.shipPosX); // shipposx
+ decVal(buf.shipPosY); // shipposy
+ decVal(buf.shipPosZ); // shipposz
+ decVal(buf.shipRotX); // shiprotx
+ decVal(buf.shipRotY); // shiproty
+ decVal(buf.shipRotZ); // shiprotz
+ decVal(buf.shipPosVelX); // shipposVelx
+ decVal(buf.shipPosVelY); // shipposVely
+ decVal(buf.shipPosVelZ); // shipposVelz
+ decVal(buf.shipRotVelX); // shiprotVelx
+ decVal(buf.shipRotVelY); // shiprotVely
+ decVal(buf.shipRotVelZ); // shiprotVelz
+}
diff --git a/bowshock/source/sav/encSav.c b/bowshock/source/sav/encSav.c
deleted file mode 100644
index ca7081c..0000000
--- a/bowshock/source/sav/encSav.c
+++ /dev/null
@@ -1,25 +0,0 @@
-// 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/encSav.cxx b/bowshock/source/sav/encSav.cxx
new file mode 100644
index 0000000..245cd22
--- /dev/null
+++ b/bowshock/source/sav/encSav.cxx
@@ -0,0 +1,29 @@
+// Copyright 2022-2023 Gabriel Jensen.
+
+#include <bow/sav.hxx>
+
+#include <zap/mem.hh>
+
+void ::bow::encSav(::zap::i8 * buf,::bow::savDat const & dat) noexcept {
+ auto const encVal = [&buf]<typename typ>(typ const & val) {
+ buf = ::zap::bytecp(buf,&val,sizeof (val)).dest;
+ };
+
+ encVal(dat.fmtVer); // fmtver
+ encVal(dat.cmdrNm); // cmdrnm
+ encVal(dat.tm); // tm
+ encVal(dat.sysId); // sysid
+ encVal(dat.shipTyp); // shiptyp
+ encVal(dat.shipPosX); // shipposx
+ encVal(dat.shipPosY); // shipposy
+ encVal(dat.shipPosZ); // shipposz
+ encVal(dat.shipRotX); // shiprotx
+ encVal(dat.shipRotY); // shiproty
+ encVal(dat.shipRotZ); // shiprotz
+ encVal(dat.shipPosVelX); // shipposelx
+ encVal(dat.shipPosVelY); // shipposely
+ encVal(dat.shipPosVelZ); // shipposelz
+ encVal(dat.shipRotVelX); // shiprotelx
+ encVal(dat.shipRotVelY); // shiprotely
+ encVal(dat.shipRotVelZ); // shiprotelz
+}
diff --git a/bowshock/source/sav/genDat.c b/bowshock/source/sav/genDat.c
deleted file mode 100644
index 0b6810f..0000000
--- a/bowshock/source/sav/genDat.c
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2022-2023 Gabriel Jensen.
-
-#include <bow/lgc.h>
-#include <bow/sav.h>
-
-#include <zap/mem.h>
-
-#include <string.h>
-
-void bow_genDat(bow_plDat * const datptr) {
- bow_log("generating player data");
-
- bow_plDat dat;
- zap_cp(&dat,datptr,sizeof (dat));
-
- 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/genDat.cxx b/bowshock/source/sav/genDat.cxx
new file mode 100644
index 0000000..341d062
--- /dev/null
+++ b/bowshock/source/sav/genDat.cxx
@@ -0,0 +1,12 @@
+// Copyright 2022-2023 Gabriel Jensen.
+
+#include <bow/lgc.hxx>
+#include <bow/sav.hxx>
+
+void ::bow::genDat(::bow::plDat & dat) noexcept {
+ bow_log("generating player data");
+
+ dat.ship.typ = ::bow::objTyp::ship;
+ dat.ship.mass = ::bow::shipMass(dat.ship.shipTyp);
+ dat.zoom = 0x4p0;
+}
diff --git a/bowshock/source/sav/new.c b/bowshock/source/sav/newSav.cxx
index 371cd07..62482b0 100644
--- a/bowshock/source/sav/new.c
+++ b/bowshock/source/sav/newSav.cxx
@@ -1,17 +1,16 @@
// Copyright 2022-2023 Gabriel Jensen.
-#include <bow/sav.h>
+#include <bow/sav.hxx>
-#include <zap/mem.h>
-
-void bow_new(bow_plDat * const datptr) {
+void ::bow::newSav(::bow::plDat & dat) noexcept {
bow_log("generating new save file");
- bow_plDat dat = {
- .nm = "Caelum\x00\x00\x00\x00\x00\x00\x00\x00\x00",
- .sysId = 0x45u,
+ dat = ::bow::plDat {
+ .nm = "Caelum\x00\x00\x00\x00\x00\x00\x00\x00",
.tm = 0x0u, // 256 julian years after the Unix Epoch.
+ .sysId = 0x45u,
.ship = {
+ .shipTyp = ::bow::ship::aq,
.pos = {
.x = 0x0p0,
.y = 0x0p0,
@@ -32,12 +31,9 @@ void bow_new(bow_plDat * const datptr) {
.y = 0x0p0,
.z = 0x0p0,
},
- .shipTyp = bow_ship_aq,
},
};
- bow_genDat(&dat);
+ ::bow::genDat(dat);
bow_log("welcome, commander %s",dat.nm);
-
- zap_cp(datptr,&dat,sizeof (dat));
}
diff --git a/bowshock/source/sav/sav.c b/bowshock/source/sav/sav.c
deleted file mode 100644
index 1d99864..0000000
--- a/bowshock/source/sav/sav.c
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2022-2023 Gabriel Jensen.
-
-#include <bow/run.h>
-#include <bow/sav.h>
-
-#include <flux/io.h>
-
-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);
-
- 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);
- unlikely (err) {
- bow_logErr("unable to create save file \"%s\"",pth);
- bow_abrt();
- }
- }
-
- zap_i8 dat[bow_savLen];
- bow_encSav(dat,plDat);
-
- flux_wr(fil,dat,bow_savLen);
- flux_cl(fil);
-}
diff --git a/bowshock/source/sav/sav.cxx b/bowshock/source/sav/sav.cxx
new file mode 100644
index 0000000..38de722
--- /dev/null
+++ b/bowshock/source/sav/sav.cxx
@@ -0,0 +1,54 @@
+// Copyright 2022-2023 Gabriel Jensen.
+
+#include <bow/run.hxx>
+#include <bow/sav.hxx>
+
+#include <flux/io.h>
+#include <zap/mem.hh>
+
+void ::bow::sav(char const * const pth,::bow::plDat const & plDat) noexcept {
+ bow_log("saving commander %s at \"%s\"",plDat.nm,pth);
+
+ ::flux_fil * fil;
+ ::flux_err err = ::flux_mkfil(&fil,pth,0644);
+
+ if (err) [[unlikely]] {
+ if (err != ::flux_err_exist) [[unlikely]] {
+ bow_logErr("unable to open save file \"%s\"",pth);
+ ::bow::abrt();
+ }
+
+ err = ::flux_op(&fil,pth,::flux_md_wr,flux_disc);
+ if (err) [[unlikely]] {
+ bow_logErr("unable to create save file \"%s\"",pth);
+ ::bow::abrt();
+ }
+ }
+
+ ::zap::i8 dat[::bow::savLen];
+
+ ::bow::savDat savDat = {
+ .fmtVer = ::bow::savVer,
+ .tm = plDat.tm,
+ .sysId = plDat.sysId,
+ .shipTyp = static_cast<::zap::i8>(plDat.ship.shipTyp),
+ .shipPosX = plDat.ship.pos.x,
+ .shipPosY = plDat.ship.pos.y,
+ .shipPosZ = plDat.ship.pos.z,
+ .shipRotX = plDat.ship.rot.x,
+ .shipRotY = plDat.ship.rot.y,
+ .shipRotZ = plDat.ship.rot.z,
+ .shipPosVelX = plDat.ship.posVel.x,
+ .shipPosVelY = plDat.ship.posVel.y,
+ .shipPosVelZ = plDat.ship.posVel.z,
+ .shipRotVelX = plDat.ship.rotVel.x,
+ .shipRotVelY = plDat.ship.rotVel.y,
+ .shipRotVelZ = plDat.ship.rotVel.z,
+ };
+ ::zap::cp(savDat.cmdrNm,plDat.nm,sizeof (savDat.cmdrNm));
+
+ ::bow::encSav(dat,savDat);
+
+ ::flux_wr(fil,dat,::bow::savLen);
+ ::flux_cl(fil);
+}
diff --git a/glad.CMakeLists.txt b/glad.CMakeLists.txt
index b77ab48..7d7c2fc 100644
--- a/glad.CMakeLists.txt
+++ b/glad.CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 3.19)
+cmake_minimum_required(VERSION 3.21)
set(CMAKE_C_STANDARD 99)
@@ -8,8 +8,6 @@ add_library(
"src/glad.c"
)
-target_enable_optimisations(glad)
-
target_include_directories(
glad PUBLIC
@@ -20,6 +18,15 @@ if("${CMAKE_C_COMPILER_ID}" MATCHES "Clang|GNU")
target_compile_options(
glad PRIVATE
+ $<IF:$<STREQUAL:"${CMAKE_BUILD_TYPE}","Debug">,-Og,-Ofast>
+ -fdiagnostics-color=always
-g
)
+elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
+ target_compile_options(
+ glad PRIVATE
+
+ /O2
+ $<IF:$<STREQUAL:"${CMAKE_BUILD_TYPE}","Debug">,/Zo>
+ )
endif()