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