diff options
| author | Polesznyák Márk <contact@pml68.dev> | 2026-04-06 23:44:45 +0200 |
|---|---|---|
| committer | Polesznyák Márk <contact@pml68.dev> | 2026-04-06 23:44:45 +0200 |
| commit | 6637fdded6f3c5fba7e7a378ca7e30d0db11f27d (patch) | |
| tree | 40f8868ae2140680645b1f90f4a1fc2a378920b3 /vendor/hare-sdl2/cmd/demo | |
| parent | docs: add README (diff) | |
| parent | Add ! after c::fromstr calls to handle nomem (diff) | |
| download | hare-chip8-6637fdded6f3c5fba7e7a378ca7e30d0db11f27d.tar.gz | |
Add 'vendor/hare-sdl2/' from commit 'fb6008be0b79a2a24b1ac960316a83f7873b4f39'
git-subtree-dir: vendor/hare-sdl2
git-subtree-mainline: ed088aa81ac23fa48d5ae48ee739c97e0fcb4490
git-subtree-split: fb6008be0b79a2a24b1ac960316a83f7873b4f39
Diffstat (limited to '')
| -rw-r--r-- | vendor/hare-sdl2/cmd/demo/main.ha | 199 |
1 files changed, 199 insertions, 0 deletions
diff --git a/vendor/hare-sdl2/cmd/demo/main.ha b/vendor/hare-sdl2/cmd/demo/main.ha new file mode 100644 index 0000000..3ba1b1c --- /dev/null +++ b/vendor/hare-sdl2/cmd/demo/main.ha @@ -0,0 +1,199 @@ +use fmt; +use fs; +use sdl2; +use sdl2::{ SDL_GameControllerAxis, SDL_EventType, SDL_RendererFlags, SDL_WindowFlags }; +use sdl2::image; +use sdl2::mixer; +use strings; + +type object = struct { + tex: *sdl2::SDL_Texture, + w: int, h: int, + x: int, y: int, + dx: int, dy: int, +}; + +type state = struct { + quit: bool, + window: *sdl2::SDL_Window, + render: *sdl2::SDL_Renderer, + nbutton: int, + hare: object, + cat: object, +}; + +export fn main() void = { + match (run()) { + case let err: sdl2::error => + fmt::fatal("SDL2 error:", sdl2::strerror(err)); + case let err: fs::error => + fmt::fatal("Error:", fs::strerror(err)); + case void => void; + }; +}; + +fn run() (void | fs::error | sdl2::error) = { + sdl2::SDL_Init(sdl2::SDL_INIT_VIDEO + | sdl2::SDL_INIT_AUDIO + | sdl2::SDL_INIT_GAMECONTROLLER)!; + defer sdl2::SDL_Quit(); + image::IMG_Init(image::IMG_InitFlags::PNG | image::IMG_InitFlags::JPG)!; + defer image::IMG_Quit(); + + mixer::Mix_Init(mixer::MIX_InitFlags::OGG)!; + defer mixer::Mix_Quit(); + mixer::Mix_OpenAudio(mixer::MIX_DEFAULT_FREQUENCY, mixer::MIX_DEFAULT_FORMAT, + mixer::MIX_DEFAULT_CHANNELS, 1024)!; + defer mixer::Mix_CloseAudio(); + + const win = sdl2::SDL_CreateWindow("Hare SDL2 demo", + sdl2::SDL_WINDOWPOS_UNDEFINED, sdl2::SDL_WINDOWPOS_UNDEFINED, + 640, 480, SDL_WindowFlags::NONE)?; + defer sdl2::SDL_DestroyWindow(win); + + const render = sdl2::SDL_CreateRenderer(win, -1, SDL_RendererFlags::NONE)?; + defer sdl2::SDL_DestroyRenderer(render); + + let controller: nullable *sdl2::SDL_GameController = null; + for (let i = 0; i < sdl2::SDL_NumJoysticks()?; i += 1) { + if (!sdl2::SDL_IsGameController(i)) { + continue; + }; + match (sdl2::SDL_GameControllerOpen(i)) { + case let c: *sdl2::SDL_GameController => + controller = c; + sdl2::SDL_GameControllerRumble(c, 0x4000, 0x4000, 1000): void; + break; + case sdl2::error => void; + }; + }; + defer match (controller) { + case null => void; + case let c: *sdl2::SDL_GameController => + sdl2::SDL_GameControllerClose(c); + }; + + let sample = mixer::load_file("sample.ogg")?; + defer mixer::Mix_FreeChunk(sample); + mixer::Mix_PlayChannelTimed(0, sample, -1)?; + + let state = state { + window = win, + render = render, + hare = load_object(render, "mascot.jpg")?, + cat = load_object(render, "cat.png")?, + ... + }; + defer sdl2::SDL_DestroyTexture(state.hare.tex); + defer sdl2::SDL_DestroyTexture(state.cat.tex); + + state.hare.dx = 2; + state.hare.dy = 2; + + for (!state.quit) { + update(&state)?; + draw(&state)?; + sdl2::SDL_Delay(1000 / 60); + }; +}; + +fn update(state: *state) (void | sdl2::error) = { + let ev = sdl2::event { ... }; + for (sdl2::SDL_PollEvent(&ev)? == 1) switch (ev.event_type) { + case SDL_EventType::QUIT => + state.quit = true; + return; + case SDL_EventType::CONTROLLERAXISMOTION => + let delta = ev.caxis.value: int * 10 / sdl2::SDL_JOYSTICK_AXIS_MAX; + if (axis_x(ev.caxis.axis)) { + state.cat.dx = delta; + }; + if (axis_y(ev.caxis.axis)) { + state.cat.dy = delta; + }; + case SDL_EventType::CONTROLLERBUTTONDOWN => + state.nbutton += 1; + case SDL_EventType::CONTROLLERBUTTONUP => + state.nbutton -= 1; + case => void; + }; + + let width = 0, height = 0; + sdl2::SDL_GetWindowSize(state.window, &width, &height); + + state.hare.x += state.hare.dx; + state.hare.y += state.hare.dy; + if (state.hare.x <= 0 || state.hare.x + state.hare.w >= width) { + state.hare.dx = -state.hare.dx; + }; + if (state.hare.y <= 0 || state.hare.y + state.hare.h >= height) { + state.hare.dy = -state.hare.dy; + }; + + state.cat.x += state.cat.dx; + state.cat.y += state.cat.dy; + if (state.cat.x <= 0) { + state.cat.x = 0; + }; + if (state.cat.x > width - state.cat.w) { + state.cat.x = width - state.cat.w; + }; + if (state.cat.y <= 0) { + state.cat.y = 0; + }; + if (state.cat.y > height - state.cat.h) { + state.cat.y = height - state.cat.h; + }; +}; + +fn draw(state: *state) (void | sdl2::error) = { + if (state.nbutton == 0) { + sdl2::SDL_SetRenderDrawColor(state.render, 50, 50, 50, 255)?; + } else { + sdl2::SDL_SetRenderDrawColor(state.render, 50, 50, 200, 255)?; + }; + sdl2::SDL_RenderClear(state.render)?; + + draw_object(state, &state.hare)?; + draw_object(state, &state.cat)?; + sdl2::SDL_RenderPresent(state.render); +}; + +fn draw_object(state: *state, obj: *object) (void | sdl2::error) = { + sdl2::SDL_RenderCopy(state.render, obj.tex, null, &sdl2::SDL_Rect { + x = obj.x, + y = obj.y, + w = obj.w, + h = obj.h, + })?; +}; + +fn axis_x(axis: SDL_GameControllerAxis) bool = { + switch (axis) { + case SDL_GameControllerAxis::LEFTX, SDL_GameControllerAxis::RIGHTX => + return true; + case => + return false; + }; +}; + +fn axis_y(axis: SDL_GameControllerAxis) bool = { + switch (axis) { + case SDL_GameControllerAxis::LEFTY, SDL_GameControllerAxis::RIGHTY => + return true; + case => + return false; + }; +}; + +fn load_object(render: *sdl2::SDL_Renderer, path: str) (object | sdl2::error) = { + const tex = image::IMG_LoadTexture(render, path)?; + let w = 0, h = 0; + sdl2::SDL_QueryTexture(tex, null, null, &w, &h)?; + return object { + tex = tex, + w = w, + h = h, + ... + }; +}; |
