From: Matthew Mondor Date: Thu, 8 Jun 2023 10:49:35 +0000 (+0000) Subject: Import of 2021 KITT inspired effect prototype. X-Git-Url: http://git.pulsar-zone.net/?a=commitdiff_plain;h=49e4e5b640855fcaa928353e9d63b3a42577c9e1;p=mmondor.git Import of 2021 KITT inspired effect prototype. --- diff --git a/tests/sdl-kitt/GNUmakefile b/tests/sdl-kitt/GNUmakefile new file mode 100644 index 0000000..e9b0aba --- /dev/null +++ b/tests/sdl-kitt/GNUmakefile @@ -0,0 +1,38 @@ +# $Id: GNUmakefile,v 1.1 2011/03/10 13:17:33 mmondor Exp $ + +CC := cc +RM := rm +UNAME := uname + +CFLAGS += -Wall + +# Enable for verbosity/debugging +#CFLAGS += -v -H -g +#LDFLAGS += -v -g + +# And to disable assertions +#CFLAGS += -DNDEBUG + +OBJS := main.o +BIN := kitt + +SDL_CFLAGS := $(shell sdl-config --cflags) +SDL_LDFLAGS := $(shell sdl-config --libs) +SDL_LDFLAGS += -lSDL_gfx + +CFLAGS += -I/usr/include -I/usr/pkg/include +LDFLAGS += -Wl,-R/usr/lib -L/usr/lib -Wl,-R/usr/pkg/lib -L/usr/pkg/lib + +CFLAGS += $(SDL_CFLAGS) +LDFLAGS += $(SDL_LDFLAGS) + +all: $(BIN) + +%.o: %.c + $(CC) -c $(CFLAGS) -o $@ $< + +$(BIN): $(OBJS) + $(CC) -o $@ $(OBJS) $(LDFLAGS) + +clean: + $(RM) -f $(BIN) $(OBJS) diff --git a/tests/sdl-kitt/main.c b/tests/sdl-kitt/main.c new file mode 100644 index 0000000..3d11470 --- /dev/null +++ b/tests/sdl-kitt/main.c @@ -0,0 +1,333 @@ +/* + * SDL-based Knight-Rider Kitt style effect + * Prototype to port to AVR+TCL. For this reason levels are 0-4095. + * Copyright (c) 2021, Matthew Mondor + * + * Example usage: + * $ gmake (or make if your OS uses GNUMake) + * $ ./kitt + * $ ./kitt -n16 -w64 -h64 -p4 -T4 -t7 -d450 + * $ ./kitt -n16 -w92 -h48 -p4 -t3 -T4 -t8 -d255 -l 2048 -r 0 -g 0 -b 255 + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + + +#define SCREEN_DEPTH 32 + +#define FPS 60 /* 0 = unrestricted */ +#define SHOWFPS false +#define FULLSCREEN false + + +int main(int, char **); +void usage(void); + +static void err(const char *); +static void warn(const char *); +static bool screen_init(int, int); +static void screen_destroy(void); + +inline static uint8_t color_scale(uint8_t, int); +static void draw_screen(void); +static void modulate(void); +static void tlc(int, int); + + +static SDL_Surface *screen_surface = NULL; + +/* Used for frame rate delay */ +#if (FPS > 0) +static FPSmanager fpsm; +#endif + +/* Simulate set/getprogname(3) on GNU */ +static const char *progname = ""; + +/* Modulator state */ +static int *levels = NULL; +static int channel = 0; +static int direction = 1; + +/* Parameters */ +static int slots = 6, slot_width = 144, slot_height = 64; +static int color_r = 0xff, color_g = 0x20, color_b = 0x20; +static int bright_min = 1024, bright_max = 4095, tail = 4, head = 2, + dim = 896, spause = 8; + + +/* ARGSUSED */ +int +main(int argc, char **argv) +{ + int ch, i, skip; + + progname = strdup(argv[0]); + while ((ch = getopt(argc, argv, "?n:w:h:l:L:T:t:d:p:r:g:b:")) != -1) { + switch (ch) { + case 'n': + slots = atoi(optarg); + break; + case 'w': + slot_width = atoi(optarg); + break; + case 'h': + slot_height = atoi(optarg); + break; + case 'l': + bright_min = atoi(optarg); + break; + case 'L': + bright_max = atoi(optarg); + break; + case 'T': + head = atoi(optarg); + break; + case 't': + tail = atoi(optarg); + break; + case 'd': + dim = atoi(optarg); + break; + case 'p': + spause = atoi(optarg); + break; + case 'r': + color_r = atoi(optarg); + break; + case 'g': + color_g = atoi(optarg); + break; + case 'b': + color_b = atoi(optarg); + break; + case '?': /* FALLTHROUGH */ + default: + usage(); + } + } + argc -= optind; + argv += optind; + + if (!screen_init(slot_width * slots, slot_height)) + err("screen_init()"); + + /* Modulator initialization */ + if ((levels = malloc(sizeof(int) * slots)) == NULL) + err("malloc()"); + channel = slots / 2; + skip = spause; + for (i = 0; i < slots; i++) + tlc(i, bright_min); + + for (;;) { + SDL_Event ev; + + if (SDL_PollEvent(&ev)) { + switch (ev.type) { + case SDL_MOUSEBUTTONDOWN: + case SDL_KEYDOWN: + case SDL_QUIT: + goto end; + } + } + + draw_screen(); + if (--skip < 1) { + modulate(); + skip = spause; + } + } + +end: + if (levels != NULL) + free(levels); + + exit(EXIT_SUCCESS); +} + +void +usage(void) +{ + + (void) fprintf(stderr, + "Usage: %s [-n ] [-w ] [-h ] " + "[-L ] [-l ] [-T ] [-t ] " + "[-d ] [-r ] [-g ] [-b ] " + "[-p ]\n", progname); + exit(EXIT_FAILURE); +} + +static void +err(const char *str) +{ + + (void) fprintf(stderr, "%s\n", str); + exit(EXIT_FAILURE); +} + +static void +warn(const char *str) +{ + + (void) fprintf(stdout, "%s\n", str); +} + +static bool +screen_init(int width, int height) +{ + const SDL_VideoInfo *vi; + int screen_flags = 0; + + if (SDL_Init(SDL_INIT_VIDEO) == -1) + return false; + + if ((vi = SDL_GetVideoInfo()) == NULL) + return false; + screen_flags |= SDL_HWPALETTE | SDL_DOUBLEBUF; +#if (FULLSCREEN == true) + screen_flags |= SDL_FULLSCREEN; +#endif + if (vi->hw_available) + screen_flags |= SDL_HWSURFACE; + else { + warn("Note: Hardware surfaces not available."); + screen_flags |= SDL_SWSURFACE; + } + if (vi->blit_hw) + screen_flags |= SDL_HWACCEL; + else + warn("Note: Hardware blitting not available."); + + if ((screen_surface = SDL_SetVideoMode(width, height, + SCREEN_DEPTH, screen_flags)) == NULL) + return false; + + /* Initialize FPS delay */ +#if (FPS > 0) + SDL_initFramerate(&fpsm); + if (SDL_setFramerate(&fpsm, FPS) == -1) + return false; +#endif + + (void) atexit(screen_destroy); + return true; +} + +static void +screen_destroy(void) +{ + + SDL_Quit(); +} + +/* + * Level is 0-4095 vs color, 0-255 (16x) + */ +inline static uint8_t +color_scale(uint8_t col, int level) +{ + + if (level == 0) + return 0; + /* level / 4096 = ? / col */ + return (level * col / 4096); +} + +static void +draw_screen(void) +{ + int i; + SDL_Rect rect; + +#if (SHOWFPS == true) + static Uint32 fps_cnt = 0, fps = 0; +#endif + + rect.x = rect.y = 0; + rect.w = slot_width; + rect.h = slot_height; + for (i = 0; i < slots; i++, rect.x += slot_width) { + uint8_t r, g, b; + uint32_t c; + int l = levels[i]; + + /* Scale level */ + r = color_scale(color_r, l); + g = color_scale(color_g, l); + b = color_scale(color_b, l); + /* Compose RGB color */ + c = (((r << 16) & 0x00ff0000) | ((g << 8) & 0x0000ff00) | \ + (b & 0x000000ff)); + + (void)SDL_FillRect(screen_surface, &rect, c); + } + + (void)SDL_Flip(screen_surface); + + /* Delay as necessary to maintain frame rate */ +#if (FPS > 0) + SDL_framerateDelay(&fpsm); +#endif +#if (SHOWFPS == true) + /* Evaluate FPS */ + fps++; + { + Uint32 t = SDL_GetTicks(); + + if (t - fps_cnt >= 5000) { + float seconds = (t - fps_cnt) / 1000.0; + float fps2 = fps / seconds; + + printf("%d frames in %g seconds = %g FPS\n", + fps, seconds, fps2); + fps_cnt = t; + fps = 0; + } + } +#endif +} + +void +modulate(void) +{ + int i, c, b; + + for (i = 0; i < slots; i++) + tlc(i, bright_min); + + for (i = 0, b = bright_max, c = channel; + i < head; + i++, b -= dim, c += direction) + tlc(c, b); + for (i = 0, b = bright_max, c = channel; + i < tail; + i++, b -= dim, c -= direction) + tlc(c, b); + + c = channel + direction; + if (c < 0 || c == slots) + direction = -direction; + else + channel = c; +} + +void +tlc(int c, int l) +{ + if (c < 0 || c >= slots) + return; + assert(l >= 0 && l < 4096); + + levels[c] = l; +// printf("%02d = %04d\n", c, l); +}