summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorP. J. McDermott <pjm@nac.net>2013-03-04 04:30:31 (EST)
committer P. J. McDermott <pjm@nac.net>2013-03-04 04:30:31 (EST)
commit44f637979c79a69fe71e708b5f654d276c066893 (patch)
treed5cd7625d8be28e62bb14e1b0166d6bd0c6d4012 /src
parentf9e339b9345b90621e6c2a585033ce20b3837570 (diff)
downloadoverworld-rpg-44f637979c79a69fe71e708b5f654d276c066893.zip
overworld-rpg-44f637979c79a69fe71e708b5f654d276c066893.tar.gz
overworld-rpg-44f637979c79a69fe71e708b5f654d276c066893.tar.bz2
Make palette cycling a real part of the engine.
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am1
-rw-r--r--src/main.c152
-rw-r--r--src/palettes.c109
-rw-r--r--src/palettes.h13
4 files changed, 180 insertions, 95 deletions
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 <math.h>
#include <SDL.h>
#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 <math.h>
+#include <SDL.h>
+#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.h>
+
+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