From 792d0a60dd05035435574633c4a13a666fe6ce5d Mon Sep 17 00:00:00 2001 From: Philip J Freeman Date: Tue, 21 Jan 2020 20:01:56 -0800 Subject: stars: mess with the starfield This commit adds some fun features to the starfield: - normalize aspect ratio to fragment size - rolling viewport - rotating viewport (with rate option) --- src/modules/stars/stars.c | 98 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 88 insertions(+), 10 deletions(-) (limited to 'src/modules/stars/stars.c') diff --git a/src/modules/stars/stars.c b/src/modules/stars/stars.c index bf7678a..df5dc3a 100644 --- a/src/modules/stars/stars.c +++ b/src/modules/stars/stars.c @@ -10,8 +10,13 @@ #include "draw.h" #include "fb.h" #include "rototiller.h" +#include "settings.h" -/* Copyright (C) 2017-19 Philip J. Freeman */ +/* Copyright (C) 2017-20 Philip J. Freeman */ + +#define DEFAULT_ROT_ADJ .00003f + +static float stars_rot_adj = DEFAULT_ROT_ADJ; struct points { @@ -19,9 +24,14 @@ struct points struct points *next; }; - typedef struct stars_context_t { struct points* points; + float rot_adj; + float rot_rate; + float rot_angle; + float offset_x; + float offset_y; + float offset_angle; } stars_context_t; @@ -41,6 +51,12 @@ static void * stars_create_context(unsigned num_cpus) return NULL; ctxt->points = NULL; + ctxt->rot_adj = stars_rot_adj; + ctxt->rot_rate = 0.00; + ctxt->rot_angle = 0; + ctxt->offset_x = 0.5; + ctxt->offset_y = 0; + ctxt->offset_angle = 0.01; //add a bunch of points for(z=0.01; z<1; z=z+0.01) { @@ -84,11 +100,18 @@ static void stars_render_fragment(void *context, unsigned cpu, fb_fragment_t *fr struct points* iterator; struct points* tmp_ptr; struct points* last_ptr=NULL; - float x, y, pos_x, pos_y, opacity; + float x, y, pos_x, pos_y, rot_x, rot_y, opacity, x_mult, y_mult, max_radius; int width = fragment->width, height = fragment->height; + if(width>height) { + x_mult=1.f; + y_mult=(float)width/(float)height; + } else { + x_mult=(float)height/(float)width; + y_mult=1.f; + } - float max_radius=1.f+((width+height)*.001f); + max_radius=1.f+((width+height)*.001f); fb_fragment_zero(fragment); @@ -109,11 +132,14 @@ static void stars_render_fragment(void *context, unsigned cpu, fb_fragment_t *fr continue; } - x = iterator->x / (1.f - iterator->z); - y = iterator->y / (1.f - iterator->z); + x = (iterator->x / (1.f - iterator->z))*x_mult; + y = (iterator->y / (1.f - iterator->z))*y_mult; + + rot_x = (x*cosf(ctxt->rot_angle))-(y*sinf(ctxt->rot_angle)); + rot_y = (x*sinf(ctxt->rot_angle))+(y*cosf(ctxt->rot_angle)); - pos_x = ((x+1.f)*.5f)*(float)width; - pos_y = ((y+1.f)*.5f)*(float)height; + pos_x = ((rot_x+ctxt->offset_x+1.f)*.5f)*(float)width; + pos_y = ((rot_y+ctxt->offset_y+1.f)*.5f)*(float)height; if(iterator->z<0.1) opacity = iterator->z*10; @@ -124,8 +150,8 @@ static void stars_render_fragment(void *context, unsigned cpu, fb_fragment_t *fr fb_fragment_put_pixel_unchecked(fragment, pos_x, pos_y, makergb(0xFF, 0xFF, 0xFF, opacity)); - for(int my_y=floorf(pos_y-max_radius); my_y<=ceilf(pos_y+max_radius); my_y++) - for(int my_x=floorf(pos_x-max_radius); my_x<=ceilf(pos_x+max_radius); my_x++) { + for(int my_y=floorf(pos_y-max_radius); my_y<=(int)ceilf(pos_y+max_radius); my_y++) + for(int my_x=floorf(pos_x-max_radius); my_x<=(int)ceilf(pos_x+max_radius); my_x++) { //Is the point within our viewing window? if (!(my_x>0 && my_x0 && my_ynext = ctxt->points; ctxt->points = tmp_ptr; } + + // handle rotation parameters + if(ctxt->rot_angle>M_PI_4) + ctxt->rot_rate=ctxt->rot_rate-ctxt->rot_adj; + else + ctxt->rot_rate=ctxt->rot_rate+ctxt->rot_adj; + ctxt->rot_angle=ctxt->rot_angle+ctxt->rot_rate; + + // handle offset parameters + float tmp_x = (ctxt->offset_x*cosf(ctxt->offset_angle))- + (ctxt->offset_y*sinf(ctxt->offset_angle)); + float tmp_y = (ctxt->offset_x*sinf(ctxt->offset_angle))+ + (ctxt->offset_y*cosf(ctxt->offset_angle)); + ctxt->offset_x = tmp_x; + ctxt->offset_y = tmp_y; +} + +int stars_setup(const settings_t *settings, setting_desc_t **next_setting) +{ + const char *rot_adj; + const char *rot_adj_values[] = { + ".0f", + ".00001f", + ".00003f", + ".0001f", + ".0003f", + ".001f", + NULL + }; + + rot_adj = settings_get_value(settings, "rot_adj"); + if(!rot_adj) { + int ret_val; + + ret_val = setting_desc_clone(&(setting_desc_t){ + .name = "Rotation Rate", + .key = "rot_adj", + .regex = "\\.[0-9]+", + .preferred = SETTINGS_STR(DEFAULT_ROT_ADJ), + .values = rot_adj_values, + .annotations = NULL + }, next_setting); + if(ret_val<0) + return ret_val; + + return 1; + } + + sscanf(rot_adj, "%f", &stars_rot_adj); + + return 0; } rototiller_module_t stars_module = { .create_context = stars_create_context, .destroy_context = stars_destroy_context, .render_fragment = stars_render_fragment, + .setup = stars_setup, .name = "stars", .description = "Basic starfield", .author = "Philip J Freeman ", -- cgit v1.2.1