Added camera and started to add map drawing.

This commit is contained in:
Ulysse Cura 2026-08-19 14:12:46 +02:00
parent 519ae78ada
commit 5eb065b1cf
8 changed files with 232 additions and 22 deletions

View File

@ -6,6 +6,7 @@ CORE_SOURCES := \
asset_manager.c \
texture.c \
map.c \
camera.c \
event_bus.c \
ecs.c \
display.c \

29
src/camera.c Normal file
View File

@ -0,0 +1,29 @@
#include "camera.h"
#include "game.h"
#include "display.h"
void camera_init(void)
{
game.camera.view_rect = (frect_t) {
.x = 0.0f,
.y = 0.0f,
.w = DISPLAY_WIDTH / 2,
.h = DISPLAY_HEIGHT / 2
};
game.camera.tracking_pos = NULL;
game.camera.tracking_center_offset = (fvector2d_t) {
.x = 0.0f,
.y = 0.0f
};
}
void camera_update(void)
{
if(game.camera.tracking_pos)
{
game.camera.view_rect.x = game.camera.tracking_pos->x + game.camera.tracking_center_offset.x - game.camera.view_rect.w / 2;
game.camera.view_rect.y = game.camera.tracking_pos->y + game.camera.tracking_center_offset.y - game.camera.view_rect.h / 2;
}
}

View File

