From ebbd44d71dda6c2cd61d05b3e50cbaaa4dc84157 Mon Sep 17 00:00:00 2001 From: Marc Date: Sat, 21 Jan 2023 14:57:11 +0100 Subject: [PATCH] winter is comming: brace yourself --- CMakeLists.txt | 1 + src/main.c | 64 ++++++++++++++++----------------- src/renderer.c | 97 +++++++------------------------------------------- src/renderer.h | 15 +------- src/scene.c | 80 +++++++++++++++++++++++++++++++++++++++++ src/scene.h | 35 ++++++++++++++++++ src/text.c | 6 +--- src/text.h | 5 ++- 8 files changed, 165 insertions(+), 138 deletions(-) create mode 100644 src/scene.c create mode 100644 src/scene.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 7b8d30b..e63d842 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,6 +26,7 @@ set(SRC src/menu.c src/input.c src/scaller.c + src/scene.c ) # add the executable diff --git a/src/main.c b/src/main.c index 101f4ce..686378a 100644 --- a/src/main.c +++ b/src/main.c @@ -1,6 +1,7 @@ #include "input.h" #include "renderer.h" #include "text.h" +#include "scene.h" #include "menu.h" #include #include @@ -24,40 +25,39 @@ static void space(void) { } } -static void game_main(void) { - long delta = time(NULL) - timecode; - //main game code +Scene_t demo; - if(iter == 0) { - menu_render(); - RenderObject_t text; - SDL_Color white = {255, 255, 255, 255}; - TTF_Init(); - if(text_renderText(&text, 0.1f, 0.1f, 1000, 1, white, "./assets/fonts/arial.ttf", 25, "Hello World") < 0){ - printf("error"); - exit(1); - } - - SDL_Surface* img = IMG_Load("./assets/img/pp.png"); - - RenderObject_t duck = { - 0.5, - 0.5, - 0, - 0.50, - 0.50, - 0, - img - }; - scaller(duck.surface, 1, &duck.width, &duck.height); - placer(duck.surface, 1, &duck.x, &duck.y); - - renderer_renderObject(text); - renderer_renderObject(duck); - - input_listen(SDL_SCANCODE_SPACE, space); +static void game_setup(void) { + menu_render(); + RenderObject_t text; + SDL_Color white = {255, 255, 255, 255}; + TTF_Init(); + if(text_renderText(&text, 1000, 1, white, "./assets/fonts/arial.ttf", 25, "Hello World") < 0){ + printf("error"); + exit(1); } + SDL_Surface* img = IMG_Load("./assets/img/pp.png"); + + RenderObject_t duck = { + 1, + 0.5, + 0.5, + 0, + img + }; + + scaller(duck.surface, 1, &duck.width, &duck.height); + + scene_addRenderObject(&demo, duck, CAMERA_WIDTH/2, CAMERA_HEIGHT/2); + scene_addRenderObject(&demo, text, CAMERA_WIDTH/2, CAMERA_HEIGHT/2); + + input_listen(SDL_SCANCODE_SPACE, space); +} + +static void game_loop(void) { + long delta = time(NULL) - timecode; + //main game code //update time timecode = time(NULL); @@ -82,7 +82,7 @@ int main(void) { timecode = time(NULL); Mix_Init(MIX_INIT_MP3); - renderer_main(game_main); + renderer_main(game_setup, game_loop); Mix_FreeMusic(prout); diff --git a/src/renderer.c b/src/renderer.c index c550f9d..b33ea1b 100644 --- a/src/renderer.c +++ b/src/renderer.c @@ -5,40 +5,23 @@ #include #include #include -#include #include #include #include #include #include #include "input.h" - -typedef struct RenderItem { - RenderObject_t object; - SDL_Texture * cache; - SDL_Rect rect; - RenderId_t id; -} RenderItem_t; - -RenderItem_t * objects = NULL; -int objectCount = 0; -int objectStorageSize = 0; -MonitorSize_t monitorSize; -pthread_t thread; -pthread_mutex_t mutex; -SDL_Window* win; - +#include "scene.h" bool running; +MonitorSize_t monitorSize; +SDL_Window* win; SDL_Renderer * renderer; - - -static int compartSort(const RenderItem_t * a, const RenderItem_t * b) { - return a->object.z - b->object.z; -} +Scene_t * scenes; +int scenesCount = 0; //int (*compar)(const void [.size], const void [.size], void *) -void renderer_main(void(*game_main)(void)) { +void renderer_main(void(*game_setup)(void), void(*game_loop)(void)) { // returns zero on success else non-zero if (SDL_Init(SDL_INIT_EVERYTHING) != 0) { printf("error initializing SDL: %s\n", SDL_GetError()); @@ -58,17 +41,18 @@ void renderer_main(void(*game_main)(void)) { } SDL_GetRendererOutputSize(renderer, &monitorSize.width, &monitorSize.height); - objectStorageSize = 1000; - objects = malloc(objectStorageSize); + scenesCount = 10; + scenes = malloc(scenesCount); input_init(); running = true; + game_setup(); while(running) { SDL_RenderClear(renderer); - game_main(); + game_loop(); SDL_Event event; @@ -92,70 +76,15 @@ void renderer_main(void(*game_main)(void)) { //no need to make an extra render pass if(!running) break; - - for(int i = 0; i < objectCount; i++) { - RenderItem_t * object = &objects[i]; - int error = SDL_RenderCopyEx(renderer, object->cache, NULL, &object->rect, object->object.angle_degre, NULL, SDL_FLIP_NONE); - if(error != 0) { - fprintf(stderr, "Render error in object %d with error %s\n", object->id, SDL_GetError()); - exit(1); - } + for(int i = 0; i < scenesCount; i++) { + scene_render(scenes + i); } SDL_RenderPresent(renderer); SDL_Delay(1000 / 400); //400fps or u a pussy } + free(scenes); } -static void buildCache(RenderItem_t * object) { - SDL_Texture * texture = SDL_CreateTextureFromSurface(renderer, object->object.surface); - if(texture == NULL) { - fprintf(stderr, "Error while creating texture %s is_null: %d\n", SDL_GetError(), object->object.surface == NULL); - exit(1); - } - SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND); - object->cache = texture; -} - -RenderId_t renderer_renderObject(RenderObject_t object) { - RenderId_t itemId = objectCount++; - - SDL_Rect rect = { - round(object.x * monitorSize.width), - round(object.y * monitorSize.height), - round(object.width * monitorSize.width), - round(object.height * monitorSize.height) - }; - - RenderItem_t item = { - object, - NULL, - rect, - itemId - }; - - buildCache(&item); - - objects[itemId] = item; - //the objects are sorted - qsort(objects, objectCount, sizeof(RenderItem_t), (__compar_fn_t)compartSort); - return itemId; -} - -void renderer_removeObject(RenderId_t id) { - bool found = false; - for(int i = 0; i < objectCount - 1; i++) { - if(objects[i].id == id) { - SDL_FreeSurface(objects[i].object.surface); - if(objects[i].cache != NULL) { - SDL_DestroyTexture(objects[i].cache); - } - } - if(found) { - objects[i] = objects[i + 1]; - } - } - objectCount--; -} MonitorSize_t renderer_getMonitorSize() { return monitorSize; diff --git a/src/renderer.h b/src/renderer.h index aad4747..2f3388a 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -5,28 +5,15 @@ #include #include - -typedef int RenderId_t; //goes to false on exit extern bool running; extern SDL_Renderer * renderer; -typedef struct RenderObject { - float x,y; - int z; - float width, height; //ratio between 0 & 1 of the monitor resolution - float angle_degre; - SDL_Surface * surface; -} RenderObject_t; - typedef struct MonitorSize { int width, height; } MonitorSize_t; -void renderer_main(void(*game_main)(void)) ; -RenderId_t renderer_renderObject(RenderObject_t); -void renderer_removeObject(RenderId_t); - +void renderer_main(void(*game_setup)(void), void(*game_loop)(void)); MonitorSize_t renderer_getMonitorSize(void); #endif diff --git a/src/scene.c b/src/scene.c new file mode 100644 index 0000000..2571bc4 --- /dev/null +++ b/src/scene.c @@ -0,0 +1,80 @@ +#include "renderer.h" +#include "scene.h" + +static int compartSort(const SceneObject_t * a, const SceneObject_t * b) { + return a->renderObj.z - b->renderObj.z; +} + +void scene_render(Scene_t * scene) { + MonitorSize_t monitorSize = renderer_getMonitorSize(); + int minX = scene->x - CAMERA_WIDTH/2; + int minY = scene->y - CAMERA_HEIGHT/2; + int maxX = scene->x - CAMERA_WIDTH/2; + int maxY = scene->y - CAMERA_HEIGHT/2; + + for(int i = 0; i < scene->objectCount; i++) { + SceneObject_t * object = &scene->objects[i]; + if(object->x > minX && object->x < maxX && object->y > minY && object->y < maxY) { + int x = (object->x - minX) / CAMERA_WIDTH; + int y = (object->y - minY) / CAMERA_HEIGHT; + //the object is to be rendered + + SDL_Rect rect = { + round(x * monitorSize.width) , + round(y * monitorSize.height), + round(object->renderObj.width * monitorSize.width), + round(object->renderObj.height * monitorSize.height) + }; + + int error = SDL_RenderCopyEx(renderer, object->cache, NULL, &rect, object->renderObj.angle_degre, NULL, SDL_FLIP_NONE); + if(error != 0) { + fprintf(stderr, "Render error in object %d with error %s\n", object->id, SDL_GetError()); + exit(1); + } + } + } +} + +static void buildCache(SceneObject_t * object) { + SDL_Texture * texture = SDL_CreateTextureFromSurface(renderer, object->renderObj.surface); + if(texture == NULL) { + fprintf(stderr, "Error while creating texture %s is_null: %d\n", SDL_GetError(), object->renderObj.surface == NULL); + exit(1); + } + SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND); + object->cache = texture; +} + +RenderId_t scene_addRenderObject(Scene_t * scene, RenderObject_t object, int x, int y) { + RenderId_t itemId = scene->objectCount++; + + SceneObject_t item = { + x, y, + object, + NULL, + itemId + }; + + buildCache(&item); + + scene->objects[itemId] = item; + //the objects are sorted + qsort(scene->objects, scene->objectCount, sizeof(RenderObject_t), (__compar_fn_t)compartSort); + return itemId; +} + +void scene_removeRenderObject(Scene_t * scene, RenderId_t id) { + bool found = false; + for(int i = 0; i < scene->objectCount - 1; i++) { + if(scene->objects[i].id == id) { + SDL_FreeSurface(scene->objects[i].renderObj.surface); + if(scene->objects[i].cache != NULL) { + SDL_DestroyTexture(scene->objects[i].cache); + } + } + if(found) { + scene->objects[i] = scene->objects[i + 1]; + } + } + scene->objectCount--; +} diff --git a/src/scene.h b/src/scene.h new file mode 100644 index 0000000..e5216d6 --- /dev/null +++ b/src/scene.h @@ -0,0 +1,35 @@ +#ifndef __SCENE_H__ +#define __SCENE_H__ + +#include + +#define CAMERA_WIDTH 160 +#define CAMERA_HEIGHT 90 + +typedef int RenderId_t; + +typedef struct RenderObject { + int z; + float width, height; //ratio between 0 & 1 of the monitor resolution + float angle_degre; + SDL_Surface * surface; +} RenderObject_t; + +typedef struct SceneObject { + float x,y; + RenderObject_t renderObj; + SDL_Texture * cache; + RenderId_t id; +} SceneObject_t; + +typedef struct Scene { + SceneObject_t * objects; + int objectCount; + int x,y; +} Scene_t; + +void scene_render(Scene_t * scene); +void scene_removeRenderObject(Scene_t * scene, RenderId_t id); +RenderId_t scene_addRenderObject(Scene_t * scene, RenderObject_t object, int x, int y); + +#endif diff --git a/src/text.c b/src/text.c index d4a84b7..4150a63 100644 --- a/src/text.c +++ b/src/text.c @@ -25,7 +25,7 @@ void text_freeFontCache(void){ fontCacheSize = 0; } -int text_renderText(RenderObject_t* renderObject, float x, float y, int z, float scale, SDL_Color color, const char* fontFilename, int fontSize, char* format, ...){ +int text_renderText(RenderObject_t* renderObject, int z, float scale, SDL_Color color, const char* fontFilename, int fontSize, char* format, ...) { if(access(fontFilename, F_OK) != 0) { fprintf(stderr, "Font file not found: %s\n", fontFilename); return -1; @@ -70,14 +70,10 @@ int text_renderText(RenderObject_t* renderObject, float x, float y, int z, float TTF_SizeText(font, text, &w, &h); MonitorSize_t monitor = renderer_getMonitorSize(); - renderObject->x = x; - renderObject->y = y; renderObject->z = z; renderObject->angle_degre = 0; renderObject->surface = surface; scaller(surface, scale, &renderObject->width, &renderObject->height); - placer(renderObject->surface, scale, &renderObject->x, &renderObject->y); - return 0; } diff --git a/src/text.h b/src/text.h index 8f41a6b..51a422d 100644 --- a/src/text.h +++ b/src/text.h @@ -1,7 +1,7 @@ #ifndef __TEXT_H__ #define __TEXT_H__ -#include "renderer.h" +#include "scene.h" #include @@ -11,8 +11,7 @@ typedef struct { int z; } Position; - -int text_renderText(RenderObject_t* renderObject, float x, float y, int z, float scale, SDL_Color color, const char* fontFilename, int fontSize, char* format, ...); +int text_renderText(RenderObject_t* renderObject, int z, float scale, SDL_Color color, const char* fontFilename, int fontSize, char* format, ...); void text_freeFontCache(void); #endif