summaryrefslogtreecommitdiff
path: root/src/modules/stars
diff options
context:
space:
mode:
Diffstat (limited to 'src/modules/stars')
-rw-r--r--src/modules/stars/Makefile.am4
-rw-r--r--src/modules/stars/draw.h32
-rw-r--r--src/modules/stars/stars.c63
-rw-r--r--src/modules/stars/stars.h8
-rw-r--r--src/modules/stars/starslib.c133
-rw-r--r--src/modules/stars/starslib.h19
6 files changed, 259 insertions, 0 deletions
diff --git a/src/modules/stars/Makefile.am b/src/modules/stars/Makefile.am
new file mode 100644
index 0000000..e709e85
--- /dev/null
+++ b/src/modules/stars/Makefile.am
@@ -0,0 +1,4 @@
+noinst_LIBRARIES = libstars.a
+libstars_a_SOURCES = draw.h stars.c stars.h starslib.c starslib.h
+libstars_a_CFLAGS = @ROTOTILLER_CFLAGS@
+libstars_a_CPPFLAGS = @ROTOTILLER_CFLAGS@ -I../../
diff --git a/src/modules/stars/draw.h b/src/modules/stars/draw.h
new file mode 100644
index 0000000..5010374
--- /dev/null
+++ b/src/modules/stars/draw.h
@@ -0,0 +1,32 @@
+#ifndef _DRAW_H
+#define _DRAW_H
+
+#include <stdint.h>
+
+#include "fb.h"
+
+/* helper for scaling rgb colors and packing them into an pixel */
+static inline uint32_t makergb(uint32_t r, uint32_t g, uint32_t b, float intensity)
+{
+ r = (((float)intensity) * r);
+ g = (((float)intensity) * g);
+ b = (((float)intensity) * b);
+
+ return (((r & 0xff) << 16) | ((g & 0xff) << 8) | (b & 0xff));
+}
+
+static inline int draw_pixel(fb_fragment_t *f, int x, int y, uint32_t pixel)
+{
+ uint32_t *pixels = f->buf;
+
+ if (y < 0 || y >= f->height || x < 0 || x >= f->width) {
+ return 0;
+ }
+
+ /* FIXME this assumes stride is aligned to 4 */
+ pixels[(y * (f->width + (f->stride >> 2))) + x] = pixel;
+
+ return 1;
+}
+
+#endif
diff --git a/src/modules/stars/stars.c b/src/modules/stars/stars.c
new file mode 100644
index 0000000..e009714
--- /dev/null
+++ b/src/modules/stars/stars.c
@@ -0,0 +1,63 @@
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <inttypes.h>
+#include <time.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "draw.h"
+#include "fb.h"
+#include "rototiller.h"
+#include "starslib.h"
+
+/* Copyright (C) 2017 Philip J. Freeman <elektron@halo.nu> */
+
+static void stars(fb_fragment_t *fragment)
+{
+ static int initialized, z;
+ static struct universe* u;
+
+ struct return_point rp;
+ int x, y, width = fragment->width, height = fragment->height;
+
+ if (!initialized) {
+ z = 128;
+ srand(time(NULL) + getpid());
+
+ // Initialize the stars lib (and pre-add a bunch of stars)
+ new_universe(&u, width, height, z);
+ for(y=0; y<z; y++) {
+ while (process_point(u, &rp) != 0);
+ for(x=0; x<rand()%128; x++){
+ new_point(u);
+ }
+ }
+ initialized = 1;
+ }
+
+ // draw space (or blank the frame, if you prefer)
+ memset(fragment->buf, 0, ((fragment->width << 2) + fragment->stride) * fragment->height);
+
+ // draw stars
+ for (;;) {
+ int ret = process_point( u, &rp );
+ if (ret==0) break;
+ if (ret==1) draw_pixel(fragment, rp.x+(width/2), rp.y+(height/2),
+ makergb(0xFF, 0xFF, 0xFF, (float)rp.opacity/OPACITY_MAX)
+ );
+ }
+
+ // add stars at horizon
+ for (x=0; x<rand()%128; x++) {
+ new_point(u);
+ }
+}
+
+rototiller_renderer_t stars_renderer = {
+ .render = stars,
+ .name = "stars",
+ .description = "basic starfield",
+ .author = "Philip J Freeman <elektron@halo.nu>",
+ .license = "GPLv2",
+};
diff --git a/src/modules/stars/stars.h b/src/modules/stars/stars.h
new file mode 100644
index 0000000..70ef6f2
--- /dev/null
+++ b/src/modules/stars/stars.h
@@ -0,0 +1,8 @@
+#ifndef _STARS_H
+#define _STARS_H
+
+#include "fb.h"
+
+void stars(fb_fragment_t *fragment);
+
+#endif
diff --git a/src/modules/stars/starslib.c b/src/modules/stars/starslib.c
new file mode 100644
index 0000000..9d43062
--- /dev/null
+++ b/src/modules/stars/starslib.c
@@ -0,0 +1,133 @@
+/*
+ * a starfield simulation library from: https://github.com/ph1l/stars
+ * Copyright 2014 Philip J. Freeman <elektron@halo.nu>
+ */
+
+#include <stdlib.h>
+#ifdef DEBUG
+#include <stdio.h>
+#endif
+#include "starslib.h"
+
+struct points
+{
+ int x, y, z;
+ struct points *next;
+};
+
+void new_universe( struct universe** u, int width, int height, int depth )
+{
+ *u = malloc(sizeof(struct universe));
+
+ (*u)->width = width;
+ (*u)->height = height;
+ (*u)->depth = depth;
+
+ (*u)->iterator = NULL;
+ (*u)->points = NULL;
+ #ifdef DEBUG
+ printf("NEW UNIVERSE: %lx: (%i,%i,%i)\n", (long unsigned int )(*u), (*u)->width, (*u)->height, (*u)->depth);
+ #endif
+
+ return;
+}
+
+void new_point( struct universe* u )
+{
+
+ struct points* p_ptr = malloc(sizeof(struct points));
+
+ p_ptr->x = (rand()%u->width - (u->width/2)) * u->depth;
+ p_ptr->y = (rand()%u->height - (u->height/2)) * u->depth;
+ p_ptr->z = u->depth;
+
+ p_ptr->next = u->points;
+ u->points = p_ptr;
+ #ifdef DEBUG
+ printf("NEW POINT: %lx: (%i,%i,%i) next=%lx\n", (long unsigned int )p_ptr, p_ptr->x, p_ptr->y, p_ptr->z, (long unsigned int) p_ptr->next);
+ #endif
+
+ return;
+}
+
+void kill_point( struct universe* universe, struct points* to_kill )
+{
+
+ struct points *p_ptr, *last_ptr = NULL;
+
+
+ for ( p_ptr = universe->points; p_ptr != NULL; p_ptr = p_ptr->next)
+ {
+ if (p_ptr == to_kill)
+ {
+ #ifdef DEBUG
+ printf("KILL POINT: %lx: (%i,%i,%i).\n", (long unsigned int )p_ptr, p_ptr->x, p_ptr->y, p_ptr->z);
+ #endif
+ if (last_ptr == NULL)
+ {
+ universe->points = p_ptr->next;
+ } else {
+ last_ptr->next = p_ptr->next;
+ }
+ free(p_ptr);
+ } else {
+ last_ptr = p_ptr;
+ }
+ }
+ #ifdef DEBUG
+ printf("KILL POINT: %lx\n", (long unsigned int )p_ptr);
+ #endif
+ return;
+}
+
+int process_point( struct universe *u, struct return_point *rp )
+{
+
+ if ( u->iterator == NULL ) {
+ if (u->points == NULL){
+ return 0;
+ } else {
+ u->iterator = u->points;
+ }
+ }
+
+ if ( u->iterator->z == 0 ){
+ // Delete point that has reached us.
+ struct points *tmp = u->iterator;
+ u->iterator = u->iterator->next;
+ kill_point( u, tmp );
+ return(-1);
+ } else {
+ // Plot the point
+ int x, y;
+ x = u->iterator->x / u->iterator->z;
+ y = u->iterator->y / u->iterator->z;
+ if ( abs(x) >= u->width/2 || abs(y) >= u->height/2 ){
+ // Delete point that is off screen
+ struct points *tmp = u->iterator;
+ u->iterator = u->iterator->next;
+ kill_point( u, tmp );
+ if ( u->iterator == NULL ) {
+ return(0);
+ } else {
+ return(-1);
+ }
+ } else {
+ int m = OPACITY_MAX*((u->depth-u->iterator->z)*4)/u->depth;
+ if ( m>OPACITY_MAX ){ m=OPACITY_MAX; }
+ u->iterator->z = u->iterator->z - 1;
+ #ifdef DEBUG
+ printf("RETURN POINT: %lx\n", (long unsigned int )u->iterator);
+ #endif
+ u->iterator = u->iterator->next;
+ rp->x = x;
+ rp->y = y;
+ rp->opacity = m;
+ if ( u->iterator == NULL ) {
+ return(0);
+ } else {
+ return(1);
+ }
+ }
+ }
+}
diff --git a/src/modules/stars/starslib.h b/src/modules/stars/starslib.h
new file mode 100644
index 0000000..0c125a3
--- /dev/null
+++ b/src/modules/stars/starslib.h
@@ -0,0 +1,19 @@
+struct universe
+{
+ int width, height, depth;
+ struct points* points;
+ struct points* iterator;
+};
+
+void new_universe( struct universe** u, int width, int height, int depth );
+void new_point( struct universe* universe );
+
+#define OPACITY_MAX 8
+struct return_point
+{
+ int x, y;
+ int opacity;
+};
+
+int process_point( struct universe *u, struct return_point *rp );
+
© All Rights Reserved