191 lines
5.5 KiB
C
191 lines
5.5 KiB
C
#include "display.h"
|
|
|
|
#include <SDL3/SDL.h>
|
|
#include <stdlib.h>
|
|
#include "asset_manager.h"
|
|
#include "game.h"
|
|
#include "texture.h"
|
|
#include "errors.h"
|
|
|
|
SDL_Window *window = NULL;
|
|
SDL_Renderer *renderer = NULL;
|
|
|
|
inline int display_init(void)
|
|
{
|
|
if(!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS))
|
|
{
|
|
error_printf("Failed to initialise SDL3 : %s", SDL_GetError());
|
|
return EXIT_FAILURE;
|
|
}
|
|
|
|
if(!SDL_SetAppMetadata("2D_Engine_SDL3_Core", "1.0", "2D_Engine"))
|
|
{
|
|
error_printf("Failed to set app metadata : %s", SDL_GetError());
|
|
return EXIT_FAILURE;
|
|
}
|
|
|
|
window = SDL_CreateWindow("2D_Engine", DISPLAY_WIDTH, DISPLAY_HEIGHT, 0);
|
|
if(!window)
|
|
{
|
|
error_printf("Failed to create window : %s", SDL_GetError());
|
|
return EXIT_FAILURE;
|
|
}
|
|
|
|
debug_printf("Listing available render drivers.");
|
|
const int NB_DRIVERS = SDL_GetNumRenderDrivers();
|
|
for(int i = 0; i < NB_DRIVERS; i++)
|
|
debug_printf("%d : %s", i, SDL_GetRenderDriver(i));
|
|
|
|
if(DRIVERS) warning_printf("This build of 2D_Engine_C only support the following drivers : %s", DRIVERS);
|
|
|
|
renderer = SDL_CreateRenderer(window, DRIVERS);
|
|
if(!renderer)
|
|
{
|
|
error_printf("Failed to create renderer : %s", SDL_GetError());
|
|
return EXIT_FAILURE;
|
|
}
|
|
|
|
if(!SDL_SetRenderVSync(renderer, SDL_RENDERER_VSYNC_ADAPTIVE))
|
|
{
|
|
error_printf("Failed to activate adaptative vsync : %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());
|
|
return EXIT_FAILURE;
|
|
}
|
|
|
|
if(!SDL_SetDefaultTextureScaleMode(renderer, SDL_SCALEMODE_NEAREST))
|
|
{
|
|
error_printf("Failed to set default texture scale mode : %s", SDL_GetError());
|
|
return EXIT_FAILURE;
|
|
}
|
|
|
|
debug_printf("Initialized display.");
|
|
return EXIT_SUCCESS;
|
|
}
|
|
|
|
inline void display_exit(void)
|
|
{
|
|
if(renderer) SDL_DestroyRenderer(renderer);
|
|
if(window) SDL_DestroyWindow(window);
|
|
SDL_Quit();
|
|
|
|
debug_printf("Exited display.");
|
|
}
|
|
|
|
inline int display_clear(void)
|
|
{
|
|
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;
|
|
}
|
|
|
|
return EXIT_SUCCESS;
|
|
}
|
|
|
|
inline int display_update(void)
|
|
{
|
|
if(!SDL_RenderPresent(renderer))
|
|
{
|
|
error_printf("Failed to present renderer : %s", SDL_GetError());
|
|
return EXIT_FAILURE;
|
|
}
|
|
|
|
#if DEBUG >= 1
|
|
float fps = 1000.0f / game.delta_time_ms;
|
|
static float max_fps_10s = 0.0f;
|
|
static float low_fps_10s = 10000000.0f;
|
|
|
|
if(fps > max_fps_10s) max_fps_10s = fps;
|
|
if(fps < low_fps_10s) low_fps_10s = fps;
|
|
|
|
static float fps_update_delta_time = 0.0f;
|
|
fps_update_delta_time += game.delta_time_ms;
|
|
|
|
if(fps_update_delta_time >= 100.0f)
|
|
{
|
|
fps_update_delta_time = 0.0f;
|
|
char title[100];
|
|
if(sprintf(title, "2D_Engine | cur: %.2ffps | max: %.2ffps | low: %.2ffps", fps, max_fps_10s, low_fps_10s) == -1)
|
|
{
|
|
error_printf("Sprintf failed : %d", errno);
|
|
return EXIT_FAILURE;
|
|
}
|
|
if(!SDL_SetWindowTitle(window, title))
|
|
{
|
|
error_printf("Failed to set window title : %s", SDL_GetError());
|
|
return EXIT_FAILURE;
|
|
}
|
|
}
|
|
|
|
static float fps_max_low_update_delta_time = 0.0f;
|
|
fps_max_low_update_delta_time += game.delta_time_ms;
|
|
|
|
if(fps_max_low_update_delta_time > 10000.0f)
|
|
{
|
|
fps_max_low_update_delta_time = 0.0f;
|
|
max_fps_10s = 0.0f;
|
|
low_fps_10s = 10000000.0f;
|
|
}
|
|
#endif // DEBUG >= 1
|
|
|
|
return EXIT_SUCCESS;
|
|
}
|
|
|
|
int display_draw_texture(texture_t *texture, const rect_t *src_rect, const rect_t *dst_rect, bool flip)
|
|
{
|
|
frect_t src_frect;
|
|
if(src_rect) rect_to_frect(src_rect, &src_frect);
|
|
|
|
frect_t dst_frect;
|
|
if(dst_rect)
|
|
dst_frect = (frect_t) {
|
|
.x = (dst_rect->x - game.camera.view_rect.x) * (DISPLAY_WIDTH / game.camera.view_rect.w),
|
|
.y = (dst_rect->y - game.camera.view_rect.y) * (DISPLAY_HEIGHT / game.camera.view_rect.h),
|
|
.w = dst_rect->w * (DISPLAY_WIDTH / game.camera.view_rect.w),
|
|
.h = dst_rect->h * (DISPLAY_HEIGHT / game.camera.view_rect.h)
|
|
};
|
|
|
|
if(!SDL_RenderTextureRotated(renderer, texture, src_rect ? &src_frect : NULL, dst_rect ? &dst_frect : NULL, 0, NULL, flip))
|
|
{
|
|
error_printf("Failed to copy texture to renderer : %s", SDL_GetError());
|
|
return EXIT_FAILURE;
|
|
}
|
|
|
|
return EXIT_SUCCESS;
|
|
}
|
|
|
|
int display_draw_frect(const frect_t *frect, unsigned int r, unsigned int g, unsigned int b, unsigned int a)
|
|
{
|
|
if(!SDL_SetRenderDrawColor(renderer, r, g, b, a))
|
|
{
|
|
error_printf("Failed to change renderer draw color : %s", SDL_GetError());
|
|
return EXIT_FAILURE;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
return EXIT_SUCCESS;
|
|
}
|