This commit is contained in:
2026-08-04 17:03:04 +02:00
commit edf1e9fd8a
15 changed files with 820 additions and 0 deletions
+185
View File
@@ -0,0 +1,185 @@
#include "../core/const.hpp"
#include <SDL3/SDL.h>
#include <SDL3/SDL_events.h>
#include <SDL3/SDL_iostream.h>
#include <SDL3/SDL_mouse.h>
#include <SDL3/SDL_rect.h>
#include <SDL3/SDL_render.h>
#include <SDL3/SDL_scancode.h>
#include <SDL3/SDL_stdinc.h>
#include <SDL3/SDL_surface.h>
#include <SDL3/SDL_timer.h>
#include <SDL3/SDL_video.h>
#include <SDL3_image/SDL_image.h>
#include <cstddef>
#include <cstdint>
#include "draw.hpp"
#include "hal/hal.hpp"
#include <curl/curl.h>
#include <curl/easy.h>
#include <iostream>
#include <nlohmann/json.hpp>
#include <nlohmann/json_fwd.hpp>
#include <tuple>
#include "../core/color.h"
struct sdl_session {
SDL_Window *window;
SDL_Renderer *renderer;
};
sdl_session main_sdl_session;
const SDL_DisplayMode *mode;
CURL *curl;
namespace hal {
int init() {
SDL_Init(SDL_INIT_VIDEO);
mode = SDL_GetCurrentDisplayMode(SDL_GetPrimaryDisplay());
main_sdl_session.window =
SDL_CreateWindow(program_name, mode->w, mode->h, SDL_WINDOW_FULLSCREEN);
main_sdl_session.renderer =
SDL_CreateRenderer(main_sdl_session.window, "gpu,vulcan");
return 0;
curl = curl_easy_init();
}
std::tuple<uint16_t, uint16_t> get_screen_size() { return {mode->w, mode->h}; }
uint64_t frame_start;
void start_frame() {
frame_start = SDL_GetTicksNS();
SDL_SetRenderDrawColor(main_sdl_session.renderer, 0, 0, 0, 255);
SDL_RenderClear(main_sdl_session.renderer);
}
const Uint64 frame_delay_ns = 1000000000ULL / 1;
void end_frame() {
SDL_RenderPresent(main_sdl_session.renderer);
uint64_t frame_time = SDL_GetTicksNS() - frame_start;
if (frame_time < frame_delay_ns) {
SDL_DelayNS(frame_delay_ns - frame_time);
}
}
} // namespace hal
namespace draw {
void pixel(const uint16_t x, const uint16_t y, const color_t color) {
SDL_SetRenderDrawColor(main_sdl_session.renderer, color.r, color.g, color.b,
0xff);
SDL_RenderPoint(main_sdl_session.renderer, x, y);
}
void filled_rect(const rect_t *rect, const color_t color) {
SDL_SetRenderDrawColor(main_sdl_session.renderer, color.r, color.g, color.b,
0xff);
const SDL_FRect frect = {
static_cast<float>(rect->x), static_cast<float>(rect->y),
static_cast<float>(rect->w), static_cast<float>(rect->h)};
SDL_RenderFillRect(main_sdl_session.renderer, &frect);
}
void circle(const uint16_t x_center, const uint16_t y_center,const uint16_t radius, const color_t color) {
SDL_SetRenderDrawColor(main_sdl_session.renderer, color.r, color.g, color.b,
0xff);
// based on https://www.geeksforgeeks.org/dsa/mid-point-circle-drawing-algorithm/
int x = radius, y = 0;
// Printing the initial point on the axes
// after translation
SDL_RenderPoint(main_sdl_session.renderer, x + x_center, y + y_center);
// When radius is zero only a single
// point will be printed
if (radius > 0)
{
SDL_RenderPoint(main_sdl_session.renderer, x + x_center, -y + y_center);
SDL_RenderPoint(main_sdl_session.renderer, y + x_center, x + y_center);
SDL_RenderPoint(main_sdl_session.renderer, -y + x_center, x + y_center);
std::cout << "\n";
}
// Initialising the value of P
int P = 1 - radius;
while (x > y)
{
y++;
// Mid-point is inside or on the perimeter
if (P <= 0)
P = P + 2*y + 1;
// Mid-point is outside the perimeter
else
{
x--;
P = P + 2*y - 2*x + 1;
}
// All the perimeter points have already been printed
if (x < y)
break;
// Printing the generated point and its reflection
// in the other octants after translation
SDL_RenderPoint(main_sdl_session.renderer, x + x_center, y + y_center);
SDL_RenderPoint(main_sdl_session.renderer, -x + x_center, y + y_center);
SDL_RenderPoint(main_sdl_session.renderer, x + x_center, -y + y_center);
SDL_RenderPoint(main_sdl_session.renderer, -x + x_center, -y + y_center);
// If the generated point is on the line x = y then
// the perimeter points have already been printed
if (x != y)
{
SDL_RenderPoint(main_sdl_session.renderer, y + x_center, x + y_center);
SDL_RenderPoint(main_sdl_session.renderer, -y + x_center, x + y_center);
SDL_RenderPoint(main_sdl_session.renderer, y + x_center, -x + y_center);
SDL_RenderPoint(main_sdl_session.renderer, -y + x_center, -x + y_center);
}
}
}
} // namespace draw
namespace net {
// Callback function to write data into a std::string
size_t WriteCallback_to_string(void *contents, size_t size, size_t nmemb,
void *userp) {
size_t totalSize = size * nmemb;
static_cast<std::string *>(userp)->append((char *)contents, totalSize);
return totalSize;
}
nlohmann::json http_get_json(const std::string &url) {
std::string response;
if (curl) {
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &WriteCallback_to_string);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
curl_easy_setopt(curl, CURLOPT_ACCEPT_ENCODING, "gzip, deflate");
curl_easy_setopt(curl, CURLOPT_USERAGENT, user_agent);
curl_easy_setopt(curl, CURLOPT_HTTPGET, 1L);
CURLcode curl_return_code = curl_easy_perform(curl);
if (curl_return_code != CURLE_OK) {
std::cerr << RED "[ERROR] " << RESET << "curl_easy_perform() failed: "
<< curl_easy_strerror(curl_return_code) << "\n";
exit(21);
}
int http_code = 0;
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code);
if (http_code < 200 || http_code >= 300) {
return nullptr;
}
return nlohmann::json::parse(response);
}
return nullptr;
}
} // namespace net