From fe22fe089508be9cdad9847e89802bc2c0cffb6a Mon Sep 17 00:00:00 2001 From: DaniTheSkunk <> Date: Tue, 24 Jan 2023 11:45:52 +0000 Subject: [PATCH] added color mixing and gsa loop stacking --- examples/gsa_simple.c | 26 ++++++++++++++++++++++++-- include/color32.h | 5 +++++ include/gsa.h | 5 +++++ src/color32.c | 12 ++++++++++++ src/gsa.c | 35 ++++++++++++++++++++++++++++++++--- 5 files changed, 78 insertions(+), 5 deletions(-) diff --git a/examples/gsa_simple.c b/examples/gsa_simple.c index 1aa2f27..e850ad3 100644 --- a/examples/gsa_simple.c +++ b/examples/gsa_simple.c @@ -1,12 +1,26 @@ +#include "color32.h" #include "gamepad.h" #include "gsa_map.h" #include "gsa_text.h" #include -void init() { +sw_color32 pal[GSA_PALETTE_SIZE]; +void fade_palette(f32 amount) { + i32 i; + + for(i = 0; i < GSA_PALETTE_SIZE; ++i) { + palette[i] = sw_color32_mix(SW_COLOR32_BLACK, pal[i], amount); + } +} + +bool tick_fade_in(); + +void init() { i32 x, y; + gsa_copy_palette_to(pal); + for(y = 0; y < 11; ++y) { for(x = 0; x < 19; ++x) { maps[0].tiles[x][y] = 0x1000; @@ -28,10 +42,18 @@ void init() { maps[1].half_tile = true; font = 0x1010; gsa_write_text(1, 7, 3, "Game Skunk Advance!!! <3"); - gsa_map_clear(0); + gsa_run_loop(tick_fade_in); } void tick() { maps[0].scrollx -= input.x_dir; maps[0].scrolly -= input.y_dir; } + +bool tick_fade_in() { + static i32 t = 0; + + fade_palette(t / 60.f); + ++t; + return t <= 60; +} diff --git a/include/color32.h b/include/color32.h index de1fdf7..cb9c13e 100644 --- a/include/color32.h +++ b/include/color32.h @@ -5,6 +5,9 @@ typedef u32 sw_color32; +#define SW_COLOR32_BLACK 0xFF000000 +#define SW_COLOR32_WHITE 0xFFFFFFFF + sw_color32 sw_color32_from_rgb(u8 r, u8 g, u8 b); sw_color32 sw_color32_from_rgba(u8 r, u8 g, u8 b, u8 a); @@ -18,4 +21,6 @@ f32 sw_color32_get_gf(sw_color32 col); f32 sw_color32_get_bf(sw_color32 col); f32 sw_color32_get_af(sw_color32 col); +sw_color32 sw_color32_mix(sw_color32 a, sw_color32 b, f32 mix); + #endif /* GUARD_99E25E7F8183EF0D8D27390EBC173C04 */ diff --git a/include/gsa.h b/include/gsa.h index 7ed05e4..698910e 100644 --- a/include/gsa.h +++ b/include/gsa.h @@ -29,6 +29,7 @@ #include "window.h" #define MAX_SPRITES 256 +#define GSA_PALETTE_SIZE 256 struct gsa_sprite { u16 tile; @@ -37,8 +38,12 @@ struct gsa_sprite { extern struct gsa_sprite sprites[MAX_SPRITES]; extern struct sw_image8 *_gfx; +extern sw_color32 palette[GSA_PALETTE_SIZE]; int gsa_main(int argc, char *argv[]); +void gsa_copy_palette_to(sw_color32 *dst); +void gsa_copy_palette_from(sw_color32 *src); +void gsa_run_loop(bool (*loopfun)()); /* to be implemented in game */ diff --git a/src/color32.c b/src/color32.c index 05633bf..4de9ca9 100644 --- a/src/color32.c +++ b/src/color32.c @@ -39,3 +39,15 @@ f32 sw_color32_get_bf(sw_color32 col) { f32 sw_color32_get_af(sw_color32 col) { return (f32)sw_color32_get_a(col) / 255.f; } + +sw_color32 sw_color32_mix(sw_color32 a, sw_color32 b, f32 mix) { + f32 imix; + imix = 1.f - mix; + + return sw_color32_from_rgba( + sw_color32_get_r(a) * imix + sw_color32_get_r(b) * mix, + sw_color32_get_g(a) * imix + sw_color32_get_g(b) * mix, + sw_color32_get_b(a) * imix + sw_color32_get_b(b) * mix, + sw_color32_get_a(a) * imix + sw_color32_get_a(b) * mix + ); +} diff --git a/src/gsa.c b/src/gsa.c index 4c33a54..7f2a6bd 100644 --- a/src/gsa.c +++ b/src/gsa.c @@ -52,10 +52,15 @@ struct render_vert { static i32 next_render_vert; static struct render_vert render_verts[MAX_RENDER_VERTS * 4]; -static sw_color32 palette[256]; +sw_color32 palette[GSA_PALETTE_SIZE]; static f32 palette_gl[1024]; static u32 tex; +#define GSA_LOOP_STACK_SIZE 16 + +static bool (*loop_stack[GSA_LOOP_STACK_SIZE])(); +static i8 loop_stack_i; + int gsa_main(int argc, char *argv[]) { (void)argc; (void)argv; @@ -63,6 +68,9 @@ int gsa_main(int argc, char *argv[]) { sw_log("Initialising GameSkunkAdvance v0.0"); + memset(loop_stack, 0, sizeof(loop_stack)); + loop_stack_i = -1; + _win = sw_window_create(sw_vec2i(304, 176), "Game Skunk Advance v0.0"); program = sw_shaderprogram_create(vert_source, frag_source); @@ -70,7 +78,6 @@ int gsa_main(int argc, char *argv[]) { sw_log("GL_MAX_VERTEX_UNIFORM_COMPONENTS: %i", max_components); memcpy(palette, _gfx->palette, sizeof(_gfx->palette)); - sw_debug("%08X", _gfx->palette[1]); glGenTextures(1, &tex); glBindTexture(GL_TEXTURE_2D, tex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); @@ -122,6 +129,22 @@ int gsa_main(int argc, char *argv[]) { return 0; } +void gsa_copy_palette_to(sw_color32 *dst) { + memcpy(dst, palette, sizeof(palette)); +} + +void gsa_copy_palette_from(sw_color32 *src) { + memcpy(palette, src, sizeof(palette)); +} + +void gsa_run_loop(bool (*loopfun)()) { + ++loop_stack_i; + if(loop_stack_i >= GSA_LOOP_STACK_SIZE) { + sw_error("exceeded loop stack size"); + } + loop_stack[loop_stack_i] = loopfun; +} + static void add_render_vert(f32 x, f32 y, f32 tx, f32 ty) { render_verts[next_render_vert].x = x; render_verts[next_render_vert].y = y; @@ -169,7 +192,13 @@ void _gsa_tick() { _gsa_input_tick(); - tick(); + if(loop_stack_i == -1) { + tick(); + } else { + if(!loop_stack[loop_stack_i]()) { + --loop_stack_i; + } + } next_render_vert = 0;