From 5516a70d57cfc6b6aea390f603f0ba01afd3f1cf Mon Sep 17 00:00:00 2001 From: Sara Date: Sat, 23 Sep 2023 22:52:55 +0200 Subject: [PATCH] removed references to old "Context" concepts and replaced with constants, declared camera functions --- src/camera.h | 24 +++++++++++++++ src/fencer.c | 2 +- src/program.c | 43 ++++++++++++++++++--------- src/program.h | 17 ++++------- src/render.c | 81 ++++++++++++++++++++++++++------------------------- src/render.h | 37 ++++++++++------------- src/tilemap.c | 22 +++++++------- src/tilemap.h | 2 +- 8 files changed, 129 insertions(+), 99 deletions(-) create mode 100644 src/camera.h diff --git a/src/camera.h b/src/camera.h new file mode 100644 index 0000000..5bd9f4e --- /dev/null +++ b/src/camera.h @@ -0,0 +1,24 @@ +#ifndef _fencer_camera_h +#define _fencer_camera_h + +#include "vmath.h" +#include + +struct Camera { + Vector centre; + float width; +}; + +typedef struct Camera Camera; + +// current world location of camera +extern Camera g_camera; + +extern void camera_init(); +// generate a screen-space rectangle that is exactly 1x1 in world units. +// With it's centre on the world origin. +extern SDL_FRect camera_calculate_world_unit_rect(Camera* self); +extern SDL_FRect camera_to_world_space(Camera* self, SDL_FRect* camera_space); +extern SDL_FRect camera_world_to_camera_space(Camera* self, SDL_FRect* world_space); + +#endif // !_fencer_camera_h diff --git a/src/fencer.c b/src/fencer.c index 970be49..2777243 100644 --- a/src/fencer.c +++ b/src/fencer.c @@ -5,7 +5,7 @@ int main(int argc, char* argv[]) { struct ProgramSettings config = { .target_fps = 0, // unbounded speed .title = "fencer", - .view_resolution = {160, 140} + .view_resolution = {1920, 1080} }; return program_run(&config); } diff --git a/src/program.c b/src/program.c index 9109b0d..4cf1be6 100644 --- a/src/program.c +++ b/src/program.c @@ -1,14 +1,19 @@ #include "program.h" #include +#include +#include "tilemap.h" + +SDL_Window* g_window; +double g_delta_time; +double g_frame_start; -struct Program g_program; #define INITFLAGS SDL_INIT_EVENTS | SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_GAMECONTROLLER int program_run(const struct ProgramSettings* settings) { SDL_Init(INITFLAGS); - g_program.window = SDL_CreateWindow( + g_window = SDL_CreateWindow( settings->title, SDL_WINDOWPOS_CENTERED_DISPLAY(0), SDL_WINDOWPOS_CENTERED_DISPLAY(0), @@ -16,45 +21,55 @@ int program_run(const struct ProgramSettings* settings) { settings->view_resolution.y, SDL_WINDOW_FULLSCREEN | SDL_WINDOW_RESIZABLE); - g_program.render_context = render_init(&g_program, settings); + render_init(g_window, settings); + + struct Tilemap map = tilemap_load("resources/box.tilemap.xml"); + struct Tileset set = { + .texture = IMG_LoadTexture(g_renderer, "resources/ts_castle.png"), + .tile_size = {32, 32}, + .shear = 10 + }; + SDL_QueryTexture(set.texture, NULL, NULL, &set.texture_resolution.x, &set.texture_resolution.y); + map.tileset = set; for(;;) { SDL_Delay(1); - program_handle_events(&g_program); - render_present(g_program.render_context); + program_handle_events(); + tilemap_render(&map); + render_present(); } return 1; } -void program_quit(struct Program* self) { - render_destroy(self->render_context); - SDL_DestroyWindow(self->window); +void program_quit() { + render_clean(); + SDL_DestroyWindow(g_window); SDL_Quit(); exit(0); } -void program_handle_events(struct Program* self) { +void program_handle_events() { SDL_Event event; while(SDL_PollEvent(&event)) { switch(event.type) { default: break; case SDL_WINDOWEVENT: - if(event.window.windowID == SDL_GetWindowID(self->window)) { - program_handle_windowevent(self, &event.window); + if(event.window.windowID == SDL_GetWindowID(g_window)) { + program_handle_windowevent(&event.window); } break; case SDL_QUIT: - program_quit(self); + program_quit(); break; } } } -void program_handle_windowevent(struct Program* self, SDL_WindowEvent* event) { +void program_handle_windowevent(SDL_WindowEvent* event) { switch(event->type) { default: - render_handle_resize(self->render_context); + render_handle_resize(); break; } } diff --git a/src/program.h b/src/program.h index d3f8e85..b9ae660 100644 --- a/src/program.h +++ b/src/program.h @@ -6,24 +6,19 @@ #include "vmath.h" #include "render.h" -extern struct Program g_program; - struct ProgramSettings { const char* title; IVector view_resolution; int target_fps; }; -struct Program { - SDL_Window* window; - struct RenderContext* render_context; - double delta_time; - double start_frame; -}; +extern SDL_Window* g_window; +extern double g_delta_time; +extern double g_frame_start; extern int program_run(const struct ProgramSettings* settings); -extern void program_quit(struct Program* self); -extern void program_handle_events(struct Program* self); -extern void program_handle_windowevent(struct Program* self, SDL_WindowEvent* event); +extern void program_quit(); +extern void program_handle_events(); +extern void program_handle_windowevent(SDL_WindowEvent* event); #endif // !_fencer_program_h diff --git a/src/render.c b/src/render.c index 7d8e0be..c9b5507 100644 --- a/src/render.c +++ b/src/render.c @@ -3,83 +3,84 @@ #include #include -struct RenderContext* render_init(const struct Program* program, const struct ProgramSettings* settings) { - struct RenderContext* self = malloc(sizeof(struct RenderContext)); +SDL_Renderer* g_renderer; +SDL_Texture* g_render_target; +SDL_Rect g_render_area; +IVector g_render_resolution; +void render_init(SDL_Window* window, const struct ProgramSettings* settings) { // create renderer, needs to be able to target textures, preferably hardware accelerated - self->renderer = SDL_CreateRenderer(program->window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE); + g_renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE); // create render target texture - self->render_target = SDL_CreateTexture( - self->renderer, + g_render_target = SDL_CreateTexture( + g_renderer, SDL_PIXELFORMAT_ARGB32, SDL_TEXTUREACCESS_TARGET, settings->view_resolution.x, settings->view_resolution.y); // store the desired view resolution - self->render_resolution = settings->view_resolution; + g_render_resolution = settings->view_resolution; // get the destination area for rendering the target onto the window - render_calculate_render_area(self); + render_calculate_render_area(); // clear target black - SDL_SetRenderTarget(self->renderer, self->render_target); - SDL_SetRenderDrawColor(self->renderer, 0, 0, 0, 255); - SDL_RenderClear(self->renderer); - - return self; + SDL_SetRenderTarget(g_renderer, g_render_target); + SDL_SetRenderDrawColor(g_renderer, 0, 0, 0, 255); + SDL_RenderClear(g_renderer); } -void render_destroy(struct RenderContext* self) { +void render_clean() { // clear up allocated SDL objects - SDL_DestroyTexture(self->render_target); - SDL_DestroyRenderer(self->renderer); + SDL_DestroyTexture(g_render_target); + SDL_DestroyRenderer(g_renderer); } -void render_present(struct RenderContext* self) { +void render_present() { // clear window white - SDL_SetRenderTarget(self->renderer, NULL); - SDL_SetRenderDrawColor(self->renderer, 0, 0, 0, 255); - SDL_RenderClear(self->renderer); + SDL_SetRenderTarget(g_renderer, NULL); + SDL_SetRenderDrawColor(g_renderer, 0, 0, 0, 255); + SDL_RenderClear(g_renderer); // copy render target - SDL_Rect source_rect = {0, 0, self->render_resolution.x, self->render_resolution.y}; - SDL_RenderCopy(self->renderer, self->render_target, &source_rect, &self->render_area); - SDL_RenderPresent(self->renderer); + SDL_Rect source_rect = {0, 0, g_render_resolution.x, g_render_resolution.y}; + SDL_RenderCopy(g_renderer, g_render_target, &source_rect, &g_render_area); + SDL_RenderPresent(g_renderer); // clear render target - SDL_SetRenderTarget(self->renderer, self->render_target); - SDL_SetRenderDrawColor(self->renderer, 0, 0, 0, 255); - SDL_RenderClear(self->renderer); + SDL_SetRenderTarget(g_renderer, g_render_target); + SDL_SetRenderDrawColor(g_renderer, 0, 0, 0, 255); + SDL_RenderClear(g_renderer); } -void render_calculate_render_area(struct RenderContext* self) { +void render_calculate_render_area() { // get aspect ratios of both the window and the rendertexture - IVector window_resolution = render_get_window_size(self); + IVector window_resolution = render_get_window_size(); float window_aspect = (float)window_resolution.x / (float)window_resolution.y; - float target_aspect = (float)self->render_resolution.x / (float)self->render_resolution.y; + float target_aspect = (float)g_render_resolution.x / (float)g_render_resolution.y; // calculate the largest area that will fit the entire rendertexture into the window space - self->render_area = (SDL_Rect) {0, 0, window_resolution.x, window_resolution.y}; + g_render_area = (SDL_Rect) {0, 0, window_resolution.x, window_resolution.y}; if(window_aspect <= target_aspect) { - self->render_area.h = window_resolution.x / target_aspect; - self->render_area.y = (window_resolution.y - self->render_area.h) / 2; + g_render_area.h = window_resolution.x / target_aspect; + g_render_area.y = (window_resolution.y - g_render_area.h) / 2; } else { - self->render_area.w = window_resolution.y * target_aspect; - self->render_area.x += (window_resolution.x - self->render_area.w) / 2; + g_render_area.w = window_resolution.y * target_aspect; + g_render_area.x += (window_resolution.x - g_render_area.w) / 2; } } -IVector render_get_window_size(struct RenderContext* self) { +IVector render_get_window_size() { // select window as target (store target to reset) - SDL_Texture* target = SDL_GetRenderTarget(self->renderer); - SDL_SetRenderTarget(self->renderer, NULL); + SDL_Texture* target = SDL_GetRenderTarget(g_renderer); + SDL_SetRenderTarget(g_renderer, NULL); // fetch output size (= window size) of renderer int window_width, window_height; - SDL_GetRendererOutputSize(self->renderer, &window_width, &window_height); + SDL_GetRendererOutputSize(g_renderer, &window_width, &window_height); // reset render target - SDL_SetRenderTarget(self->renderer, target); + SDL_SetRenderTarget(g_renderer, target); // construct IVector from fetched output size return (IVector){window_width, window_height}; } -void render_handle_resize(struct RenderContext* self) { - render_calculate_render_area(self); +void render_handle_resize() { + render_calculate_render_area(); } diff --git a/src/render.h b/src/render.h index 240eecd..cbfc1d1 100644 --- a/src/render.h +++ b/src/render.h @@ -5,32 +5,25 @@ #include #include "vmath.h" -struct Program; struct ProgramSettings; -struct RenderContext { - // renderer created from window in Program passed to render_init - SDL_Renderer* renderer; +// renderer created from window in Program passed to render_init +extern SDL_Renderer* g_renderer; +// render target +extern SDL_Texture* g_render_target; +// area of window to render render_target to +extern SDL_Rect g_render_area; +// size of render_target +extern IVector g_render_resolution; - // render target - SDL_Texture* render_target; - // area of window to render render_target to - SDL_Rect render_area; +extern void render_init(SDL_Window* window, const struct ProgramSettings* settings); +extern void render_clean(); +extern void render_present(); - // size of render_target - IVector render_resolution; - - // current world location of camera - IVector camera_offset; -}; - -extern struct RenderContext* render_init(const struct Program* program, const struct ProgramSettings* settings); -extern void render_destroy(struct RenderContext* self); -extern void render_present(struct RenderContext* self); - -extern void render_calculate_render_area(struct RenderContext* self); -extern IVector render_get_window_size(struct RenderContext* self); -extern void render_handle_resize(struct RenderContext* self); +extern SDL_FRect render_calculate_unit_rect(); +extern void render_calculate_render_area(); +extern IVector render_get_window_size(); +extern void render_handle_resize(); #endif // !_fencer_render_h diff --git a/src/tilemap.c b/src/tilemap.c index 58d7595..496af9b 100644 --- a/src/tilemap.c +++ b/src/tilemap.c @@ -1,11 +1,9 @@ #include "tilemap.h" -#include "libxml/threads.h" -#include "libxml/tree.h" -#include "libxml/xmlstring.h" +#include "camera.h" #include "program.h" -#include -#include #include +#include +#include #define XML(__str) (const xmlChar*)__str @@ -135,7 +133,7 @@ struct Tileset tileset_load(const char* filename) { } } while(n != ','); - self.texture = IMG_LoadTexture(g_program.render_context->renderer, texture_path); + self.texture = IMG_LoadTexture(g_renderer, texture_path); SDL_QueryTexture(self.texture, NULL, NULL, &self.texture_resolution.x, &self.texture_resolution.y); self.shear = floor((float)self.texture_resolution.x / self.tile_size.x); @@ -169,14 +167,18 @@ SDL_Rect tileset_index_to_rect(struct Tileset* self, size_t index) { return rect; } -void tilemap_render(struct Tilemap* self, struct RenderContext* render) { +void tilemap_render(struct Tilemap* self) { size_t num_tiles = self->dimensions.x * self->dimensions.y; + SDL_Rect source_rect = {0, 0, self->tileset.tile_size.x, self->tileset.tile_size.y}; - SDL_Rect dest_rect = source_rect; + SDL_FRect dest_rect = { .w = 1, .h = 1 }; + for(int i = 0; i < num_tiles; ++i) { source_rect = tileset_index_to_rect(&self->tileset, self->tiles[i]); + dest_rect.x = (i % self->dimensions.x) * dest_rect.w; - dest_rect.y = (i / self->dimensions.y) * dest_rect.h; - SDL_RenderCopy(render->renderer, self->tileset.texture, &source_rect, &dest_rect); + dest_rect.y = (float)floor((float)i / self->dimensions.y) * dest_rect.h; + + SDL_RenderCopyF(g_renderer, self->tileset.texture, &source_rect, &dest_rect); } } \ No newline at end of file diff --git a/src/tilemap.h b/src/tilemap.h index 6cc11a5..f8fdd5e 100644 --- a/src/tilemap.h +++ b/src/tilemap.h @@ -22,6 +22,6 @@ extern struct Tilemap tilemap_load(const char* tilemap_file); extern struct Tileset tileset_load(const char* filename); extern SDL_Rect tileset_index_to_rect(struct Tileset* self, size_t index); -extern void tilemap_render(struct Tilemap* map, struct RenderContext* render); +extern void tilemap_render(struct Tilemap* map); #endif // !_fencer_tilemap_h