commit 73d5a61e3648268c12ed04a39f99bdfd75b2d9ef parent 7b41dc97b81181db6d739454165f742e55441414 Author: Michael Savage <mikejsavage@gmail.com> Date: Sun Aug 9 21:40:17 +0200 Move bsp/hm to shared libraries, add medfall binary with support for code reloading Diffstat:
.gitignore | | | 4 | ++-- |
Makefile | | | 29 | +++++++++++++---------------- |
game.h | | | 13 | +++++++++++++ |
hm.cc | | | 141 | ++++++++++++++++++++++++++++++++++--------------------------------------------- |
main.cc | | | 97 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
diff --git a/.gitignore b/.gitignore @@ -1,6 +1,6 @@ -bsp -hm +medfall pp *.o +*.so ttvfs *.bsp diff --git a/Makefile b/Makefile @@ -1,21 +1,15 @@ -all: hm pp +all: medfall hm.so pp -BSPSRCS = bsp.cc bsp_renderer.cc gl.cc -BSPOBJS := $(patsubst %.cc,%.o,$(BSPSRCS)) - -HMSRCS = hm.cc gl.cc heightmap.cc terrain_manager.cc stb_image.cc stb_perlin.cc -HMOBJS := $(patsubst %.cc,%.o,$(HMSRCS)) - -PPSRCS = pp.cc stb_image.cc stb_image_write.cc -PPOBJS := $(patsubst %.cc,%.o,$(PPSRCS)) +OBJS = main.o gl.o +BSPOBJS = bsp.o bsp_renderer.o gl.o +HMOBJS = hm.o heightmap.o terrain_manager.o stb_image.o stb_perlin.o +PPOBJS = pp.o stb_image.o stb_image_write.o WARNINGS = -Wall -Wextra -Wno-unused-parameter -Wno-unused-function -Wno-write-strings CXXFLAGS += -std=c++11 -O2 $(WARNINGS) -ggdb3 -DGL_GLEXT_PROTOTYPES # OS detection -uname := $(shell uname -s) - -ifneq ($(uname),Darwin) +ifneq ($(shell uname -s),Darwin) LDFLAGS += -lGL -lGLEW -lglfw LDFLAGS += -lGLU else @@ -31,17 +25,20 @@ endif picky: WARNINGS += -Wunused-parameter -Wunused-function -Wwrite-strings picky: all -hm: $(HMOBJS) +medfall: main.o gl.o $(CXX) $^ $(LDFLAGS) -o $@ -bsp: $(BSPOBJS) - $(CXX) $^ $(LDFLAGS) -o $@ +hm.so: $(HMOBJS) + $(CXX) $^ $(LDFLAGS) -o $@ -shared + +bsp.so: $(BSPOBJS) + $(CXX) $^ $(LDFLAGS) -o $@ -shared pp: $(PPOBJS) $(CXX) $^ $(LDFLAGS) -o $@ clean: - rm -f bsp hm $(BSPOBJS) $(HMOBJS) $(PPOBJS) + rm -f medfall bsp.so hm.so $(BSPOBJS) $(HMOBJS) $(PPOBJS) stb_image.o: stb_image.cc $(CXX) $(CXXFLAGS) -c -o $@ $^ -DSTB_IMAGE_IMPLEMENTATION diff --git a/game.h b/game.h @@ -0,0 +1,13 @@ +#ifndef _ASDF_H_ +#define _ASDF_H_ + +struct GameMemory { +}; + +struct GameInput { +}; + +#define GAME_FRAME( name ) void name( GameMemory & mem, const GameInput & input, const float dt ) +typedef GAME_FRAME( GameFrame ); + +#endif // _ASDF_H_ diff --git a/hm.cc b/hm.cc @@ -8,8 +8,8 @@ #include <glm/gtc/matrix_transform.hpp> #include <glm/gtc/type_ptr.hpp> +#include "game.h" #include "int.h" -#include "gl.h" #include "heightmap.h" #include "terrain_manager.h" #include "stb_easy_font.h" @@ -43,95 +43,76 @@ void print_vec3( const std::string & name, const glm::vec3 & v ) { printf( "%s: %.3f %.3f %.3f\n", name.c_str(), v.x, v.y, v.z ); } -int main( int argc, char ** argv ) { - GLFWwindow * const window = GL::init(); - - const std::string map = argc == 2 ? argv[ 1 ] : "mountains512.png" ; - - TerrainManager tm( map + ".parts" ); - - const float start_time = glfwGetTime(); - u32 frames = 0; - float last_frame = start_time; - - glClearColor( 0, 0.5, 0.7, 1 ); - - glm::vec3 pos( 15000, 3000, 50 ); - glm::vec3 angles = glm::radians( glm::vec3( -90, 45, 0 ) ); - - tm.teleport( pos ); - - const glm::mat4 P = glm::perspective( glm::radians( 120.0f ), 640.0f / 480.0f, 0.1f, 10000.0f ); +bool init = false; +glm::vec3 pos( 15000, 3000, 50 ); +glm::vec3 angles( glm::radians( glm::vec3( -90, 45, 0 ) ) ); +glm::mat4 P( glm::perspective( glm::radians( 120.0f ), 640.0f / 480.0f, 0.1f, 10000.0f ) ); +TerrainManager tm( "Srtm_ramp2.world.21600x10800.jpg.parts" ); + +extern "C" GAME_FRAME( game_frame ) { + if( !init ) { + glClearColor( 0, 0.5, 0.7, 1 ); + tm.teleport( pos ); + init = true; + } - while( !glfwWindowShouldClose( window ) ) { - const float now = glfwGetTime(); - const float dt = now - last_frame; + // if( glfwGetKey( window, 'Q' ) ) { + // break; + // } - if( glfwGetKey( window, 'Q' ) ) { - break; - } + glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); - glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); + // const int fb = glfwGetKey( window, 'W' ) - glfwGetKey( window, 'S' ); + // const int lr = glfwGetKey( window, 'A' ) - glfwGetKey( window, 'D' ); + // const int dz = glfwGetKey( window, GLFW_KEY_SPACE ) - glfwGetKey( window, GLFW_KEY_LEFT_SHIFT ); - const int fb = glfwGetKey( window, 'W' ) - glfwGetKey( window, 'S' ); - const int lr = glfwGetKey( window, 'A' ) - glfwGetKey( window, 'D' ); - const int dz = glfwGetKey( window, GLFW_KEY_SPACE ) - glfwGetKey( window, GLFW_KEY_LEFT_SHIFT ); + // const int pitch = glfwGetKey( window, GLFW_KEY_UP ) - glfwGetKey( window, GLFW_KEY_DOWN ); + // const int yaw = glfwGetKey( window, GLFW_KEY_RIGHT ) - glfwGetKey( window, GLFW_KEY_LEFT ); - const int pitch = glfwGetKey( window, GLFW_KEY_UP ) - glfwGetKey( window, GLFW_KEY_DOWN ); - const int yaw = glfwGetKey( window, GLFW_KEY_RIGHT ) - glfwGetKey( window, GLFW_KEY_LEFT ); + const int fb = 0; + const int lr = 0; + const int dz = 0; + const int pitch = 0; + const int yaw = 0; - angles.x += pitch * dt * 2; - angles.y += yaw * dt * 2; + angles.x += pitch * dt * 2; + angles.y += yaw * dt * 2; - pos += angles_to_vector_xy( angles ) * 100.0f * dt * ( float ) fb; - const glm::vec3 sideways = glm::vec3( -cosf( angles.y ), sinf( angles.y ), 0 ); - pos += sideways * 100.0f * dt * ( float ) lr; - // pos.z = hm.height( pos.x, pos.y ) + 8; - pos.z += dz * 50.0f * dt; + pos += angles_to_vector_xy( angles ) * 100.0f * dt * ( float ) fb; + const glm::vec3 sideways = glm::vec3( -cosf( angles.y ), sinf( angles.y ), 0 ); + pos += sideways * 100.0f * dt * ( float ) lr; + // pos.z = hm.height( pos.x, pos.y ) + 8; + pos.z += dz * 50.0f * dt; - tm.update( pos ); + tm.update( pos ); - const glm::mat4 VP = glm::translate( + const glm::mat4 VP = glm::translate( + glm::rotate( glm::rotate( - glm::rotate( - P, - angles.x, - glm::vec3( 1, 0, 0 ) - ), - angles.y, - glm::vec3( 0, 0, 1 ) + P, + angles.x, + glm::vec3( 1, 0, 0 ) ), - -pos - ); - - tm.render( VP ); - - // glLoadIdentity(); - // - // glBegin( GL_TRIANGLE_STRIP ); - // glColor3f( 0.2, 0.2, 0.2 ); - // glVertex2f( -1, 1 ); - // glVertex2f( 1, 1 ); - // glVertex2f( -1, 0.95 ); - // glVertex2f( 1, 0.95 ); - // glEnd(); - // - // glOrtho( 0, 640, 480, 0, -1, 1 ); - // TEXT( 2, 2, "%d", ( int ) ( 1 / dt ) ); - // - // glPopMatrix(); - - glfwSwapBuffers( window ); - glfwPollEvents(); - - last_frame = now; - frames++; - } - - const float end_time = glfwGetTime(); - printf( "%u frames in %.1fs. %.1f FPS\n", frames, end_time - start_time, frames / ( end_time - start_time ) ); - - GL::term(); + angles.y, + glm::vec3( 0, 0, 1 ) + ), + -pos + ); - return 0; + tm.render( VP ); + + // glLoadIdentity(); + // + // glBegin( GL_TRIANGLE_STRIP ); + // glColor3f( 0.2, 0.2, 0.2 ); + // glVertex2f( -1, 1 ); + // glVertex2f( 1, 1 ); + // glVertex2f( -1, 0.95 ); + // glVertex2f( 1, 0.95 ); + // glEnd(); + // + // glOrtho( 0, 640, 480, 0, -1, 1 ); + // TEXT( 2, 2, "%d", ( int ) ( 1 / dt ) ); + // + // glPopMatrix(); } diff --git a/main.cc b/main.cc @@ -0,0 +1,97 @@ +#include <stdio.h> +#include <time.h> +#include <dlfcn.h> +#include <sys/stat.h> +#include <sys/types.h> + +#include <GLFW/glfw3.h> + +#include "game.h" +#include "int.h" +#include "gl.h" + +#define GAME_LIBRARY_PATH "hm.so" + +struct Game { + void * lib; + GameFrame * frame; + + time_t lib_write_time; +}; + +time_t file_last_write_time( const char * const path ) { + struct stat buf; + if( stat( path, &buf ) == -1 ) { + return 0; + } + + return buf.st_mtime; +} + +Game load_game( const char * const path ) { + Game game = { }; + + game.lib = dlopen( path, RTLD_NOW ); + if( game.lib ) { + game.frame = ( GameFrame * ) dlsym( game.lib, "game_frame" ); + } + + printf( "loaded game: %p %p\n", game.lib, game.frame ); + + game.lib_write_time = file_last_write_time( path ); + + return game; +} + +void unload_game( Game * game ) { + if( game->lib ) { + dlclose( game->lib ); + } + + game->frame = nullptr; +} + +bool should_reload_game( const char * const path, const time_t lib_write_time ) { + return file_last_write_time( path ) > lib_write_time; +} + +int main( int argc, char ** argv ) { + GLFWwindow * const window = GL::init(); + + Game game = load_game( GAME_LIBRARY_PATH ); + GameMemory mem = { }; + + bool running = true; + float last_frame_time = glfwGetTime(); + + while( !glfwWindowShouldClose( window ) ) { + const float current_frame_time = glfwGetTime(); + const float dt = current_frame_time - last_frame_time; + + if( ( i32 ) current_frame_time != ( i32 ) last_frame_time ) { + if( should_reload_game( GAME_LIBRARY_PATH, game.lib_write_time ) ) { + unload_game( &game ); + game = load_game( GAME_LIBRARY_PATH ); + } + } + + // TODO: keyboard events + + GameInput input = { }; + + if( game.frame ) { + game.frame( mem, input, dt ); + } + + glfwSwapBuffers( window ); + glfwPollEvents(); + + last_frame_time = current_frame_time; + } + + unload_game( &game ); + + GL::term(); + + return 0; +}