From 44f637979c79a69fe71e708b5f654d276c066893 Mon Sep 17 00:00:00 2001 From: P. J. McDermott Date: Mon, 04 Mar 2013 04:30:31 -0500 Subject: Make palette cycling a real part of the engine. --- diff --git a/src/Makefile.am b/src/Makefile.am index 65ae0ab..25a3c12 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -9,4 +9,5 @@ src_SOURCES = \ src/compression.h src/compression.c \ src/viewport.h src/viewport.c \ src/area.h src/area.c \ + src/palettes.h src/palettes.c \ $(src_resources_SOURCES) diff --git a/src/main.c b/src/main.c index c0b26a4..abfbf8d 100644 --- a/src/main.c +++ b/src/main.c @@ -1,4 +1,3 @@ -#include #include #include "init.h" #include "logging.h" @@ -6,57 +5,7 @@ #include "resources/map.h" #include "viewport.h" #include "area.h" - -#define CYCLE_LINEAR(t_max, r1, g1, b1, r2, g2, b2) \ - do { \ - x = (double) t / (double) t_max; \ - y_end = (i % 8) * 36; \ - y_start = y_end * r1; \ - y_end = y_end * r2; \ - colors[i].r = x * (y_end - y_start) + y_start; \ - y_end = (i % 64 / 8) * 36; \ - y_start = y_end * g1; \ - y_end = y_end * g2; \ - colors[i].g = x * (y_end - y_start) + y_start; \ - y_end = (i / 64) * 85; \ - y_start = y_end * b1; \ - y_end = y_end * b2; \ - colors[i].b = x * (y_end - y_start) + y_start; \ - } while (0) -#define CYCLE_COS(t_max, r1, g1, b1, r2, g2, b2) \ - do { \ - /* \ - * t = t \ - * t_max = t_max \ - * x = (t / t_max) * π \ - * for y in {r, g, b}: \ - * m = y_end - y_start \ - * x = x \ - * b = y_start \ - * y = m * ((cos(x) / 2) + 0.5) + b \ - */ \ - /* \ - * cos(x) => [-1 .. 1] \ - * (cos(x)/2)+0.5 => [0 .. 1] \ - * y => [y_start .. y_end] \ - */ \ - x = (double) t / (double) t_max * 3.14159; \ - y_end = (i % 8) * 36; \ - y_start = y_end * r2; \ - y_end = y_end * r1; \ - colors[i].r = ((cos(x) / 2) + 0.5) * \ - (y_end - y_start) + y_start; \ - y_end = (i % 64 / 8) * 36; \ - y_start = y_end * g2; \ - y_end = y_end * g1; \ - colors[i].g = ((cos(x) / 2) + 0.5) * \ - (y_end - y_start) + y_start; \ - y_end = (i / 64) * 85; \ - y_start = y_end * b2; \ - y_end = y_end * b1; \ - colors[i].b = ((cos(x) / 2) + 0.5) * \ - (y_end - y_start) + y_start; \ - } while (0) +#include "palettes.h" #define DEMO() \ do { \ @@ -74,7 +23,7 @@ main(void) struct viewport *vp; struct map *map; struct area *a; - SDL_Color colors[256]; + SDL_Palette *pal; int i; struct map_exit *e; @@ -88,12 +37,9 @@ main(void) if (map == NULL) { err(1, "Where's the map, George?"); } - for (i = 0; i < 256; ++i) { - colors[i].r = (i % 8) * 36; - colors[i].g = (i % 64 / 8) * 36; - colors[i].b = (i / 64) * 85; - } - if (!SDL_SetPalette(vp->screen, SDL_LOGPAL, colors, 0, 256)) { + pal = map->palettes[MAP_PALETTE_DAY].palette->palette; + if (!SDL_SetPalette(vp->screen, SDL_LOGPAL, pal->colors, + 0, pal->ncolors)) { warn("Failed to set palette"); } a = area_new(map, vp); @@ -111,65 +57,84 @@ main(void) render_area_to_viewport(a, vp); { Uint32 d, t; - double x; - int y_start, y_end; + + pal = malloc(sizeof(*pal)); + pal->colors = calloc(58, sizeof(*pal->colors)); + pal->ncolors = 58; for (d = 0; d < 4; ++d) { + t = 0; + debug("Day %d morn", d); /* morn -> day */ - for (t = 0; t < 360; t += 1) { - for (i = 0; i < 256; ++i) { - CYCLE_COS(360, - 1.000, 0.875, 0.625, - 1.000, 1.000, 1.000 - ); + for (; t < 360; t += 1) { + if (cycle_palettes_cosine(t, 360, + map->palettes[MAP_PALETTE_MORN] + .palette->palette, + map->palettes[MAP_PALETTE_DAY] + .palette->palette, + pal) == NULL) { + warn("Failed to cycle palettes"); } if (!SDL_SetPalette(vp->screen, SDL_LOGPAL, - colors, 0, 256)) { + pal->colors, + 0, pal->ncolors)) { warn("Failed to set palette"); } SDL_Flip(vp->screen); SDL_Delay(10); } + debug("Day %d day", d); /* day -> eve */ - for (t = 0; t < 360; t += 1) { - for (i = 0; i < 256; ++i) { - CYCLE_COS(360, - 1.000, 1.000, 1.000, - 0.875, 0.625, 0.625 - ); + for (; t < 720; t += 1) { + if (cycle_palettes_cosine(t, 360, + map->palettes[MAP_PALETTE_DAY] + .palette->palette, + map->palettes[MAP_PALETTE_EVE] + .palette->palette, + pal) == NULL) { + warn("Failed to cycle palettes"); } if (!SDL_SetPalette(vp->screen, SDL_LOGPAL, - colors, 0, 256)) { + pal->colors, + 0, pal->ncolors)) { warn("Failed to set palette"); } SDL_Flip(vp->screen); SDL_Delay(10); } + debug("Day %d eve", d); /* eve -> night */ - for (t = 0; t < 360; t += 1) { - for (i = 0; i < 256; ++i) { - CYCLE_COS(360, - 0.875, 0.625, 0.625, - 0.250, 0.250, 0.500 - ); + for (; t < 1080; t += 1) { + if (cycle_palettes_cosine(t, 360, + map->palettes[MAP_PALETTE_EVE] + .palette->palette, + map->palettes[MAP_PALETTE_NIGHT] + .palette->palette, + pal) == NULL) { + warn("Failed to cycle palettes"); } if (!SDL_SetPalette(vp->screen, SDL_LOGPAL, - colors, 0, 256)) { + pal->colors, + 0, pal->ncolors)) { warn("Failed to set palette"); } SDL_Flip(vp->screen); SDL_Delay(10); } + debug("Day %d night", d); /* night -> morn */ - for (t = 0; t < 360; t += 1) { - for (i = 0; i < 256; ++i) { - CYCLE_COS(360, - 0.250, 0.250, 0.500, - 1.000, 0.875, 0.625 - ); + for (; t < 1440; t += 1) { + if (cycle_palettes_cosine(t, 360, + map->palettes[MAP_PALETTE_NIGHT] + .palette->palette, + map->palettes[MAP_PALETTE_MORN] + .palette->palette, + pal) == NULL) { + warn("Failed to cycle palettes"); } if (!SDL_SetPalette(vp->screen, SDL_LOGPAL, - colors, 0, 256)) { + pal->colors, + 0, pal->ncolors)) { warn("Failed to set palette"); } SDL_Flip(vp->screen); @@ -180,12 +145,9 @@ main(void) quit(0); /* Demo */ - for (i = 0; i < 256; ++i) { - colors[i].r = (i % 8) * 36; - colors[i].g = (i % 64 / 8) * 36; - colors[i].b = (i / 64) * 85; - } - if (!SDL_SetPalette(vp->screen, SDL_LOGPAL, colors, 0, 256)) { + pal = map->palettes[MAP_PALETTE_DAY].palette->palette; + if (!SDL_SetPalette(vp->screen, SDL_LOGPAL, pal->colors, + 0, pal->ncolors)) { warn("Failed to set palette"); } diff --git a/src/palettes.c b/src/palettes.c new file mode 100644 index 0000000..19a41bf --- /dev/null +++ b/src/palettes.c @@ -0,0 +1,109 @@ +#include +#include +#include "palettes.h" +#include "logging.h" + +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +static inline Uint8 cycle_palettes_cosine_channel(Uint8, Uint8, double); +static inline Uint8 cycle_palettes_linear_channel(Uint8, Uint8, double); + +SDL_Palette * +cycle_palettes_cosine(Uint32 t, Uint32 t_max, + SDL_Palette *pal_start, SDL_Palette *pal_end, + SDL_Palette *pal_step) +{ + double x; + int col_i; + + if (pal_start->ncolors != pal_end->ncolors) { + return NULL; + } + if (pal_start->ncolors != pal_step->ncolors) { + return NULL; + } + + x = (double) (t % t_max) / (double) t_max * M_PI; + + for (col_i = 0; col_i < pal_step->ncolors; ++col_i) { + pal_step->colors[col_i].r = cycle_palettes_cosine_channel( + pal_start->colors[col_i].r, + pal_end->colors[col_i].r, + x); + pal_step->colors[col_i].g = cycle_palettes_cosine_channel( + pal_start->colors[col_i].g, + pal_end->colors[col_i].g, + x); + pal_step->colors[col_i].b = cycle_palettes_cosine_channel( + pal_start->colors[col_i].b, + pal_end->colors[col_i].b, + x); + } + + return pal_step; +} + +SDL_Palette * +cycle_palettes_linear(Uint32 t, Uint32 t_max, + SDL_Palette *pal_start, SDL_Palette *pal_end, + SDL_Palette *pal_step) +{ + double x; + int col_i; + + if (pal_start->ncolors != pal_end->ncolors) { + return NULL; + } + if (pal_start->ncolors != pal_step->ncolors) { + return NULL; + } + + x = (double) (t % t_max) / (double) t_max; + + for (col_i = 0; col_i < pal_step->ncolors; ++col_i) { + pal_step->colors[col_i].r = cycle_palettes_linear_channel( + pal_start->colors[col_i].r, + pal_end->colors[col_i].r, + x); + pal_step->colors[col_i].g = cycle_palettes_linear_channel( + pal_start->colors[col_i].g, + pal_end->colors[col_i].g, + x); + pal_step->colors[col_i].b = cycle_palettes_linear_channel( + pal_start->colors[col_i].b, + pal_end->colors[col_i].b, + x); + } + + return pal_step; +} + +static inline Uint8 +cycle_palettes_cosine_channel(Uint8 y_start, Uint8 y_end, double x) +{ + double m; + Uint8 b; + Uint8 y; + + m = y_end - y_start; + b = y_start; + y = m * ((cos(x) / -2.0) + 0.5) + b; + + return y; +} + +static inline Uint8 +cycle_palettes_linear_channel(Uint8 y_start, Uint8 y_end, double x) +{ + double m; + Uint8 b; + Uint8 y; + + m = y_end - y_start; + b = y_start; + y = m * x + b; + + return y; +} diff --git a/src/palettes.h b/src/palettes.h new file mode 100644 index 0000000..c5f007a --- /dev/null +++ b/src/palettes.h @@ -0,0 +1,13 @@ +#ifndef PALETTES_H +#define PALETTES_H + +#include + +SDL_Palette *cycle_palettes_cosine(Uint32 t, Uint32 t_max, + SDL_Palette *pal_start, SDL_Palette *pal_end, + SDL_Palette *pal_step); +SDL_Palette *cycle_palettes_linear(Uint32 t, Uint32 t_max, + SDL_Palette *pal_start, SDL_Palette *pal_end, + SDL_Palette *pal_step); + +#endif -- cgit v0.9.1