Add SDL example

This commit is contained in:
Lexi / Zoe 2025-10-18 00:49:05 +02:00
parent 1402505a6d
commit c9ffc52ee4
Signed by: binaryDiv
GPG Key ID: F8D4956E224DA232
7 changed files with 179 additions and 0 deletions

4
examples/sdl_app/.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
# Build files
/build
/build.ninja
/shuriken.override.yaml

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

@ -0,0 +1,10 @@
defaults:
cpp_standard: c++20
cpp_flags: -Wall -Wextra -Werror -pedantic
linker_args: -lSDL3 -lSDL3_image
default_target: linux
targets:
linux:
output_file: sdl_example

View File

@ -0,0 +1,23 @@
import sdl_app;
#define SDL_MAIN_USE_CALLBACKS
#include <SDL3/SDL_main.h>
SDL_AppResult SDL_AppInit(void** appstate, int /*argc*/, char** /*argv*/) {
*appstate = new AppState;
return sdl_app_init(static_cast<AppState*>(*appstate));
}
SDL_AppResult SDL_AppIterate(void* appstate) {
return sdl_app_iterate(static_cast<AppState*>(appstate));
}
SDL_AppResult SDL_AppEvent(void* appstate, SDL_Event* event) {
return sdl_app_event(static_cast<AppState*>(appstate), event);
}
void SDL_AppQuit(void* appstate, SDL_AppResult /*result*/) {
const auto game_app_state = static_cast<AppState*>(appstate);
sdl_app_shutdown(game_app_state);
delete game_app_state;
}

View File

@ -0,0 +1,89 @@
module;
#include <iostream>
#include <string>
#include <SDL3/SDL.h>
import sprite;
export module sdl_app;
export {
struct AppState {
SDL_Window* window = nullptr;
SDL_Renderer* renderer = nullptr;
Sprite* sprite = nullptr;
};
SDL_AppResult sdl_panic(
const std::string& error_prefix,
SDL_Window* window = nullptr,
SDL_Renderer* renderer = nullptr
) {
std::cerr << error_prefix << ": " << SDL_GetError() << std::endl;
if (renderer != nullptr) {
SDL_DestroyRenderer(renderer);
}
if (window != nullptr) {
SDL_DestroyWindow(window);
}
SDL_Quit();
return SDL_APP_FAILURE;
}
SDL_AppResult sdl_app_init(AppState* app_state) {
if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS)) {
return sdl_panic("SDL_Init error");
}
app_state->window = SDL_CreateWindow("BuildSystemTest", 640, 480, 0);
if (app_state->window == nullptr) {
return sdl_panic("SDL_CreateWindow error");
}
app_state->renderer = SDL_CreateRenderer(app_state->window, nullptr);
if (app_state->renderer == nullptr) {
return sdl_panic("SDL_CreateRenderer error", app_state->window);
}
try {
app_state->sprite = new Sprite(app_state->renderer, "assets/neocat.png", 100, 100);
}
catch (const std::runtime_error& e) {
return sdl_panic(e.what(), app_state->window, app_state->renderer);
}
return SDL_APP_CONTINUE;
}
SDL_AppResult sdl_app_event(const AppState* app_state, const SDL_Event* event) {
if (event->type == SDL_EVENT_QUIT) {
return SDL_APP_SUCCESS;
}
if (event->type == SDL_EVENT_MOUSE_MOTION) {
app_state->sprite->move(
event->motion.x - 50,
event->motion.y - 50
);
}
return SDL_APP_CONTINUE;
}
SDL_AppResult sdl_app_iterate(const AppState* app_state) {
SDL_RenderClear(app_state->renderer);
app_state->sprite->render(app_state->renderer);
SDL_RenderPresent(app_state->renderer);
return SDL_APP_CONTINUE;
}
void sdl_app_shutdown(const AppState* app_state) {
delete app_state->sprite;
SDL_DestroyRenderer(app_state->renderer);
SDL_DestroyWindow(app_state->window);
}
}

View File

@ -0,0 +1,52 @@
module;
#include <stdexcept>
#include <string>
#include <SDL3/SDL.h>
#include <SDL3_image/SDL_image.h>
export module sprite;
export class Sprite {
private:
SDL_Texture* sdl_texture;
SDL_FRect dest_rect{0, 0, 0, 0};
public:
explicit Sprite(
SDL_Renderer* renderer,
const std::string& filename,
const int width,
const int height
) {
SDL_Surface* texture_surface = IMG_Load(filename.c_str());
if (texture_surface == nullptr) {
throw std::runtime_error("IMG_Load error");
}
sdl_texture = SDL_CreateTextureFromSurface(renderer, texture_surface);
SDL_DestroySurface(texture_surface);
if (sdl_texture == nullptr) {
throw std::runtime_error("SDL_CreateTextureFromSurface error");
}
dest_rect.w = static_cast<float>(width);
dest_rect.h = static_cast<float>(height);
}
~Sprite() {
if (sdl_texture) {
SDL_DestroyTexture(sdl_texture);
}
}
void move(const float x, const float y) {
dest_rect.x = x;
dest_rect.y = y;
}
void render(SDL_Renderer* renderer) const {
SDL_RenderTexture(renderer, sdl_texture, nullptr, &dest_rect);
}
};

View File

@ -0,0 +1 @@
../../../src/shuriken.py