@ -24,7 +24,7 @@ inline int display_init(void)
return EXIT_FAILURE;
}
window = SDL_CreateWindow("2D_Engine", DISPLAY_WIDTH * RENDER_SCALE, DISPLAY_HEIGHT * RENDER_SCALE, 0);
window = SDL_CreateWindow("2D_Engine", DISPLAY_WIDTH, DISPLAY_HEIGHT, 0);
if(!window)
{
error_printf("Failed to create window : %s", SDL_GetError());
@ -51,12 +51,6 @@ inline int display_init(void)
return EXIT_FAILURE;
}
if(!SDL_SetRenderScale(renderer, RENDER_SCALE, RENDER_SCALE))
{
error_printf("Failed to set renderer scale presentation : %s", SDL_GetError());
return EXIT_FAILURE;
}
if(!SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND))
{
error_printf("Failed to set renderer draw blend mode : %s", SDL_GetError());
@ -148,15 +142,30 @@ inline int display_update(void)
return EXIT_SUCCESS;
}
int display_draw_texture(texture_t *texture, const rect_t *src_rect, const frect_t *dst_frect, bool flip)
int display_draw_texture(texture_t *texture, const frect_t *src_frect, const frect_t *dst_frect, bool flip)
{
frect_t src_frect;
rect_to_frect(src_rect, &src_frect);
if(!SDL_RenderTextureRotated(renderer, texture, &src_frect, dst_frect, 0, NULL, flip))
if(dst_frect)
{
error_printf("Failed to copy texture to renderer : %s", SDL_GetError());
return EXIT_FAILURE;
frect_t display_frect = {
.x = (dst_frect->x - game.camera.view_rect.x) * (DISPLAY_WIDTH / game.camera.view_rect.w),
.y = (dst_frect->y - game.camera.view_rect.y) * (DISPLAY_HEIGHT / game.camera.view_rect.h),
.w = dst_frect->w * (DISPLAY_WIDTH / game.camera.view_rect.w),
.h = dst_frect->h * (DISPLAY_HEIGHT / game.camera.view_rect.h)
};
if(!SDL_RenderTextureRotated(renderer, texture, src_frect, &display_frect, 0, NULL, flip))
{
error_printf("Failed to copy texture to renderer : %s", SDL_GetError());
return EXIT_FAILURE;
}
}
else
{
if(!SDL_RenderTextureRotated(renderer, texture, src_frect, NULL, 0, NULL, flip))
{
error_printf("Failed to copy texture to renderer : %s", SDL_GetError());
return EXIT_FAILURE;
}
}
return EXIT_SUCCESS;
@ -170,7 +179,14 @@ int display_draw_frect(const frect_t *frect, unsigned int r, unsigned int g, uns
return EXIT_FAILURE;
}
if(!SDL_RenderRect(renderer, frect))
frect_t display_frect = {
.x = (frect->x - game.camera.view_rect.x) * (DISPLAY_WIDTH / game.camera.view_rect.w),
.y = (frect->y - game.camera.view_rect.y) * (DISPLAY_HEIGHT / game.camera.view_rect.h),
.w = frect->w * (DISPLAY_WIDTH / game.camera.view_rect.w),
.h = frect->h * (DISPLAY_HEIGHT / game.camera.view_rect.h)
};
if(!SDL_RenderRect(renderer, &display_frect))
{
error_printf("Failed to draw rectangle to renderer : %s", SDL_GetError());
return EXIT_FAILURE;

16
src/headers/camera.h Normal file
View File

@ -0,0 +1,16 @@
#ifndef CAMERA_H
#define CAMERA_H
#include "vector2d.h"
typedef struct camera_t {
frect_t view_rect;
fvector2d_t *tracking_pos;
fvector2d_t tracking_center_offset;
} camera_t;
void camera_init(void);
void camera_update(void);
#endif // CAMERA_H

View File

@ -12,9 +12,8 @@
#define C_BLUE 0, 0, 255
#define C_WHITE 255, 255, 255
#define DISPLAY_WIDTH 396
#define DISPLAY_HEIGHT 224
#define RENDER_SCALE 2
#define DISPLAY_WIDTH 720
#define DISPLAY_HEIGHT 480
//#define DRIVERS NULL
#define DRIVERS "vulkan,gpu,software"
@ -28,7 +27,7 @@ void display_exit(void);
int display_clear(void);
int display_update(void);
int display_draw_texture(texture_t *texture, const rect_t *src_rect, const frect_t *dst_frect, bool flip);
int display_draw_texture(texture_t *texture, const frect_t *src_frect, const frect_t *dst_frect, bool flip);
int display_draw_frect(const frect_t *frect, unsigned int r, unsigned int g, unsigned int b, unsigned int a);
#endif // DISPLAY_H

View File

@ -3,8 +3,10 @@
#include <stdbool.h>
#include "asset_manager.h"
#include "ecs.h"
#include "camera.h"
#include "event_bus.h"
#include "ecs.h"
#include "map.h"
#include "inputs.h"
/**
@ -18,10 +20,13 @@
* @param delta_time_ms Frame time
*/
typedef struct game_t {
camera_t camera;
asset_manager_t asset_manager;
entity_manager_t entity_manager;
event_bus_t event_bus;
entity_manager_t entity_manager;
tilemap_display_t tilemap_display;
inputs_t inputs;
map_t *map;
float delta_time_ms;
bool is_running;

View File

@ -2,6 +2,8 @@
#define MAP_H
#include <stdint.h>
#include "vector2d.h"
#include "texture.h"
typedef struct map_entity_component_def_t {
uint32_t type;
@ -33,4 +35,24 @@ int map_load_entities(map_t *map);
int map_remove_entities(map_t *map);
#define TILE_SIZE 16
typedef struct tilemap_display_t {
frect_t view_rect;
texture_t *tileset;
texture_t *background;
texture_t *foreground;
texture_t *buffer;
} tilemap_display_t;
int tilemap_display_init(void);
int tilemap_display_update(void);
int tilemap_display_background(void);
int tilemap_display_foreground(void);
void tilemap_display_exit(void);
#endif // MAP_H

124
src/map.c
View File

@ -5,6 +5,7 @@
#include "ecs.h"
#include "components.h"
#include "vector2d.h"
#include "display.h"
#include "memory_alloc.h"
#include "errors.h"
@ -219,6 +220,7 @@ int map_load_entities(map_t *map)
map_entity_component_def_t *component_def = &entity_def->components_defs[j];
component_t *component = entity_new_component(entity, component_def->type);
if(!entity) return_failure_int;
switch(component_def->type)
{
@ -267,7 +269,7 @@ int map_load_entities(map_t *map)
system_data->loop = data->loop;
system_data->reverse = data->reverse;
animation_system_apply_changes(component);
if(animation_system_apply_changes(component)) return_failure_int;
break;
}
@ -394,3 +396,123 @@ int map_remove_entities(map_t *map)
return EXIT_SUCCESS;
}
int tilemap_display_init(void)
{
game.tilemap_display.view_rect = (frect_t) {
.x = 0.0f,
.y = 0.0f,
.w = 0.0f,
.h = 0.0f
};
game.tilemap_display.background = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGB565, SDL_TEXTUREACCESS_TARGET, DISPLAY_WIDTH, DISPLAY_HEIGHT);
if(!game.tilemap_display.background)
{
error_printf("Failed to create texture : %s", SDL_GetError());
return EXIT_FAILURE;
}
game.tilemap_display.foreground = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGB565, SDL_TEXTUREACCESS_TARGET, DISPLAY_WIDTH, DISPLAY_HEIGHT);
if(!game.tilemap_display.foreground)
{
error_printf("Failed to create texture : %s", SDL_GetError());
return EXIT_FAILURE;
}
game.tilemap_display.buffer = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGB565, SDL_TEXTUREACCESS_TARGET, DISPLAY_WIDTH, DISPLAY_HEIGHT);
if(!game.tilemap_display.buffer)
{
error_printf("Failed to create texture : %s", SDL_GetError());
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
int tilemap_display_update(void)
{
frect_t buffer_view_rect = {
.x = game.tilemap_display.view_rect.x - game.camera.view_rect.x,
.y = game.tilemap_display.view_rect.y - game.camera.view_rect.y,
.w = game.tilemap_display.view_rect.w - game.camera.view_rect.w,
.h = game.tilemap_display.view_rect.h - game.camera.view_rect.h
};
if(game.tilemap_display.view_rect.x != game.camera.view_rect.x
|| game.tilemap_display.view_rect.y != game.camera.view_rect.y
|| game.tilemap_display.view_rect.w != game.camera.view_rect.w
|| game.tilemap_display.view_rect.h != game.camera.view_rect.h)
{
// Update background
if(!SDL_SetRenderTarget(renderer, game.tilemap_display.buffer))
{
error_printf("Failed to set texture as render target : %s", SDL_GetError());
return EXIT_FAILURE;
}
if(!SDL_SetRenderDrawColor(renderer, C_WHITE, 255))
{
error_printf("Failed to change renderer draw color : %s", SDL_GetError());
return EXIT_FAILURE;
}
if(!SDL_RenderClear(renderer))
{
error_printf("Failed to clear renderer : %s", SDL_GetError());
return EXIT_FAILURE;
}
if(!SDL_RenderTexture(renderer, game.tilemap_display.background, &game.tilemap_display.view_rect, &buffer_view_rect))
{
error_printf("Failed to render texture : %s", SDL_GetError());
return EXIT_FAILURE;
}
if(display_draw_frect(&game.tilemap_display.view_rect, C_BLACK, 255)) return_failure_int;
// Rewrite buffer to background texture
if(!SDL_SetRenderTarget(renderer, game.tilemap_display.background))
{
error_printf("Failed to reset render target : %s", SDL_GetError());
return EXIT_FAILURE;
}
if(!SDL_RenderTexture(renderer, game.tilemap_display.buffer, NULL, NULL))
{
error_printf("Failed to render texture : %s", SDL_GetError());
return EXIT_FAILURE;
}
if(!SDL_SetRenderTarget(renderer, NULL))
{
error_printf("Failed to reset render target : %s", SDL_GetError());
return EXIT_FAILURE;
}
}
game.tilemap_display.view_rect = game.camera.view_rect;
return EXIT_SUCCESS;
}
int tilemap_display_background(void)
{
if(display_draw_texture(game.tilemap_display.background, NULL, NULL, false)) return_failure_int;
return EXIT_SUCCESS;
}
int tilemap_display_foreground(void)
{
// if(display_draw_texture(game.tilemap_display.foreground, NULL, NULL, false)) return_failure_int;
return EXIT_SUCCESS;
}
void tilemap_display_exit(void)
{
SDL_DestroyTexture(game.tilemap_display.background);
SDL_DestroyTexture(game.tilemap_display.foreground);
SDL_DestroyTexture(game.tilemap_display.buffer);
}