From a296f2c6604c27b480a39f74f34a57269866bd23 Mon Sep 17 00:00:00 2001 From: Charlie Malmqvist Date: Fri, 23 Aug 2024 18:13:02 +0200 Subject: [PATCH] Sprite sheet animation and window woopsie fix --- build.c | 3 +- changelog.txt | 4 +- oogabooga/examples/male_animation.png | Bin 0 -> 13052 bytes oogabooga/examples/sprite_animation.c | 95 ++++++++++++++++++++++++++ oogabooga/linmath.c | 4 ++ oogabooga/os_impl_windows.c | 24 +++---- oogabooga/utility.c | 4 +- 7 files changed, 119 insertions(+), 15 deletions(-) create mode 100644 oogabooga/examples/male_animation.png create mode 100644 oogabooga/examples/sprite_animation.c diff --git a/build.c b/build.c index b721335..7fc2086 100644 --- a/build.c +++ b/build.c @@ -33,7 +33,7 @@ typedef struct Context_Extra { // // This is a minimal starting point for new projects. Copy & rename to get started -#include "oogabooga/examples/minimal_game_loop.c" +// #include "oogabooga/examples/minimal_game_loop.c" // #include "oogabooga/examples/text_rendering.c" // #include "oogabooga/examples/custom_logger.c" @@ -43,6 +43,7 @@ typedef struct Context_Extra { // #include "oogabooga/examples/custom_shader.c" // #include "oogabooga/examples/growing_array_example.c" // #include "oogabooga/examples/input_example.c" +#include "oogabooga/examples/sprite_animation.c" // #include "oogabooga/examples/sanity_tests.c" diff --git a/changelog.txt b/changelog.txt index 44cc9a2..9bf2a79 100644 --- a/changelog.txt +++ b/changelog.txt @@ -8,7 +8,9 @@ This also gets rid of the weird window resize and reposition at startup. - Renderer - Added gfx_read_image_data() to read pixels from a Gfx_Image* - + + - Misc + - Added examples/sprite_animation.c ## v0.01.004 - Gamepad input, text wrapping, bug fixes - Input diff --git a/oogabooga/examples/male_animation.png b/oogabooga/examples/male_animation.png new file mode 100644 index 0000000000000000000000000000000000000000..cea9f98a1081cab2bcd2d5926a796ab1484cdc3a GIT binary patch literal 13052 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 N^|g()Dl{A-{|}aoqZ0rC literal 0 HcmV?d00001 diff --git a/oogabooga/examples/sprite_animation.c b/oogabooga/examples/sprite_animation.c new file mode 100644 index 0000000..3f1d9cb --- /dev/null +++ b/oogabooga/examples/sprite_animation.c @@ -0,0 +1,95 @@ + + + +int entry(int argc, char **argv) { + + window.title = STR("Sprite animation example"); + + Gfx_Image *anim_sheet = load_image_from_disk(STR("oogabooga/examples/male_animation.png"), get_heap_allocator()); + assert(anim_sheet, "Could not open oogabooga/examples/male_animation.png"); + + // Configure information about the whole image as a sprite sheet + u32 number_of_columns = 10; + u32 number_of_rows = 6; + u32 total_number_of_frames = number_of_rows * number_of_columns; + + u32 anim_frame_width = anim_sheet->width / number_of_columns; + u32 anim_frame_height = anim_sheet->height / number_of_rows; + + // Configure the animation by setting the start & end frames in the grid of frames + // (Inspect sheet image and count the frame indices you want) + // In sprite sheet animations, it usually goes down. So Y 0 is actuall the top of the + // sprite sheet, and +Y is down on the sprite sheet. + u32 anim_start_frame_x = 2; + u32 anim_start_frame_y = 1; + u32 anim_end_frame_x = 6; + u32 anim_end_frame_y = 2; + u32 anim_start_index = anim_start_frame_y * number_of_columns + anim_start_frame_x; + u32 anim_end_index = anim_end_frame_y * number_of_columns + anim_end_frame_x; + u32 anim_number_of_frames = max(anim_end_index, anim_start_index)-min(anim_end_index, anim_start_index)+1; + + // Sanity check configuration + assert(anim_end_index > anim_start_index, "The last frame must come before the first frame"); + assert(anim_start_frame_x < number_of_columns, "anim_start_frame_x is out of bounds"); + assert(anim_start_frame_y < number_of_rows, "anim_start_frame_y is out of bounds"); + assert(anim_end_frame_x < number_of_columns, "anim_end_frame_x is out of bounds"); + assert(anim_end_frame_y < number_of_rows, "anim_end_frame_y is out of bounds"); + + // Calculate duration per frame in seconds + float32 playback_fps = 4; + float32 anim_time_per_frame = 1.0 / playback_fps; + float32 anim_duration = anim_time_per_frame * (float32)anim_number_of_frames; + + float32 anim_start_time = os_get_elapsed_seconds(); + + float64 last_time = os_get_elapsed_seconds(); + while (!window.should_close) { + reset_temporary_storage(); + + + float64 now = os_get_elapsed_seconds(); + float64 delta = now-last_time; + last_time = now; + + draw_frame.projection = m4_make_orthographic_projection(window.pixel_width * -0.5, window.pixel_width * 0.5, window.pixel_height * -0.5, window.pixel_height * 0.5, -1, 10); + + // Float modulus to "loop" around the timer over the anim duration + float32 anim_elapsed = fmodf(now - anim_start_time, anim_duration); + + // Get current progression in animation from 0.0 to 1.0 + float32 anim_progression_factor = anim_elapsed / anim_duration; + + u32 anim_current_index = anim_number_of_frames * anim_progression_factor; + u32 anim_absolute_index_in_sheet = anim_start_index + anim_current_index; + + u32 anim_index_x = anim_absolute_index_in_sheet % number_of_columns; + u32 anim_index_y = anim_absolute_index_in_sheet / number_of_columns + 1; + + u32 anim_sheet_pos_x = anim_index_x * anim_frame_width; + u32 anim_sheet_pos_y = (number_of_rows - anim_index_y) * anim_frame_height; // Remember, Y inverted. + + // Draw the sprite sheet, with the uv box for the current frame. + // Uv box is a Vector4 of x1, y1, x2, y2 where each value is a percentage value 0.0 to 1.0 + // from left to right / bottom to top in the texture. + Draw_Quad *quad = draw_image(anim_sheet, v2(0, 0), v2(anim_frame_width*4, anim_frame_height*4), COLOR_WHITE); + quad->uv.x1 = (float32)(anim_sheet_pos_x)/(float32)anim_sheet->width; + quad->uv.y1 = (float32)(anim_sheet_pos_y)/(float32)anim_sheet->height; + quad->uv.x2 = (float32)(anim_sheet_pos_x+anim_frame_width) /(float32)anim_sheet->width; + quad->uv.y2 = (float32)(anim_sheet_pos_y+anim_frame_height)/(float32)anim_sheet->height; + + + // Visualize sprite sheet animation + Vector2 sheet_pos = v2(-window.width/2+40, -window.height/2+40); + Vector2 sheet_size = v2(anim_sheet->width, anim_sheet->height); + Vector2 frame_pos_in_sheet = v2(anim_sheet_pos_x, anim_sheet_pos_y); + Vector2 frame_size = v2(anim_frame_width, anim_frame_height); + draw_rect(sheet_pos, sheet_size, COLOR_BLACK); // Draw black background + draw_rect(v2_add(sheet_pos, frame_pos_in_sheet), frame_size, COLOR_WHITE); // Draw white rect on current frame + draw_image(anim_sheet, sheet_pos, sheet_size, COLOR_WHITE); // Draw the seet + + os_update(); + gfx_update(); + } + + return 0; +} \ No newline at end of file diff --git a/oogabooga/linmath.c b/oogabooga/linmath.c index fd65c2b..cbcb57a 100644 --- a/oogabooga/linmath.c +++ b/oogabooga/linmath.c @@ -319,6 +319,10 @@ Matrix4 m4_scalar(float32 scalar) { return m; } +inline Matrix4 m4_identity() { + return m4_scalar(1.0); +} + Matrix4 m4_make_translation(Vector3 translation) { Matrix4 m = m4_scalar(1.0); m.m[0][0] = 1.0f; m.m[1][1] = 1.0f; m.m[2][2] = 1.0f; m.m[3][3] = 1.0f; diff --git a/oogabooga/os_impl_windows.c b/oogabooga/os_impl_windows.c index c524684..ed637f9 100644 --- a/oogabooga/os_impl_windows.c +++ b/oogabooga/os_impl_windows.c @@ -297,10 +297,10 @@ win32_init_window() { memset(&window, 0, sizeof(window)); window.title = STR("Unnamed Window"); - window.width = 1280; - window.height = 720; - window.x = 0; - window.y = 0; + window.scaled_width = 1280; + window.scaled_height = 720; + window.x = 200; + window.y = 150; window.should_close = false; window._initialized = false; window.clear_color.r = 0.392f; @@ -348,10 +348,10 @@ win32_init_window() { UpdateWindow(window._os_handle); ShowWindow(window._os_handle, SW_HIDE); - style = GetWindowLong(window._os_handle, GWL_EXSTYLE); - style &= ~WS_EX_APPWINDOW; // Remove from taskbar - style |= WS_EX_TOOLWINDOW; // Make it a tool window - SetWindowLong(window._os_handle, GWL_EXSTYLE, style); + //style = GetWindowLong(window._os_handle, GWL_EXSTYLE); + //style &= ~WS_EX_APPWINDOW; // Remove from taskbar + //style |= WS_EX_TOOLWINDOW; // Make it a tool window + //SetWindowLong(window._os_handle, GWL_EXSTYLE, style); } void @@ -1877,10 +1877,10 @@ void os_update() { // Only show window after first call to os_update if (!has_os_update_been_called_at_all) { ShowWindow(window._os_handle, SW_SHOW); - DWORD style = GetWindowLong(window._os_handle, GWL_EXSTYLE); - style &= ~WS_EX_TOOLWINDOW; - style |= WS_EX_APPWINDOW; - SetWindowLong(window._os_handle, GWL_EXSTYLE, style); + //DWORD style = GetWindowLong(window._os_handle, GWL_EXSTYLE); + //style &= ~(WS_EX_TOOLWINDOW); + //style |= WS_EX_APPWINDOW; + //SetWindowLong(window._os_handle, GWL_EXSTYLE, style); } has_os_update_been_called_at_all = true; diff --git a/oogabooga/utility.c b/oogabooga/utility.c index 4b89fc9..45f701e 100644 --- a/oogabooga/utility.c +++ b/oogabooga/utility.c @@ -99,4 +99,6 @@ void merge_sort(void *collection, void *help_buffer, u64 item_count, u64 item_si } } -inline bool bytes_match(void *a, void *b, u64 count) { return memcmp(a, b, count) == 0; } \ No newline at end of file +inline bool bytes_match(void *a, void *b, u64 count) { return memcmp(a, b, count) == 0; } + +#define swap(a, b, type) { type t = a; a = b; b = t; } \ No newline at end of file