Compare commits
59 commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
adaa01ae4b | ||
![]() |
37ec5a7558 | ||
![]() |
2b7af06d00 | ||
![]() |
5d512b6c7a | ||
![]() |
2f65ef014f | ||
![]() |
1d18873f4b | ||
![]() |
dd0af050c9 | ||
![]() |
08a5befc82 | ||
![]() |
8c3bcbce85 | ||
![]() |
f7607f71ab | ||
![]() |
3e0490d5bf | ||
![]() |
1ffbd74a08 | ||
![]() |
b0a4de6037 | ||
![]() |
efdd5f29db | ||
![]() |
3c647ccfc2 | ||
![]() |
2b1aa6236f | ||
![]() |
36d378ec37 | ||
![]() |
913bb32a39 | ||
![]() |
51b889c6ef | ||
![]() |
5d8d996c91 | ||
![]() |
663d6e36c2 | ||
![]() |
686c3c7578 | ||
![]() |
109cd51d14 | ||
![]() |
918e73c306 | ||
![]() |
ad983812f6 | ||
![]() |
f300c8b4a5 | ||
![]() |
cd2de223fc | ||
![]() |
9e643e7cec | ||
![]() |
0ccdc8c5d0 | ||
![]() |
d57bc1e4e2 | ||
![]() |
7a0a60846a | ||
![]() |
fd0183d34a | ||
![]() |
d4d650c2c7 | ||
![]() |
5aae7dd1a5 | ||
![]() |
2032488149 | ||
![]() |
3ebc370ca4 | ||
![]() |
5cb53f39f2 | ||
![]() |
9f3bfcb879 | ||
![]() |
76c9ecd2e9 | ||
![]() |
960783ac42 | ||
![]() |
4e5ed0af94 | ||
![]() |
8961e38113 | ||
![]() |
810761aedf | ||
![]() |
db2938353b | ||
![]() |
c78dbba674 | ||
![]() |
6e5d16e4cc | ||
![]() |
5755efb529 | ||
![]() |
f435a96052 | ||
![]() |
e479ecf0ad | ||
![]() |
6bd6b348f0 | ||
![]() |
9d34f2cbeb | ||
![]() |
c440e7d435 | ||
![]() |
23a134aedc | ||
![]() |
c10c4ad629 | ||
![]() |
c6d4351c48 | ||
![]() |
9bc74046d6 | ||
![]() |
5ab93d62ad | ||
![]() |
96867d6e1b | ||
![]() |
956b2ab02f |
20
.gitignore
vendored
20
.gitignore
vendored
|
@ -1,8 +1,14 @@
|
|||
.cache/clangd/index
|
||||
bin
|
||||
maps/fencer.tiled-session
|
||||
fencer
|
||||
build/obj/Debug
|
||||
build/Makefile
|
||||
Makefile
|
||||
.vscode
|
||||
.cache
|
||||
compile_commands/
|
||||
bin/
|
||||
build/
|
||||
intermediate/
|
||||
packages/
|
||||
*.vcxproj
|
||||
*.vcxproj.user
|
||||
compile_commands.json
|
||||
Makefile
|
||||
.vs
|
||||
.idea
|
||||
*.sln
|
||||
|
|
26
Build.lua
Normal file
26
Build.lua
Normal file
|
@ -0,0 +1,26 @@
|
|||
workspace "Fencer-Template"
|
||||
architecture "x64"
|
||||
configurations { "Debug", "Release", "Dist" }
|
||||
language "C"
|
||||
startproject "Game"
|
||||
|
||||
filter "system:windows"
|
||||
defines { "SDL_MAIN_HANDLED", "_CRT_SECURE_NO_WARNINGS" }
|
||||
buildoptions { "/EHsc", "/Zc:preprocessor" }
|
||||
|
||||
OutputDir = "%{cfg.system}-%{cfg.architecture}/%{cfg.buildcfg}"
|
||||
|
||||
|
||||
group "Core"
|
||||
include "core/Build-Core.lua"
|
||||
group ""
|
||||
|
||||
libdirs {
|
||||
os.findlib("SDL2"),
|
||||
os.findlib("SDL2_image"),
|
||||
os.findlib("SDL2_ttf"),
|
||||
os.findlib("m"),
|
||||
os.findlib("cJSON")
|
||||
}
|
||||
|
||||
include "game/Build-Game.lua"
|
BIN
SDL2_image.dll
Normal file
BIN
SDL2_image.dll
Normal file
Binary file not shown.
BIN
SDL2_image.lib
Normal file
BIN
SDL2_image.lib
Normal file
Binary file not shown.
BIN
SDL2main.lib
Normal file
BIN
SDL2main.lib
Normal file
Binary file not shown.
BIN
SDL2test.lib
Normal file
BIN
SDL2test.lib
Normal file
Binary file not shown.
34
core/Build-Core.lua
Normal file
34
core/Build-Core.lua
Normal file
|
@ -0,0 +1,34 @@
|
|||
project "Engine-Core"
|
||||
kind "StaticLib"
|
||||
language "C"
|
||||
targetdir "bin/%{cfg.buildcfg}"
|
||||
staticruntime "off"
|
||||
|
||||
defines { "VMATH_SDL" }
|
||||
|
||||
files { "src/**.c", "src/**.h" }
|
||||
includedirs { "src/" }
|
||||
|
||||
targetdir ( "../bin/" .. OutputDir .. "/%{prj.name}" )
|
||||
objdir ( "../intermediate/" .. OutputDir .. "/%{prj.name}" )
|
||||
|
||||
filter "system:windows"
|
||||
systemversion "latest"
|
||||
defines {}
|
||||
|
||||
filter "configurations:Debug"
|
||||
defines { "DEBUG" }
|
||||
runtime "Debug"
|
||||
symbols "On"
|
||||
|
||||
filter "configurations:Release"
|
||||
defines { "RELEASE" }
|
||||
runtime "Release"
|
||||
optimize "On"
|
||||
symbols "On"
|
||||
|
||||
filter "configurations:Dist"
|
||||
defines { "DIST" }
|
||||
runtime "Release"
|
||||
optimize "On"
|
||||
symbols "Off"
|
58
core/src/animation_sprite.c
Normal file
58
core/src/animation_sprite.c
Normal file
|
@ -0,0 +1,58 @@
|
|||
#include "animation_sprite.h"
|
||||
#include "debug.h"
|
||||
#include "program.h"
|
||||
|
||||
struct AnimationSprite {
|
||||
Spritesheet* sheet;
|
||||
Sprite* sprite;
|
||||
|
||||
AnimationSpriteLoopMode loop_mode;
|
||||
|
||||
float frame_interval;
|
||||
float start_time;
|
||||
};
|
||||
|
||||
AnimationSprite* animation_sprite_new(Spritesheet* sheet, float framerate) {
|
||||
AnimationSprite* self = malloc(sizeof(AnimationSprite));
|
||||
ASSERT_RETURN(self != NULL, NULL, "Failed to allocate memory for AnimationSprite");
|
||||
*self = (AnimationSprite){
|
||||
.sheet = sheet,
|
||||
.frame_interval = 1.0f / framerate,
|
||||
.loop_mode = LoopMode_Loop,
|
||||
.start_time = game_time(),
|
||||
.sprite = sprite_from_spritesheet(sheet, 0)
|
||||
};
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
void animation_sprite_destroy(AnimationSprite* self) {
|
||||
sprite_destroy(self->sprite);
|
||||
spritesheet_destroy(self->sheet);
|
||||
free(self);
|
||||
}
|
||||
|
||||
void animation_sprite_play_from(AnimationSprite* self, float normalized_time) {
|
||||
self->start_time = game_time() - normalized_time * animation_sprite_get_length(self);
|
||||
}
|
||||
|
||||
void animation_sprite_draw(AnimationSprite* self, Transform* transform) {
|
||||
const float time = game_time() - self->start_time;
|
||||
const size_t frame = time / self->frame_interval;
|
||||
|
||||
sprite_set_spritesheet(self->sprite, self->sheet);
|
||||
sprite_set_tile(self->sprite, frame);
|
||||
sprite_draw(self->sprite, *transform);
|
||||
}
|
||||
|
||||
float animation_sprite_get_length(AnimationSprite* self) {
|
||||
return (float)spritesheet_get_tile_count(self->sheet) * self->frame_interval;
|
||||
}
|
||||
|
||||
void animation_sprite_set_framerate(AnimationSprite* self, float framerate) {
|
||||
self->frame_interval = 1.0f / framerate;
|
||||
}
|
||||
|
||||
float animation_sprite_get_framerate(const AnimationSprite* self) {
|
||||
return 1.0f / self->frame_interval;
|
||||
}
|
26
core/src/animation_sprite.h
Normal file
26
core/src/animation_sprite.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
#ifndef _fencer_animation_sprite_h
|
||||
#define _fencer_animation_sprite_h
|
||||
|
||||
#include "sprite.h"
|
||||
#include "spritesheet.h"
|
||||
|
||||
typedef enum AnimationSpriteLoopMode {
|
||||
LoopMode_Stop,
|
||||
LoopMode_Hide,
|
||||
LoopMode_Loop,
|
||||
LoopMode_PingPong,
|
||||
} AnimationSpriteLoopMode;
|
||||
|
||||
typedef struct AnimationSprite AnimationSprite;
|
||||
|
||||
extern AnimationSprite* animation_sprite_new(Spritesheet* sheet, float framerate);
|
||||
extern void animation_sprite_destroy(AnimationSprite* self);
|
||||
|
||||
extern void animation_sprite_play_from(AnimationSprite* self, float normalized_time);
|
||||
extern void animation_sprite_draw(AnimationSprite* self, Transform* transform);
|
||||
|
||||
extern float animation_sprite_get_length(AnimationSprite* self);
|
||||
extern void animation_sprite_set_framerate(AnimationSprite* self, float framerate);
|
||||
extern float animation_sprite_get_framerate(const AnimationSprite* self);
|
||||
|
||||
#endif // !_fencer_animation_sprite_h
|
|
@ -23,7 +23,7 @@ static inline Asset T##_as_Asset(T* x) {\
|
|||
TC_FN_TYPECHECK(asset_id, get_id_f, T*);\
|
||||
TC_FN_TYPECHECK(void, set_id_f, T*, asset_id);\
|
||||
TC_FN_TYPECHECK(Drop, T##_as_Drop, T*);\
|
||||
static IAsset tc = (IAsset){\
|
||||
static IAsset const tc = {\
|
||||
.get_id = (asset_id(*const)(void*)) get_id_f,\
|
||||
.set_id = (void(*const)(void*,asset_id)) set_id_f,\
|
||||
};\
|
|
@ -10,16 +10,16 @@ static asset_id _next_id = 0;
|
|||
|
||||
static
|
||||
size_t file_length(FILE* fp) {
|
||||
size_t start = ftell(fp);
|
||||
long start = ftell(fp);
|
||||
fseek(fp, 0, SEEK_END);
|
||||
size_t r = ftell(fp);
|
||||
long r = ftell(fp);
|
||||
fseek(fp, start, SEEK_SET);
|
||||
return r;
|
||||
return (size_t)r;
|
||||
}
|
||||
|
||||
static
|
||||
void read_file(FILE* fp, char* out_buffer, size_t out_size) {
|
||||
size_t start = ftell(fp);
|
||||
long start = ftell(fp);
|
||||
fread(out_buffer, 1, out_size, fp);
|
||||
fseek(fp, start, SEEK_SET);
|
||||
}
|
||||
|
@ -88,15 +88,13 @@ asset_id get_asset_id(void* asset) {
|
|||
}
|
||||
|
||||
void free_asset(asset_id id) {
|
||||
Asset* found;
|
||||
size_t found_index;
|
||||
Asset* found = NULL;
|
||||
size_t found_index = _assets.len;
|
||||
for(size_t i = 0; i < _assets.len; ++i) {
|
||||
found = list_at_as(Asset, &_assets, i);
|
||||
if(found->tc->get_id(found->data) == id) {
|
||||
found_index = i;
|
||||
break;
|
||||
} else {
|
||||
found = NULL;
|
||||
}
|
||||
}
|
||||
ASSERT_RETURN(found != NULL,, "Attempt to free nonexistent asset.");
|
|
@ -31,8 +31,8 @@ size_t json_array_len(cJSON* array);
|
|||
static inline
|
||||
Vector json_array_to_vector(cJSON* array) {
|
||||
return (Vector) {
|
||||
cJSON_GetArrayItem(array, 0)->valuedouble,
|
||||
cJSON_GetArrayItem(array, 1)->valuedouble,
|
||||
(float)cJSON_GetArrayItem(array, 0)->valuedouble,
|
||||
(float)cJSON_GetArrayItem(array, 1)->valuedouble,
|
||||
};
|
||||
}
|
||||
static inline
|
|
@ -21,7 +21,7 @@ SDL_FRect camera_world_to_pixel_rect(Camera* self, SDL_FRect* world_space) {
|
|||
t.scale = OneVector;
|
||||
t = transform_invert(t);
|
||||
|
||||
Vector tl = {world_space->x + (self->fov / 2.0), world_space->y + (_camera_height(self) / 2.0)};
|
||||
Vector tl = {world_space->x + (self->fov / 2.0f), world_space->y + (_camera_height(self) / 2.0f)};
|
||||
Vector size = {world_space->w, world_space->h};
|
||||
|
||||
tl = vmulff(transform_point(&t, tl), g_render_resolution.x / self->fov);
|
||||
|
@ -40,7 +40,7 @@ Vector camera_world_to_pixel_point(Camera* self, Vector point) {
|
|||
t.scale = OneVector;
|
||||
t = transform_invert(t);
|
||||
|
||||
point = (Vector){point.x + (self->fov / 2.0), point.y + (_camera_height(self) / 2.0)};
|
||||
point = (Vector){point.x + (self->fov / 2.0f), point.y + (_camera_height(self) / 2.0f)};
|
||||
|
||||
return vmulff(transform_point(&t, point), g_render_resolution.x / self->fov);
|
||||
}
|
6
core/src/drop.c
Normal file
6
core/src/drop.c
Normal file
|
@ -0,0 +1,6 @@
|
|||
#include "drop.h"
|
||||
#include "stdlib.h"
|
||||
|
||||
void default_drop(void* data) {
|
||||
free(data);
|
||||
}
|
|
@ -19,8 +19,13 @@ static inline Drop T##_as_Drop(T* x) {\
|
|||
return (Drop){.tc = &tc, .data = x};\
|
||||
}
|
||||
|
||||
#define impl_default_Drop_for(T)\
|
||||
static void default_drop_##T(T* v) { free(v); }\
|
||||
impl_Drop_for(T, default_drop_##T)
|
||||
extern void default_drop(void*);
|
||||
|
||||
#define impl_default_Drop_for(T)\
|
||||
static inline Drop T##_as_Drop(T* x) {\
|
||||
static IDrop const tc = {\
|
||||
.drop = default_drop,\
|
||||
};\
|
||||
return (Drop){.tc = &tc, .data = x};\
|
||||
}
|
||||
#endif // !_fencer_drop_h
|
|
@ -73,7 +73,7 @@ void game_world_update() {
|
|||
_internal_clear_removed();
|
||||
}
|
||||
|
||||
void game_word_draw() {
|
||||
void game_world_draw() {
|
||||
list_foreach(BehaviourEntity*, entity, &_game_entities) {
|
||||
entity->tc->draw(entity->data);
|
||||
}
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
KeyBind* keybind_new(SDL_Scancode key) {
|
||||
KeyBind* self = malloc(sizeof(KeyBind));
|
||||
ASSERT_RETURN(self != NULL, NULL, "Failed to allocate space for KeyBind instance");
|
||||
*self = (KeyBind) {
|
||||
.device = NULL,
|
||||
.scancode = key,
|
||||
|
@ -31,6 +32,7 @@ void keybind_set_device(KeyBind* self, InputDevice* device) {
|
|||
|
||||
ControllerAxis* controlleraxis_new(int axis) {
|
||||
ControllerAxis* self = malloc(sizeof(ControllerAxis));
|
||||
ASSERT_RETURN(self != NULL, NULL, "Failed to allocate space for ControllerAxis instance");
|
||||
*self = (ControllerAxis){
|
||||
.axis = axis,
|
||||
.device = NULL
|
||||
|
@ -48,7 +50,6 @@ int controlleraxis_is_changed_by(ControllerAxis* self, SDL_Event event) {
|
|||
|
||||
InputEvent controlleraxis_evaluate(ControllerAxis* self, SDL_Event event) {
|
||||
float result = (float)event.caxis.value / 32767.0;
|
||||
LOG_INFO("axis %f", result);
|
||||
return (InputEvent) {
|
||||
.type = InputEvent_Float,
|
||||
.as_float = result
|
||||
|
@ -61,6 +62,7 @@ void controlleraxis_set_device(ControllerAxis* self, InputDevice* device) {
|
|||
|
||||
ControllerButton* controllerbutton_new(int button) {
|
||||
ControllerButton* self = malloc(sizeof(ControllerButton));
|
||||
ASSERT_RETURN(self != NULL, NULL, "Failed to allocate space for ControllerButton instance");
|
||||
*self = (ControllerButton) {
|
||||
.button = button,
|
||||
.device = NULL
|
||||
|
@ -88,6 +90,7 @@ void controllerbutton_set_device(ControllerButton* self, InputDevice* device) {
|
|||
|
||||
CompositeAxis1D* compositeaxis1d_new(InputAxis left, InputAxis right, InputEventType type) {
|
||||
CompositeAxis1D* self = malloc(sizeof(CompositeAxis1D));
|
||||
ASSERT_RETURN(self != NULL, NULL, "Failed to allocate space for CompositeAxis1D instance");
|
||||
*self = (CompositeAxis1D) {
|
||||
.left = left,
|
||||
.right = right,
|
|
@ -18,11 +18,11 @@ void physics_entity_debug_draw(PhysicsEntity self) {
|
|||
lhs = camera_world_to_pixel_point(&g_camera, lhs);
|
||||
rhs = camera_world_to_pixel_point(&g_camera, rhs);
|
||||
SDL_SetRenderDrawColor(g_renderer, 0, 255, 0, 255);
|
||||
SDL_RenderDrawLine(g_renderer, lhs.x, lhs.y, rhs.x, rhs.y);
|
||||
SDL_RenderDrawLineF(g_renderer, lhs.x, lhs.y, rhs.x, rhs.y);
|
||||
|
||||
rhs = camera_world_to_pixel_point(&g_camera, vaddf(transform->position, rigidbody_get_force(body)));
|
||||
SDL_SetRenderDrawColor(g_renderer, 0, 255, 255, 255);
|
||||
SDL_RenderDrawLine(g_renderer, lhs.x, lhs.y, rhs.x, rhs.y);
|
||||
SDL_RenderDrawLineF(g_renderer, lhs.x, lhs.y, rhs.x, rhs.y);
|
||||
}
|
||||
static inline
|
||||
Vector _internal_calculate_contact_force(RigidBody* self, Contact* contact) {
|
|
@ -1,7 +1,9 @@
|
|||
#include "player_input.h"
|
||||
#include "debug.h"
|
||||
|
||||
PlayerInput* playerinput_new(void* target, int device) {
|
||||
PlayerInput* self = malloc(sizeof(PlayerInput));
|
||||
ASSERT_RETURN(self != NULL, NULL, "Could not allocate memory for PlayerInput instance");
|
||||
self->listeners = list_from_type(InputListener);
|
||||
self->device = input_get_device_by_id(device);
|
||||
self->target = target;
|
|
@ -25,7 +25,7 @@ double tstos(struct timespec ts) {
|
|||
|
||||
struct timespec get_time() {
|
||||
struct timespec ts;
|
||||
timespec_get(&ts, TIME_UTC);
|
||||
(void)timespec_get(&ts, TIME_UTC);
|
||||
return ts;
|
||||
}
|
||||
|
||||
|
@ -80,6 +80,7 @@ void program_run(const struct ProgramSettings* settings) {
|
|||
physics_world_tick();
|
||||
}
|
||||
settings->on_draw();
|
||||
game_world_draw();
|
||||
SDL_Delay(1);
|
||||
}
|
||||
|
||||
|
@ -132,10 +133,10 @@ void program_handle_windowevent(SDL_WindowEvent* event) {
|
|||
|
||||
inline
|
||||
float delta_time() {
|
||||
return _target_delta_time == 0 ? _delta_time : _target_delta_time;
|
||||
return (float)(_target_delta_time == 0 ? _delta_time : _target_delta_time);
|
||||
}
|
||||
|
||||
inline
|
||||
float game_time() {
|
||||
return get_time_s() - _game_start_time;
|
||||
return (float)(get_time_s() - _game_start_time);
|
||||
}
|
|
@ -42,10 +42,10 @@ void sprite_draw(Sprite* self, Transform transform) {
|
|||
|
||||
Vector origin = self->origin;
|
||||
if(self->flip_state && SDL_FLIP_HORIZONTAL) {
|
||||
origin.x = 1.0-origin.x;
|
||||
origin.x = 1.0f-origin.x;
|
||||
}
|
||||
if((self->flip_state & SDL_FLIP_VERTICAL) != 0) {
|
||||
origin.y = 1.0-origin.y;
|
||||
origin.y = 1.0f-origin.y;
|
||||
}
|
||||
|
||||
Vector left_top = transform_point(&transform, vinvf(origin));
|
||||
|
@ -75,8 +75,7 @@ size_t sprite_get_tile(const Sprite* self) {
|
|||
}
|
||||
|
||||
void sprite_set_tile(Sprite* self, size_t frame) {
|
||||
frame = frame % spritesheet_get_tile_count(self->spritesheet);
|
||||
self->tile_index = frame;
|
||||
self->tile_index = frame % spritesheet_get_tile_count(self->spritesheet);
|
||||
}
|
||||
|
||||
Spritesheet* sprite_get_spritesheet(const Sprite* self) {
|
|
@ -43,8 +43,8 @@ Spritesheet* spritesheet_from_texture(SDL_Texture* texture, IVector tile_size) {
|
|||
SDL_QueryTexture(self->texture, NULL, NULL, &self->resolution.x, &self->resolution.y);
|
||||
|
||||
self->tile_size = tile_size;
|
||||
self->tile_shear = self->resolution.x / self->tile_size.x;
|
||||
self->tile_count = self->resolution.x / self->tile_size.x * self->resolution.y / self->tile_size.y;
|
||||
self->tile_shear = (size_t)self->resolution.x / self->tile_size.x;
|
||||
self->tile_count = (size_t)self->resolution.x / self->tile_size.x * self->resolution.y / self->tile_size.y;
|
||||
return self;
|
||||
}
|
||||
|
||||
|
@ -57,7 +57,7 @@ SDL_Texture* spritesheet_get_texture(const Spritesheet* self) {
|
|||
}
|
||||
|
||||
SDL_Rect spritesheet_get_tile_rect(const Spritesheet* self, size_t index) {
|
||||
IVector tile_coord = {index % self->tile_shear, index / self->tile_shear};
|
||||
IVector tile_coord = {(int)(index % self->tile_shear), (int)(index / self->tile_shear)};
|
||||
tile_coord = vmuli(tile_coord, self->tile_size);
|
||||
|
||||
return (SDL_Rect) {
|
|
@ -25,7 +25,7 @@ impl_Drop_for(Spritesheet,
|
|||
_internal_spritesheet_destroy
|
||||
)
|
||||
|
||||
impl_Asset_for(Spritesheet,
|
||||
impl_Asset_for(Spritesheet,
|
||||
spritesheet_get_asset_id,
|
||||
spritesheet_set_asset_id
|
||||
)
|
27
core/src/state.h
Normal file
27
core/src/state.h
Normal file
|
@ -0,0 +1,27 @@
|
|||
#ifndef _fencer_state_h
|
||||
#define _fencer_state_h
|
||||
|
||||
#include "typeclass_helpers.h"
|
||||
|
||||
typedef struct State State;
|
||||
|
||||
struct State {
|
||||
void (*const enter)(void* data);
|
||||
void (*const exit)(void* data);
|
||||
const State* (*const update)(void* data, float dt);
|
||||
};
|
||||
|
||||
#define DefineState(_StateName, _DataType, enter_fn, exit_fn, update_fn)\
|
||||
static inline const State* _StateName() {\
|
||||
TC_FN_TYPECHECK(void, enter_fn, _DataType*);\
|
||||
TC_FN_TYPECHECK(void, exit_fn, _DataType*);\
|
||||
TC_FN_TYPECHECK(const State*, update_fn, _DataType*, float);\
|
||||
static const State instance = {\
|
||||
.enter = (void(*const)(void*)) enter_fn,\
|
||||
.exit = (void(*const)(void*)) exit_fn,\
|
||||
.update = (const State*(*const)(void*, float)) update_fn,\
|
||||
};\
|
||||
return &instance;\
|
||||
}
|
||||
|
||||
#endif // !_fencer_state_h
|
42
core/src/state_machine.c
Normal file
42
core/src/state_machine.c
Normal file
|
@ -0,0 +1,42 @@
|
|||
#include "state_machine.h"
|
||||
#include "stdlib.h"
|
||||
#include "debug.h"
|
||||
|
||||
struct StateMachine {
|
||||
const State* current_state;
|
||||
void* data;
|
||||
};
|
||||
|
||||
static inline
|
||||
void internal_state_machine_set_state(StateMachine* self, const State* state) {
|
||||
self->current_state->exit(self->data);
|
||||
self->current_state = state;
|
||||
self->current_state->enter(self->data);
|
||||
}
|
||||
|
||||
StateMachine* state_machine_init(void* data, const State* start_state) {
|
||||
StateMachine* self = malloc(sizeof(StateMachine));
|
||||
ASSERT_RETURN(self != NULL, NULL, "Failed to allocate space for StateMachine instance");
|
||||
*self = (StateMachine){
|
||||
.current_state = start_state,
|
||||
.data = data
|
||||
};
|
||||
|
||||
self->current_state->enter(self->data);
|
||||
return self;
|
||||
}
|
||||
|
||||
void state_machine_destroy(StateMachine* self) {
|
||||
self->current_state->exit(self->data);
|
||||
free(self);
|
||||
}
|
||||
|
||||
void state_machine_update(StateMachine* self, float dt) {
|
||||
const State* next = self->current_state->update(self->data, dt);
|
||||
if(next != self->current_state)
|
||||
internal_state_machine_set_state(self, next);
|
||||
}
|
||||
|
||||
const State* state_machine_get_current_state(StateMachine* self) {
|
||||
return self->current_state;
|
||||
}
|
15
core/src/state_machine.h
Normal file
15
core/src/state_machine.h
Normal file
|
@ -0,0 +1,15 @@
|
|||
#ifndef _fencer_state_machine_h
|
||||
#define _fencer_state_machine_h
|
||||
|
||||
#include "state.h"
|
||||
|
||||
typedef struct StateMachine StateMachine;
|
||||
|
||||
extern StateMachine* state_machine_init(void* data, const State* start_state);
|
||||
extern void state_machine_destroy(StateMachine* self);
|
||||
|
||||
extern void state_machine_update(StateMachine* self, float dt);
|
||||
|
||||
extern const State* state_machine_get_current_state(StateMachine* self);
|
||||
|
||||
#endif // !_fencer_state_machine_h
|
|
@ -1,8 +1,14 @@
|
|||
#ifndef _fencer_vmath_h
|
||||
#define _fencer_vmath_h
|
||||
|
||||
#include "stddef.h"
|
||||
#include <math.h>
|
||||
|
||||
#if defined _WIN32 && ! defined isnanf
|
||||
# define isnanf(x) _isnanf(x)
|
||||
# define HAVE_ISNANF
|
||||
#endif
|
||||
|
||||
#if VMATH_SDL == 1
|
||||
|
||||
#include <SDL2/SDL_rect.h>
|
||||
|
@ -33,6 +39,9 @@ typedef struct IVector {
|
|||
#define LeftVector (Vector){-1.0f,0.0f}
|
||||
#define DownVector (Vector){0.0f,1.0f}
|
||||
|
||||
#define MakeVector(__X, __Y) (Vector){__X, __Y}
|
||||
#define VectorFrom(__A) (Vector){__A, __A}
|
||||
|
||||
// Integer Vector Constant Macros
|
||||
#define ZeroIVector (IVector){0,0}
|
||||
#define OneIVector (IVector){1,1}
|
||||
|
@ -42,6 +51,9 @@ typedef struct IVector {
|
|||
#define RightIVector (IVector){1,0}
|
||||
#define LeftIVector (IVector){-1,0}
|
||||
|
||||
#define MakeIVector(__X, __Y) (IVector){__X, __Y}
|
||||
#define IVectorFrom(__A) (IVector){__A, __A}
|
||||
|
||||
///
|
||||
// Floating point vector maths functions.
|
||||
///
|
||||
|
@ -94,7 +106,7 @@ float vsqrmagnitudef(Vector a) {
|
|||
static inline
|
||||
Vector vnormalizedf(Vector a) {
|
||||
if(veqf(a, ZeroVector)) return ZeroVector;
|
||||
return vmulff(a, 1.0/vmagnitudef(a));
|
||||
return vmulff(a, 1.0f/vmagnitudef(a));
|
||||
}
|
||||
static inline
|
||||
float vdotf(Vector a, Vector b) {
|
||||
|
@ -110,7 +122,7 @@ float vsqrdistf(Vector a, Vector b) {
|
|||
}
|
||||
static inline
|
||||
Vector vreciprocalf(Vector a) {
|
||||
return (Vector){1.0/a.x, 1.0/a.y};
|
||||
return (Vector){1.0f/a.x, 1.0f/a.y};
|
||||
}
|
||||
static inline
|
||||
Vector vrotatef(Vector a, float t) {
|
||||
|
@ -145,7 +157,7 @@ Vector vaveragef(Vector* array, size_t count) {
|
|||
for(size_t i = 0; i < count; ++i) {
|
||||
acc = vaddf(acc, array[i]);
|
||||
}
|
||||
return vmulff(acc, 1.0/(float)count);
|
||||
return vmulff(acc, 1.0f/(float)count);
|
||||
}
|
||||
|
||||
static inline
|
|
@ -1,26 +0,0 @@
|
|||
# Mechanics
|
||||
|
||||
## Movement
|
||||
|
||||
Slow and considered.
|
||||
The walking speed is slow, the running speed slightly less so.
|
||||
Walkable parts of environments are relatively small.
|
||||
|
||||
## Combat
|
||||
|
||||
|
||||
|
||||
## Exploration
|
||||
|
||||
Resources are scattered throughout the environment.
|
||||
It should be rewarding to stop and gather them.
|
||||
|
||||
## Upgrades
|
||||
|
||||
|
||||
|
||||
# Dynamics
|
||||
|
||||
## Careful Progress
|
||||
|
||||
The player should be careful and considered during second to second gameplay.
|
48
game/Build-Game.lua
Normal file
48
game/Build-Game.lua
Normal file
|
@ -0,0 +1,48 @@
|
|||
project "Game"
|
||||
kind "WindowedApp"
|
||||
language "C"
|
||||
staticruntime "Off"
|
||||
targetdir "bin/%{cfg.buildcfg}"
|
||||
debugdir "."
|
||||
|
||||
defines { "VMATH_SDL" }
|
||||
|
||||
files { "src/**.c", "src/**.h" }
|
||||
includedirs {
|
||||
"src/",
|
||||
"../core/src/"
|
||||
}
|
||||
links {
|
||||
"Engine-Core"
|
||||
}
|
||||
|
||||
postbuildcommands {
|
||||
"{COPYDIR} assets/ %{cfg.targetdir}/assets"
|
||||
}
|
||||
|
||||
targetdir ("../bin/" .. OutputDir .. "/%{prj.name}" )
|
||||
objdir ("../intermediate/" .. OutputDir .. "/%{prj.name}" )
|
||||
|
||||
filter "system:linux"
|
||||
links { "SDL2", "SDL2_image", "SDL2_ttf", "m", "cjson"}
|
||||
|
||||
filter "system:windows"
|
||||
linkoptions { "/ENTRY:mainCRTStartup" }
|
||||
links { "../SDL2.dll", "../SDL2_image.dll" }
|
||||
|
||||
filter "configurations:Debug"
|
||||
defines { "DEBUG" }
|
||||
runtime "Debug"
|
||||
symbols "On"
|
||||
|
||||
filter "configurations:Release"
|
||||
defines { "RELEASE" }
|
||||
runtime "Release"
|
||||
optimize "On"
|
||||
symbols "On"
|
||||
|
||||
filter "configurations:Dist"
|
||||
defines { "DIST" }
|
||||
runtime "Release"
|
||||
optimize "On"
|
||||
symbols "Off"
|
|
@ -1,10 +1,7 @@
|
|||
#include "camera.h"
|
||||
#include "program.h"
|
||||
|
||||
static
|
||||
void play() {
|
||||
g_camera.fov = 40;
|
||||
}
|
||||
void play() {}
|
||||
|
||||
static
|
||||
void tick() {}
|
20
premake5.lua
20
premake5.lua
|
@ -1,20 +0,0 @@
|
|||
workspace "fencer"
|
||||
configurations { "Debug", "Release" }
|
||||
location "."
|
||||
|
||||
project "fencer"
|
||||
kind "WindowedApp"
|
||||
language "C"
|
||||
location "build/"
|
||||
files { "src/**.c" }
|
||||
links { "SDL2", "SDL2_image", "cjson", "m" }
|
||||
buildoptions { "-Wall", "-DVMATH_SDL=1" }
|
||||
targetdir "bin/"
|
||||
filter "configurations:Debug"
|
||||
defines { "DEBUG" }
|
||||
buildoptions { "-g3" }
|
||||
symbols "On"
|
||||
filter "configurations:Release"
|
||||
buildoptions { "-g0" }
|
||||
defines { "NDEBUG" }
|
||||
optimize "On"
|
Loading…
Reference in a new issue