diff options
| author | Drew DeVault <sir@cmpwn.com> | 2021-12-09 16:16:33 +0100 |
|---|---|---|
| committer | Drew DeVault <sir@cmpwn.com> | 2021-12-09 16:16:33 +0100 |
| commit | 4b9ce55ebe2fce02841a2d5d283b5f02f9a534eb (patch) | |
| tree | 05b6a204b4b1a42ee7b78326916489c6db8a0179 | |
| parent | cmd/demo: add hare mascot (diff) | |
| download | hare-chip8-4b9ce55ebe2fce02841a2d5d283b5f02f9a534eb.tar.gz | |
Add timer.h functions
| -rw-r--r-- | cmd/demo/main.ha | 114 | ||||
| -rw-r--r-- | sdl2/timer.ha | 32 | ||||
| -rw-r--r-- | sdl2/video.ha | 13 |
3 files changed, 115 insertions, 44 deletions
diff --git a/cmd/demo/main.ha b/cmd/demo/main.ha index f7ece50..43aea33 100644 --- a/cmd/demo/main.ha +++ b/cmd/demo/main.ha @@ -5,11 +5,21 @@ use sdl2; use sdl2::image; use strings; +type texture = struct { + tex: *sdl2::texture, + w: int, + h: int, +}; + type state = struct { - hare: *sdl2::texture, - cat: *sdl2::texture, + window: *sdl2::window, + render: *sdl2::renderer, + hare: texture, + cat: texture, hare_x: int, hare_y: int, + hare_dx: int, + hare_dy: int, cat_x: int, cat_y: int, }; @@ -41,67 +51,83 @@ export fn main() void = { defer sdl2::destroy_renderer(render); let state = state { - hare = { - const path = strings::to_c("mascot.jpg"); - defer free(path); - yield match (image::load_texture(render, path)) { - case let tex: *sdl2::texture => - yield tex; - case null => - fmt::fatal("sdl2::image::load_texture failed for mascot.jpg"); - }; - }, - cat = { - const path = strings::to_c("cat.png"); - defer free(path); - yield match (image::load_texture(render, path)) { - case let tex: *sdl2::texture => - yield tex; - case null => - fmt::fatal("sdl2::image::load_texture failed for cat.png"); - }; - }, + window = win, + render = render, + hare = load_texture(render, "mascot.jpg"), + cat = load_texture(render, "cat.png"), hare_x = 100, hare_y = 100, + hare_dx = 2, + hare_dy = 2, ... }; - defer sdl2::destroy_texture(state.hare); - defer sdl2::destroy_texture(state.cat); - - draw_frame(&state, render); + defer sdl2::destroy_texture(state.hare.tex); + defer sdl2::destroy_texture(state.cat.tex); let ev = sdl2::event { ... }; - for (sdl2::wait_event(&ev) == 1) { - switch (ev.event_type) { + for (true) { + if (sdl2::poll_event(&ev) == 1) switch (ev.event_type) { case event_type::QUIT => break; case => void; }; + + update(&state); + draw(&state); + + sdl2::delay(1000 / 60); }; os::exit(0); // https://todo.sr.ht/~sircmpwn/hare/525 }; -fn draw_frame(state: *state, render: *sdl2::renderer) void = { - sdl2::set_render_draw_color(render, 50, 50, 50, 255); - sdl2::render_clear(render); - draw_tex(render, state.cat, state.cat_x, state.cat_y); - draw_tex(render, state.hare, state.hare_x, state.hare_y); - sdl2::render_present(render); +fn load_texture(render: *sdl2::renderer, path: str) texture = { + const path = strings::to_c(path); + defer free(path); + + const tex = match (image::load_texture(render, path)) { + case let tex: *sdl2::texture => + yield tex; + case null => + fmt::fatal("sdl2::image::load_texture failed for cat.png"); + }; + + let w = 0, h = 0; + sdl2::query_texture(tex, null, null, &w, &h); + return texture { + tex = tex, + w = w, + h = h, + }; }; -fn draw_tex( - render: *sdl2::renderer, - tex: *sdl2::texture, - x: int, - y: int, -) void = { +fn update(state: *state) void = { let width = 0, height = 0; - sdl2::query_texture(tex, null, null, &width, &height); - sdl2::render_copy(render, tex, null, &sdl2::rect { + sdl2::get_window_size(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; + }; +}; + +fn draw(state: *state) void = { + sdl2::set_render_draw_color(state.render, 50, 50, 50, 255); + sdl2::render_clear(state.render); + draw_tex(state, &state.hare, state.hare_x, state.hare_y); + draw_tex(state, &state.cat, state.cat_x, state.cat_y); + sdl2::render_present(state.render); +}; + +fn draw_tex(state: *state, tex: *texture, x: int, y: int) void = { + sdl2::render_copy(state.render, tex.tex, null, &sdl2::rect { x = x, y = y, - w = width, - h = height, + w = tex.w, + h = tex.h, }); }; diff --git a/sdl2/timer.ha b/sdl2/timer.ha new file mode 100644 index 0000000..da958b6 --- /dev/null +++ b/sdl2/timer.ha @@ -0,0 +1,32 @@ +// Get the number of milliseconds since SDL library initialization. +// +// This value wraps if the program runs for more than ~49 days. +// +// Returns an unsigned 32-bit value representing the number of milliseconds +// since the SDL library initialized. +export @symbol("SDL_GetTicks") fn getticks() u32; + +// Get the current value of the high resolution counter. +// +// This function is typically used for profiling. +// +// The counter values are only meaningful relative to each other. Differences +// between values can be converted to times by using +// [[getperformancefrequency]]. +// +// Returns the current counter value. +export @symbol("SDL_GetPerformanceCounter") fn getperformancecounter() u64; + +// Get the count per second of the high resolution counter. +// +// Returns a platform-specific count per second. +export @symbol("SDL_GetPerformanceFrequency") fn getperformancefrequency() u64; + +// Wait a specified number of milliseconds before returning. +// +// This function waits a specified number of milliseconds before returning. It +// waits at least the specified time, but possibly longer due to OS +// scheduling. +export @symbol("SDL_Delay") fn delay(ms: u32) void; + +// TODO: Timers diff --git a/sdl2/video.ha b/sdl2/video.ha index e12ca12..e6dfa58 100644 --- a/sdl2/video.ha +++ b/sdl2/video.ha @@ -71,3 +71,16 @@ export @symbol("SDL_CreateWindow") fn create_window(title: const *char, // Destroy a window. export @symbol("SDL_DestroyWindow") fn destroy_window(window: *window) void; + +// Get the size of a window's client area. +// +// Null may safely be passed as the 'w' or 'h' parameter if the width or +// height value is not desired. +// +// The window size in screen coordinates may differ from the size in pixels, if +// the window was created with `ALLOW_HIGHDPI` on a platform with high-dpi +// support (e.g. iOS or macOS). Use [[gl_getdrawablesize]], +// [[vulkan_getdrawablesize]], or [[getrendereroutputsize]] to get the real +// client area size in pixels. +export @symbol("SDL_GetWindowSize") fn get_window_size(window: *window, + w: nullable *int, h: nullable *int) void; |
