commit 61f32352777508b042fb9a2a3e337282ac954248 Author: VegOwOtenks Date: Fri Feb 28 23:55:22 2025 +0100 Yay diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..a8fbf12 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,7 @@ +[submodule "submodules/SDL_ttf"] + path = submodules/SDL_ttf + url = https://github.com/libsdl-org/SDL_ttf.git +[submodule "submodules/SDL"] + path = submodules/SDL + url = https://github.com/libsdl-org/SDL.git + diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..865bc98 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_minimum_required(VERSION 3.30) + +project(SDL_FPSCounter C) + +add_subdirectory(src/) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..6179702 --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,4 @@ +add_library(SDL_FPSCounter STATIC SDL_FPSCounter.c) + +add_executable(fps-counter WIN32 main.c) +target_link_libraries(fps-counter SDL_FPSCounter SDL3 SDL3_ttf) diff --git a/src/SDL_FPSCounter.c b/src/SDL_FPSCounter.c new file mode 100644 index 0000000..384c75e --- /dev/null +++ b/src/SDL_FPSCounter.c @@ -0,0 +1,52 @@ +#include "SDL_FPSCounter.h" + +#include + +#include + +int SDL_CreateFPSCounter(SDL_FPSCounter* counter, uint32_t window_length) +{ + counter->window = malloc(sizeof(uint64_t) * window_length); + if (counter->window == NULL) { + SDL_OutOfMemory(); + return -1; + } + memset(counter->window, 0, window_length * sizeof(uint64_t)); + counter->frequency = SDL_GetPerformanceFrequency(); + counter->window_index = 0; + counter->window_length = window_length; + + return EXIT_SUCCESS; +} + +void SDL_DestroyFPSCounter(SDL_FPSCounter* counter) +{ + free(counter->window); + memset(counter, 0, sizeof *counter); +} + +int SDL_FPSCounterTick(SDL_FPSCounter* counter) +{ + counter->window[counter->window_index] = SDL_GetPerformanceCounter(); + counter->window_index++; + counter->window_index = counter->window_index % counter->window_length; + + return EXIT_SUCCESS; +} + +uint64_t SDL_FPSCounterFPS(SDL_FPSCounter* counter) +{ + uint64_t last = counter->window[counter->window_index]; + uint64_t current; + uint64_t acc_difference = 0; + + for (uint32_t i = (counter->window_index + 1) % counter->window_length; i != counter->window_index; i = (i + 1) % counter->window_length) { + current = counter->window[i]; + acc_difference += current - last; + + last = current; + } + + uint64_t average_difference = acc_difference / (counter->window_length - 1); + return counter->frequency / average_difference; +} diff --git a/src/SDL_FPSCounter.h b/src/SDL_FPSCounter.h new file mode 100644 index 0000000..ca18f95 --- /dev/null +++ b/src/SDL_FPSCounter.h @@ -0,0 +1,19 @@ +#ifndef SDL_FPSCOUNTER_H +#define SDL_FPSCOUNTER_H + +#include + +typedef struct SDL_FPSCounter_s { + uint64_t frequency; + uint32_t window_index; + uint32_t window_length; + uint64_t* window; +} SDL_FPSCounter; + +int SDL_CreateFPSCounter(SDL_FPSCounter* counter, uint32_t window_length); +void SDL_DestroyFPSCounter(SDL_FPSCounter* counter); + +int SDL_FPSCounterTick(SDL_FPSCounter* counter); +uint64_t SDL_FPSCounterFPS(SDL_FPSCounter* counter); + +#endif diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..bd1d234 --- /dev/null +++ b/src/main.c @@ -0,0 +1,111 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "SDL_FPSCounter.h" + +#define INITIAL_WINDOW_HEIGHT 600 +#define INITIAL_WINDOW_WIDTH 600 + +void DrawNumber(SDL_Window* window, SDL_Renderer* renderer, SDL_Texture* digits[10], int number) +{ + char number_string[snprintf(NULL, 0, "%i", number) + 1]; + snprintf(number_string, sizeof(number_string), "%i", number); + + int window_height, window_width; + SDL_GetWindowSize(window, &window_width, &window_height); + + int current_x = 0; + char* digit_p = number_string; + for (; *digit_p; digit_p++) { + int index = (*digit_p) - '0'; + SDL_Texture* digit_texture = digits[index]; + SDL_FRect target_rect; + target_rect.x = current_x; + target_rect.y = 0; + + SDL_GetTextureSize(digit_texture, &target_rect.w, &target_rect.h); + + SDL_RenderTexture(renderer, digit_texture, NULL, &target_rect); + + current_x += target_rect.w; + } +} + +int main(int argc, char* argv[]) +{ + (void) argc; + (void) argv; + + SDL_Init( SDL_INIT_VIDEO | SDL_INIT_EVENTS); + if (TTF_Init()) { + fprintf(stderr, "Initializing SDL2_ttf failed: %s\n", SDL_GetError()); + } + + SDL_Window* window = SDL_CreateWindow( + "FPS-Counter", + INITIAL_WINDOW_WIDTH, INITIAL_WINDOW_HEIGHT, + 0 + ); + if (window == NULL) { + fprintf(stderr, "Creating the window failed: %s\n", SDL_GetError()); + } + + SDL_Renderer* renderer = SDL_CreateRenderer(window, NULL); + if (renderer == NULL) { + fprintf(stderr, "Creating the window renderer failed: %s\n", SDL_GetError()); + } + + + TTF_Font* number_font = TTF_OpenFont("/usr/share/fonts/urw-base35/NimbusMonoPS-Regular.otf", 300); + SDL_Texture* digits[10]; + for (int i = 0; i < 10; i++) { + char string[3]; + snprintf(string, 3, "%i", i); + SDL_Surface* digit_surface = TTF_RenderText_Solid(number_font, string, strlen(string),((SDL_Color) {0x2D, 0x2D, 0x2D, 0xFF})); + digits[i] = SDL_CreateTextureFromSurface(renderer, digit_surface); + SDL_DestroySurface(digit_surface); + } + TTF_CloseFont(number_font); + + + bool continue_ = true; + + SDL_FPSCounter fpscounter; + if (SDL_CreateFPSCounter(&fpscounter, 1000)) { + fprintf(stderr, "Failed to create fps counter: %s\n", SDL_GetError()); + return 1; + } + + while (continue_) { + + SDL_Event event; + while(SDL_PollEvent(&event)) { + switch (event.type) { + case SDL_EVENT_QUIT: + continue_ = false; + break; + } + } + + SDL_SetRenderDrawColor(renderer, 0xFF, 0xC2, 0xDE, 0xFF); + SDL_RenderClear(renderer); + + SDL_FPSCounterTick(&fpscounter); + DrawNumber(window, renderer, digits, SDL_FPSCounterFPS(&fpscounter)); + + SDL_RenderPresent(renderer); + } + + SDL_DestroyFPSCounter(&fpscounter); + SDL_DestroyWindow(window); + SDL_Quit(); + + return EXIT_SUCCESS; +}