diff options
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) @@ -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(",&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(",&src,quotId)) { - bow_logErr("invalid quote identifier (%" PRIXLEAST8 ")",quotId); - bow_getQuot(",&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() |