diff --git a/src/credits.c b/src/credits.c index 6bb2b46b87..3cbef74bcc 100644 --- a/src/credits.c +++ b/src/credits.c @@ -211,7 +211,7 @@ static void credits_towerwall_draw(vec3 pos) { static void credits_init(void) { memset(&credits, 0, sizeof(credits)); - init_stage3d(&stage_3d_context); + init_stage3d(&stage_3d_context, 16); add_model(&stage_3d_context, credits_towerwall_draw, stage6_towerwall_pos); diff --git a/src/resource/resource.c b/src/resource/resource.c index 9988521afe..2142ac092f 100644 --- a/src/resource/resource.c +++ b/src/resource/resource.c @@ -553,7 +553,7 @@ void free_resources(bool all) { unload_resource(ires); free(c); - log_debug( + log_info( "Unloaded %s '%s' (%s)", type_name(type), name, diff --git a/src/stages/stage1.c b/src/stages/stage1.c index 90c93b1ea0..4fd4a44ed0 100644 --- a/src/stages/stage1.c +++ b/src/stages/stage1.c @@ -207,9 +207,9 @@ static void stage1_water_draw(vec3 pos) { r_state_pop(); } -static vec3 **stage1_bg_pos(vec3 p, float maxrange) { +static uint stage1_bg_pos(Stage3D *s3d, vec3 p, float maxrange) { vec3 q = {0,0,0}; - return single3dpos(p, INFINITY, q); + return single3dpos(s3d, p, INFINITY, q); } static void stage1_smoke_draw(vec3 pos) { @@ -233,10 +233,10 @@ static void stage1_smoke_draw(vec3 pos) { r_state_pop(); } -static vec3 **stage1_smoke_pos(vec3 p, float maxrange) { +static uint stage1_smoke_pos(Stage3D *s3d, vec3 p, float maxrange) { vec3 q = {0,0,-300}; vec3 r = {0,300,0}; - return linear3dpos(p, maxrange/2.0, q, r); + return linear3dpos(s3d, p, maxrange/2.0, q, r); } static bool stage1_fog(Framebuffer *fb) { @@ -309,7 +309,7 @@ static void stage1_waterplants_draw(vec3 pos) { } static void stage1_start(void) { - init_stage3d(&stage_3d_context); + init_stage3d(&stage_3d_context, 16); add_model(&stage_3d_context, stage1_water_draw, stage1_bg_pos); add_model(&stage_3d_context, stage1_waterplants_draw, stage1_smoke_pos); add_model(&stage_3d_context, stage1_smoke_draw, stage1_smoke_pos); diff --git a/src/stages/stage2.c b/src/stages/stage2.c index a742d8af02..03ad19796d 100644 --- a/src/stages/stage2.c +++ b/src/stages/stage2.c @@ -128,25 +128,25 @@ static void stage2_bg_ground_draw(vec3 pos) { r_mat_mode(MM_MODELVIEW); } -static vec3 **stage2_bg_pos(vec3 pos, float maxrange) { +static uint stage2_bg_pos(Stage3D *s3d, vec3 pos, float maxrange) { vec3 p = {0, 0, 0}; vec3 r = {0, 1000, 0}; - return linear3dpos(pos, maxrange, p, r); + return linear3dpos(s3d, pos, maxrange, p, r); } -static vec3 **stage2_bg_grass_pos(vec3 pos, float maxrange) { +static uint stage2_bg_grass_pos(Stage3D *s3d, vec3 pos, float maxrange) { vec3 p = {0, 0, 0}; vec3 r = {0, 2000, 0}; - return linear3dpos(pos, maxrange, p, r); + return linear3dpos(s3d, pos, maxrange, p, r); } -static vec3 **stage2_bg_grass_pos2(vec3 pos, float maxrange) { +static uint stage2_bg_grass_pos2(Stage3D *s3d, vec3 pos, float maxrange) { vec3 p = {0, 1234, 40}; vec3 r = {0, 2000, 0}; - return linear3dpos(pos, maxrange, p, r); + return linear3dpos(s3d, pos, maxrange, p, r); } static bool stage2_fog(Framebuffer *fb) { @@ -173,7 +173,7 @@ static bool stage2_bloom(Framebuffer *fb) { } static void stage2_start(void) { - init_stage3d(&stage_3d_context); + init_stage3d(&stage_3d_context, 16); stage_3d_context.cx[2] = 1000; stage_3d_context.cx[0] = -850; stage_3d_context.crot[0] = 60; diff --git a/src/stages/stage3.c b/src/stages/stage3.c index 3701d9bb69..2a55b6fc53 100644 --- a/src/stages/stage3.c +++ b/src/stages/stage3.c @@ -64,7 +64,7 @@ static struct { float tunnel_side; } stgstate; -static vec3 **stage3_bg_pos(vec3 pos, float maxrange) { +static uint stage3_bg_pos(Stage3D *s3d, vec3 pos, float maxrange) { //vec3 p = {100 * cos(global.frames / 52.0), 100, 50 * sin(global.frames / 50.0)}; vec3 p = { stgstate.tunnel_side * cos(global.frames / 52.0), @@ -73,7 +73,7 @@ static vec3 **stage3_bg_pos(vec3 pos, float maxrange) { }; vec3 r = {0, 3000, 0}; - return linear3dpos(pos, maxrange, p, r); + return linear3dpos(s3d, pos, maxrange, p, r); } static void stage3_bg_tunnel_draw(vec3 pos) { @@ -145,7 +145,7 @@ static bool stage3_glitch(Framebuffer *fb) { } static void stage3_start(void) { - init_stage3d(&stage_3d_context); + init_stage3d(&stage_3d_context, 16); stage_3d_context.cx[2] = -10; stage_3d_context.crot[0] = -95; diff --git a/src/stages/stage4.c b/src/stages/stage4.c index 7c9e6bd1d5..36d779d49e 100644 --- a/src/stages/stage4.c +++ b/src/stages/stage4.c @@ -85,20 +85,19 @@ static bool stage4_fog(Framebuffer *fb) { return true; } -static vec3 **stage4_fountain_pos(vec3 pos, float maxrange) { +static uint stage4_fountain_pos(Stage3D *s3d, vec3 pos, float maxrange) { vec3 p = {0, 400, 1500}; vec3 r = {0, 0, 3000}; - vec3 **list = linear3dpos(pos, maxrange, p, r); + uint num = linear3dpos(s3d, pos, maxrange, p, r); - int i; - - for(i = 0; list[i] != NULL; i++) { - if((*list[i])[2] > 0) - (*list[i])[2] = -9000; + for(uint i = 0; i < num; ++i) { + if(s3d->pos_buffer[i][2] > 0) { + s3d->pos_buffer[i][2] = -9000; + } } - return list; + return num; } static void stage4_fountain_draw(vec3 pos) { @@ -114,27 +113,9 @@ static void stage4_fountain_draw(vec3 pos) { r_mat_pop(); } -static vec3 **stage4_lake_pos(vec3 pos, float maxrange) { +static uint stage4_lake_pos(Stage3D *s3d, vec3 pos, float maxrange) { vec3 p = {0, 600, 0}; - vec3 d; - - int i; - - for(i = 0; i < 3; i++) - d[i] = p[i] - pos[i]; - - if(glm_vec3_norm(d) > maxrange) { - return NULL; - } else { - vec3 **list = calloc(2, sizeof(vec3*)); - - list[0] = malloc(sizeof(vec3)); - for(i = 0; i < 3; i++) - (*list[0])[i] = p[i]; - list[1] = NULL; - - return list; - } + return single3dpos(s3d, pos, maxrange, p); } static void stage4_lake_draw(vec3 pos) { @@ -153,20 +134,19 @@ static void stage4_lake_draw(vec3 pos) { r_mat_pop(); } -static vec3 **stage4_corridor_pos(vec3 pos, float maxrange) { +static uint stage4_corridor_pos(Stage3D *s3d, vec3 pos, float maxrange) { vec3 p = {0, 2400, 50}; vec3 r = {0, 2000, 0}; - vec3 **list = linear3dpos(pos, maxrange, p, r); - - int i; + uint num = linear3dpos(s3d, pos, maxrange, p, r); - for(i = 0; list[i] != NULL; i++) { - if((*list[i])[1] < p[1]) - (*list[i])[1] = -9000; + for(uint i = 0; i < num; ++i) { + if(s3d->pos_buffer[i][1] < p[1]) { + s3d->pos_buffer[i][1] = -9000; + } } - return list; + return num; } static void stage4_corridor_draw(vec3 pos) { @@ -229,7 +209,7 @@ static void stage4_corridor_draw(vec3 pos) { } static void stage4_start(void) { - init_stage3d(&stage_3d_context); + init_stage3d(&stage_3d_context, 16); stage_3d_context.cx[2] = -10000; stage_3d_context.cv[2] = 19.7; diff --git a/src/stages/stage5.c b/src/stages/stage5.c index 7e1bd3cc8a..a1de93d35c 100644 --- a/src/stages/stage5.c +++ b/src/stages/stage5.c @@ -59,11 +59,11 @@ struct { float rad; } stagedata; -static vec3 **stage5_stairs_pos(vec3 pos, float maxrange) { +static uint stage5_stairs_pos(Stage3D *s3d, vec3 pos, float maxrange) { vec3 p = {0, 0, 0}; vec3 r = {0, 0, 6000}; - return linear3dpos(pos, maxrange, p, r); + return linear3dpos(s3d, pos, maxrange, p, r); } static void stage5_stairs_draw(vec3 pos) { @@ -153,7 +153,7 @@ void iku_spell_bg(Boss *b, int t) { static void stage5_start(void) { memset(&stagedata, 0, sizeof(stagedata)); - init_stage3d(&stage_3d_context); + init_stage3d(&stage_3d_context, 16); add_model(&stage_3d_context, stage5_stairs_draw, stage5_stairs_pos); stage_3d_context.crot[0] = 60; diff --git a/src/stages/stage6.c b/src/stages/stage6.c index c7b6b84eb2..005fb56642 100644 --- a/src/stages/stage6.c +++ b/src/stages/stage6.c @@ -82,20 +82,19 @@ static float starpos[3*NUM_STARS]; Framebuffer *baryon_aux_fb; FBPair baryon_fbpair; -vec3 **stage6_towerwall_pos(vec3 pos, float maxrange) { +uint stage6_towerwall_pos(Stage3D *s3d, vec3 pos, float maxrange) { vec3 p = {0, 0, -220}; vec3 r = {0, 0, 300}; - vec3 **list = linear3dpos(pos, maxrange, p, r); + uint num = linear3dpos(s3d, pos, maxrange, p, r); - int i; - - for(i = 0; list[i] != NULL; i++) { - if((*list[i])[2] > 0) - (*list[i])[1] = -90000; + for(uint i = 0; i < num; ++i) { + if(s3d->pos_buffer[i][2] > 0) { + s3d->pos_buffer[i][1] = -90000; + } } - return list; + return num; } void stage6_towerwall_draw(vec3 pos) { @@ -111,10 +110,9 @@ void stage6_towerwall_draw(vec3 pos) { r_shader_standard(); } -static vec3 **stage6_towertop_pos(vec3 pos, float maxrange) { +static uint stage6_towertop_pos(Stage3D *s3d, vec3 pos, float maxrange) { vec3 p = {0, 0, 70}; - - return single3dpos(pos, maxrange, p); + return single3dpos(s3d, pos, maxrange, p); } static void stage6_towertop_draw(vec3 pos) { @@ -127,8 +125,8 @@ static void stage6_towertop_draw(vec3 pos) { r_mat_pop(); } -static vec3 **stage6_skysphere_pos(vec3 pos, float maxrange) { - return single3dpos(pos, maxrange, stage_3d_context.cx); +static uint stage6_skysphere_pos(Stage3D *s3d, vec3 pos, float maxrange) { + return single3dpos(s3d, pos, maxrange, s3d->cx); } static void stage6_skysphere_draw(vec3 pos) { @@ -216,7 +214,9 @@ void start_fall_over(void) { //troll } static void stage6_start(void) { - init_stage3d(&stage_3d_context); + // TODO: make this background slightly less horribly inefficient + + init_stage3d(&stage_3d_context, 128); fall_over = 0; add_model(&stage_3d_context, stage6_skysphere_draw, stage6_skysphere_pos); diff --git a/src/stages/stage6.h b/src/stages/stage6.h index f38d7b4ef8..3fef7e225b 100644 --- a/src/stages/stage6.h +++ b/src/stages/stage6.h @@ -62,7 +62,7 @@ extern Framebuffer *baryon_aux_fb; void start_fall_over(void); -vec3 **stage6_towerwall_pos(vec3 pos, float maxrange); +uint stage6_towerwall_pos(Stage3D *s3d, vec3 pos, float maxrange); void stage6_towerwall_draw(vec3 pos); #endif // IGUARD_stages_stage6_h diff --git a/src/stageutils.c b/src/stageutils.c index 112532e80b..3dbd469215 100644 --- a/src/stageutils.c +++ b/src/stageutils.c @@ -17,9 +17,11 @@ Stage3D stage_3d_context; -void init_stage3d(Stage3D *s) { +void init_stage3d(Stage3D *s, uint pos_buffer_size) { memset(s, 0, sizeof(Stage3D)); s->projangle = 45; + s->pos_buffer_size = pos_buffer_size; + s->pos_buffer = calloc(s->pos_buffer_size, sizeof(vec3)); } void add_model(Stage3D *s, SegmentDrawRule draw, SegmentPositionRule pos) { @@ -65,16 +67,12 @@ void draw_stage3d(Stage3D *s, float maxrange) { if(s->cx[0] || s->cx[1] || s->cx[2]) r_mat_translate(-s->cx[0],-s->cx[1],-s->cx[2]); - for(int i = 0; i < s->msize; i++) { - vec3 **list; - list = s->models[i].pos(s->cx, maxrange); + for(uint i = 0; i < s->msize; i++) { + uint num = s->models[i].pos(s, s->cx, maxrange); - for(int j = 0; list && list[j] != NULL; j++) { - s->models[i].draw(*list[j]); - free(list[j]); + for(uint j = 0; j < num; ++j) { + s->models[i].draw(s->pos_buffer[j]); } - - free(list); } r_mat_pop(); @@ -82,34 +80,35 @@ void draw_stage3d(Stage3D *s, float maxrange) { void free_stage3d(Stage3D *s) { free(s->models); + free(s->pos_buffer); } -vec3 **linear3dpos(vec3 q, float maxrange, vec3 p, vec3 r) { - int i; +uint linear3dpos(Stage3D *s3d, vec3 q, float maxrange, vec3 p, vec3 r) { float n = 0, z = 0; - for(i = 0; i < 3; i++) { + + for(uint i = 0; i < 3; i++) { n += q[i]*r[i] - p[i]*r[i]; z += r[i]*r[i]; } float t = n/z; - - vec3 **list = NULL; - int size = 0; int mod = 1; - int num = t; - while(1) { + uint size = 0; + + while(size < s3d->pos_buffer_size) { vec3 dif; - for(i = 0; i < 3; i++) + for(uint i = 0; i < 3; i++) { dif[i] = q[i] - p[i] - r[i]*num; + } if(glm_vec3_norm(dif) < maxrange) { - list = realloc(list, (++size)*sizeof(vec3*)); - list[size-1] = malloc(sizeof(vec3)); - for(i = 0; i < 3; i++) - (*list[size-1])[i] = p[i] + r[i]*num; + for(uint i = 0; i < 3; i++) { + s3d->pos_buffer[size][i] = p[i] + r[i]*num; + } + + ++size; } else if(mod == 1) { mod = -1; num = t; @@ -120,31 +119,22 @@ vec3 **linear3dpos(vec3 q, float maxrange, vec3 p, vec3 r) { num += mod; } - list = realloc(list, (++size)*sizeof(vec3*)); - list[size-1] = NULL; - - return list; + return size; } -vec3 **single3dpos(vec3 q, float maxrange, vec3 p) { +uint single3dpos(Stage3D *s3d, vec3 q, float maxrange, vec3 p) { + assume(s3d->pos_buffer_size > 0); vec3 d; - int i; - - for(i = 0; i < 3; i++) + for(uint i = 0; i < 3; i++) { d[i] = p[i] - q[i]; + } if(glm_vec3_norm(d) > maxrange) { - return NULL; + return 0; } else { - vec3 **list = calloc(2, sizeof(vec3*)); - - list[0] = malloc(sizeof(vec3)); - for(i = 0; i < 3; i++) - (*list[0])[i] = p[i]; - list[1] = NULL; - - return list; + memcpy(s3d->pos_buffer, p, sizeof(vec3)); + return 1; } } diff --git a/src/stageutils.h b/src/stageutils.h index 026de8ff63..50ea2d5222 100644 --- a/src/stageutils.h +++ b/src/stageutils.h @@ -14,20 +14,23 @@ #include "util.h" typedef struct StageSegment StageSegment; +typedef struct Stage3D Stage3D; typedef void (*SegmentDrawRule)(vec3 pos); -typedef vec3 **(*SegmentPositionRule)(vec3 q, float maxrange); // returns NULL-terminated array +typedef uint (*SegmentPositionRule)(Stage3D *s3d, vec3 q, float maxrange); // returns number of elements written to Stage3D pos_buffer struct StageSegment { SegmentDrawRule draw; SegmentPositionRule pos; }; -typedef struct Stage3D Stage3D; struct Stage3D { StageSegment *models; int msize; + vec3 *pos_buffer; + uint pos_buffer_size; + // Camera vec3 cx; // x vec3 cv; // x' @@ -39,7 +42,7 @@ struct Stage3D { extern Stage3D stage_3d_context; -void init_stage3d(Stage3D *s); +void init_stage3d(Stage3D *s, uint pos_buffer_size); void add_model(Stage3D *s, SegmentDrawRule draw, SegmentPositionRule pos); @@ -50,9 +53,8 @@ void update_stage3d(Stage3D *s); void free_stage3d(Stage3D *s); -vec3 **linear3dpos(vec3 q, float maxrange, vec3 p, vec3 r); - -vec3 **single3dpos(vec3 q, float maxrange, vec3 p); +uint linear3dpos(Stage3D *s3d, vec3 q, float maxrange, vec3 p, vec3 r); +uint single3dpos(Stage3D *s3d, vec3 q, float maxrange, vec3 p); void skip_background_anim(void (*update_func)(void), int frames, int *timer, int *timer2);