From 4c9b8adfa6b702d9d49a4759ccedb4f2b49ede37 Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Sun, 23 Mar 2025 20:08:55 +0100 Subject: [PATCH] migrat a SDL3 --- source/dbgtxt.h | 44 +++++++++ source/defines.h | 18 ++++ source/dot.h | 122 ++++++++++++++++++++++++ source/main.cpp | 240 +++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 424 insertions(+) create mode 100644 source/dbgtxt.h create mode 100644 source/defines.h create mode 100644 source/dot.h create mode 100644 source/main.cpp diff --git a/source/dbgtxt.h b/source/dbgtxt.h new file mode 100644 index 0000000..1643949 --- /dev/null +++ b/source/dbgtxt.h @@ -0,0 +1,44 @@ +#pragma once + +#include + +namespace +{ + SDL_Texture *dbg_tex = nullptr; + SDL_Renderer *dbg_ren = nullptr; +} + +void dbg_init(SDL_Renderer *renderer) +{ + dbg_ren = renderer; + Uint8 font[448] = {0x42, 0x4D, 0xC0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x01, 0x00, 0x00, 0x12, 0x0B, 0x00, 0x00, 0x12, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x18, 0xF3, 0x83, 0x83, 0xCF, 0x83, 0x87, 0x00, 0x00, 0xF3, 0x39, 0x39, 0xCF, 0x79, 0xF3, 0x00, 0x00, 0x01, 0xF9, 0x39, 0xCF, 0x61, 0xF9, 0x00, 0x00, 0x33, 0xF9, 0x03, 0xE7, 0x87, 0x81, 0x00, 0x00, 0x93, 0x03, 0x3F, 0xF3, 0x1B, 0x39, 0x00, 0x00, 0xC3, 0x3F, 0x9F, 0x39, 0x3B, 0x39, 0x00, 0x41, 0xE3, 0x03, 0xC3, 0x01, 0x87, 0x83, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xE7, 0x01, 0xC7, 0x81, 0x01, 0x83, 0x00, 0x00, 0xE7, 0x1F, 0x9B, 0xE7, 0x1F, 0x39, 0x00, 0x00, 0xE7, 0x8F, 0x39, 0xE7, 0x87, 0xF9, 0x00, 0x00, 0xC3, 0xC7, 0x39, 0xE7, 0xC3, 0xC3, 0x00, 0x00, 0x99, 0xE3, 0x39, 0xE7, 0xF1, 0xE7, 0x00, 0x00, 0x99, 0xF1, 0xB3, 0xC7, 0x39, 0xF3, 0x00, 0x00, 0x99, 0x01, 0xC7, 0xE7, 0x83, 0x81, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x83, 0xE7, 0x83, 0xEF, 0x39, 0x39, 0x00, 0x00, 0x39, 0xE7, 0x39, 0xC7, 0x11, 0x11, 0x00, 0x00, 0xF9, 0xE7, 0x39, 0x83, 0x01, 0x83, 0x00, 0x00, 0x83, 0xE7, 0x39, 0x11, 0x01, 0xC7, 0x00, 0x00, 0x3F, 0xE7, 0x39, 0x39, 0x29, 0x83, 0x00, 0x00, 0x33, 0xE7, 0x39, 0x39, 0x39, 0x11, 0x00, 0x00, 0x87, 0x81, 0x39, 0x39, 0x39, 0x39, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x39, 0x39, 0x83, 0x3F, 0x85, 0x31, 0x00, 0x00, 0x39, 0x31, 0x39, 0x3F, 0x33, 0x23, 0x00, 0x00, 0x29, 0x21, 0x39, 0x03, 0x21, 0x07, 0x00, 0x00, 0x01, 0x01, 0x39, 0x39, 0x39, 0x31, 0x00, 0x00, 0x01, 0x09, 0x39, 0x39, 0x39, 0x39, 0x00, 0x00, 0x11, 0x19, 0x39, 0x39, 0x39, 0x39, 0x00, 0x00, 0x39, 0x39, 0x83, 0x03, 0x83, 0x03, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xC1, 0x39, 0x81, 0x83, 0x31, 0x01, 0x00, 0x00, 0x99, 0x39, 0xE7, 0x39, 0x23, 0x3F, 0x00, 0x00, 0x39, 0x39, 0xE7, 0xF9, 0x07, 0x3F, 0x00, 0x00, 0x31, 0x01, 0xE7, 0xF9, 0x0F, 0x3F, 0x00, 0x00, 0x3F, 0x39, 0xE7, 0xF9, 0x27, 0x3F, 0x00, 0x00, 0x9F, 0x39, 0xE7, 0xF9, 0x33, 0x3F, 0x00, 0x00, 0xC1, 0x39, 0x81, 0xF9, 0x39, 0x3F, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x39, 0x03, 0xC3, 0x07, 0x01, 0x3F, 0x00, 0x00, 0x39, 0x39, 0x99, 0x33, 0x3F, 0x3F, 0x00, 0x00, 0x01, 0x39, 0x3F, 0x39, 0x3F, 0x3F, 0x00, 0x00, 0x39, 0x03, 0x3F, 0x39, 0x03, 0x03, 0x00, 0x00, 0x39, 0x39, 0x3F, 0x39, 0x3F, 0x3F, 0x00, 0x00, 0x93, 0x39, 0x99, 0x33, 0x3F, 0x3F, 0x00, 0x00, 0xC7, 0x03, 0xC3, 0x07, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00}; + dbg_tex = SDL_CreateTextureFromSurface(dbg_ren, SDL_LoadBMP_IO(SDL_IOFromMem(font, 448), 1)); +} + +void dbg_print(int x, int y, const char *text, Uint8 r, Uint8 g, Uint8 b) +{ + int cc = 0; + SDL_SetTextureColorMod(dbg_tex, r, g, b); + SDL_FRect src = {0, 0, 8, 8}; + SDL_FRect dst = {static_cast(x), static_cast(y), 8, 8}; + while (text[cc] != 0) + { + if (text[cc] != 32) + { + if (text[cc] >= 65) + { + src.x = ((text[cc] - 65) % 6) * 8; + src.y = ((text[cc] - 65) / 6) * 8; + } + else + { + src.x = ((text[cc] - 22) % 6) * 8; + src.y = ((text[cc] - 22) / 6) * 8; + } + + SDL_RenderTexture(dbg_ren, dbg_tex, &src, &dst); + } + cc++; + dst.x += 8; + } +} \ No newline at end of file diff --git a/source/defines.h b/source/defines.h new file mode 100644 index 0000000..77fc669 --- /dev/null +++ b/source/defines.h @@ -0,0 +1,18 @@ +#pragma once + +#include "SDL3/SDL.h" +#include + +constexpr char WINDOW_CAPTION[] = "demo3_pixels_bouncing"; +constexpr int WIDTH = 320; +constexpr int HEIGHT = 240; +constexpr int ZOOM = 3; +constexpr float GRAVITY = 0.2f; +constexpr int DOT_SIZE = 1; +constexpr int MAX_DOTS = 200000; +constexpr int TEXT_TIME = 100; + +struct Color +{ + int r, g, b; +}; \ No newline at end of file diff --git a/source/dot.h b/source/dot.h new file mode 100644 index 0000000..cf5929f --- /dev/null +++ b/source/dot.h @@ -0,0 +1,122 @@ +#pragma once + +#include "defines.h" + +namespace Dot +{ + struct DotData + { + float x; // Posición x + float y; // Posición y + int w; // Ancho + int h; // Alto + float vx, vy; // Velocidad + float g; // Gravedad + Color color; // Color de la pelota + bool on_floor; // Indica si la pelota está ya en el suelo + bool stopped; // Indica si la pelota ha terminado de moverse; + float loss; // Coeficiente de rebote. Pérdida de energía en cada rebote + }; + + // Inicializa la estructura + DotData ini(float x, float vx, float vy, Color color); + + // Actualiza la lógica de la clase + SDL_FPoint update(DotData &dot); + + // Modifica la velocidad + void modVel(DotData &dot, float vx, float vy); + + // Constructor + DotData ini(float x, float vx, float vy, Color color) + { + DotData dot; + dot.x = x; + dot.y = 0.0f; + dot.vx = vx; + dot.vy = vy; + dot.color = color; + dot.g = GRAVITY; + dot.on_floor = false; + dot.stopped = false; + dot.loss = ((rand() % 30) * 0.01f) + 0.6f; + return dot; + } + + // Actualiza la lógica de la clase + SDL_FPoint update(DotData &dot) + { + if (dot.stopped) + { + return {dot.x, dot.y}; + } + + // Aplica la gravedad a la velocidad + if (!dot.on_floor && (dot.y - HEIGHT) < DOT_SIZE * 2) + { + dot.vy += dot.g; + } + + // Actualiza la posición en función de la velocidad + dot.x += dot.vx; + dot.y += dot.vy; + + // Comprueba las colisiones con el lateral izquierdo + if (dot.x < 0) + { + dot.x = 0; + dot.vx = -dot.vx; + } + + // Comprueba las colisiones con el lateral derecho + if (dot.x >= WIDTH) + { + dot.x = WIDTH - 1; + dot.vx = -dot.vx; + } + + // Comprueba las colisiones con la parte superior + if (dot.y < 0) + { + dot.y = 0; + dot.vy = -dot.vy; + } + + // Comprueba las colisiones con la parte inferior + if (dot.y >= HEIGHT) + { + dot.y = HEIGHT - 1; + dot.vy = -dot.vy * dot.loss; + if (abs(dot.vy) < 0.1f) + { + dot.vy = 0.0f; + dot.on_floor = true; + } + } + + // Aplica rozamiento al rodar por el suelo + if (dot.on_floor) + { + dot.vx = dot.vx * 0.97f; + if (abs(dot.vx) < 0.1f) + { + dot.vx = 0.0f; + dot.stopped = true; + } + } + + return {dot.x, dot.y}; + } + + // Modifica la velocidad + void modVel(DotData &dot, float vx, float vy) + { + if (dot.stopped) + { + dot.vx = dot.vx + vx; + } + dot.vy = dot.vy + vy; + dot.on_floor = false; + dot.stopped = false; + } +} \ No newline at end of file diff --git a/source/main.cpp b/source/main.cpp new file mode 100644 index 0000000..f889b1f --- /dev/null +++ b/source/main.cpp @@ -0,0 +1,240 @@ +#include +#include "dot.h" +#include "defines.h" +#include "dbgtxt.h" +#include +#include + +SDL_Window *window = NULL; +SDL_Renderer *renderer = NULL; +Dot::DotData dots[MAX_DOTS]; +SDL_FPoint dot_points[MAX_DOTS]; +int test[8] = {1, 10, 100, 500, 1000, 10000, 50000, MAX_DOTS}; +int scenario = 0; +std::string text = ""; +int text_pos = 0; +bool show_text = true; +int counter = 0; + +bool should_exit = false; +Uint32 ticks = 0; + +void setText() +{ + const std::string text2 = test[scenario] == 1 ? " PIXEL" : " PIXELS"; + text = std::to_string(test[scenario]) + text2; + const int size = text.size() * 8; + text_pos = WIDTH / 2 - size / 2; + counter = TEXT_TIME; + show_text = true; +} + +void initDots() +{ + for (int i = 0; i < test[scenario]; ++i) + { + const int sign = ((rand() % 2) * 2) - 1; + const float x = (rand() % (WIDTH / 2)) + (WIDTH / 4); + const float vx = (((rand() % 20) + 10) * 0.1f) * sign; + const float vy = ((rand() % 60) - 30) * 0.1f; + const Color color = {(rand() % 192) + 32, (rand() % 192) + 32, (rand() % 192) + 32}; + dots[i] = Dot::ini(x, vx, vy, color); + } + setText(); +} + +void pushUpDots() +{ + for (int i = 0; i < test[scenario]; ++i) + { + const int sign = ((rand() % 2) * 2) - 1; + const float vx = (((rand() % 20) + 10) * 0.1f) * sign; + const float vy = ((rand() % 40) * 0.1f) + 5; + Dot::modVel(dots[i], vx, -vy); + } +} + +bool init() +{ + // Initialization flag + bool success = true; + + // Initialize SDL + if (!SDL_Init(SDL_INIT_VIDEO)) + { + printf("SDL could not initialize! SDL Error: %s\n", SDL_GetError()); + success = false; + } + else + { + // Create window + window = SDL_CreateWindow(WINDOW_CAPTION, WIDTH * ZOOM, HEIGHT * ZOOM, SDL_WINDOW_OPENGL); + if (window == nullptr) + { + printf("Window could not be created! SDL Error: %s\n", SDL_GetError()); + success = false; + } + else + { + // Create renderer for window + renderer = SDL_CreateRenderer(window, nullptr); + if (renderer == nullptr) + { + printf("Renderer could not be created! SDL Error: %s\n", SDL_GetError()); + success = false; + } + else + { + // Initialize renderer color + SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0xFF, 0xFF); + + // Establece el tamaño del renderizador + SDL_SetRenderLogicalPresentation(renderer, WIDTH, HEIGHT, SDL_LOGICAL_PRESENTATION_INTEGER_SCALE); + } + } + } + + ticks = SDL_GetTicks(); + srand(time(nullptr)); + dbg_init(renderer); + initDots(); + setText(); + + return success; +} + +void close() +{ + // Destroy window + SDL_DestroyRenderer(renderer); + SDL_DestroyWindow(window); + + // Quit SDL subsystems + SDL_Quit(); +} + +void checkEvents() +{ + SDL_Event event; + // Comprueba los eventos que hay en la cola + while (SDL_PollEvent(&event) != 0) + { + // Evento de salida de la aplicación + if (event.type == SDL_EVENT_QUIT) + { + should_exit = true; + break; + } + + if (event.type == SDL_EVENT_KEY_DOWN && event.key.repeat == 0) + { + switch (event.key.key) + { + case SDLK_ESCAPE: + should_exit = true; + break; + + case SDLK_SPACE: + pushUpDots(); + break; + + case SDLK_1: + scenario = 0; + initDots(); + break; + + case SDLK_2: + scenario = 1; + initDots(); + break; + + case SDLK_3: + scenario = 2; + initDots(); + break; + + case SDLK_4: + scenario = 3; + initDots(); + break; + + case SDLK_5: + scenario = 4; + initDots(); + break; + + case SDLK_6: + scenario = 5; + initDots(); + break; + + case SDLK_7: + scenario = 6; + initDots(); + break; + + case SDLK_8: + scenario = 7; + initDots(); + break; + + default: + break; + } + } + } +} + +void update() +{ + if (SDL_GetTicks() - ticks > 15) + { + ticks = SDL_GetTicks(); + + for (int i = 0; i < test[scenario]; ++i) + { + dot_points[i] = Dot::update(dots[i]); + } + + if (counter > 0) + { + counter--; + } + else + { + show_text = false; + } + } +} + +void render() +{ + SDL_SetRenderDrawColor(renderer, 32, 32, 32, 255); + SDL_RenderClear(renderer); + + SDL_SetRenderDrawColor(renderer, 224, 224, 224, 255); + SDL_RenderPoints(renderer, dot_points, test[scenario]); + + if (show_text) + { + dbg_print(text_pos, 8, text.c_str(), 255, 32, 32); + } + + SDL_RenderPresent(renderer); +} + +int main(int argc, char *args[]) +{ + init(); + + while (!should_exit) + { + update(); + checkEvents(); + render(); + } + + close(); + + return 0; +} \ No newline at end of file