From c72e431b1ea784b12b94936aa5a2de8203fcb24f Mon Sep 17 00:00:00 2001 From: parasti Date: Thu, 10 Feb 2011 18:59:50 +0000 Subject: [PATCH] Split SOL data structures into base, varying and rendering parts git-svn-id: https://s.snth.net/svn/neverball/trunk@3485 78b8d119-cf0a-0410-b17c-f493084dd1d7 --- Makefile | 12 +- ball/demo.c | 1 - ball/game_client.c | 203 ++++++------ ball/game_client.h | 2 - ball/game_common.c | 22 +- ball/game_common.h | 4 +- ball/game_draw.c | 238 +++++++------- ball/game_draw.h | 6 +- ball/game_server.c | 66 ++-- ball/game_server.h | 3 - ball/level.c | 21 +- ball/st_demo.c | 1 - putt/game.c | 116 +++---- share/ball.c | 57 ++-- share/geom.c | 1 - share/geom.h | 4 - share/item.c | 35 +- share/item.h | 6 +- share/mapc.c | 300 +++++++++--------- share/solid.c | 646 ------------------------------------- share/solid.h | 343 -------------------- share/solid_all.c | 155 ++++----- share/solid_all.h | 29 +- share/solid_base.c | 635 +++++++++++++++++++++++++++++++++++++ share/solid_base.h | 329 +++++++++++++++++++ share/solid_draw.c | 841 +++++++++++++++++++++++++++++++++++++++++++++++++ share/solid_draw.h | 83 +++++ share/solid_gl.c | 758 -------------------------------------------- share/solid_gl.h | 35 -- share/solid_sim.h | 10 +- share/solid_sim_sol.c | 137 ++++---- share/solid_vary.c | 137 ++++++++ share/solid_vary.h | 96 ++++++ 33 files changed, 2834 insertions(+), 2498 deletions(-) delete mode 100644 share/solid.c delete mode 100644 share/solid.h create mode 100644 share/solid_base.c create mode 100644 share/solid_base.h create mode 100644 share/solid_draw.c create mode 100644 share/solid_draw.h delete mode 100644 share/solid_gl.c delete mode 100644 share/solid_gl.h create mode 100644 share/solid_vary.c create mode 100644 share/solid_vary.h diff --git a/Makefile b/Makefile index 3579a60..169b9f8 100644 --- a/Makefile +++ b/Makefile @@ -166,7 +166,7 @@ endif MAPC_OBJS := \ share/vec3.o \ share/base_image.o \ - share/solid.o \ + share/solid_base.o \ share/binary.o \ share/base_config.o \ share/common.o \ @@ -183,8 +183,9 @@ BALL_OBJS := \ share/vec3.o \ share/base_image.o \ share/image.o \ - share/solid.o \ - share/solid_gl.o \ + share/solid_base.o \ + share/solid_vary.o \ + share/solid_draw.o \ share/solid_cmd.o \ share/solid_all.o \ share/part.o \ @@ -252,8 +253,9 @@ PUTT_OBJS := \ share/vec3.o \ share/base_image.o \ share/image.o \ - share/solid.o \ - share/solid_gl.o \ + share/solid_base.o \ + share/solid_vary.o \ + share/solid_draw.o \ share/solid_cmd.o \ share/solid_all.o \ share/part.o \ diff --git a/ball/demo.c b/ball/demo.c index 9f18cd0..b843e56 100644 --- a/ball/demo.c +++ b/ball/demo.c @@ -20,7 +20,6 @@ #include "demo.h" #include "audio.h" -#include "solid.h" #include "config.h" #include "binary.h" #include "common.h" diff --git a/ball/game_client.c b/ball/game_client.c index 0a53260..631d95b 100644 --- a/ball/game_client.c +++ b/ball/game_client.c @@ -25,10 +25,11 @@ #include "ball.h" #include "image.h" #include "audio.h" -#include "solid_gl.h" #include "config.h" #include "video.h" +#include "solid_draw.h" + #include "game_client.h" #include "game_common.h" #include "game_proxy.h" @@ -42,7 +43,7 @@ int game_compat_map; /* Client/server map compat flag */ /*---------------------------------------------------------------------------*/ -static struct game_draw dr; +static struct game_draw gd; static float timer = 0.0f; /* Clock time */ static int status = GAME_NONE; /* Outcome of the game */ @@ -70,11 +71,11 @@ static int got_tilt_axes; static void game_run_cmd(const union cmd *cmd) { - if (dr.state) + if (gd.state) { - struct s_file *fp = &dr.file; - struct s_item *hp; - struct s_ball *up; + struct s_vary *vary = &gd.file.vary; + struct v_item *hp; + struct v_ball *up; float v[3]; float dt; @@ -95,9 +96,9 @@ static void game_run_cmd(const union cmd *cmd) /* Compute gravity for particle effects. */ if (status == GAME_GOAL) - game_tilt_grav(v, GRAVITY_UP, &dr.tilt); + game_tilt_grav(v, GRAVITY_UP, &gd.tilt); else - game_tilt_grav(v, GRAVITY_DN, &dr.tilt); + game_tilt_grav(v, GRAVITY_DN, &gd.tilt); /* Step particle, goal and jump effects. */ @@ -105,15 +106,15 @@ static void game_run_cmd(const union cmd *cmd) { dt = 1.0f / (float) ups; - if (dr.goal_e && dr.goal_k < 1.0f) - dr.goal_k += dt; + if (gd.goal_e && gd.goal_k < 1.0f) + gd.goal_k += dt; - if (dr.jump_b) + if (gd.jump_b) { - dr.jump_dt += dt; + gd.jump_dt += dt; - if (1.0f < dr.jump_dt) - dr.jump_b = 0; + if (1.0f < gd.jump_dt) + gd.jump_b = 0; } part_step(v, dt); @@ -124,29 +125,29 @@ static void game_run_cmd(const union cmd *cmd) case CMD_MAKE_BALL: /* Allocate a new ball and mark it as the current ball. */ - if ((up = realloc(fp->uv, sizeof (*up) * (fp->uc + 1)))) + if ((up = realloc(vary->uv, sizeof (*up) * (vary->uc + 1)))) { - fp->uv = up; - curr_ball = fp->uc; - fp->uc++; + vary->uv = up; + curr_ball = vary->uc; + vary->uc++; } break; case CMD_MAKE_ITEM: /* Allocate and initialise a new item. */ - if ((hp = realloc(fp->hv, sizeof (*hp) * (fp->hc + 1)))) + if ((hp = realloc(vary->hv, sizeof (*hp) * (vary->hc + 1)))) { - struct s_item h; + struct v_item h; v_cpy(h.p, cmd->mkitem.p); h.t = cmd->mkitem.t; h.n = cmd->mkitem.n; - fp->hv = hp; - fp->hv[fp->hc] = h; - fp->hc++; + vary->hv = hp; + vary->hv[vary->hc] = h; + vary->hc++; } break; @@ -154,9 +155,9 @@ static void game_run_cmd(const union cmd *cmd) case CMD_PICK_ITEM: /* Set up particle effects and discard the item. */ - assert(cmd->pkitem.hi < fp->hc); + assert(cmd->pkitem.hi < vary->hc); - hp = fp->hv + cmd->pkitem.hi; + hp = vary->hv + cmd->pkitem.hi; item_color(hp, v); part_burst(hp->p, v); @@ -167,10 +168,10 @@ static void game_run_cmd(const union cmd *cmd) case CMD_TILT_ANGLES: if (!got_tilt_axes) - game_tilt_axes(&dr.tilt, dr.view.e); + game_tilt_axes(&gd.tilt, gd.view.e); - dr.tilt.rx = cmd->tiltangles.x; - dr.tilt.rz = cmd->tiltangles.z; + gd.tilt.rx = cmd->tiltangles.x; + gd.tilt.rz = cmd->tiltangles.z; break; case CMD_SOUND: @@ -194,21 +195,21 @@ static void game_run_cmd(const union cmd *cmd) break; case CMD_JUMP_ENTER: - dr.jump_b = 1; - dr.jump_e = 0; - dr.jump_dt = 0.0f; + gd.jump_b = 1; + gd.jump_e = 0; + gd.jump_dt = 0.0f; break; case CMD_JUMP_EXIT: - dr.jump_e = 1; + gd.jump_e = 1; break; case CMD_BODY_PATH: - fp->bv[cmd->bodypath.bi].pi = cmd->bodypath.pi; + vary->bv[cmd->bodypath.bi].pi = cmd->bodypath.pi; break; case CMD_BODY_TIME: - fp->bv[cmd->bodytime.bi].t = cmd->bodytime.t; + vary->bv[cmd->bodytime.bi].t = cmd->bodytime.t; break; case CMD_GOAL_OPEN: @@ -217,23 +218,23 @@ static void game_run_cmd(const union cmd *cmd) * this is the first update. */ - if (!dr.goal_e) + if (!gd.goal_e) { - dr.goal_e = 1; - dr.goal_k = first_update ? 1.0f : 0.0f; + gd.goal_e = 1; + gd.goal_k = first_update ? 1.0f : 0.0f; } break; case CMD_SWCH_ENTER: - fp->xv[cmd->swchenter.xi].e = 1; + vary->xv[cmd->swchenter.xi].e = 1; break; case CMD_SWCH_TOGGLE: - fp->xv[cmd->swchtoggle.xi].f = !fp->xv[cmd->swchtoggle.xi].f; + vary->xv[cmd->swchtoggle.xi].f = !vary->xv[cmd->swchtoggle.xi].f; break; case CMD_SWCH_EXIT: - fp->xv[cmd->swchexit.xi].e = 0; + vary->xv[cmd->swchexit.xi].e = 0; break; case CMD_UPDATES_PER_SECOND: @@ -241,35 +242,35 @@ static void game_run_cmd(const union cmd *cmd) break; case CMD_BALL_RADIUS: - fp->uv[curr_ball].r = cmd->ballradius.r; + vary->uv[curr_ball].r = cmd->ballradius.r; break; case CMD_CLEAR_ITEMS: - if (fp->hv) + if (vary->hv) { - free(fp->hv); - fp->hv = NULL; + free(vary->hv); + vary->hv = NULL; } - fp->hc = 0; + vary->hc = 0; break; case CMD_CLEAR_BALLS: - if (fp->uv) + if (vary->uv) { - free(fp->uv); - fp->uv = NULL; + free(vary->uv); + vary->uv = NULL; } - fp->uc = 0; + vary->uc = 0; break; case CMD_BALL_POSITION: - up = fp->uv + curr_ball; + up = vary->uv + curr_ball; v_cpy(up->p, cmd->ballpos.p); break; case CMD_BALL_BASIS: - up = fp->uv + curr_ball; + up = vary->uv + curr_ball; v_cpy(up->e[0], cmd->ballbasis.e[0]); v_cpy(up->e[1], cmd->ballbasis.e[1]); @@ -277,7 +278,7 @@ static void game_run_cmd(const union cmd *cmd) break; case CMD_BALL_PEND_BASIS: - up = fp->uv + curr_ball; + up = vary->uv + curr_ball; v_cpy(up->E[0], cmd->ballpendbasis.E[0]); v_cpy(up->E[1], cmd->ballpendbasis.E[1]); @@ -285,17 +286,17 @@ static void game_run_cmd(const union cmd *cmd) break; case CMD_VIEW_POSITION: - v_cpy(dr.view.p, cmd->viewpos.p); + v_cpy(gd.view.p, cmd->viewpos.p); break; case CMD_VIEW_CENTER: - v_cpy(dr.view.c, cmd->viewcenter.c); + v_cpy(gd.view.c, cmd->viewcenter.c); break; case CMD_VIEW_BASIS: - v_cpy(dr.view.e[0], cmd->viewbasis.e[0]); - v_cpy(dr.view.e[1], cmd->viewbasis.e[1]); - v_crs(dr.view.e[2], dr.view.e[0], dr.view.e[1]); + v_cpy(gd.view.e[0], cmd->viewbasis.e[0]); + v_cpy(gd.view.e[1], cmd->viewbasis.e[1]); + v_crs(gd.view.e[2], gd.view.e[0], gd.view.e[1]); break; case CMD_CURRENT_BALL: @@ -303,7 +304,7 @@ static void game_run_cmd(const union cmd *cmd) break; case CMD_PATH_FLAG: - fp->pv[cmd->pathflag.pi].f = cmd->pathflag.f; + vary->pv[cmd->pathflag.pi].f = cmd->pathflag.f; break; case CMD_STEP_SIMULATION: @@ -321,10 +322,10 @@ static void game_run_cmd(const union cmd *cmd) dt = cmd->stepsim.dt; - for (i = 0; i < fp->bc; i++) + for (i = 0; i < vary->bc; i++) { - struct s_body *bp = fp->bv + i; - struct s_path *pp = fp->pv + bp->pi; + struct v_body *bp = vary->bv + i; + struct v_path *pp = vary->pv + bp->pi; if (bp->pi >= 0 && pp->f) bp->t += dt; @@ -342,8 +343,8 @@ static void game_run_cmd(const union cmd *cmd) case CMD_TILT_AXES: got_tilt_axes = 1; - v_cpy(dr.tilt.x, cmd->tiltaxes.x); - v_cpy(dr.tilt.z, cmd->tiltaxes.z); + v_cpy(gd.tilt.x, cmd->tiltaxes.x); + v_cpy(gd.tilt.z, cmd->tiltaxes.z); break; case CMD_NONE: @@ -377,39 +378,39 @@ int game_client_init(const char *file_name) coins = 0; status = GAME_NONE; - if (dr.state) + if (gd.state) game_client_free(); - if (!sol_load_gl(&dr.file, file_name, config_get_d(CONFIG_SHADOW))) - return (dr.state = 0); + if (!sol_load_full(&gd.file, file_name, config_get_d(CONFIG_SHADOW))) + return (gd.state = 0); - dr.reflective = sol_reflective(&dr.file); + gd.reflective = sol_reflective(&gd.file.draw); - dr.state = 1; + gd.state = 1; - game_tilt_init(&dr.tilt); + game_tilt_init(&gd.tilt); /* Initialize jump and goal states. */ - dr.jump_e = 1; - dr.jump_b = 0; + gd.jump_e = 1; + gd.jump_b = 0; - dr.goal_e = 0; - dr.goal_k = 0.0f; + gd.goal_e = 0; + gd.goal_k = 0.0f; /* Initialise the level, background, particles, fade, and view. */ - dr.fade_k = 1.0f; - dr.fade_d = -2.0f; + gd.fade_k = 1.0f; + gd.fade_d = -2.0f; version.x = 0; version.y = 0; - for (i = 0; i < dr.file.dc; i++) + for (i = 0; i < gd.file.base.dc; i++) { - char *k = dr.file.av + dr.file.dv[i].ai; - char *v = dr.file.av + dr.file.dv[i].aj; + char *k = gd.file.base.av + gd.file.base.dv[i].ai; + char *v = gd.file.base.av + gd.file.base.dv[i].aj; if (strcmp(k, "back") == 0) back_name = v; if (strcmp(k, "grad") == 0) grad_name = v; @@ -433,28 +434,28 @@ int game_client_init(const char *file_name) first_update = 1; back_init(grad_name); - sol_load_gl(&dr.back, back_name, 0); + sol_load_full(&gd.back, back_name, 0); - return dr.state; + return gd.state; } void game_client_free(void) { - if (dr.state) + if (gd.state) { game_proxy_clr(); - sol_free_gl(&dr.file); - sol_free_gl(&dr.back); + sol_free_full(&gd.file); + sol_free_full(&gd.back); back_free(); } - dr.state = 0; + gd.state = 0; } /*---------------------------------------------------------------------------*/ void game_client_draw(int pose, float t) { - game_draw(&dr, pose, t); + game_draw(&gd, pose, t); } /*---------------------------------------------------------------------------*/ @@ -479,47 +480,47 @@ int curr_status(void) void game_look(float phi, float theta) { - dr.view.c[0] = dr.view.p[0] + fsinf(V_RAD(theta)) * fcosf(V_RAD(phi)); - dr.view.c[1] = dr.view.p[1] + fsinf(V_RAD(phi)); - dr.view.c[2] = dr.view.p[2] - fcosf(V_RAD(theta)) * fcosf(V_RAD(phi)); + gd.view.c[0] = gd.view.p[0] + fsinf(V_RAD(theta)) * fcosf(V_RAD(phi)); + gd.view.c[1] = gd.view.p[1] + fsinf(V_RAD(phi)); + gd.view.c[2] = gd.view.p[2] - fcosf(V_RAD(theta)) * fcosf(V_RAD(phi)); } /*---------------------------------------------------------------------------*/ void game_kill_fade(void) { - dr.fade_k = 0.0f; - dr.fade_d = 0.0f; + gd.fade_k = 0.0f; + gd.fade_d = 0.0f; } void game_step_fade(float dt) { - if ((dr.fade_k < 1.0f && dr.fade_d > 0.0f) || - (dr.fade_k > 0.0f && dr.fade_d < 0.0f)) - dr.fade_k += dr.fade_d * dt; + if ((gd.fade_k < 1.0f && gd.fade_d > 0.0f) || + (gd.fade_k > 0.0f && gd.fade_d < 0.0f)) + gd.fade_k += gd.fade_d * dt; - if (dr.fade_k < 0.0f) + if (gd.fade_k < 0.0f) { - dr.fade_k = 0.0f; - dr.fade_d = 0.0f; + gd.fade_k = 0.0f; + gd.fade_d = 0.0f; } - if (dr.fade_k > 1.0f) + if (gd.fade_k > 1.0f) { - dr.fade_k = 1.0f; - dr.fade_d = 0.0f; + gd.fade_k = 1.0f; + gd.fade_d = 0.0f; } } void game_fade(float d) { - dr.fade_d = d; + gd.fade_d = d; } /*---------------------------------------------------------------------------*/ void game_client_fly(float k) { - game_view_fly(&dr.view, &dr.file, k); + game_view_fly(&gd.view, &gd.file.vary, k); } /*---------------------------------------------------------------------------*/ diff --git a/ball/game_client.h b/ball/game_client.h index b3c64a9..4e28b18 100644 --- a/ball/game_client.h +++ b/ball/game_client.h @@ -1,8 +1,6 @@ #ifndef GAME_CLIENT_H #define GAME_CLIENT_H -#include -#include "solid.h" #include "fs.h" /*---------------------------------------------------------------------------*/ diff --git a/ball/game_common.c b/ball/game_common.c index 7675609..5788d73 100644 --- a/ball/game_common.c +++ b/ball/game_common.c @@ -15,7 +15,7 @@ #include "game_common.h" #include "vec3.h" #include "config.h" -#include "solid.h" +#include "solid_vary.h" /*---------------------------------------------------------------------------*/ @@ -113,7 +113,7 @@ void game_view_init(struct game_view *view) view->e[2][2] = 1.0f; } -void game_view_fly(struct game_view *view, const struct s_file *fp, float k) +void game_view_fly(struct game_view *view, const struct s_vary *vary, float k) { /* float x[3] = { 1.f, 0.f, 0.f }; */ float y[3] = { 0.f, 1.f, 0.f }; @@ -128,10 +128,10 @@ void game_view_fly(struct game_view *view, const struct s_file *fp, float k) /* k = 0.0 view is at the ball. */ - if (fp->uc > 0) + if (vary->uc > 0) { - v_cpy(c0, fp->uv[0].p); - v_cpy(p0, fp->uv[0].p); + v_cpy(c0, vary->uv[0].p); + v_cpy(p0, vary->uv[0].p); } v_mad(p0, p0, y, view->dp); @@ -140,18 +140,18 @@ void game_view_fly(struct game_view *view, const struct s_file *fp, float k) /* k = +1.0 view is s_view 0 */ - if (k >= 0 && fp->wc > 0) + if (k >= 0 && vary->base->wc > 0) { - v_cpy(p1, fp->wv[0].p); - v_cpy(c1, fp->wv[0].q); + v_cpy(p1, vary->base->wv[0].p); + v_cpy(c1, vary->base->wv[0].q); } /* k = -1.0 view is s_view 1 */ - if (k <= 0 && fp->wc > 1) + if (k <= 0 && vary->base->wc > 1) { - v_cpy(p1, fp->wv[1].p); - v_cpy(c1, fp->wv[1].q); + v_cpy(p1, vary->base->wv[1].p); + v_cpy(c1, vary->base->wv[1].q); } /* Interpolate the views. */ diff --git a/ball/game_common.h b/ball/game_common.h index 103d0e8..f958b1e 100644 --- a/ball/game_common.h +++ b/ball/game_common.h @@ -2,7 +2,7 @@ #define GAME_COMMON_H #include "lang.h" -#include "solid.h" +#include "solid_vary.h" /*---------------------------------------------------------------------------*/ @@ -89,7 +89,7 @@ struct game_view }; void game_view_init(struct game_view *); -void game_view_fly(struct game_view *, const struct s_file *, float); +void game_view_fly(struct game_view *, const struct s_vary *, float); /*---------------------------------------------------------------------------*/ diff --git a/ball/game_draw.c b/ball/game_draw.c index 7f00267..f3d8384 100644 --- a/ball/game_draw.c +++ b/ball/game_draw.c @@ -12,23 +12,23 @@ * General Public License for more details. */ -#include "solid.h" #include "vec3.h" #include "glext.h" #include "ball.h" #include "item.h" #include "part.h" #include "geom.h" -#include "solid_gl.h" #include "config.h" #include "back.h" #include "video.h" +#include "solid_draw.h" + #include "game_draw.h" /*---------------------------------------------------------------------------*/ -static void game_draw_balls(const struct s_file *fp, +static void game_draw_balls(const struct s_vary *vary, const float *bill_M, float t) { float c[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; @@ -36,18 +36,18 @@ static void game_draw_balls(const struct s_file *fp, float ball_M[16]; float pend_M[16]; - m_basis(ball_M, fp->uv[0].e[0], fp->uv[0].e[1], fp->uv[0].e[2]); - m_basis(pend_M, fp->uv[0].E[0], fp->uv[0].E[1], fp->uv[0].E[2]); + m_basis(ball_M, vary->uv[0].e[0], vary->uv[0].e[1], vary->uv[0].e[2]); + m_basis(pend_M, vary->uv[0].E[0], vary->uv[0].E[1], vary->uv[0].E[2]); glPushAttrib(GL_LIGHTING_BIT); glPushMatrix(); { - glTranslatef(fp->uv[0].p[0], - fp->uv[0].p[1] + BALL_FUDGE, - fp->uv[0].p[2]); - glScalef(fp->uv[0].r, - fp->uv[0].r, - fp->uv[0].r); + glTranslatef(vary->uv[0].p[0], + vary->uv[0].p[1] + BALL_FUDGE, + vary->uv[0].p[2]); + glScalef(vary->uv[0].r, + vary->uv[0].r, + vary->uv[0].r); glColor4fv(c); ball_draw(ball_M, pend_M, bill_M, t); @@ -56,7 +56,7 @@ static void game_draw_balls(const struct s_file *fp, glPopAttrib(); } -static void game_draw_items(const struct s_file *fp, float t) +static void game_draw_items(const struct s_vary *vary, float t) { float r = 360.f * t; int hi; @@ -65,17 +65,17 @@ static void game_draw_items(const struct s_file *fp, float t) { item_push(ITEM_COIN); { - for (hi = 0; hi < fp->hc; hi++) + for (hi = 0; hi < vary->hc; hi++) - if (fp->hv[hi].t == ITEM_COIN && fp->hv[hi].n > 0) + if (vary->hv[hi].t == ITEM_COIN && vary->hv[hi].n > 0) { glPushMatrix(); { - glTranslatef(fp->hv[hi].p[0], - fp->hv[hi].p[1], - fp->hv[hi].p[2]); + glTranslatef(vary->hv[hi].p[0], + vary->hv[hi].p[1], + vary->hv[hi].p[2]); glRotatef(r, 0.0f, 1.0f, 0.0f); - item_draw(&fp->hv[hi], r); + item_draw(&vary->hv[hi], r); } glPopMatrix(); } @@ -84,17 +84,17 @@ static void game_draw_items(const struct s_file *fp, float t) item_push(ITEM_SHRINK); { - for (hi = 0; hi < fp->hc; hi++) + for (hi = 0; hi < vary->hc; hi++) - if (fp->hv[hi].t == ITEM_SHRINK) + if (vary->hv[hi].t == ITEM_SHRINK) { glPushMatrix(); { - glTranslatef(fp->hv[hi].p[0], - fp->hv[hi].p[1], - fp->hv[hi].p[2]); + glTranslatef(vary->hv[hi].p[0], + vary->hv[hi].p[1], + vary->hv[hi].p[2]); glRotatef(r, 0.0f, 1.0f, 0.0f); - item_draw(&fp->hv[hi], r); + item_draw(&vary->hv[hi], r); } glPopMatrix(); } @@ -103,17 +103,17 @@ static void game_draw_items(const struct s_file *fp, float t) item_push(ITEM_GROW); { - for (hi = 0; hi < fp->hc; hi++) + for (hi = 0; hi < vary->hc; hi++) - if (fp->hv[hi].t == ITEM_GROW) + if (vary->hv[hi].t == ITEM_GROW) { glPushMatrix(); { - glTranslatef(fp->hv[hi].p[0], - fp->hv[hi].p[1], - fp->hv[hi].p[2]); + glTranslatef(vary->hv[hi].p[0], + vary->hv[hi].p[1], + vary->hv[hi].p[2]); glRotatef(r, 0.0f, 1.0f, 0.0f); - item_draw(&fp->hv[hi], r); + item_draw(&vary->hv[hi], r); } glPopMatrix(); } @@ -123,11 +123,12 @@ static void game_draw_items(const struct s_file *fp, float t) glPopAttrib(); } -static void game_draw_goals(const struct game_draw *dr, - const struct s_file *fp, +static void game_draw_goals(const struct game_draw *gd, const float *M, float t) { - if (dr->goal_e) + const struct s_base *base = &gd->file.base; + + if (gd->goal_e) { int zi; @@ -135,15 +136,15 @@ static void game_draw_goals(const struct game_draw *dr, glEnable(GL_TEXTURE_2D); { - for (zi = 0; zi < fp->zc; zi++) + for (zi = 0; zi < base->zc; zi++) { glPushMatrix(); { - glTranslatef(fp->zv[zi].p[0], - fp->zv[zi].p[1], - fp->zv[zi].p[2]); + glTranslatef(base->zv[zi].p[0], + base->zv[zi].p[1], + base->zv[zi].p[2]); - part_draw_goal(M, fp->zv[zi].r, dr->goal_k, t); + part_draw_goal(M, base->zv[zi].r, gd->goal_k, t); } glPopMatrix(); } @@ -152,17 +153,17 @@ static void game_draw_goals(const struct game_draw *dr, /* Draw the goal column. */ - for (zi = 0; zi < fp->zc; zi++) + for (zi = 0; zi < base->zc; zi++) { glPushMatrix(); { - glTranslatef(fp->zv[zi].p[0], - fp->zv[zi].p[1], - fp->zv[zi].p[2]); + glTranslatef(base->zv[zi].p[0], + base->zv[zi].p[1], + base->zv[zi].p[2]); - glScalef(fp->zv[zi].r, - dr->goal_k, - fp->zv[zi].r); + glScalef(base->zv[zi].r, + gd->goal_k, + base->zv[zi].r); goal_draw(); } @@ -171,65 +172,68 @@ static void game_draw_goals(const struct game_draw *dr, } } -static void game_draw_jumps(const struct game_draw *dr, - const struct s_file *fp, +static void game_draw_jumps(const struct game_draw *gd, const float *M, float t) { + const struct s_base *base = &gd->file.base; + int ji; glEnable(GL_TEXTURE_2D); { - for (ji = 0; ji < fp->jc; ji++) + for (ji = 0; ji < base->jc; ji++) { glPushMatrix(); { - glTranslatef(fp->jv[ji].p[0], - fp->jv[ji].p[1], - fp->jv[ji].p[2]); + glTranslatef(base->jv[ji].p[0], + base->jv[ji].p[1], + base->jv[ji].p[2]); - part_draw_jump(M, fp->jv[ji].r, 1.0f, t); + part_draw_jump(M, base->jv[ji].r, 1.0f, t); } glPopMatrix(); } } glDisable(GL_TEXTURE_2D); - for (ji = 0; ji < fp->jc; ji++) + for (ji = 0; ji < base->jc; ji++) { glPushMatrix(); { - glTranslatef(fp->jv[ji].p[0], - fp->jv[ji].p[1], - fp->jv[ji].p[2]); - glScalef(fp->jv[ji].r, + glTranslatef(base->jv[ji].p[0], + base->jv[ji].p[1], + base->jv[ji].p[2]); + glScalef(base->jv[ji].r, 1.0f, - fp->jv[ji].r); + base->jv[ji].r); - jump_draw(!dr->jump_e); + jump_draw(!gd->jump_e); } glPopMatrix(); } } -static void game_draw_swchs(const struct s_file *fp) +static void game_draw_swchs(const struct s_vary *vary) { int xi; - for (xi = 0; xi < fp->xc; xi++) + for (xi = 0; xi < vary->xc; xi++) { - if (fp->xv[xi].i) + struct v_swch *xp = vary->xv + xi; + + if (xp->base->i) continue; glPushMatrix(); { - glTranslatef(fp->xv[xi].p[0], - fp->xv[xi].p[1], - fp->xv[xi].p[2]); - glScalef(fp->xv[xi].r, + glTranslatef(xp->base->p[0], + xp->base->p[1], + xp->base->p[2]); + glScalef(xp->base->r, 1.0f, - fp->xv[xi].r); + xp->base->r); - swch_draw(fp->xv[xi].f, fp->xv[xi].e); + swch_draw(xp->f, xp->e); } glPopMatrix(); } @@ -237,10 +241,10 @@ static void game_draw_swchs(const struct s_file *fp) /*---------------------------------------------------------------------------*/ -static void game_draw_tilt(const struct game_draw *dr, int d) +static void game_draw_tilt(const struct game_draw *gd, int d) { - const struct game_tilt *tilt = &dr->tilt; - const float *ball_p = dr->file.uv->p; + const struct game_tilt *tilt = &gd->tilt; + const float *ball_p = gd->file.vary.uv[0].p; /* Rotate the environment about the position of the ball. */ @@ -250,15 +254,15 @@ static void game_draw_tilt(const struct game_draw *dr, int d) glTranslatef(-ball_p[0], -ball_p[1] * d, -ball_p[2]); } -static void game_refl_all(const struct game_draw *dr) +static void game_refl_all(const struct game_draw *gd) { glPushMatrix(); { - game_draw_tilt(dr, 1); + game_draw_tilt(gd, 1); /* Draw the floor. */ - sol_refl(&dr->file); + sol_refl(&gd->file.draw); } glPopMatrix(); } @@ -289,30 +293,32 @@ static void game_draw_light(void) glLightfv(GL_LIGHT1, GL_SPECULAR, light_c[1]); } -static void game_draw_back(const struct game_draw *dr, int pose, int d, float t) +static void game_draw_back(const struct game_draw *gd, int pose, int d, float t) { if (pose == POSE_BALL) return; glPushMatrix(); { + const struct game_view *view = &gd->view; + if (d < 0) { - const struct game_tilt *tilt = &dr->tilt; + const struct game_tilt *tilt = &gd->tilt; glRotatef(tilt->rz * 2, tilt->z[0], tilt->z[1], tilt->z[2]); glRotatef(tilt->rx * 2, tilt->x[0], tilt->x[1], tilt->x[2]); } - glTranslatef(dr->view.p[0], dr->view.p[1] * d, dr->view.p[2]); + glTranslatef(view->p[0], view->p[1] * d, view->p[2]); if (config_get_d(CONFIG_BACKGROUND)) { /* Draw all background layers back to front. */ - sol_back(&dr->back, BACK_DIST, FAR_DIST, t); + sol_back(&gd->back.draw, BACK_DIST, FAR_DIST, t); back_draw(0); - sol_back(&dr->back, 0, BACK_DIST, t); + sol_back(&gd->back.draw, 0, BACK_DIST, t); } else back_draw(0); } @@ -333,7 +339,7 @@ static void game_clip_refl(int d) glClipPlane(GL_CLIP_PLANE0, e); } -static void game_clip_ball(const struct game_draw *dr, int d, const float *p) +static void game_clip_ball(const struct game_draw *gd, int d, const float *p) { GLdouble r, c[3], pz[4], nz[4]; @@ -343,9 +349,9 @@ static void game_clip_ball(const struct game_draw *dr, int d, const float *p) c[1] = p[1] * d; c[2] = p[2]; - pz[0] = dr->view.p[0] - c[0]; - pz[1] = dr->view.p[1] - c[1]; - pz[2] = dr->view.p[2] - c[2]; + pz[0] = gd->view.p[0] - c[0]; + pz[1] = gd->view.p[1] - c[1]; + pz[2] = gd->view.p[2] - c[2]; r = sqrt(pz[0] * pz[0] + pz[1] * pz[1] + pz[2] * pz[2]); @@ -372,25 +378,25 @@ static void game_clip_ball(const struct game_draw *dr, int d, const float *p) glClipPlane(GL_CLIP_PLANE2, pz); } -static void game_draw_fore(const struct game_draw *dr, +static void game_draw_fore(const struct game_draw *gd, int pose, const float *M, int d, float t) { - const float *ball_p = dr->file.uv->p; - const float ball_r = dr->file.uv->r; + const float *ball_p = gd->file.vary.uv[0].p; + const float ball_r = gd->file.vary.uv[0].r; - const struct s_file *fp = &dr->file; + const struct s_draw *draw = &gd->file.draw; glPushMatrix(); { /* Rotate the environment about the position of the ball. */ - game_draw_tilt(dr, d); + game_draw_tilt(gd, d); /* Compute clipping planes for reflection and ball facing. */ game_clip_refl(d); - game_clip_ball(dr, d, ball_p); + game_clip_ball(gd, d, ball_p); if (d < 0) glEnable(GL_CLIP_PLANE0); @@ -398,17 +404,17 @@ static void game_draw_fore(const struct game_draw *dr, switch (pose) { case POSE_LEVEL: - sol_draw(fp, 0, 1); + sol_draw(draw, 0, 1); break; case POSE_NONE: /* Draw the coins. */ - game_draw_items(fp, t); + game_draw_items(draw->vary, t); /* Draw the floor. */ - sol_draw(fp, 0, 1); + sol_draw(draw, 0, 1); /* Fall through. */ @@ -419,13 +425,13 @@ static void game_draw_fore(const struct game_draw *dr, if (d > 0 && config_get_d(CONFIG_SHADOW)) { shad_draw_set(ball_p, ball_r); - sol_shad(fp); + sol_shad(draw); shad_draw_clr(); } /* Draw the ball. */ - game_draw_balls(fp, M, t); + game_draw_balls(draw->vary, M, t); break; } @@ -438,14 +444,14 @@ static void game_draw_fore(const struct game_draw *dr, { glColor3f(1.0f, 1.0f, 1.0f); - sol_bill(fp, M, t); + sol_bill(draw, M, t); part_draw_coin(M, t); glDisable(GL_TEXTURE_2D); { - game_draw_goals(dr, fp, M, t); - game_draw_jumps(dr, fp, M, t); - game_draw_swchs(fp); + game_draw_goals(gd, M, t); + game_draw_jumps(gd, M, t); + game_draw_swchs(draw->vary); } glEnable(GL_TEXTURE_2D); @@ -463,15 +469,15 @@ static void game_draw_fore(const struct game_draw *dr, /*---------------------------------------------------------------------------*/ -void game_draw(const struct game_draw *dr, int pose, float t) +void game_draw(const struct game_draw *gd, int pose, float t) { float fov = (float) config_get_d(CONFIG_VIEW_FOV); - if (dr->jump_b) fov *= 2.f * fabsf(dr->jump_dt - 0.5); + if (gd->jump_b) fov *= 2.f * fabsf(gd->jump_dt - 0.5); - if (dr->state) + if (gd->state) { - const struct game_view *view = &dr->view; + const struct game_view *view = &gd->view; video_push_persp(fov, 0.1f, FAR_DIST); glPushMatrix(); @@ -498,7 +504,7 @@ void game_draw(const struct game_draw *dr, int pose, float t) glMultMatrixf(M); glTranslatef(-view->c[0], -view->c[1], -view->c[2]); - if (dr->reflective && config_get_d(CONFIG_REFLECTION)) + if (gd->reflective && config_get_d(CONFIG_REFLECTION)) { glEnable(GL_STENCIL_TEST); { @@ -509,7 +515,7 @@ void game_draw(const struct game_draw *dr, int pose, float t) glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); glDepthMask(GL_FALSE); - game_refl_all(dr); + game_refl_all(gd); glDepthMask(GL_TRUE); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); @@ -524,8 +530,8 @@ void game_draw(const struct game_draw *dr, int pose, float t) glScalef(+1.0f, -1.0f, +1.0f); game_draw_light(); - game_draw_back(dr, pose, -1, t); - game_draw_fore(dr, pose, U, -1, t); + game_draw_back(gd, pose, -1, t); + game_draw_fore(gd, pose, U, -1, t); } glPopMatrix(); glFrontFace(GL_CCW); @@ -537,7 +543,7 @@ void game_draw(const struct game_draw *dr, int pose, float t) game_draw_light(); - if (dr->reflective) + if (gd->reflective) { if (config_get_d(CONFIG_REFLECTION)) { @@ -546,19 +552,19 @@ void game_draw(const struct game_draw *dr, int pose, float t) glEnable(GL_STENCIL_TEST); { glStencilFunc(GL_NOTEQUAL, 1, 0xFFFFFFFF); - game_draw_back(dr, pose, +1, t); + game_draw_back(gd, pose, +1, t); } glDisable(GL_STENCIL_TEST); /* Draw mirrors. */ - game_refl_all(dr); + game_refl_all(gd); } else { /* Draw background. */ - game_draw_back(dr, pose, +1, t); + game_draw_back(gd, pose, +1, t); /* * Draw mirrors, first fully opaque with a custom @@ -571,28 +577,28 @@ void game_draw(const struct game_draw *dr, int pose, float t) glEnable(GL_COLOR_MATERIAL); { glColor4f(0.0, 0.0, 0.05, 1.0); - game_refl_all(dr); + game_refl_all(gd); glColor4f(1.0, 1.0, 1.0, 1.0); } glDisable(GL_COLOR_MATERIAL); - game_refl_all(dr); + game_refl_all(gd); } } else { - game_draw_back(dr, pose, +1, t); - game_refl_all(dr); + game_draw_back(gd, pose, +1, t); + game_refl_all(gd); } - game_draw_fore(dr, pose, T, +1, t); + game_draw_fore(gd, pose, T, +1, t); } glPopMatrix(); video_pop_matrix(); /* Draw the fade overlay. */ - fade_draw(dr->fade_k); + fade_draw(gd->fade_k); } } diff --git a/ball/game_draw.h b/ball/game_draw.h index bb4930d..5228e1a 100644 --- a/ball/game_draw.h +++ b/ball/game_draw.h @@ -1,15 +1,15 @@ #ifndef GAME_DRAW_H #define GAME_DRAW_H -#include "solid.h" +#include "solid_draw.h" #include "game_common.h" struct game_draw { int state; - struct s_file file; - struct s_file back; + struct s_full file; + struct s_full back; int reflective; /* Reflective geometry used? */ diff --git a/ball/game_server.c b/ball/game_server.c index 8fa65fe..0d7b1ab 100644 --- a/ball/game_server.c +++ b/ball/game_server.c @@ -36,7 +36,8 @@ static int server_state = 0; -static struct s_file file; +static struct s_base base; +static struct s_vary file; static float timer = 0.f; /* Clock time */ static int timer_down = 1; /* Timer go up or down? */ @@ -322,11 +323,11 @@ static int got_orig = 0; /* Do we know original ball size? */ static int grow_state = 0; /* Current state (values -1, 0, +1) */ -static void grow_init(const struct s_file *fp, int type) +static void grow_init(const struct s_vary *vary, int type) { if (!got_orig) { - grow_orig = fp->uv->r; + grow_orig = vary->uv->r; grow_goal = grow_orig; grow_strt = grow_orig; @@ -383,11 +384,11 @@ static void grow_init(const struct s_file *fp, int type) if (grow) { grow_t = 0.0; - grow_strt = fp->uv->r; + grow_strt = vary->uv->r; } } -static void grow_step(const struct s_file *fp, float dt) +static void grow_step(const struct s_vary *vary, float dt) { float dr; @@ -408,8 +409,8 @@ static void grow_step(const struct s_file *fp, float dt) /* No sinking through the floor! Keeps ball's bottom constant. */ - fp->uv->p[1] += (dr - fp->uv->r); - fp->uv->r = dr; + vary->uv->p[1] += (dr - vary->uv->r); + vary->uv->r = dr; game_cmd_ballradius(); } @@ -435,7 +436,10 @@ int game_server_init(const char *file_name, int t, int e) if (server_state) game_server_free(); - if (!sol_load_only_file(&file, file_name)) + if (!sol_load_base(&base, file_name)) + return (server_state = 0); + + if (!sol_load_vary(&file, &base)) return (server_state = 0); server_state = 1; @@ -443,10 +447,10 @@ int game_server_init(const char *file_name, int t, int e) version.x = 0; version.y = 0; - for (i = 0; i < file.dc; i++) + for (i = 0; i < file.base->dc; i++) { - char *k = file.av + file.dv[i].ai; - char *v = file.av + file.dv[i].aj; + char *k = file.base->av + file.base->dv[i].ai; + char *v = file.base->av + file.base->dv[i].aj; if (strcmp(k, "version") == 0) sscanf(v, "%d.%d", &version.x, &version.y); @@ -512,7 +516,7 @@ void game_server_free(void) if (server_state) { sol_quit_sim(); - sol_free(&file); + sol_free_vary(&file); server_state = 0; } } @@ -622,21 +626,21 @@ static void game_update_time(float dt, int b) static int game_update_state(int bt) { - struct s_file *fp = &file; - struct s_goal *zp; + struct s_vary *vary = &file; + struct b_goal *zp; int hi; float p[3]; /* Test for an item. */ - if (bt && (hi = sol_item_test(fp, p, ITEM_RADIUS)) != -1) + if (bt && (hi = sol_item_test(vary, p, ITEM_RADIUS)) != -1) { - struct s_item *hp = &file.hv[hi]; + struct v_item *hp = file.hv + hi; game_cmd_pkitem(hi); - grow_init(fp, hp->t); + grow_init(vary, hp->t); if (hp->t == ITEM_COIN) { @@ -653,26 +657,26 @@ static int game_update_state(int bt) /* Test for a switch. */ - if (sol_swch_test(fp, 0) == SWCH_TRIGGER) + if (sol_swch_test(vary, 0) == SWCH_TRIGGER) audio_play(AUD_SWITCH, 1.f); /* Test for a jump. */ - if (jump_e == 1 && jump_b == 0 && (sol_jump_test(fp, jump_p, 0) == + if (jump_e == 1 && jump_b == 0 && (sol_jump_test(vary, jump_p, 0) == JUMP_TRIGGER)) { jump_b = 1; jump_e = 0; jump_dt = 0.f; - v_sub(jump_w, jump_p, fp->uv->p); + v_sub(jump_w, jump_p, vary->uv->p); v_add(jump_w, view.p, jump_w); audio_play(AUD_JUMP, 1.f); game_cmd_jump(1); } - if (jump_e == 0 && jump_b == 0 && (sol_jump_test(fp, jump_p, 0) == + if (jump_e == 0 && jump_b == 0 && (sol_jump_test(vary, jump_p, 0) == JUMP_OUTSIDE)) { jump_e = 1; @@ -681,7 +685,7 @@ static int game_update_state(int bt) /* Test for a goal. */ - if (bt && goal_e && (zp = sol_goal_test(fp, p, 0))) + if (bt && goal_e && (zp = sol_goal_test(vary, p, 0))) { audio_play(AUD_GOAL, 1.0f); return GAME_GOAL; @@ -697,7 +701,7 @@ static int game_update_state(int bt) /* Test for fall-out. */ - if (bt && fp->uv[0].p[1] < fp->vv[0].p[1]) + if (bt && vary->uv[0].p[1] < vary->base->vv[0].p[1]) { audio_play(AUD_FALL, 1.0f); return GAME_FALL; @@ -710,7 +714,7 @@ static int game_step(const float g[3], float dt, int bt) { if (server_state) { - struct s_file *fp = &file; + struct s_vary *vary = &file; float h[3]; @@ -724,7 +728,7 @@ static int game_step(const float g[3], float dt, int bt) game_cmd_tiltaxes(); game_cmd_tiltangles(); - grow_step(fp, dt); + grow_step(vary, dt); game_tilt_grav(h, g, &tilt); @@ -736,8 +740,8 @@ static int game_step(const float g[3], float dt, int bt) if (0.5f < jump_dt) { - v_cpy(fp->uv->p, jump_p); - v_cpy(view.p, jump_w); + v_cpy(vary->uv->p, jump_p); + v_cpy(view.p, jump_w); } if (1.0f < jump_dt) jump_b = 0; @@ -746,7 +750,7 @@ static int game_step(const float g[3], float dt, int bt) { /* Run the sim. */ - float b = sol_step(fp, h, dt, 0, NULL); + float b = sol_step(vary, h, dt, 0, NULL); /* Mix the sound of a ball bounce. */ @@ -756,9 +760,9 @@ static int game_step(const float g[3], float dt, int bt) if (got_orig) { - if (fp->uv->r > grow_orig) audio_play(AUD_BUMPL, k); - else if (fp->uv->r < grow_orig) audio_play(AUD_BUMPS, k); - else audio_play(AUD_BUMPM, k); + if (vary->uv->r > grow_orig) audio_play(AUD_BUMPL, k); + else if (vary->uv->r < grow_orig) audio_play(AUD_BUMPS, k); + else audio_play(AUD_BUMPM, k); } else audio_play(AUD_BUMPM, k); } diff --git a/ball/game_server.h b/ball/game_server.h index d069c95..07137b1 100644 --- a/ball/game_server.h +++ b/ball/game_server.h @@ -1,9 +1,6 @@ #ifndef GAME_SERVER_H #define GAME_SERVER_H -#include "solid.h" -#include "fs.h" - /*---------------------------------------------------------------------------*/ #define RESPONSE 0.05f /* Input smoothing time */ diff --git a/ball/level.c b/ball/level.c index 6026620..ac733ca 100644 --- a/ball/level.c +++ b/ball/level.c @@ -18,15 +18,16 @@ #include #include +#include "solid_base.h" + #include "common.h" -#include "solid.h" #include "config.h" #include "level.h" #include "set.h" /*---------------------------------------------------------------------------*/ -static void scan_level_attribs(struct level *l, const struct s_file *fp) +static void scan_level_attribs(struct level *l, const struct s_base *base) { int i; @@ -37,10 +38,10 @@ static void scan_level_attribs(struct level *l, const struct s_file *fp) int need_goal_easy = 0; int need_coin_easy = 0; - for (i = 0; i < fp->dc; i++) + for (i = 0; i < base->dc; i++) { - char *k = fp->av + fp->dv[i].ai; - char *v = fp->av + fp->dv[i].aj; + char *k = base->av + base->dv[i].ai; + char *v = base->av + base->dv[i].aj; if (strcmp(k, "message") == 0) SAFECPY(l->message, v); @@ -124,12 +125,12 @@ static void scan_level_attribs(struct level *l, const struct s_file *fp) int level_load(const char *filename, struct level *level) { - struct s_file sol; + struct s_base base; memset(level, 0, sizeof (struct level)); - memset(&sol, 0, sizeof (sol)); + memset(&base, 0, sizeof (base)); - if (!sol_load_only_head(&sol, filename)) + if (!sol_load_meta(&base, filename)) { fprintf(stderr, L_("Failure to load level file '%s'\n"), filename); return 0; @@ -142,9 +143,9 @@ int level_load(const char *filename, struct level *level) score_init_hs(&level->scores[SCORE_GOAL], 59999, 0); score_init_hs(&level->scores[SCORE_COIN], 59999, 0); - scan_level_attribs(level, &sol); + scan_level_attribs(level, &base); - sol_free(&sol); + sol_free_base(&base); return 1; } diff --git a/ball/st_demo.c b/ball/st_demo.c index dbe331d..cb13b1f 100644 --- a/ball/st_demo.c +++ b/ball/st_demo.c @@ -20,7 +20,6 @@ #include "demo.h" #include "progress.h" #include "audio.h" -#include "solid.h" #include "config.h" #include "util.h" #include "common.h" diff --git a/putt/game.c b/putt/game.c index 44d1537..746edbb 100644 --- a/putt/game.c +++ b/putt/game.c @@ -28,13 +28,13 @@ #include "config.h" #include "video.h" -#include "solid_gl.h" +#include "solid_draw.h" #include "solid_sim.h" #include "solid_all.h" /*---------------------------------------------------------------------------*/ -static struct s_file file; +static struct s_full file; static int ball; static float view_a; /* Ideal view rotation about Y axis */ @@ -94,13 +94,13 @@ void game_init(const char *s) idle_t = 1.0f; view_init(); - sol_load_gl(&file, s, config_get_d(CONFIG_SHADOW)); - sol_init_sim(&file); + sol_load_full(&file, s, config_get_d(CONFIG_SHADOW)); + sol_init_sim(&file.vary); - for (i = 0; i < file.dc; i++) + for (i = 0; i < file.base.dc; i++) { - const char *k = file.av + file.dv[i].ai; - const char *v = file.av + file.dv[i].aj; + const char *k = file.base.av + file.base.dv[i].ai; + const char *v = file.base.av + file.base.dv[i].aj; if (strcmp(k, "idle") == 0) { @@ -115,12 +115,12 @@ void game_init(const char *s) void game_free(void) { sol_quit_sim(); - sol_free_gl(&file); + sol_free_full(&file); } /*---------------------------------------------------------------------------*/ -static void game_draw_vect_prim(const struct s_file *fp, GLenum mode) +static void game_draw_vect_prim(const struct s_vary *fp, GLenum mode) { float p[3]; float x[3]; @@ -153,7 +153,7 @@ static void game_draw_vect_prim(const struct s_file *fp, GLenum mode) glEnd(); } -static void game_draw_vect(const struct s_file *fp) +static void game_draw_vect(const struct s_vary *fp) { if (view_m > 0.f) { @@ -180,7 +180,7 @@ static void game_draw_vect(const struct s_file *fp) } } -static void game_draw_balls(const struct s_file *fp, +static void game_draw_balls(const struct s_vary *fp, const float *bill_M, float t) { static const GLfloat color[5][4] = { @@ -242,7 +242,7 @@ static void game_draw_balls(const struct s_file *fp, glColor4f(1.0f, 1.0f, 1.0f, 1.0f); } -static void game_draw_goals(const struct s_file *fp) +static void game_draw_goals(const struct s_base *fp) { int zi; @@ -259,7 +259,7 @@ static void game_draw_goals(const struct s_file *fp) } } -static void game_draw_jumps(const struct s_file *fp) +static void game_draw_jumps(const struct s_base *fp) { int ji; @@ -278,23 +278,25 @@ static void game_draw_jumps(const struct s_file *fp) } } -static void game_draw_swchs(const struct s_file *fp) +static void game_draw_swchs(const struct s_vary *fp) { int xi; for (xi = 0; xi < fp->xc; xi++) { - if (fp->xv[xi].i) + struct v_swch *xp = fp->xv + xi; + + if (xp->base->i) continue; glPushMatrix(); { - glTranslatef(fp->xv[xi].p[0], - fp->xv[xi].p[1], - fp->xv[xi].p[2]); + glTranslatef(xp->base->p[0], + xp->base->p[1], + xp->base->p[2]); - glScalef(fp->xv[xi].r, 1.f, fp->xv[xi].r); - swch_draw(fp->xv[xi].f, fp->xv[xi].e); + glScalef(xp->base->r, 1.f, xp->base->r); + swch_draw(xp->f, xp->e); } glPopMatrix(); } @@ -311,7 +313,7 @@ void game_draw(int pose, float t) const float light_p[4] = { 8.f, 32.f, 8.f, 0.f }; - const struct s_file *fp = &file; + const struct s_draw *fp = &file.draw; float fov = FOV; @@ -353,7 +355,7 @@ void game_draw(int pose, float t) if (config_get_d(CONFIG_SHADOW) && !pose) { - shad_draw_set(fp->uv[ball].p, fp->uv[ball].r); + shad_draw_set(fp->vary->uv[ball].p, fp->vary->uv[ball].r); sol_shad(fp); shad_draw_clr(); } @@ -365,8 +367,8 @@ void game_draw(int pose, float t) if (pose == 0) { - game_draw_balls(fp, T, t); - game_draw_vect(fp); + game_draw_balls(fp->vary, T, t); + game_draw_vect(fp->vary); } glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, a); @@ -374,15 +376,15 @@ void game_draw(int pose, float t) glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, e); glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, h); - game_draw_goals(fp); + game_draw_goals(fp->base); glEnable(GL_COLOR_MATERIAL); glDisable(GL_LIGHTING); glDisable(GL_TEXTURE_2D); glDepthMask(GL_FALSE); { - game_draw_jumps(fp); - game_draw_swchs(fp); + game_draw_jumps(fp->base); + game_draw_swchs(fp->vary); } glDepthMask(GL_TRUE); glEnable(GL_TEXTURE_2D); @@ -409,8 +411,8 @@ void game_update_view(float dt) /* Center the view about the ball. */ - v_cpy(view_c, file.uv[ball].p); - v_inv(view_v, file.uv[ball].v); + v_cpy(view_c, file.vary.uv[ball].p); + v_inv(view_v, file.vary.uv[ball].v); switch (config_get_d(CONFIG_CAMERA)) { @@ -467,7 +469,7 @@ static int game_update_state(float dt) { static float t = 0.f; - struct s_file *fp = &file; + struct s_vary *fp = &file.vary; float p[3]; if (dt > 0.f) @@ -536,7 +538,7 @@ static int game_update_state(float dt) int game_step(const float g[3], float dt) { - struct s_file *fp = &file; + struct s_vary *fp = &file.vary; static float s = 0.f; static float t = 0.f; @@ -602,9 +604,9 @@ void game_putt(void) * friction too early and stopping the ball prematurely. */ - file.uv[ball].v[0] = -4.f * view_e[2][0] * view_m; - file.uv[ball].v[1] = -4.f * view_e[2][1] * view_m + BALL_FUDGE; - file.uv[ball].v[2] = -4.f * view_e[2][2] * view_m; + file.vary.uv[ball].v[0] = -4.f * view_e[2][0] * view_m; + file.vary.uv[ball].v[1] = -4.f * view_e[2][1] * view_m + BALL_FUDGE; + file.vary.uv[ball].v[2] = -4.f * view_e[2][2] * view_m; view_m = 0.f; } @@ -631,7 +633,7 @@ void game_set_mag(int d) void game_set_fly(float k) { - struct s_file *fp = &file; + struct s_vary *fp = &file.vary; float x[3] = { 1.f, 0.f, 0.f }; float y[3] = { 0.f, 1.f, 0.f }; @@ -644,7 +646,7 @@ void game_set_fly(float k) v_cpy(view_e[0], x); v_cpy(view_e[1], y); - v_sub(view_e[2], fp->uv[ball].p, fp->zv[0].p); + v_sub(view_e[2], fp->uv[ball].p, fp->base->zv[0].p); if (fabs(v_dot(view_e[1], view_e[2])) > 0.999) v_cpy(view_e[2], z); @@ -668,18 +670,18 @@ void game_set_fly(float k) /* k = +1.0 view is s_view 0 */ - if (k >= 0 && fp->wc > 0) + if (k >= 0 && fp->base->wc > 0) { - v_cpy(p1, fp->wv[0].p); - v_cpy(c1, fp->wv[0].q); + v_cpy(p1, fp->base->wv[0].p); + v_cpy(c1, fp->base->wv[0].q); } /* k = -1.0 view is s_view 1 */ - if (k <= 0 && fp->wc > 1) + if (k <= 0 && fp->base->wc > 1) { - v_cpy(p1, fp->wv[1].p); - v_cpy(c1, fp->wv[1].q); + v_cpy(p1, fp->base->wv[1].p); + v_cpy(c1, fp->base->wv[1].q); } /* Interpolate the views. */ @@ -710,32 +712,32 @@ void game_ball(int i) jump_e = 1; jump_b = 0; - for (ui = 0; ui < file.uc; ui++) + for (ui = 0; ui < file.vary.uc; ui++) { - file.uv[ui].v[0] = 0.f; - file.uv[ui].v[1] = 0.f; - file.uv[ui].v[2] = 0.f; + file.vary.uv[ui].v[0] = 0.f; + file.vary.uv[ui].v[1] = 0.f; + file.vary.uv[ui].v[2] = 0.f; - file.uv[ui].w[0] = 0.f; - file.uv[ui].w[1] = 0.f; - file.uv[ui].w[2] = 0.f; + file.vary.uv[ui].w[0] = 0.f; + file.vary.uv[ui].w[1] = 0.f; + file.vary.uv[ui].w[2] = 0.f; } } void game_get_pos(float p[3], float e[3][3]) { - v_cpy(p, file.uv[ball].p); - v_cpy(e[0], file.uv[ball].e[0]); - v_cpy(e[1], file.uv[ball].e[1]); - v_cpy(e[2], file.uv[ball].e[2]); + v_cpy(p, file.vary.uv[ball].p); + v_cpy(e[0], file.vary.uv[ball].e[0]); + v_cpy(e[1], file.vary.uv[ball].e[1]); + v_cpy(e[2], file.vary.uv[ball].e[2]); } void game_set_pos(float p[3], float e[3][3]) { - v_cpy(file.uv[ball].p, p); - v_cpy(file.uv[ball].e[0], e[0]); - v_cpy(file.uv[ball].e[1], e[1]); - v_cpy(file.uv[ball].e[2], e[2]); + v_cpy(file.vary.uv[ball].p, p); + v_cpy(file.vary.uv[ball].e[0], e[0]); + v_cpy(file.vary.uv[ball].e[1], e[1]); + v_cpy(file.vary.uv[ball].e[2], e[2]); } /*---------------------------------------------------------------------------*/ diff --git a/share/ball.c b/share/ball.c index de26f07..b70ce25 100644 --- a/share/ball.c +++ b/share/ball.c @@ -18,18 +18,19 @@ #include "vec3.h" #include "glext.h" #include "config.h" -#include "solid_gl.h" #include "common.h" +#include "solid_draw.h" + /*---------------------------------------------------------------------------*/ static int has_solid = 0; static int has_inner = 0; static int has_outer = 0; -static struct s_file solid; -static struct s_file inner; -static struct s_file outer; +static struct s_full solid; +static struct s_full inner; +static struct s_full outer; #define F_PENDULUM 1 #define F_DRAWBACK 2 @@ -49,15 +50,15 @@ static float outer_alpha; #define SET(B, v, b) ((v) ? ((B) | (b)) : ((B) & ~(b))) -static int ball_opts(const struct s_file *fp, float *alpha) +static int ball_opts(const struct s_base *base, float *alpha) { int flags = F_DEPTHTEST; int di; - for (di = 0; di < fp->dc; ++di) + for (di = 0; di < base->dc; ++di) { - char *k = fp->av + fp->dv[di].ai; - char *v = fp->av + fp->dv[di].aj; + char *k = base->av + base->dv[di].ai; + char *v = base->av + base->dv[di].aj; if (strcmp(k, "pendulum") == 0) flags = SET(flags, atoi(v), F_PENDULUM); @@ -93,14 +94,14 @@ void ball_init(void) inner_alpha = 1.0f; outer_alpha = 1.0f; - if ((has_solid = sol_load_gl(&solid, solid_file, 0))) - solid_flags = ball_opts(&solid, &solid_alpha); + if ((has_solid = sol_load_full(&solid, solid_file, 0))) + solid_flags = ball_opts(&solid.base, &solid_alpha); - if ((has_inner = sol_load_gl(&inner, inner_file, 0))) - inner_flags = ball_opts(&inner, &inner_alpha); + if ((has_inner = sol_load_full(&inner, inner_file, 0))) + inner_flags = ball_opts(&inner.base, &inner_alpha); - if ((has_outer = sol_load_gl(&outer, outer_file, 0))) - outer_flags = ball_opts(&outer, &outer_alpha); + if ((has_outer = sol_load_full(&outer, outer_file, 0))) + outer_flags = ball_opts(&outer.base, &outer_alpha); free(solid_file); free(inner_file); @@ -109,9 +110,9 @@ void ball_init(void) void ball_free(void) { - if (has_outer) sol_free_gl(&outer); - if (has_inner) sol_free_gl(&inner); - if (has_solid) sol_free_gl(&solid); + if (has_outer) sol_free_full(&outer); + if (has_inner) sol_free_full(&inner); + if (has_solid) sol_free_full(&solid); has_solid = has_inner = has_outer = 0; } @@ -140,13 +141,13 @@ static void ball_draw_solid(const float *ball_M, /* Draw the solid billboard geometry. */ - if (solid.rc) + if (solid.base.rc) { if (test == 0) glDisable(GL_DEPTH_TEST); if (mask == 0) glDepthMask(GL_FALSE); glDisable(GL_LIGHTING); { - sol_bill(&solid, ball_bill_M, t); + sol_bill(&solid.draw, ball_bill_M, t); } glEnable(GL_LIGHTING); if (mask == 0) glDepthMask(GL_TRUE); @@ -155,7 +156,7 @@ static void ball_draw_solid(const float *ball_M, /* Draw the solid opaque and transparent geometry. */ - sol_draw(&solid, mask, test); + sol_draw(&solid.draw, mask, test); } glPopMatrix(); @@ -190,20 +191,20 @@ static void ball_draw_inner(const float *pend_M, /* Draw the inner opaque and transparent geometry. */ - sol_draw(&inner, mask, test); + sol_draw(&inner.draw, mask, test); /* Draw the inner billboard geometry. */ - if (inner.rc) + if (inner.base.rc) { if (test == 0) glDisable(GL_DEPTH_TEST); if (mask == 0) glDepthMask(GL_FALSE); glDisable(GL_LIGHTING); { if (pend) - sol_bill(&inner, pend_bill_M, t); + sol_bill(&inner.draw, pend_bill_M, t); else - sol_bill(&inner, bill_M, t); + sol_bill(&inner.draw, bill_M, t); } glEnable(GL_LIGHTING); @@ -245,20 +246,20 @@ static void ball_draw_outer(const float *pend_M, /* Draw the outer opaque and transparent geometry. */ - sol_draw(&outer, mask, test); + sol_draw(&outer.draw, mask, test); /* Draw the outer billboard geometry. */ - if (outer.rc) + if (outer.base.rc) { if (test == 0) glDisable(GL_DEPTH_TEST); if (mask == 0) glDepthMask(GL_FALSE); glDisable(GL_LIGHTING); { if (pend) - sol_bill(&outer, pend_bill_M, t); + sol_bill(&outer.draw, pend_bill_M, t); else - sol_bill(&outer, bill_M, t); + sol_bill(&outer.draw, bill_M, t); } glEnable(GL_LIGHTING); if (mask == 0) glDepthMask(GL_TRUE); diff --git a/share/geom.c b/share/geom.c index eb19670..0dd3694 100644 --- a/share/geom.c +++ b/share/geom.c @@ -21,7 +21,6 @@ #include "geom.h" #include "part.h" #include "vec3.h" -#include "solid.h" #include "image.h" #include "config.h" #include "video.h" diff --git a/share/geom.h b/share/geom.h index 7e54e3d..f704027 100644 --- a/share/geom.h +++ b/share/geom.h @@ -3,10 +3,6 @@ /*---------------------------------------------------------------------------*/ -#include "solid.h" - -/*---------------------------------------------------------------------------*/ - #define IMG_SHAD "png/shadow.png" #define JUMP_HEIGHT 2.00f diff --git a/share/item.c b/share/item.c index ce272d1..8af06db 100644 --- a/share/item.c +++ b/share/item.c @@ -15,17 +15,18 @@ #include "item.h" #include "glext.h" #include "vec3.h" -#include "solid_gl.h" #include "image.h" #include "config.h" +#include "solid_draw.h" + /*---------------------------------------------------------------------------*/ -static struct s_file item_coin_file; -static struct s_file item_grow_file; -static struct s_file item_shrink_file; +static struct s_full item_coin_file; +static struct s_full item_grow_file; +static struct s_full item_shrink_file; -void item_color(const struct s_item *hp, float *c) +void item_color(const struct v_item *hp, float *c) { switch (hp->t) { @@ -80,16 +81,16 @@ void item_color(const struct s_item *hp, float *c) void item_init(void) { - sol_load_gl(&item_coin_file, "item/coin/coin.sol", 0); - sol_load_gl(&item_grow_file, "item/grow/grow.sol", 0); - sol_load_gl(&item_shrink_file, "item/shrink/shrink.sol", 0); + sol_load_full(&item_coin_file, "item/coin/coin.sol", 0); + sol_load_full(&item_grow_file, "item/grow/grow.sol", 0); + sol_load_full(&item_shrink_file, "item/shrink/shrink.sol", 0); } void item_free(void) { - sol_free_gl(&item_coin_file); - sol_free_gl(&item_grow_file); - sol_free_gl(&item_shrink_file); + sol_free_full(&item_coin_file); + sol_free_full(&item_grow_file); + sol_free_full(&item_shrink_file); } void item_push(int type) @@ -97,22 +98,22 @@ void item_push(int type) glEnable(GL_COLOR_MATERIAL); } -void item_draw(const struct s_item *hp, float r) +void item_draw(const struct v_item *hp, float r) { + struct s_draw *draw = NULL; float c[3]; - struct s_file *fp = NULL; switch (hp->t) { - case ITEM_COIN: fp = &item_coin_file; break; - case ITEM_GROW: fp = &item_grow_file; break; - case ITEM_SHRINK: fp = &item_shrink_file; break; + case ITEM_COIN: draw = &item_coin_file.draw; break; + case ITEM_GROW: draw = &item_grow_file.draw; break; + case ITEM_SHRINK: draw = &item_shrink_file.draw; break; } item_color(hp, c); glColor3fv(c); - sol_draw(fp, 0, 1); + sol_draw(draw, 0, 1); } void item_pull(void) diff --git a/share/item.h b/share/item.h index 6ac4bc5..4d72414 100644 --- a/share/item.h +++ b/share/item.h @@ -15,16 +15,16 @@ #ifndef ITEM_H #define ITEM_H -#include "solid.h" +#include "solid_vary.h" #define ITEM_RADIUS 0.15f -void item_color(const struct s_item *, float *); +void item_color(const struct v_item *, float *); void item_init(void); void item_free(void); void item_push(int); -void item_draw(const struct s_item *, float); +void item_draw(const struct v_item *, float); void item_pull(void); #endif diff --git a/share/mapc.c b/share/mapc.c index defb7b4..175e7d5 100644 --- a/share/mapc.c +++ b/share/mapc.c @@ -19,8 +19,9 @@ #include #include +#include "solid_base.h" + #include "vec3.h" -#include "solid.h" #include "base_image.h" #include "base_config.h" #include "fs.h" @@ -77,102 +78,102 @@ static int overflow(const char *s) return 0; } -static int incm(struct s_file *fp) +static int incm(struct s_base *fp) { return (fp->mc < MAXM) ? fp->mc++ : overflow("mtrl"); } -static int incv(struct s_file *fp) +static int incv(struct s_base *fp) { return (fp->vc < MAXV) ? fp->vc++ : overflow("vert"); } -static int ince(struct s_file *fp) +static int ince(struct s_base *fp) { return (fp->ec < MAXE) ? fp->ec++ : overflow("edge"); } -static int incs(struct s_file *fp) +static int incs(struct s_base *fp) { return (fp->sc < MAXS) ? fp->sc++ : overflow("side"); } -static int inct(struct s_file *fp) +static int inct(struct s_base *fp) { return (fp->tc < MAXT) ? fp->tc++ : overflow("texc"); } -static int incg(struct s_file *fp) +static int incg(struct s_base *fp) { return (fp->gc < MAXG) ? fp->gc++ : overflow("geom"); } -static int incl(struct s_file *fp) +static int incl(struct s_base *fp) { return (fp->lc < MAXL) ? fp->lc++ : overflow("lump"); } -static int incn(struct s_file *fp) +static int incn(struct s_base *fp) { return (fp->nc < MAXN) ? fp->nc++ : overflow("node"); } -static int incp(struct s_file *fp) +static int incp(struct s_base *fp) { return (fp->pc < MAXP) ? fp->pc++ : overflow("path"); } -static int incb(struct s_file *fp) +static int incb(struct s_base *fp) { return (fp->bc < MAXB) ? fp->bc++ : overflow("body"); } -static int inch(struct s_file *fp) +static int inch(struct s_base *fp) { return (fp->hc < MAXH) ? fp->hc++ : overflow("item"); } -static int incz(struct s_file *fp) +static int incz(struct s_base *fp) { return (fp->zc < MAXZ) ? fp->zc++ : overflow("goal"); } -static int incj(struct s_file *fp) +static int incj(struct s_base *fp) { return (fp->jc < MAXJ) ? fp->jc++ : overflow("jump"); } -static int incx(struct s_file *fp) +static int incx(struct s_base *fp) { return (fp->xc < MAXX) ? fp->xc++ : overflow("swch"); } -static int incr(struct s_file *fp) +static int incr(struct s_base *fp) { return (fp->rc < MAXR) ? fp->rc++ : overflow("bill"); } -static int incu(struct s_file *fp) +static int incu(struct s_base *fp) { return (fp->uc < MAXU) ? fp->uc++ : overflow("ball"); } -static int incw(struct s_file *fp) +static int incw(struct s_base *fp) { return (fp->wc < MAXW) ? fp->wc++ : overflow("view"); } -static int incd(struct s_file *fp) +static int incd(struct s_base *fp) { return (fp->dc < MAXD) ? fp->dc++ : overflow("dict"); } -static int inci(struct s_file *fp) +static int inci(struct s_base *fp) { return (fp->ic < MAXI) ? fp->ic++ : overflow("indx"); } -static void init_file(struct s_file *fp) +static void init_file(struct s_base *fp) { fp->mc = 0; fp->vc = 0; @@ -195,26 +196,26 @@ static void init_file(struct s_file *fp) fp->ac = 0; fp->ic = 0; - fp->mv = (struct s_mtrl *) calloc(MAXM, sizeof (struct s_mtrl)); - fp->vv = (struct s_vert *) calloc(MAXV, sizeof (struct s_vert)); - fp->ev = (struct s_edge *) calloc(MAXE, sizeof (struct s_edge)); - fp->sv = (struct s_side *) calloc(MAXS, sizeof (struct s_side)); - fp->tv = (struct s_texc *) calloc(MAXT, sizeof (struct s_texc)); - fp->gv = (struct s_geom *) calloc(MAXG, sizeof (struct s_geom)); - fp->lv = (struct s_lump *) calloc(MAXL, sizeof (struct s_lump)); - fp->nv = (struct s_node *) calloc(MAXN, sizeof (struct s_node)); - fp->pv = (struct s_path *) calloc(MAXP, sizeof (struct s_path)); - fp->bv = (struct s_body *) calloc(MAXB, sizeof (struct s_body)); - fp->hv = (struct s_item *) calloc(MAXH, sizeof (struct s_item)); - fp->zv = (struct s_goal *) calloc(MAXZ, sizeof (struct s_goal)); - fp->jv = (struct s_jump *) calloc(MAXJ, sizeof (struct s_jump)); - fp->xv = (struct s_swch *) calloc(MAXX, sizeof (struct s_swch)); - fp->rv = (struct s_bill *) calloc(MAXR, sizeof (struct s_bill)); - fp->uv = (struct s_ball *) calloc(MAXU, sizeof (struct s_ball)); - fp->wv = (struct s_view *) calloc(MAXW, sizeof (struct s_view)); - fp->dv = (struct s_dict *) calloc(MAXD, sizeof (struct s_dict)); - fp->av = (char *) calloc(MAXA, sizeof (char)); - fp->iv = (int *) calloc(MAXI, sizeof (int)); + fp->mv = (struct b_mtrl *) calloc(MAXM, sizeof (*fp->mv)); + fp->vv = (struct b_vert *) calloc(MAXV, sizeof (*fp->vv)); + fp->ev = (struct b_edge *) calloc(MAXE, sizeof (*fp->ev)); + fp->sv = (struct b_side *) calloc(MAXS, sizeof (*fp->sv)); + fp->tv = (struct b_texc *) calloc(MAXT, sizeof (*fp->tv)); + fp->gv = (struct b_geom *) calloc(MAXG, sizeof (*fp->gv)); + fp->lv = (struct b_lump *) calloc(MAXL, sizeof (*fp->lv)); + fp->nv = (struct b_node *) calloc(MAXN, sizeof (*fp->nv)); + fp->pv = (struct b_path *) calloc(MAXP, sizeof (*fp->pv)); + fp->bv = (struct b_body *) calloc(MAXB, sizeof (*fp->bv)); + fp->hv = (struct b_item *) calloc(MAXH, sizeof (*fp->hv)); + fp->zv = (struct b_goal *) calloc(MAXZ, sizeof (*fp->zv)); + fp->jv = (struct b_jump *) calloc(MAXJ, sizeof (*fp->jv)); + fp->xv = (struct b_swch *) calloc(MAXX, sizeof (*fp->xv)); + fp->rv = (struct b_bill *) calloc(MAXR, sizeof (*fp->rv)); + fp->uv = (struct b_ball *) calloc(MAXU, sizeof (*fp->uv)); + fp->wv = (struct b_view *) calloc(MAXW, sizeof (*fp->wv)); + fp->dv = (struct b_dict *) calloc(MAXD, sizeof (*fp->dv)); + fp->av = (char *) calloc(MAXA, sizeof (*fp->av)); + fp->iv = (int *) calloc(MAXI, sizeof (*fp->iv)); } /*---------------------------------------------------------------------------*/ @@ -277,7 +278,7 @@ static int targ_wi[MAXW]; static int targ_ji[MAXW]; static int targ_n; -static void targets(struct s_file *fp) +static void targets(struct s_base *fp) { int i; @@ -396,10 +397,10 @@ static void size_image(const char *name, int *w, int *h) if (fs_gets((s), sizeof (s), (f))) \ sscanf((s), "%f %f %f %f", (v), (v) + 1, (v) + 2, (v) + 3) -static int read_mtrl(struct s_file *fp, const char *name) +static int read_mtrl(struct s_base *fp, const char *name) { static char line[MAXSTR]; - struct s_mtrl *mp; + struct b_mtrl *mp; fs_file fin; int mi; @@ -456,18 +457,18 @@ static int read_mtrl(struct s_file *fp, const char *name) * specification. */ -static void move_side(struct s_side *sp, const float p[3]) +static void move_side(struct b_side *sp, const float p[3]) { sp->d -= v_dot(sp->n, p); } -static void move_vert(struct s_vert *vp, const float p[3]) +static void move_vert(struct b_vert *vp, const float p[3]) { v_sub(vp->p, vp->p, p); } -static void move_lump(struct s_file *fp, - struct s_lump *lp, const float p[3]) +static void move_lump(struct s_base *fp, + struct b_lump *lp, const float p[3]) { int i; @@ -477,8 +478,8 @@ static void move_lump(struct s_file *fp, move_vert(fp->vv + fp->iv[lp->v0 + i], p); } -static void move_body(struct s_file *fp, - struct s_body *bp) +static void move_body(struct s_base *fp, + struct b_body *bp) { int i, *b; @@ -510,7 +511,7 @@ static void move_body(struct s_file *fp, } } -static void move_file(struct s_file *fp) +static void move_file(struct s_base *fp) { int i; @@ -529,31 +530,31 @@ static void move_file(struct s_file *fp) * references to Neverball materials, rather than MTL definitions. */ -static void read_vt(struct s_file *fp, const char *line) +static void read_vt(struct s_base *fp, const char *line) { - struct s_texc *tp = fp->tv + inct(fp); + struct b_texc *tp = fp->tv + inct(fp); sscanf(line, "%f %f", tp->u, tp->u + 1); } -static void read_vn(struct s_file *fp, const char *line) +static void read_vn(struct s_base *fp, const char *line) { - struct s_side *sp = fp->sv + incs(fp); + struct b_side *sp = fp->sv + incs(fp); sscanf(line, "%f %f %f", sp->n, sp->n + 1, sp->n + 2); } -static void read_v(struct s_file *fp, const char *line) +static void read_v(struct s_base *fp, const char *line) { - struct s_vert *vp = fp->vv + incv(fp); + struct b_vert *vp = fp->vv + incv(fp); sscanf(line, "%f %f %f", vp->p, vp->p + 1, vp->p + 2); } -static void read_f(struct s_file *fp, const char *line, +static void read_f(struct s_base *fp, const char *line, int v0, int t0, int s0, int mi) { - struct s_geom *gp = fp->gv + incg(fp); + struct b_geom *gp = fp->gv + incg(fp); char c1; char c2; @@ -576,7 +577,7 @@ static void read_f(struct s_file *fp, const char *line, gp->mi = mi; } -static void read_obj(struct s_file *fp, const char *name, int mi) +static void read_obj(struct s_base *fp, const char *name, int mi) { char line[MAXSTR]; char mtrl[MAXSTR]; @@ -764,13 +765,13 @@ static int map_token(fs_file fin, int pi, char key[MAXSTR], char val[MAXSTR]) /* Parse a lump from the given file and add it to the solid. */ -static void read_lump(struct s_file *fp, fs_file fin) +static void read_lump(struct s_base *fp, fs_file fin) { char k[MAXSTR]; char v[MAXSTR]; int t; - struct s_lump *lp = fp->lv + incl(fp); + struct b_lump *lp = fp->lv + incl(fp); lp->s0 = fp->ic; @@ -797,13 +798,13 @@ static void read_lump(struct s_file *fp, fs_file fin) /*---------------------------------------------------------------------------*/ -static void make_path(struct s_file *fp, +static void make_path(struct s_base *fp, char k[][MAXSTR], char v[][MAXSTR], int c) { int i, pi = incp(fp); - struct s_path *pp = fp->pv + pi; + struct b_path *pp = fp->pv + pi; pp->p[0] = 0.f; pp->p[1] = 0.f; @@ -888,13 +889,13 @@ static void make_path(struct s_file *fp, } } -static void make_dict(struct s_file *fp, +static void make_dict(struct s_base *fp, const char *k, const char *v) { int space_left, space_needed, di = incd(fp); - struct s_dict *dp = fp->dv + di; + struct b_dict *dp = fp->dv + di; space_left = MAXA - fp->ac; space_needed = strlen(k) + 1 + strlen(v) + 1; @@ -915,7 +916,7 @@ static void make_dict(struct s_file *fp, static int read_dict_entries = 0; -static void make_body(struct s_file *fp, +static void make_body(struct s_base *fp, char k[][MAXSTR], char v[][MAXSTR], int c, int l0) { @@ -930,9 +931,8 @@ static void make_body(struct s_file *fp, float y = 0.f; float z = 0.f; - struct s_body *bp = fp->bv + bi; + struct b_body *bp = fp->bv + bi; - bp->t = 0.f; bp->pi = -1; bp->ni = -1; @@ -975,13 +975,13 @@ static void make_body(struct s_file *fp, read_dict_entries = 0; } -static void make_item(struct s_file *fp, +static void make_item(struct s_base *fp, char k[][MAXSTR], char v[][MAXSTR], int c) { int i, hi = inch(fp); - struct s_item *hp = fp->hv + hi; + struct b_item *hp = fp->hv + hi; hp->p[0] = 0.f; hp->p[1] = 0.f; @@ -1018,15 +1018,15 @@ static void make_item(struct s_file *fp, } } -static void make_bill(struct s_file *fp, +static void make_bill(struct s_base *fp, char k[][MAXSTR], char v[][MAXSTR], int c) { int i, ri = incr(fp); - struct s_bill *rp = fp->rv + ri; + struct b_bill *rp = fp->rv + ri; - memset(rp, 0, sizeof (struct s_bill)); + memset(rp, 0, sizeof (struct b_bill)); rp->t = 1.0f; for (i = 0; i < c; i++) @@ -1072,13 +1072,13 @@ static void make_bill(struct s_file *fp, fp->mv[rp->mi].fl |= M_ADDITIVE; } -static void make_goal(struct s_file *fp, +static void make_goal(struct s_base *fp, char k[][MAXSTR], char v[][MAXSTR], int c) { int i, zi = incz(fp); - struct s_goal *zp = fp->zv + zi; + struct b_goal *zp = fp->zv + zi; zp->p[0] = 0.f; zp->p[1] = 0.f; @@ -1103,13 +1103,13 @@ static void make_goal(struct s_file *fp, } } -static void make_view(struct s_file *fp, +static void make_view(struct s_base *fp, char k[][MAXSTR], char v[][MAXSTR], int c) { int i, wi = incw(fp); - struct s_view *wp = fp->wv + wi; + struct b_view *wp = fp->wv + wi; wp->p[0] = 0.f; wp->p[1] = 0.f; @@ -1136,13 +1136,13 @@ static void make_view(struct s_file *fp, } } -static void make_jump(struct s_file *fp, +static void make_jump(struct s_base *fp, char k[][MAXSTR], char v[][MAXSTR], int c) { int i, ji = incj(fp); - struct s_jump *jp = fp->jv + ji; + struct b_jump *jp = fp->jv + ji; jp->p[0] = 0.f; jp->p[1] = 0.f; @@ -1173,22 +1173,20 @@ static void make_jump(struct s_file *fp, } } -static void make_swch(struct s_file *fp, +static void make_swch(struct s_base *fp, char k[][MAXSTR], char v[][MAXSTR], int c) { int i, xi = incx(fp); - struct s_swch *xp = fp->xv + xi; + struct b_swch *xp = fp->xv + xi; xp->p[0] = 0.f; xp->p[1] = 0.f; xp->p[2] = 0.f; xp->r = 0.5; xp->pi = 0; - xp->t0 = 0; xp->t = 0; - xp->f0 = 0; xp->f = 0; xp->i = 0; @@ -1201,16 +1199,10 @@ static void make_swch(struct s_file *fp, make_ref(v[i], &xp->pi); if (strcmp(k[i], "timer") == 0) - { - sscanf(v[i], "%f", &xp->t0); - xp->t = xp->t0; - } + sscanf(v[i], "%f", &xp->t); if (strcmp(k[i], "state") == 0) - { - xp->f = atoi(v[i]); - xp->f0 = atoi(v[i]); - } + xp->f = atoi(v[i]); if (strcmp(k[i], "invisible") == 0) xp->i = atoi(v[i]); @@ -1228,7 +1220,7 @@ static void make_swch(struct s_file *fp, } } -static void make_targ(struct s_file *fp, +static void make_targ(struct s_base *fp, char k[][MAXSTR], char v[][MAXSTR], int c) { @@ -1258,13 +1250,13 @@ static void make_targ(struct s_file *fp, targ_n++; } -static void make_ball(struct s_file *fp, +static void make_ball(struct s_base *fp, char k[][MAXSTR], char v[][MAXSTR], int c) { int i, ui = incu(fp); - struct s_ball *up = fp->uv + ui; + struct b_ball *up = fp->uv + ui; up->p[0] = 0.0f; up->p[1] = 0.0f; @@ -1293,7 +1285,7 @@ static void make_ball(struct s_file *fp, /*---------------------------------------------------------------------------*/ -static void read_ent(struct s_file *fp, fs_file fin) +static void read_ent(struct s_base *fp, fs_file fin) { char k[MAXKEY][MAXSTR]; char v[MAXKEY][MAXSTR]; @@ -1333,7 +1325,7 @@ static void read_ent(struct s_file *fp, fs_file fin) if (!strcmp(v[i], "misc_model")) make_body(fp, k, v, c, l0); } -static void read_map(struct s_file *fp, fs_file fin) +static void read_map(struct s_base *fp, fs_file fin) { char k[MAXSTR]; char v[MAXSTR]; @@ -1348,12 +1340,12 @@ static void read_map(struct s_file *fp, fs_file fin) /* Test the location of a point with respect to a side plane. */ -static int fore_side(const float p[3], const struct s_side *sp) +static int fore_side(const float p[3], const struct b_side *sp) { return (v_dot(p, sp->n) - sp->d > +SMALL) ? 1 : 0; } -static int on_side(const float p[3], const struct s_side *sp) +static int on_side(const float p[3], const struct b_side *sp) { float d = v_dot(p, sp->n) - sp->d; @@ -1366,8 +1358,8 @@ static int on_side(const float p[3], const struct s_side *sp) * geometry. */ -static int ok_vert(const struct s_file *fp, - const struct s_lump *lp, const float p[3]) +static int ok_vert(const struct s_base *fp, + const struct b_lump *lp, const float p[3]) { float r[3]; int i; @@ -1401,8 +1393,8 @@ static int ok_vert(const struct s_file *fp, * Confirm that this point falls within the current lump, and that it * is unique. Add it as a vert of the solid. */ -static void clip_vert(struct s_file *fp, - struct s_lump *lp, int si, int sj, int sk) +static void clip_vert(struct s_base *fp, + struct b_lump *lp, int si, int sj, int sk) { float M[16], X[16], I[16]; float d[3], p[3]; @@ -1444,8 +1436,8 @@ static void clip_vert(struct s_file *fp, * finding a pair of vertices that fall on both planes. Add it to the * solid. */ -static void clip_edge(struct s_file *fp, - struct s_lump *lp, int si, int sj) +static void clip_edge(struct s_base *fp, + struct b_lump *lp, int si, int sj) { int i, j; @@ -1482,15 +1474,15 @@ static void clip_edge(struct s_file *fp, * verts to have a counter-clockwise winding about the plane normal. * Create geoms to tessellate the resulting convex polygon. */ -static void clip_geom(struct s_file *fp, - struct s_lump *lp, int si) +static void clip_geom(struct s_base *fp, + struct b_lump *lp, int si) { int m[256], t[256], d, i, j, n = 0; float u[3]; float v[3]; float w[3]; - struct s_side *sp = fp->sv + si; + struct b_side *sp = fp->sv + si; /* Find em. */ @@ -1563,7 +1555,7 @@ static void clip_geom(struct s_file *fp, * each trio of planes, a new edge for each pair of planes, and a new * set of geom for each visible plane. */ -static void clip_lump(struct s_file *fp, struct s_lump *lp) +static void clip_lump(struct s_base *fp, struct b_lump *lp) { int i, j, k; @@ -1600,7 +1592,7 @@ static void clip_lump(struct s_file *fp, struct s_lump *lp) lp->fl |= L_DETAIL; } -static void clip_file(struct s_file *fp) +static void clip_file(struct s_base *fp) { int i; @@ -1618,7 +1610,7 @@ static void clip_file(struct s_file *fp) * the number of elements that can be eliminated. */ -static int comp_mtrl(const struct s_mtrl *mp, const struct s_mtrl *mq) +static int comp_mtrl(const struct b_mtrl *mp, const struct b_mtrl *mq) { if (fabs(mp->d[0] - mq->d[0]) > SMALL) return 0; if (fabs(mp->d[1] - mq->d[1]) > SMALL) return 0; @@ -1647,7 +1639,7 @@ static int comp_mtrl(const struct s_mtrl *mp, const struct s_mtrl *mq) return 1; } -static int comp_vert(const struct s_vert *vp, const struct s_vert *vq) +static int comp_vert(const struct b_vert *vp, const struct b_vert *vq) { if (fabs(vp->p[0] - vq->p[0]) > SMALL) return 0; if (fabs(vp->p[1] - vq->p[1]) > SMALL) return 0; @@ -1656,7 +1648,7 @@ static int comp_vert(const struct s_vert *vp, const struct s_vert *vq) return 1; } -static int comp_edge(const struct s_edge *ep, const struct s_edge *eq) +static int comp_edge(const struct b_edge *ep, const struct b_edge *eq) { if (ep->vi != eq->vi && ep->vi != eq->vj) return 0; if (ep->vj != eq->vi && ep->vj != eq->vj) return 0; @@ -1664,7 +1656,7 @@ static int comp_edge(const struct s_edge *ep, const struct s_edge *eq) return 1; } -static int comp_side(const struct s_side *sp, const struct s_side *sq) +static int comp_side(const struct b_side *sp, const struct b_side *sq) { if (fabs(sp->d - sq->d) > SMALL) return 0; if (v_dot(sp->n, sq->n) < 0.9999) return 0; @@ -1672,7 +1664,7 @@ static int comp_side(const struct s_side *sp, const struct s_side *sq) return 1; } -static int comp_texc(const struct s_texc *tp, const struct s_texc *tq) +static int comp_texc(const struct b_texc *tp, const struct b_texc *tq) { if (fabs(tp->u[0] - tq->u[0]) > SMALL) return 0; if (fabs(tp->u[1] - tq->u[1]) > SMALL) return 0; @@ -1680,7 +1672,7 @@ static int comp_texc(const struct s_texc *tp, const struct s_texc *tq) return 1; } -static int comp_geom(const struct s_geom *gp, const struct s_geom *gq) +static int comp_geom(const struct b_geom *gp, const struct b_geom *gq) { if (gp->mi != gq->mi) return 0; @@ -1707,7 +1699,7 @@ static int comp_geom(const struct s_geom *gp, const struct s_geom *gq) * and sorting the file. */ -static void swap_mtrl(struct s_file *fp, int mi, int mj) +static void swap_mtrl(struct s_base *fp, int mi, int mj) { int i; @@ -1719,7 +1711,7 @@ static void swap_mtrl(struct s_file *fp, int mi, int mj) static int vert_swaps[MAXV]; -static void apply_vert_swaps(struct s_file *fp) +static void apply_vert_swaps(struct s_base *fp) { int i, j; @@ -1741,7 +1733,7 @@ static void apply_vert_swaps(struct s_file *fp) fp->iv[fp->lv[i].v0 + j] = vert_swaps[fp->iv[fp->lv[i].v0 + j]]; } -static void swap_vert(struct s_file *fp, int vi, int vj) +static void swap_vert(struct s_base *fp, int vi, int vj) { int i, j; @@ -1766,7 +1758,7 @@ static void swap_vert(struct s_file *fp, int vi, int vj) static int edge_swaps[MAXE]; -static void apply_edge_swaps(struct s_file *fp) +static void apply_edge_swaps(struct s_base *fp) { int i, j; @@ -1777,7 +1769,7 @@ static void apply_edge_swaps(struct s_file *fp) static int side_swaps[MAXS]; -static void apply_side_swaps(struct s_file *fp) +static void apply_side_swaps(struct s_base *fp) { int i, j; @@ -1797,7 +1789,7 @@ static void apply_side_swaps(struct s_file *fp) static int texc_swaps[MAXT]; -static void apply_texc_swaps(struct s_file *fp) +static void apply_texc_swaps(struct s_base *fp) { int i; @@ -1811,7 +1803,7 @@ static void apply_texc_swaps(struct s_file *fp) static int geom_swaps[MAXG]; -static void apply_geom_swaps(struct s_file *fp) +static void apply_geom_swaps(struct s_base *fp) { int i, j; @@ -1826,7 +1818,7 @@ static void apply_geom_swaps(struct s_file *fp) /*---------------------------------------------------------------------------*/ -static void uniq_mtrl(struct s_file *fp) +static void uniq_mtrl(struct s_base *fp) { int i, j, k = 0; @@ -1853,7 +1845,7 @@ static void uniq_mtrl(struct s_file *fp) fp->mc = k; } -static void uniq_vert(struct s_file *fp) +static void uniq_vert(struct s_base *fp) { int i, j, k = 0; @@ -1878,7 +1870,7 @@ static void uniq_vert(struct s_file *fp) fp->vc = k; } -static void uniq_edge(struct s_file *fp) +static void uniq_edge(struct s_base *fp) { int i, j, k = 0; @@ -1906,7 +1898,7 @@ static void uniq_edge(struct s_file *fp) static int geomlist[MAXV]; static int nextgeom[MAXG]; -static void uniq_geom(struct s_file *fp) +static void uniq_geom(struct s_base *fp) { int i, j, k = 0; @@ -1938,7 +1930,7 @@ found: fp->gc = k; } -static void uniq_texc(struct s_file *fp) +static void uniq_texc(struct s_base *fp) { int i, j, k = 0; @@ -1963,7 +1955,7 @@ static void uniq_texc(struct s_file *fp) fp->tc = k; } -static void uniq_side(struct s_file *fp) +static void uniq_side(struct s_base *fp) { int i, j, k = 0; @@ -1988,7 +1980,7 @@ static void uniq_side(struct s_file *fp) fp->sc = k; } -static void uniq_file(struct s_file *fp) +static void uniq_file(struct s_base *fp) { /* Debug mode skips optimization, producing oversized output files. */ @@ -2005,7 +1997,7 @@ static void uniq_file(struct s_file *fp) /*---------------------------------------------------------------------------*/ -struct s_trip +struct b_trip { int vi; int mi; @@ -2015,8 +2007,8 @@ struct s_trip static int comp_trip(const void *p, const void *q) { - const struct s_trip *tp = (const struct s_trip *) p; - const struct s_trip *tq = (const struct s_trip *) q; + const struct b_trip *tp = (const struct b_trip *) p; + const struct b_trip *tq = (const struct b_trip *) q; if (tp->vi < tq->vi) return -1; if (tp->vi > tq->vi) return +1; @@ -2026,13 +2018,13 @@ static int comp_trip(const void *p, const void *q) return 0; } -static void smth_file(struct s_file *fp) +static void smth_file(struct s_base *fp) { - struct s_trip temp, *T; + struct b_trip temp, *T; if (debug_output == 0) { - if ((T = (struct s_trip *) malloc(fp->gc * 3 * sizeof (struct s_trip)))) + if ((T = (struct b_trip *) malloc(fp->gc * 3 * sizeof (struct b_trip)))) { int gi, i, j, k, l, c = 0; @@ -2040,7 +2032,7 @@ static void smth_file(struct s_file *fp) for (gi = 0; gi < fp->gc; ++gi) { - struct s_geom *gp = fp->gv + gi; + struct b_geom *gp = fp->gv + gi; T[c].vi = gp->vi; T[c].mi = gp->mi; @@ -2063,7 +2055,7 @@ static void smth_file(struct s_file *fp) /* Sort all triplets by vertex index and material. */ - qsort(T, c, sizeof (struct s_trip), comp_trip); + qsort(T, c, sizeof (struct b_trip), comp_trip); /* For each set of triplets sharing vertex index and material... */ @@ -2138,7 +2130,7 @@ static void smth_file(struct s_file *fp) for (i = 0; i < c; ++i) { - struct s_geom *gp = fp->gv + T[i].gi; + struct b_geom *gp = fp->gv + T[i].gi; if (gp->vi == T[i].vi) gp->si = T[i].si; if (gp->vj == T[i].vi) gp->sj = T[i].si; @@ -2155,7 +2147,7 @@ static void smth_file(struct s_file *fp) /*---------------------------------------------------------------------------*/ -static void sort_file(struct s_file *fp) +static void sort_file(struct s_base *fp) { int i, j; @@ -2167,7 +2159,7 @@ static void sort_file(struct s_file *fp) (fp->rv[j].d == fp->rv[i].d && fp->rv[j].mi > fp->rv[i].mi)) { - struct s_bill t; + struct b_bill t; t = fp->rv[i]; fp->rv[i] = fp->rv[j]; @@ -2179,7 +2171,7 @@ static void sort_file(struct s_file *fp) for (i = 0; i < fp->vc; i++) if (fp->vv[0].p[1] > fp->vv[i].p[1]) { - struct s_vert t; + struct b_vert t; t = fp->vv[0]; fp->vv[0] = fp->vv[i]; @@ -2193,9 +2185,9 @@ static void sort_file(struct s_file *fp) /*---------------------------------------------------------------------------*/ -static int test_lump_side(const struct s_file *fp, - const struct s_lump *lp, - const struct s_side *sp, +static int test_lump_side(const struct s_base *fp, + const struct b_lump *lp, + const struct b_side *sp, float bsphere[4]) { int si; @@ -2242,7 +2234,7 @@ static int test_lump_side(const struct s_file *fp, return 0; } -static int node_node(struct s_file *fp, int l0, int lc, float bsphere[][4]) +static int node_node(struct s_base *fp, int l0, int lc, float bsphere[][4]) { if (lc < 8) { @@ -2328,7 +2320,7 @@ static int node_node(struct s_file *fp, int l0, int lc, float bsphere[][4]) for (lj = 0; lj < li; lj++) if (fp->lv[l0 + li].fl < fp->lv[l0 + lj].fl) { - struct s_lump l; + struct b_lump l; float f; int i; @@ -2376,8 +2368,8 @@ static int node_node(struct s_file *fp, int l0, int lc, float bsphere[][4]) /* * Compute a bounding sphere for a lump (not optimal) */ -static void lump_bounding_sphere(struct s_file *fp, - struct s_lump *lp, +static void lump_bounding_sphere(struct s_base *fp, + struct b_lump *lp, float bsphere[4]) { float bbox[6]; @@ -2393,7 +2385,7 @@ static void lump_bounding_sphere(struct s_file *fp, for (i = 1; i < lp->vc; i++) { - struct s_vert *vp = fp->vv + fp->iv[lp->v0 + i]; + struct b_vert *vp = fp->vv + fp->iv[lp->v0 + i]; int j; for (j = 0; j < 3; j++) @@ -2416,7 +2408,7 @@ static void lump_bounding_sphere(struct s_file *fp, bsphere[3] = fsqrtf(r); } -static void node_file(struct s_file *fp) +static void node_file(struct s_base *fp) { float bsphere[MAXL][4]; int i; @@ -2434,7 +2426,7 @@ static void node_file(struct s_file *fp) /*---------------------------------------------------------------------------*/ -static void dump_file(struct s_file *p, const char *name) +static void dump_file(struct s_base *p, const char *name) { int i, j; int c = 0; @@ -2488,7 +2480,7 @@ int main(int argc, char *argv[]) { char src[MAXSTR] = ""; char dst[MAXSTR] = ""; - struct s_file f; + struct s_base f; fs_file fin; if (!fs_init(argv[0])) @@ -2542,7 +2534,7 @@ int main(int argc, char *argv[]) node_file(&f); dump_file(&f, dst); - sol_stor(&f, base_name(dst)); + sol_stor_base(&f, base_name(dst)); fs_close(fin); diff --git a/share/solid.c b/share/solid.c deleted file mode 100644 index c45bb72..0000000 --- a/share/solid.c +++ /dev/null @@ -1,646 +0,0 @@ -/* - * Copyright (C) 2003 Robert Kooima - * - * NEVERBALL is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2 of the License, - * or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - */ - -#include -#include -#include - -#include "solid.h" -#include "base_config.h" -#include "binary.h" -#include "common.h" -#include "fs.h" - -enum -{ - SOL_VER_MINIMUM = 6, - SOL_VER_PATH_FLAGS, - SOL_VER_CURRENT = SOL_VER_PATH_FLAGS -}; - -#define SOL_MAGIC (0xAF | 'S' << 8 | 'O' << 16 | 'L' << 24) - -/*---------------------------------------------------------------------------*/ - -static int sol_version; - -static int sol_file(fs_file fin) -{ - int magic; - int version; - - get_index(fin, &magic); - get_index(fin, &version); - - if (magic != SOL_MAGIC || (version < SOL_VER_MINIMUM || - version > SOL_VER_CURRENT)) - return 0; - - sol_version = version; - - return 1; -} - -static void sol_load_mtrl(fs_file fin, struct s_mtrl *mp) -{ - get_array(fin, mp->d, 4); - get_array(fin, mp->a, 4); - get_array(fin, mp->s, 4); - get_array(fin, mp->e, 4); - get_array(fin, mp->h, 1); - get_index(fin, &mp->fl); - - fs_read(mp->f, 1, PATHMAX, fin); -} - -static void sol_load_vert(fs_file fin, struct s_vert *vp) -{ - get_array(fin, vp->p, 3); -} - -static void sol_load_edge(fs_file fin, struct s_edge *ep) -{ - get_index(fin, &ep->vi); - get_index(fin, &ep->vj); -} - -static void sol_load_side(fs_file fin, struct s_side *sp) -{ - get_array(fin, sp->n, 3); - get_float(fin, &sp->d); -} - -static void sol_load_texc(fs_file fin, struct s_texc *tp) -{ - get_array(fin, tp->u, 2); -} - -static void sol_load_geom(fs_file fin, struct s_geom *gp) -{ - get_index(fin, &gp->mi); - get_index(fin, &gp->ti); - get_index(fin, &gp->si); - get_index(fin, &gp->vi); - get_index(fin, &gp->tj); - get_index(fin, &gp->sj); - get_index(fin, &gp->vj); - get_index(fin, &gp->tk); - get_index(fin, &gp->sk); - get_index(fin, &gp->vk); -} - -static void sol_load_lump(fs_file fin, struct s_lump *lp) -{ - get_index(fin, &lp->fl); - get_index(fin, &lp->v0); - get_index(fin, &lp->vc); - get_index(fin, &lp->e0); - get_index(fin, &lp->ec); - get_index(fin, &lp->g0); - get_index(fin, &lp->gc); - get_index(fin, &lp->s0); - get_index(fin, &lp->sc); -} - -static void sol_load_node(fs_file fin, struct s_node *np) -{ - get_index(fin, &np->si); - get_index(fin, &np->ni); - get_index(fin, &np->nj); - get_index(fin, &np->l0); - get_index(fin, &np->lc); -} - -static void sol_load_path(fs_file fin, struct s_path *pp) -{ - get_array(fin, pp->p, 3); - get_float(fin, &pp->t); - get_index(fin, &pp->pi); - get_index(fin, &pp->f); - get_index(fin, &pp->s); - - pp->tm = TIME_TO_MS(pp->t); - pp->t = MS_TO_TIME(pp->tm); - - if (sol_version >= SOL_VER_PATH_FLAGS) - get_index(fin, &pp->fl); - - pp->e[0] = 1.0f; - pp->e[1] = 0.0f; - pp->e[2] = 0.0f; - pp->e[3] = 0.0f; - - if (pp->fl & P_ORIENTED) - get_array(fin, pp->e, 4); -} - -static void sol_load_body(fs_file fin, struct s_body *bp) -{ - get_index(fin, &bp->pi); - get_index(fin, &bp->ni); - get_index(fin, &bp->l0); - get_index(fin, &bp->lc); - get_index(fin, &bp->g0); - get_index(fin, &bp->gc); -} - -static void sol_load_item(fs_file fin, struct s_item *hp) -{ - get_array(fin, hp->p, 3); - get_index(fin, &hp->t); - get_index(fin, &hp->n); -} - -static void sol_load_goal(fs_file fin, struct s_goal *zp) -{ - get_array(fin, zp->p, 3); - get_float(fin, &zp->r); -} - -static void sol_load_swch(fs_file fin, struct s_swch *xp) -{ - get_array(fin, xp->p, 3); - get_float(fin, &xp->r); - get_index(fin, &xp->pi); - get_float(fin, &xp->t0); - get_float(fin, &xp->t); - get_index(fin, &xp->f0); - get_index(fin, &xp->f); - get_index(fin, &xp->i); - - xp->t0m = TIME_TO_MS(xp->t0); - xp->tm = TIME_TO_MS(xp->t); - - xp->t0 = MS_TO_TIME(xp->t0m); - xp->t = MS_TO_TIME(xp->tm); -} - -static void sol_load_bill(fs_file fin, struct s_bill *rp) -{ - get_index(fin, &rp->fl); - get_index(fin, &rp->mi); - get_float(fin, &rp->t); - get_float(fin, &rp->d); - get_array(fin, rp->w, 3); - get_array(fin, rp->h, 3); - get_array(fin, rp->rx, 3); - get_array(fin, rp->ry, 3); - get_array(fin, rp->rz, 3); - get_array(fin, rp->p, 3); -} - -static void sol_load_jump(fs_file fin, struct s_jump *jp) -{ - get_array(fin, jp->p, 3); - get_array(fin, jp->q, 3); - get_float(fin, &jp->r); -} - -static void sol_load_ball(fs_file fin, struct s_ball *bp) -{ - get_array(fin, bp->p, 3); - get_float(fin, &bp->r); - - bp->e[0][0] = bp->E[0][0] = 1.0f; - bp->e[0][1] = bp->E[0][1] = 0.0f; - bp->e[0][2] = bp->E[0][2] = 0.0f; - - bp->e[1][0] = bp->E[1][0] = 0.0f; - bp->e[1][1] = bp->E[1][1] = 1.0f; - bp->e[1][2] = bp->E[1][2] = 0.0f; - - bp->e[2][0] = bp->E[2][0] = 0.0f; - bp->e[2][1] = bp->E[2][1] = 0.0f; - bp->e[2][2] = bp->E[2][2] = 1.0f; -} - -static void sol_load_view(fs_file fin, struct s_view *wp) -{ - get_array(fin, wp->p, 3); - get_array(fin, wp->q, 3); -} - -static void sol_load_dict(fs_file fin, struct s_dict *dp) -{ - get_index(fin, &dp->ai); - get_index(fin, &dp->aj); -} - -static void sol_load_indx(fs_file fin, struct s_file *fp) -{ - get_index(fin, &fp->ac); - get_index(fin, &fp->dc); - get_index(fin, &fp->mc); - get_index(fin, &fp->vc); - get_index(fin, &fp->ec); - get_index(fin, &fp->sc); - get_index(fin, &fp->tc); - get_index(fin, &fp->gc); - get_index(fin, &fp->lc); - get_index(fin, &fp->nc); - get_index(fin, &fp->pc); - get_index(fin, &fp->bc); - get_index(fin, &fp->hc); - get_index(fin, &fp->zc); - get_index(fin, &fp->jc); - get_index(fin, &fp->xc); - get_index(fin, &fp->rc); - get_index(fin, &fp->uc); - get_index(fin, &fp->wc); - get_index(fin, &fp->ic); -} - -static int sol_load_file(fs_file fin, struct s_file *fp) -{ - int i; - - if (!sol_file(fin)) - return 0; - - sol_load_indx(fin, fp); - - if (fp->ac) - fp->av = (char *) calloc(fp->ac, sizeof (char)); - if (fp->mc) - fp->mv = (struct s_mtrl *) calloc(fp->mc, sizeof (struct s_mtrl)); - if (fp->vc) - fp->vv = (struct s_vert *) calloc(fp->vc, sizeof (struct s_vert)); - if (fp->ec) - fp->ev = (struct s_edge *) calloc(fp->ec, sizeof (struct s_edge)); - if (fp->sc) - fp->sv = (struct s_side *) calloc(fp->sc, sizeof (struct s_side)); - if (fp->tc) - fp->tv = (struct s_texc *) calloc(fp->tc, sizeof (struct s_texc)); - if (fp->gc) - fp->gv = (struct s_geom *) calloc(fp->gc, sizeof (struct s_geom)); - if (fp->lc) - fp->lv = (struct s_lump *) calloc(fp->lc, sizeof (struct s_lump)); - if (fp->nc) - fp->nv = (struct s_node *) calloc(fp->nc, sizeof (struct s_node)); - if (fp->pc) - fp->pv = (struct s_path *) calloc(fp->pc, sizeof (struct s_path)); - if (fp->bc) - fp->bv = (struct s_body *) calloc(fp->bc, sizeof (struct s_body)); - if (fp->hc) - fp->hv = (struct s_item *) calloc(fp->hc, sizeof (struct s_item)); - if (fp->zc) - fp->zv = (struct s_goal *) calloc(fp->zc, sizeof (struct s_goal)); - if (fp->jc) - fp->jv = (struct s_jump *) calloc(fp->jc, sizeof (struct s_jump)); - if (fp->xc) - fp->xv = (struct s_swch *) calloc(fp->xc, sizeof (struct s_swch)); - if (fp->rc) - fp->rv = (struct s_bill *) calloc(fp->rc, sizeof (struct s_bill)); - if (fp->uc) - fp->uv = (struct s_ball *) calloc(fp->uc, sizeof (struct s_ball)); - if (fp->wc) - fp->wv = (struct s_view *) calloc(fp->wc, sizeof (struct s_view)); - if (fp->dc) - fp->dv = (struct s_dict *) calloc(fp->dc, sizeof (struct s_dict)); - if (fp->ic) - fp->iv = (int *) calloc(fp->ic, sizeof (int)); - - if (fp->ac) - fs_read(fp->av, 1, fp->ac, fin); - - for (i = 0; i < fp->dc; i++) sol_load_dict(fin, fp->dv + i); - for (i = 0; i < fp->mc; i++) sol_load_mtrl(fin, fp->mv + i); - for (i = 0; i < fp->vc; i++) sol_load_vert(fin, fp->vv + i); - for (i = 0; i < fp->ec; i++) sol_load_edge(fin, fp->ev + i); - for (i = 0; i < fp->sc; i++) sol_load_side(fin, fp->sv + i); - for (i = 0; i < fp->tc; i++) sol_load_texc(fin, fp->tv + i); - for (i = 0; i < fp->gc; i++) sol_load_geom(fin, fp->gv + i); - for (i = 0; i < fp->lc; i++) sol_load_lump(fin, fp->lv + i); - for (i = 0; i < fp->nc; i++) sol_load_node(fin, fp->nv + i); - for (i = 0; i < fp->pc; i++) sol_load_path(fin, fp->pv + i); - for (i = 0; i < fp->bc; i++) sol_load_body(fin, fp->bv + i); - for (i = 0; i < fp->hc; i++) sol_load_item(fin, fp->hv + i); - for (i = 0; i < fp->zc; i++) sol_load_goal(fin, fp->zv + i); - for (i = 0; i < fp->jc; i++) sol_load_jump(fin, fp->jv + i); - for (i = 0; i < fp->xc; i++) sol_load_swch(fin, fp->xv + i); - for (i = 0; i < fp->rc; i++) sol_load_bill(fin, fp->rv + i); - for (i = 0; i < fp->uc; i++) sol_load_ball(fin, fp->uv + i); - for (i = 0; i < fp->wc; i++) sol_load_view(fin, fp->wv + i); - for (i = 0; i < fp->ic; i++) get_index(fin, fp->iv + i); - - return 1; -} - -static int sol_load_head(fs_file fin, struct s_file *fp) -{ - if (!sol_file(fin)) - return 0; - - sol_load_indx(fin, fp); - - if (fp->ac) - { - fp->av = (char *) calloc(fp->ac, sizeof (char)); - fs_read(fp->av, 1, fp->ac, fin); - } - - if (fp->dc) - { - int i; - - fp->dv = (struct s_dict *) calloc(fp->dc, sizeof (struct s_dict)); - - for (i = 0; i < fp->dc; i++) - sol_load_dict(fin, fp->dv + i); - } - - return 1; -} - -int sol_load_only_file(struct s_file *fp, const char *filename) -{ - fs_file fin; - int res = 0; - - if ((fin = fs_open(filename, "r"))) - { - res = sol_load_file(fin, fp); - fs_close(fin); - } - return res; -} - -int sol_load_only_head(struct s_file *fp, const char *filename) -{ - fs_file fin; - int res = 0; - - if ((fin = fs_open(filename, "r"))) - { - res = sol_load_head(fin, fp); - fs_close(fin); - } - return res; -} - -/*---------------------------------------------------------------------------*/ - -static void sol_stor_mtrl(fs_file fout, struct s_mtrl *mp) -{ - put_array(fout, mp->d, 4); - put_array(fout, mp->a, 4); - put_array(fout, mp->s, 4); - put_array(fout, mp->e, 4); - put_array(fout, mp->h, 1); - put_index(fout, mp->fl); - - fs_write(mp->f, 1, PATHMAX, fout); -} - -static void sol_stor_vert(fs_file fout, struct s_vert *vp) -{ - put_array(fout, vp->p, 3); -} - -static void sol_stor_edge(fs_file fout, struct s_edge *ep) -{ - put_index(fout, ep->vi); - put_index(fout, ep->vj); -} - -static void sol_stor_side(fs_file fout, struct s_side *sp) -{ - put_array(fout, sp->n, 3); - put_float(fout, sp->d); -} - -static void sol_stor_texc(fs_file fout, struct s_texc *tp) -{ - put_array(fout, tp->u, 2); -} - -static void sol_stor_geom(fs_file fout, struct s_geom *gp) -{ - put_index(fout, gp->mi); - put_index(fout, gp->ti); - put_index(fout, gp->si); - put_index(fout, gp->vi); - put_index(fout, gp->tj); - put_index(fout, gp->sj); - put_index(fout, gp->vj); - put_index(fout, gp->tk); - put_index(fout, gp->sk); - put_index(fout, gp->vk); -} - -static void sol_stor_lump(fs_file fout, struct s_lump *lp) -{ - put_index(fout, lp->fl); - put_index(fout, lp->v0); - put_index(fout, lp->vc); - put_index(fout, lp->e0); - put_index(fout, lp->ec); - put_index(fout, lp->g0); - put_index(fout, lp->gc); - put_index(fout, lp->s0); - put_index(fout, lp->sc); -} - -static void sol_stor_node(fs_file fout, struct s_node *np) -{ - put_index(fout, np->si); - put_index(fout, np->ni); - put_index(fout, np->nj); - put_index(fout, np->l0); - put_index(fout, np->lc); -} - -static void sol_stor_path(fs_file fout, struct s_path *pp) -{ - put_array(fout, pp->p, 3); - put_float(fout, pp->t); - put_index(fout, pp->pi); - put_index(fout, pp->f); - put_index(fout, pp->s); - put_index(fout, pp->fl); - - if (pp->fl & P_ORIENTED) - put_array(fout, pp->e, 4); -} - -static void sol_stor_body(fs_file fout, struct s_body *bp) -{ - put_index(fout, bp->pi); - put_index(fout, bp->ni); - put_index(fout, bp->l0); - put_index(fout, bp->lc); - put_index(fout, bp->g0); - put_index(fout, bp->gc); -} - -static void sol_stor_item(fs_file fout, struct s_item *hp) -{ - put_array(fout, hp->p, 3); - put_index(fout, hp->t); - put_index(fout, hp->n); -} - -static void sol_stor_goal(fs_file fout, struct s_goal *zp) -{ - put_array(fout, zp->p, 3); - put_float(fout, zp->r); -} - -static void sol_stor_swch(fs_file fout, struct s_swch *xp) -{ - put_array(fout, xp->p, 3); - put_float(fout, xp->r); - put_index(fout, xp->pi); - put_float(fout, xp->t0); - put_float(fout, xp->t); - put_index(fout, xp->f0); - put_index(fout, xp->f); - put_index(fout, xp->i); -} - -static void sol_stor_bill(fs_file fout, struct s_bill *rp) -{ - put_index(fout, rp->fl); - put_index(fout, rp->mi); - put_float(fout, rp->t); - put_float(fout, rp->d); - put_array(fout, rp->w, 3); - put_array(fout, rp->h, 3); - put_array(fout, rp->rx, 3); - put_array(fout, rp->ry, 3); - put_array(fout, rp->rz, 3); - put_array(fout, rp->p, 3); -} - -static void sol_stor_jump(fs_file fout, struct s_jump *jp) -{ - put_array(fout, jp->p, 3); - put_array(fout, jp->q, 3); - put_float(fout, jp->r); -} - -static void sol_stor_ball(fs_file fout, struct s_ball *bp) -{ - put_array(fout, bp->p, 3); - put_float(fout, bp->r); -} - -static void sol_stor_view(fs_file fout, struct s_view *wp) -{ - put_array(fout, wp->p, 3); - put_array(fout, wp->q, 3); -} - -static void sol_stor_dict(fs_file fout, struct s_dict *dp) -{ - put_index(fout, dp->ai); - put_index(fout, dp->aj); -} - -static void sol_stor_file(fs_file fout, struct s_file *fp) -{ - int i; - int magic = SOL_MAGIC; - int version = SOL_VER_CURRENT; - - put_index(fout, magic); - put_index(fout, version); - - put_index(fout, fp->ac); - put_index(fout, fp->dc); - put_index(fout, fp->mc); - put_index(fout, fp->vc); - put_index(fout, fp->ec); - put_index(fout, fp->sc); - put_index(fout, fp->tc); - put_index(fout, fp->gc); - put_index(fout, fp->lc); - put_index(fout, fp->nc); - put_index(fout, fp->pc); - put_index(fout, fp->bc); - put_index(fout, fp->hc); - put_index(fout, fp->zc); - put_index(fout, fp->jc); - put_index(fout, fp->xc); - put_index(fout, fp->rc); - put_index(fout, fp->uc); - put_index(fout, fp->wc); - put_index(fout, fp->ic); - - fs_write(fp->av, 1, fp->ac, fout); - - for (i = 0; i < fp->dc; i++) sol_stor_dict(fout, fp->dv + i); - for (i = 0; i < fp->mc; i++) sol_stor_mtrl(fout, fp->mv + i); - for (i = 0; i < fp->vc; i++) sol_stor_vert(fout, fp->vv + i); - for (i = 0; i < fp->ec; i++) sol_stor_edge(fout, fp->ev + i); - for (i = 0; i < fp->sc; i++) sol_stor_side(fout, fp->sv + i); - for (i = 0; i < fp->tc; i++) sol_stor_texc(fout, fp->tv + i); - for (i = 0; i < fp->gc; i++) sol_stor_geom(fout, fp->gv + i); - for (i = 0; i < fp->lc; i++) sol_stor_lump(fout, fp->lv + i); - for (i = 0; i < fp->nc; i++) sol_stor_node(fout, fp->nv + i); - for (i = 0; i < fp->pc; i++) sol_stor_path(fout, fp->pv + i); - for (i = 0; i < fp->bc; i++) sol_stor_body(fout, fp->bv + i); - for (i = 0; i < fp->hc; i++) sol_stor_item(fout, fp->hv + i); - for (i = 0; i < fp->zc; i++) sol_stor_goal(fout, fp->zv + i); - for (i = 0; i < fp->jc; i++) sol_stor_jump(fout, fp->jv + i); - for (i = 0; i < fp->xc; i++) sol_stor_swch(fout, fp->xv + i); - for (i = 0; i < fp->rc; i++) sol_stor_bill(fout, fp->rv + i); - for (i = 0; i < fp->uc; i++) sol_stor_ball(fout, fp->uv + i); - for (i = 0; i < fp->wc; i++) sol_stor_view(fout, fp->wv + i); - for (i = 0; i < fp->ic; i++) put_index(fout, fp->iv[i]); -} - -/*---------------------------------------------------------------------------*/ - -int sol_stor(struct s_file *fp, const char *filename) -{ - fs_file fout; - - if ((fout = fs_open(filename, "w"))) - { - sol_stor_file(fout, fp); - fs_close(fout); - - return 1; - } - return 0; -} - -void sol_free(struct s_file *fp) -{ - if (fp->av) free(fp->av); - if (fp->mv) free(fp->mv); - if (fp->vv) free(fp->vv); - if (fp->ev) free(fp->ev); - if (fp->sv) free(fp->sv); - if (fp->tv) free(fp->tv); - if (fp->gv) free(fp->gv); - if (fp->lv) free(fp->lv); - if (fp->nv) free(fp->nv); - if (fp->pv) free(fp->pv); - if (fp->bv) free(fp->bv); - if (fp->hv) free(fp->hv); - if (fp->zv) free(fp->zv); - if (fp->jv) free(fp->jv); - if (fp->xv) free(fp->xv); - if (fp->rv) free(fp->rv); - if (fp->uv) free(fp->uv); - if (fp->wv) free(fp->wv); - if (fp->dv) free(fp->dv); - if (fp->iv) free(fp->iv); - - memset(fp, 0, sizeof (struct s_file)); -} - -/*---------------------------------------------------------------------------*/ diff --git a/share/solid.h b/share/solid.h deleted file mode 100644 index 23d1ae1..0000000 --- a/share/solid.h +++ /dev/null @@ -1,343 +0,0 @@ -/* - * Copyright (C) 2003 Robert Kooima - * - * NEVERBALL is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2 of the License, - * or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - */ - -#ifndef SOL_H -#define SOL_H - -#include "glext.h" -#include "base_config.h" - -/* - * Some might be taken aback at the terseness of the names of the - * structure members and the variables used by the functions that - * access them. Yes, yes, I know: readability. I contend that once - * the naming convention is embraced, the names become more readable - * than any verbose alternative, and their brevity and uniformity do - * more to augment readability than longVariableNames ever could. - * - * Members and variables are named XY. X determines the type of - * structure to which the variable refers. Y determines the usage of - * the variable. - * - * The Xs are as documented by struct s_file: - * - * f File (struct s_file) - * m Material (struct s_mtrl) - * v Vertex (struct s_vert) - * e Edge (struct s_edge) - * s Side (struct s_side) - * t Texture coord (struct s_texc) - * g Geometry (struct s_geom) - * l Lump (struct s_lump) - * n Node (struct s_node) - * p Path (struct s_path) - * b Body (struct s_body) - * h Item (struct s_item) - * z Goal (struct s_goal) - * j Jump (struct s_jump) - * x Switch (struct s_swch) - * r Billboard (struct s_bill) - * u User (struct s_ball) - * w Viewpoint (struct s_view) - * d Dictionary (struct s_dict) - * i Index (int) - * a Text (char) - * - * The Ys are as follows: - * - * c Counter - * p Pointer - * v Vector (array) - * 0 Index of the first - * i Index - * j Subindex - * k Subsubindex - * - * Thus "up" is a pointer to a user structure. "lc" is the number of - * lumps. "ei" and "ej" are edge indices into some "ev" edge vector. - * An edge is defined by two vertices, so an edge structure consists - * of "vi" and "vj". And so on. - * - * Those members that do not conform to this convention are explicitly - * documented with a comment. - * - * These prefixes are still available: c k o q y. - */ - -/*---------------------------------------------------------------------------*/ - -/* Material type flags */ - -#define M_OPAQUE 1 -#define M_TRANSPARENT 2 -#define M_REFLECTIVE 4 -#define M_ENVIRONMENT 8 -#define M_ADDITIVE 16 -#define M_CLAMPED 32 -#define M_DECAL 64 -#define M_TWO_SIDED 128 -#define M_SHADOWED 256 - -/* Billboard types. */ - -#define B_EDGE 1 -#define B_FLAT 2 -#define B_ADDITIVE 4 -#define B_NOFACE 8 - -/* Lump flags. */ - -#define L_DETAIL 1 - -/* Item types. */ - -#define ITEM_NONE 0 -#define ITEM_COIN 1 -#define ITEM_GROW 2 -#define ITEM_SHRINK 3 - -/* Path flags. */ - -#define P_ORIENTED 1 - -/*---------------------------------------------------------------------------*/ - -struct s_mtrl -{ - float d[4]; /* diffuse color */ - float a[4]; /* ambient color */ - float s[4]; /* specular color */ - float e[4]; /* emission color */ - float h[1]; /* specular exponent */ - float angle; - - int fl; /* material flags */ - - GLuint o; /* OpenGL texture object */ - char f[PATHMAX]; /* texture file name */ -}; - -struct s_vert -{ - float p[3]; /* vertex position */ -}; - -struct s_edge -{ - int vi; - int vj; -}; - -struct s_side -{ - float n[3]; /* plane normal vector */ - float d; /* distance from origin */ -}; - -struct s_texc -{ - float u[2]; /* texture coordinate */ -}; - -struct s_geom -{ - int mi; - int ti, si, vi; - int tj, sj, vj; - int tk, sk, vk; -}; - -struct s_lump -{ - int fl; /* lump flags */ - int v0, vc; - int e0, ec; - int g0, gc; - int s0, sc; -}; - -struct s_node -{ - int si; - int ni; - int nj; - int l0; - int lc; -}; - -struct s_path -{ - float p[3]; /* starting position */ - float e[4]; /* orientation (quaternion) */ - float t; /* travel time */ - int tm; /* milliseconds */ - - int pi; - int f; /* enable flag */ - int s; /* smooth flag */ - - int fl; /* flags */ - - /* TODO: merge enable and smooth into flags. */ -}; - -struct s_body -{ - float t; /* time on current path */ - int tm; /* milliseconds */ - - GLuint ol; /* opaque geometry list */ - GLuint tl; /* transparent geometry list */ - GLuint rl; /* reflective geometry list */ - GLuint sl; /* shadowed geometry list */ - - int pi; - int ni; - int l0; - int lc; - int g0; - int gc; -}; - -struct s_item -{ - float p[3]; /* position */ - int t; /* type */ - int n; /* value */ -}; - -struct s_goal -{ - float p[3]; /* position */ - float r; /* radius */ -}; - -struct s_swch -{ - float p[3]; /* position */ - float r; /* radius */ - int pi; /* the linked path */ - - float t0; /* default timer */ - int t0m; /* milliseconds */ - float t; /* current timer */ - int tm; /* milliseconds */ - int f0; /* default state */ - int f; /* current state */ - int i; /* is invisible? */ - int e; /* is a ball inside it? */ -}; - -struct s_bill -{ - int fl; - int mi; - float t; /* repeat time interval */ - float d; /* distance */ - - float w[3]; /* width coefficients */ - float h[3]; /* height coefficients */ - - float rx[3]; /* X rotation coefficients */ - float ry[3]; /* Y rotation coefficients */ - float rz[3]; /* Z rotation coefficients */ - - float p[3]; -}; - -struct s_jump -{ - float p[3]; /* position */ - float q[3]; /* target position */ - float r; /* radius */ -}; - -struct s_ball -{ - float e[3][3]; /* basis of orientation */ - float p[3]; /* position vector */ - float v[3]; /* velocity vector */ - float w[3]; /* angular velocity vector */ - float E[3][3]; /* basis of pendulum */ - float W[3]; /* angular pendulum velocity */ - float r; /* radius */ -}; - -struct s_view -{ - float p[3]; - float q[3]; -}; - -struct s_dict -{ - int ai; - int aj; -}; - -struct s_file -{ - int ac; - int mc; - int vc; - int ec; - int sc; - int tc; - int gc; - int lc; - int nc; - int pc; - int bc; - int hc; - int zc; - int jc; - int xc; - int rc; - int uc; - int wc; - int dc; - int ic; - - char *av; - struct s_mtrl *mv; - struct s_vert *vv; - struct s_edge *ev; - struct s_side *sv; - struct s_texc *tv; - struct s_geom *gv; - struct s_lump *lv; - struct s_node *nv; - struct s_path *pv; - struct s_body *bv; - struct s_item *hv; - struct s_goal *zv; - struct s_jump *jv; - struct s_swch *xv; - struct s_bill *rv; - struct s_ball *uv; - struct s_view *wv; - struct s_dict *dv; - int *iv; -}; - -/*---------------------------------------------------------------------------*/ - -int sol_load_only_file(struct s_file *, const char *); -int sol_load_only_head(struct s_file *, const char *); -int sol_stor(struct s_file *, const char *); -void sol_free(struct s_file *); - -/*---------------------------------------------------------------------------*/ - -#endif diff --git a/share/solid_all.c b/share/solid_all.c index ea2836c..eb828ee 100644 --- a/share/solid_all.c +++ b/share/solid_all.c @@ -17,7 +17,8 @@ #include "solid_all.h" #include "solid_cmd.h" -#include "solid.h" +#include "solid_vary.h" + #include "common.h" #include "vec3.h" #include "geom.h" @@ -36,14 +37,14 @@ static float derp(float t) } #endif -void sol_body_p(float p[3], const struct s_file *fp, int pi, float t) +void sol_body_p(float p[3], const struct s_vary *vary, int pi, float t) { float v[3]; if (pi >= 0) { - const struct s_path *pp = fp->pv + pi; - const struct s_path *pq = fp->pv + pp->pi; + const struct b_path *pp = vary->base->pv + pi; + const struct b_path *pq = vary->base->pv + pp->pi; float s = MIN(t / pp->t, 1.0f); @@ -59,15 +60,15 @@ void sol_body_p(float p[3], const struct s_file *fp, int pi, float t) } void sol_body_v(float v[3], - const struct s_file *fp, + const struct s_vary *vary, int pi, float t, float dt) { - if (pi >= 0 && fp->pv[pi].f) + if (pi >= 0 && vary->pv[pi].f) { float p[3], q[3]; - sol_body_p(p, fp, pi, t); - sol_body_p(q, fp, pi, t + dt); + sol_body_p(p, vary, pi, t); + sol_body_p(q, vary, pi, t + dt); v_sub(v, q, p); @@ -84,19 +85,19 @@ void sol_body_v(float v[3], } void sol_body_e(float e[4], - const struct s_file *fp, - const struct s_body *bp, + const struct s_vary *vary, + const struct v_body *bp, float dt) { - struct s_path *pp = fp->pv + bp->pi; + struct b_path *pp = vary->base->pv + bp->pi; if (bp->pi >= 0) { - struct s_path *pq = fp->pv + pp->pi; + struct b_path *pq = vary->base->pv + pp->pi; if (pp->fl & P_ORIENTED || pq->fl & P_ORIENTED) { - if (!pp->f) + if (!vary->pv[bp->pi].f) dt = 0; q_slerp(e, pp->e, pq->e, (bp->t + dt) / pp->t); @@ -111,14 +112,14 @@ void sol_body_e(float e[4], } void sol_body_w(float w[3], - const struct s_file *fp, - const struct s_body *bp) + const struct s_vary *vary, + const struct v_body *bp) { - struct s_path *pp = fp->pv + bp->pi; + struct b_path *pp = vary->base->pv + bp->pi; - if (bp->pi >= 0 && pp->f) + if (bp->pi >= 0 && vary->pv[bp->pi].f) { - struct s_path *pq = fp->pv + pp->pi; + struct b_path *pq = vary->base->pv + pp->pi; if (pp->fl & P_ORIENTED || pq->fl & P_ORIENTED) { @@ -200,7 +201,7 @@ void sol_rotate(float e[3][3], const float w[3], float dt) * Compute the new angular velocity and orientation of a ball pendulum. * A gives the accelleration of the ball. G gives the gravity vector. */ -void sol_pendulum(struct s_ball *up, +void sol_pendulum(struct v_ball *up, const float a[3], const float g[3], float dt) { @@ -248,22 +249,22 @@ void sol_pendulum(struct s_ball *up, /*---------------------------------------------------------------------------*/ -static void sol_path_flag(struct s_file *fp, int pi, int f) +static void sol_path_flag(struct s_vary *vary, int pi, int f) { union cmd cmd; - if (fp->pv[pi].f == f) + if (vary->pv[pi].f == f) return; - fp->pv[pi].f = f; + vary->pv[pi].f = f; cmd.type = CMD_PATH_FLAG; cmd.pathflag.pi = pi; - cmd.pathflag.f = fp->pv[pi].f; + cmd.pathflag.f = vary->pv[pi].f; sol_cmd_enq(&cmd); } -static void sol_path_loop(struct s_file *fp, int p0, int f) +static void sol_path_loop(struct s_vary *vary, int p0, int f) { int pi = p0; int pj = p0; @@ -271,11 +272,11 @@ static void sol_path_loop(struct s_file *fp, int p0, int f) do /* Tortoise and hare cycle traverser. */ { - sol_path_flag(fp, pi, f); + sol_path_flag(vary, pi, f); - pi = fp->pv[pi].pi; - pj = fp->pv[pj].pi; - pj = fp->pv[pj].pi; + pi = vary->base->pv[pi].pi; + pj = vary->base->pv[pj].pi; + pj = vary->base->pv[pj].pi; } while (pi != pj); @@ -292,10 +293,10 @@ static void sol_path_loop(struct s_file *fp, int p0, int f) do { - sol_path_flag(fp, pi, f); + sol_path_flag(vary, pi, f); - pi = fp->pv[pi].pi; - pj = fp->pv[pj].pi; + pi = vary->base->pv[pi].pi; + pj = vary->base->pv[pj].pi; } while (pi != pj && pi != pk); } @@ -305,26 +306,26 @@ static void sol_path_loop(struct s_file *fp, int p0, int f) /* * Compute the states of all switches after DT seconds have passed. */ -void sol_swch_step(struct s_file *fp, float dt, int ms) +void sol_swch_step(struct s_vary *vary, float dt, int ms) { int xi; union cmd cmd; - for (xi = 0; xi < fp->xc; xi++) + for (xi = 0; xi < vary->xc; xi++) { - struct s_swch *xp = fp->xv + xi; + struct v_swch *xp = vary->xv + xi; - if (xp->tm < xp->t0m) + if (xp->tm < xp->base->tm) { xp->t += dt; xp->tm += ms; - if (xp->tm >= xp->t0m) + if (xp->tm >= xp->base->tm) { - sol_path_loop(fp, xp->pi, xp->f0); + sol_path_loop(vary, xp->base->pi, xp->base->f); - xp->f = xp->f0; + xp->f = xp->base->f; cmd.type = CMD_SWCH_TOGGLE; cmd.swchtoggle.xi = xi; @@ -337,27 +338,27 @@ void sol_swch_step(struct s_file *fp, float dt, int ms) /* * Compute the positions of all bodies after DT seconds have passed. */ -void sol_body_step(struct s_file *fp, float dt, int ms) +void sol_body_step(struct s_vary *vary, float dt, int ms) { int i; union cmd cmd; - for (i = 0; i < fp->bc; i++) + for (i = 0; i < vary->bc; i++) { - struct s_body *bp = fp->bv + i; - struct s_path *pp = fp->pv + bp->pi; + struct v_body *bp = vary->bv + i; + struct v_path *pp = vary->pv + bp->pi; if (bp->pi >= 0 && pp->f) { bp->t += dt; bp->tm += ms; - if (bp->tm >= pp->tm) + if (bp->tm >= pp->base->tm) { bp->t = 0; bp->tm = 0; - bp->pi = pp->pi; + bp->pi = pp->base->pi; cmd.type = CMD_BODY_TIME; cmd.bodytime.bi = i; @@ -376,13 +377,13 @@ void sol_body_step(struct s_file *fp, float dt, int ms) /* * Compute the positions of all balls after DT seconds have passed. */ -void sol_ball_step(struct s_file *fp, float dt) +void sol_ball_step(struct s_vary *vary, float dt) { int i; - for (i = 0; i < fp->uc; i++) + for (i = 0; i < vary->uc; i++) { - struct s_ball *up = fp->uv + i; + struct v_ball *up = vary->uv + i; v_mad(up->p, up->p, up->v, dt); @@ -392,15 +393,15 @@ void sol_ball_step(struct s_file *fp, float dt) /*---------------------------------------------------------------------------*/ -int sol_item_test(struct s_file *fp, float *p, float item_r) +int sol_item_test(struct s_vary *vary, float *p, float item_r) { - const float *ball_p = fp->uv->p; - const float ball_r = fp->uv->r; + const float *ball_p = vary->uv->p; + const float ball_r = vary->uv->r; int hi; - for (hi = 0; hi < fp->hc; hi++) + for (hi = 0; hi < vary->hc; hi++) { - struct s_item *hp = fp->hv + hi; + struct v_item *hp = vary->hv + hi; float r[3]; v_sub(r, ball_p, hp->p); @@ -417,15 +418,15 @@ int sol_item_test(struct s_file *fp, float *p, float item_r) return -1; } -struct s_goal *sol_goal_test(struct s_file *fp, float *p, int ui) +struct b_goal *sol_goal_test(struct s_vary *vary, float *p, int ui) { - const float *ball_p = fp->uv[ui].p; - const float ball_r = fp->uv[ui].r; + const float *ball_p = vary->uv[ui].p; + const float ball_r = vary->uv[ui].r; int zi; - for (zi = 0; zi < fp->zc; zi++) + for (zi = 0; zi < vary->base->zc; zi++) { - struct s_goal *zp = fp->zv + zi; + struct b_goal *zp = vary->base->zv + zi; float r[3]; r[0] = ball_p[0] - zp->p[0]; @@ -449,15 +450,15 @@ struct s_goal *sol_goal_test(struct s_file *fp, float *p, int ui) /* * Test for a ball entering a teleporter. */ -int sol_jump_test(struct s_file *fp, float *p, int ui) +int sol_jump_test(struct s_vary *vary, float *p, int ui) { - const float *ball_p = fp->uv[ui].p; - const float ball_r = fp->uv[ui].r; + const float *ball_p = vary->uv[ui].p; + const float ball_r = vary->uv[ui].r; int ji, in = 0; - for (ji = 0; ji < fp->jc; ji++) + for (ji = 0; ji < vary->base->jc; ji++) { - struct s_jump *jp = fp->jv + ji; + struct b_jump *jp = vary->base->jv + ji; float d, r[3]; r[0] = ball_p[0] - jp->p[0]; @@ -496,32 +497,32 @@ int sol_jump_test(struct s_file *fp, float *p, int ui) /* * Test for a ball entering a switch. */ -int sol_swch_test(struct s_file *fp, int ui) +int sol_swch_test(struct s_vary *vary, int ui) { - const float *ball_p = fp->uv[ui].p; - const float ball_r = fp->uv[ui].r; + const float *ball_p = vary->uv[ui].p; + const float ball_r = vary->uv[ui].r; union cmd cmd; int xi, rc = SWCH_OUTSIDE; - for (xi = 0; xi < fp->xc; xi++) + for (xi = 0; xi < vary->xc; xi++) { - struct s_swch *xp = fp->xv + xi; + struct v_swch *xp = vary->xv + xi; /* FIXME enter/exit events don't work for timed switches */ - if (xp->t0m == 0 || xp->f == xp->f0) + if (xp->base->t == 0 || xp->f == xp->base->f) { float d, r[3]; - r[0] = ball_p[0] - xp->p[0]; - r[1] = ball_p[2] - xp->p[2]; + r[0] = ball_p[0] - xp->base->p[0]; + r[1] = ball_p[2] - xp->base->p[2]; r[2] = 0; /* Distance of the far side from the edge of the halo. */ - d = v_len(r) + ball_r - xp->r; + d = v_len(r) + ball_r - xp->base->r; /* * The "inside" distance, which must be cleared before @@ -530,14 +531,14 @@ int sol_swch_test(struct s_file *fp, int ui) */ if (d <= ball_r * 2 && - ball_p[1] > xp->p[1] && - ball_p[1] < xp->p[1] + SWCH_HEIGHT / 2) + ball_p[1] > xp->base->p[1] && + ball_p[1] < xp->base->p[1] + SWCH_HEIGHT / 2) { if (!xp->e && d <= 0.0f) { /* The ball enters. */ - if (xp->t0m == 0) + if (xp->base->tm == 0) { xp->e = 1; @@ -554,11 +555,11 @@ int sol_swch_test(struct s_file *fp, int ui) cmd.swchtoggle.xi = xi; sol_cmd_enq(&cmd); - sol_path_loop(fp, xp->pi, xp->f); + sol_path_loop(vary, xp->base->pi, xp->f); /* It toggled to non-default state, start the timer. */ - if (xp->f != xp->f0) + if (xp->f != xp->base->f) { xp->t = 0.0f; xp->tm = 0; @@ -566,7 +567,7 @@ int sol_swch_test(struct s_file *fp, int ui) /* If visible, set the result. */ - if (!xp->i) + if (!xp->base->i) rc = SWCH_TRIGGER; } } diff --git a/share/solid_all.h b/share/solid_all.h index 56ecbfc..d6d2c6a 100644 --- a/share/solid_all.h +++ b/share/solid_all.h @@ -1,24 +1,23 @@ #ifndef SOLID_ALL_H #define SOLID_ALL_H -#include "solid.h" +#include "solid_vary.h" -void sol_body_p(float p[3], const struct s_file *fp, int pi, float t); -void sol_body_v(float v[3], const struct s_file *fp, int pi, float t, float dt); -void sol_body_e(float e[3], - const struct s_file *fp, - const struct s_body *bp, float dt); -void sol_body_w(float w[3], const struct s_file *fp, const struct s_body *bp); +void sol_body_p(float p[3], const struct s_vary *, int pi, float t); +void sol_body_v(float v[3], const struct s_vary *, int pi, float t, float dt); +void sol_body_e(float e[3], const struct s_vary *, const struct v_body *bp, + float dt); +void sol_body_w(float w[3], const struct s_vary *, const struct v_body *bp); void sol_rotate(float e[3][3], const float w[3], float dt); -void sol_pendulum(struct s_ball *up, +void sol_pendulum(struct v_ball *up, const float a[3], const float g[3], float dt); -void sol_swch_step(struct s_file *fp, float dt, int ms); -void sol_body_step(struct s_file *fp, float dt, int ms); -void sol_ball_step(struct s_file *fp, float dt); +void sol_swch_step(struct s_vary *, float dt, int ms); +void sol_body_step(struct s_vary *, float dt, int ms); +void sol_ball_step(struct s_vary *, float dt); enum { @@ -34,9 +33,9 @@ enum SWCH_INSIDE }; -int sol_item_test(struct s_file *fp, float *p, float item_r); -struct s_goal *sol_goal_test(struct s_file *fp, float *p, int ui); -int sol_jump_test(struct s_file *fp, float *p, int ui); -int sol_swch_test(struct s_file *fp, int ui); +int sol_item_test(struct s_vary *, float *p, float item_r); +struct b_goal *sol_goal_test(struct s_vary *, float *p, int ui); +int sol_jump_test(struct s_vary *, float *p, int ui); +int sol_swch_test(struct s_vary *, int ui); #endif diff --git a/share/solid_base.c b/share/solid_base.c new file mode 100644 index 0000000..dbbff30 --- /dev/null +++ b/share/solid_base.c @@ -0,0 +1,635 @@ +/* + * Copyright (C) 2003 Robert Kooima + * + * NEVERBALL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2 of the License, + * or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#include +#include +#include + +#include "solid_base.h" +#include "base_config.h" +#include "binary.h" +#include "common.h" +#include "fs.h" +#include "vec3.h" + +enum +{ + SOL_VER_MINIMUM = 6, + SOL_VER_PATH_FLAGS, + SOL_VER_CURRENT = SOL_VER_PATH_FLAGS +}; + +#define SOL_MAGIC (0xAF | 'S' << 8 | 'O' << 16 | 'L' << 24) + +/*---------------------------------------------------------------------------*/ + +static int sol_version; + +static int sol_file(fs_file fin) +{ + int magic; + int version; + + get_index(fin, &magic); + get_index(fin, &version); + + if (magic != SOL_MAGIC || (version < SOL_VER_MINIMUM || + version > SOL_VER_CURRENT)) + return 0; + + sol_version = version; + + return 1; +} + +static void sol_load_mtrl(fs_file fin, struct b_mtrl *mp) +{ + get_array(fin, mp->d, 4); + get_array(fin, mp->a, 4); + get_array(fin, mp->s, 4); + get_array(fin, mp->e, 4); + get_array(fin, mp->h, 1); + get_index(fin, &mp->fl); + + fs_read(mp->f, 1, PATHMAX, fin); +} + +static void sol_load_vert(fs_file fin, struct b_vert *vp) +{ + get_array(fin, vp->p, 3); +} + +static void sol_load_edge(fs_file fin, struct b_edge *ep) +{ + get_index(fin, &ep->vi); + get_index(fin, &ep->vj); +} + +static void sol_load_side(fs_file fin, struct b_side *sp) +{ + get_array(fin, sp->n, 3); + get_float(fin, &sp->d); +} + +static void sol_load_texc(fs_file fin, struct b_texc *tp) +{ + get_array(fin, tp->u, 2); +} + +static void sol_load_geom(fs_file fin, struct b_geom *gp) +{ + get_index(fin, &gp->mi); + get_index(fin, &gp->ti); + get_index(fin, &gp->si); + get_index(fin, &gp->vi); + get_index(fin, &gp->tj); + get_index(fin, &gp->sj); + get_index(fin, &gp->vj); + get_index(fin, &gp->tk); + get_index(fin, &gp->sk); + get_index(fin, &gp->vk); +} + +static void sol_load_lump(fs_file fin, struct b_lump *lp) +{ + get_index(fin, &lp->fl); + get_index(fin, &lp->v0); + get_index(fin, &lp->vc); + get_index(fin, &lp->e0); + get_index(fin, &lp->ec); + get_index(fin, &lp->g0); + get_index(fin, &lp->gc); + get_index(fin, &lp->s0); + get_index(fin, &lp->sc); +} + +static void sol_load_node(fs_file fin, struct b_node *np) +{ + get_index(fin, &np->si); + get_index(fin, &np->ni); + get_index(fin, &np->nj); + get_index(fin, &np->l0); + get_index(fin, &np->lc); +} + +static void sol_load_path(fs_file fin, struct b_path *pp) +{ + get_array(fin, pp->p, 3); + get_float(fin, &pp->t); + get_index(fin, &pp->pi); + get_index(fin, &pp->f); + get_index(fin, &pp->s); + + pp->tm = TIME_TO_MS(pp->t); + pp->t = MS_TO_TIME(pp->tm); + + if (sol_version >= SOL_VER_PATH_FLAGS) + get_index(fin, &pp->fl); + + pp->e[0] = 1.0f; + pp->e[1] = 0.0f; + pp->e[2] = 0.0f; + pp->e[3] = 0.0f; + + if (pp->fl & P_ORIENTED) + get_array(fin, pp->e, 4); +} + +static void sol_load_body(fs_file fin, struct b_body *bp) +{ + get_index(fin, &bp->pi); + get_index(fin, &bp->ni); + get_index(fin, &bp->l0); + get_index(fin, &bp->lc); + get_index(fin, &bp->g0); + get_index(fin, &bp->gc); +} + +static void sol_load_item(fs_file fin, struct b_item *hp) +{ + get_array(fin, hp->p, 3); + get_index(fin, &hp->t); + get_index(fin, &hp->n); +} + +static void sol_load_goal(fs_file fin, struct b_goal *zp) +{ + get_array(fin, zp->p, 3); + get_float(fin, &zp->r); +} + +static void sol_load_swch(fs_file fin, struct b_swch *xp) +{ + float f; + int i; + + get_array(fin, xp->p, 3); + get_float(fin, &xp->r); + get_index(fin, &xp->pi); + get_float(fin, &xp->t); + get_float(fin, &f); + get_index(fin, &xp->f); + get_index(fin, &i); + get_index(fin, &xp->i); + + xp->tm = TIME_TO_MS(xp->t); + xp->t = MS_TO_TIME(xp->tm); +} + +static void sol_load_bill(fs_file fin, struct b_bill *rp) +{ + get_index(fin, &rp->fl); + get_index(fin, &rp->mi); + get_float(fin, &rp->t); + get_float(fin, &rp->d); + get_array(fin, rp->w, 3); + get_array(fin, rp->h, 3); + get_array(fin, rp->rx, 3); + get_array(fin, rp->ry, 3); + get_array(fin, rp->rz, 3); + get_array(fin, rp->p, 3); +} + +static void sol_load_jump(fs_file fin, struct b_jump *jp) +{ + get_array(fin, jp->p, 3); + get_array(fin, jp->q, 3); + get_float(fin, &jp->r); +} + +static void sol_load_ball(fs_file fin, struct b_ball *bp) +{ + get_array(fin, bp->p, 3); + get_float(fin, &bp->r); +} + +static void sol_load_view(fs_file fin, struct b_view *wp) +{ + get_array(fin, wp->p, 3); + get_array(fin, wp->q, 3); +} + +static void sol_load_dict(fs_file fin, struct b_dict *dp) +{ + get_index(fin, &dp->ai); + get_index(fin, &dp->aj); +} + +static void sol_load_indx(fs_file fin, struct s_base *fp) +{ + get_index(fin, &fp->ac); + get_index(fin, &fp->dc); + get_index(fin, &fp->mc); + get_index(fin, &fp->vc); + get_index(fin, &fp->ec); + get_index(fin, &fp->sc); + get_index(fin, &fp->tc); + get_index(fin, &fp->gc); + get_index(fin, &fp->lc); + get_index(fin, &fp->nc); + get_index(fin, &fp->pc); + get_index(fin, &fp->bc); + get_index(fin, &fp->hc); + get_index(fin, &fp->zc); + get_index(fin, &fp->jc); + get_index(fin, &fp->xc); + get_index(fin, &fp->rc); + get_index(fin, &fp->uc); + get_index(fin, &fp->wc); + get_index(fin, &fp->ic); +} + +static int sol_load_file(fs_file fin, struct s_base *fp) +{ + int i; + + if (!sol_file(fin)) + return 0; + + sol_load_indx(fin, fp); + + if (fp->ac) + fp->av = (char *) calloc(fp->ac, sizeof (*fp->av)); + if (fp->mc) + fp->mv = (struct b_mtrl *) calloc(fp->mc, sizeof (*fp->mv)); + if (fp->vc) + fp->vv = (struct b_vert *) calloc(fp->vc, sizeof (*fp->vv)); + if (fp->ec) + fp->ev = (struct b_edge *) calloc(fp->ec, sizeof (*fp->ev)); + if (fp->sc) + fp->sv = (struct b_side *) calloc(fp->sc, sizeof (*fp->sv)); + if (fp->tc) + fp->tv = (struct b_texc *) calloc(fp->tc, sizeof (*fp->tv)); + if (fp->gc) + fp->gv = (struct b_geom *) calloc(fp->gc, sizeof (*fp->gv)); + if (fp->lc) + fp->lv = (struct b_lump *) calloc(fp->lc, sizeof (*fp->lv)); + if (fp->nc) + fp->nv = (struct b_node *) calloc(fp->nc, sizeof (*fp->nv)); + if (fp->pc) + fp->pv = (struct b_path *) calloc(fp->pc, sizeof (*fp->pv)); + if (fp->bc) + fp->bv = (struct b_body *) calloc(fp->bc, sizeof (*fp->bv)); + if (fp->hc) + fp->hv = (struct b_item *) calloc(fp->hc, sizeof (*fp->hv)); + if (fp->zc) + fp->zv = (struct b_goal *) calloc(fp->zc, sizeof (*fp->zv)); + if (fp->jc) + fp->jv = (struct b_jump *) calloc(fp->jc, sizeof (*fp->jv)); + if (fp->xc) + fp->xv = (struct b_swch *) calloc(fp->xc, sizeof (*fp->xv)); + if (fp->rc) + fp->rv = (struct b_bill *) calloc(fp->rc, sizeof (*fp->rv)); + if (fp->uc) + fp->uv = (struct b_ball *) calloc(fp->uc, sizeof (*fp->uv)); + if (fp->wc) + fp->wv = (struct b_view *) calloc(fp->wc, sizeof (*fp->wv)); + if (fp->dc) + fp->dv = (struct b_dict *) calloc(fp->dc, sizeof (*fp->dv)); + if (fp->ic) + fp->iv = (int *) calloc(fp->ic, sizeof (*fp->iv)); + + if (fp->ac) + fs_read(fp->av, 1, fp->ac, fin); + + for (i = 0; i < fp->dc; i++) sol_load_dict(fin, fp->dv + i); + for (i = 0; i < fp->mc; i++) sol_load_mtrl(fin, fp->mv + i); + for (i = 0; i < fp->vc; i++) sol_load_vert(fin, fp->vv + i); + for (i = 0; i < fp->ec; i++) sol_load_edge(fin, fp->ev + i); + for (i = 0; i < fp->sc; i++) sol_load_side(fin, fp->sv + i); + for (i = 0; i < fp->tc; i++) sol_load_texc(fin, fp->tv + i); + for (i = 0; i < fp->gc; i++) sol_load_geom(fin, fp->gv + i); + for (i = 0; i < fp->lc; i++) sol_load_lump(fin, fp->lv + i); + for (i = 0; i < fp->nc; i++) sol_load_node(fin, fp->nv + i); + for (i = 0; i < fp->pc; i++) sol_load_path(fin, fp->pv + i); + for (i = 0; i < fp->bc; i++) sol_load_body(fin, fp->bv + i); + for (i = 0; i < fp->hc; i++) sol_load_item(fin, fp->hv + i); + for (i = 0; i < fp->zc; i++) sol_load_goal(fin, fp->zv + i); + for (i = 0; i < fp->jc; i++) sol_load_jump(fin, fp->jv + i); + for (i = 0; i < fp->xc; i++) sol_load_swch(fin, fp->xv + i); + for (i = 0; i < fp->rc; i++) sol_load_bill(fin, fp->rv + i); + for (i = 0; i < fp->uc; i++) sol_load_ball(fin, fp->uv + i); + for (i = 0; i < fp->wc; i++) sol_load_view(fin, fp->wv + i); + for (i = 0; i < fp->ic; i++) get_index(fin, fp->iv + i); + + return 1; +} + +static int sol_load_head(fs_file fin, struct s_base *fp) +{ + if (!sol_file(fin)) + return 0; + + sol_load_indx(fin, fp); + + if (fp->ac) + { + fp->av = (char *) calloc(fp->ac, sizeof (*fp->av)); + fs_read(fp->av, 1, fp->ac, fin); + } + + if (fp->dc) + { + int i; + + fp->dv = (struct b_dict *) calloc(fp->dc, sizeof (*fp->dv)); + + for (i = 0; i < fp->dc; i++) + sol_load_dict(fin, fp->dv + i); + } + + return 1; +} + +int sol_load_base(struct s_base *fp, const char *filename) +{ + fs_file fin; + int res = 0; + + memset(fp, 0, sizeof (*fp)); + + if ((fin = fs_open(filename, "r"))) + { + res = sol_load_file(fin, fp); + fs_close(fin); + } + return res; +} + +int sol_load_meta(struct s_base *fp, const char *filename) +{ + fs_file fin; + int res = 0; + + if ((fin = fs_open(filename, "r"))) + { + res = sol_load_head(fin, fp); + fs_close(fin); + } + return res; +} + +void sol_free_base(struct s_base *fp) +{ + if (fp->av) free(fp->av); + if (fp->mv) free(fp->mv); + if (fp->vv) free(fp->vv); + if (fp->ev) free(fp->ev); + if (fp->sv) free(fp->sv); + if (fp->tv) free(fp->tv); + if (fp->gv) free(fp->gv); + if (fp->lv) free(fp->lv); + if (fp->nv) free(fp->nv); + if (fp->pv) free(fp->pv); + if (fp->bv) free(fp->bv); + if (fp->hv) free(fp->hv); + if (fp->zv) free(fp->zv); + if (fp->jv) free(fp->jv); + if (fp->xv) free(fp->xv); + if (fp->rv) free(fp->rv); + if (fp->uv) free(fp->uv); + if (fp->wv) free(fp->wv); + if (fp->dv) free(fp->dv); + if (fp->iv) free(fp->iv); + + memset(fp, 0, sizeof (*fp)); +} + +/*---------------------------------------------------------------------------*/ + +static void sol_stor_mtrl(fs_file fout, struct b_mtrl *mp) +{ + put_array(fout, mp->d, 4); + put_array(fout, mp->a, 4); + put_array(fout, mp->s, 4); + put_array(fout, mp->e, 4); + put_array(fout, mp->h, 1); + put_index(fout, mp->fl); + + fs_write(mp->f, 1, PATHMAX, fout); +} + +static void sol_stor_vert(fs_file fout, struct b_vert *vp) +{ + put_array(fout, vp->p, 3); +} + +static void sol_stor_edge(fs_file fout, struct b_edge *ep) +{ + put_index(fout, ep->vi); + put_index(fout, ep->vj); +} + +static void sol_stor_side(fs_file fout, struct b_side *sp) +{ + put_array(fout, sp->n, 3); + put_float(fout, sp->d); +} + +static void sol_stor_texc(fs_file fout, struct b_texc *tp) +{ + put_array(fout, tp->u, 2); +} + +static void sol_stor_geom(fs_file fout, struct b_geom *gp) +{ + put_index(fout, gp->mi); + put_index(fout, gp->ti); + put_index(fout, gp->si); + put_index(fout, gp->vi); + put_index(fout, gp->tj); + put_index(fout, gp->sj); + put_index(fout, gp->vj); + put_index(fout, gp->tk); + put_index(fout, gp->sk); + put_index(fout, gp->vk); +} + +static void sol_stor_lump(fs_file fout, struct b_lump *lp) +{ + put_index(fout, lp->fl); + put_index(fout, lp->v0); + put_index(fout, lp->vc); + put_index(fout, lp->e0); + put_index(fout, lp->ec); + put_index(fout, lp->g0); + put_index(fout, lp->gc); + put_index(fout, lp->s0); + put_index(fout, lp->sc); +} + +static void sol_stor_node(fs_file fout, struct b_node *np) +{ + put_index(fout, np->si); + put_index(fout, np->ni); + put_index(fout, np->nj); + put_index(fout, np->l0); + put_index(fout, np->lc); +} + +static void sol_stor_path(fs_file fout, struct b_path *pp) +{ + put_array(fout, pp->p, 3); + put_float(fout, pp->t); + put_index(fout, pp->pi); + put_index(fout, pp->f); + put_index(fout, pp->s); + put_index(fout, pp->fl); + + if (pp->fl & P_ORIENTED) + put_array(fout, pp->e, 4); +} + +static void sol_stor_body(fs_file fout, struct b_body *bp) +{ + put_index(fout, bp->pi); + put_index(fout, bp->ni); + put_index(fout, bp->l0); + put_index(fout, bp->lc); + put_index(fout, bp->g0); + put_index(fout, bp->gc); +} + +static void sol_stor_item(fs_file fout, struct b_item *hp) +{ + put_array(fout, hp->p, 3); + put_index(fout, hp->t); + put_index(fout, hp->n); +} + +static void sol_stor_goal(fs_file fout, struct b_goal *zp) +{ + put_array(fout, zp->p, 3); + put_float(fout, zp->r); +} + +static void sol_stor_swch(fs_file fout, struct b_swch *xp) +{ + put_array(fout, xp->p, 3); + put_float(fout, xp->r); + put_index(fout, xp->pi); + put_float(fout, xp->t); + put_float(fout, xp->t); + put_index(fout, xp->f); + put_index(fout, xp->f); + put_index(fout, xp->i); +} + +static void sol_stor_bill(fs_file fout, struct b_bill *rp) +{ + put_index(fout, rp->fl); + put_index(fout, rp->mi); + put_float(fout, rp->t); + put_float(fout, rp->d); + put_array(fout, rp->w, 3); + put_array(fout, rp->h, 3); + put_array(fout, rp->rx, 3); + put_array(fout, rp->ry, 3); + put_array(fout, rp->rz, 3); + put_array(fout, rp->p, 3); +} + +static void sol_stor_jump(fs_file fout, struct b_jump *jp) +{ + put_array(fout, jp->p, 3); + put_array(fout, jp->q, 3); + put_float(fout, jp->r); +} + +static void sol_stor_ball(fs_file fout, struct b_ball *bp) +{ + put_array(fout, bp->p, 3); + put_float(fout, bp->r); +} + +static void sol_stor_view(fs_file fout, struct b_view *wp) +{ + put_array(fout, wp->p, 3); + put_array(fout, wp->q, 3); +} + +static void sol_stor_dict(fs_file fout, struct b_dict *dp) +{ + put_index(fout, dp->ai); + put_index(fout, dp->aj); +} + +static void sol_stor_file(fs_file fout, struct s_base *fp) +{ + int i; + int magic = SOL_MAGIC; + int version = SOL_VER_CURRENT; + + put_index(fout, magic); + put_index(fout, version); + + put_index(fout, fp->ac); + put_index(fout, fp->dc); + put_index(fout, fp->mc); + put_index(fout, fp->vc); + put_index(fout, fp->ec); + put_index(fout, fp->sc); + put_index(fout, fp->tc); + put_index(fout, fp->gc); + put_index(fout, fp->lc); + put_index(fout, fp->nc); + put_index(fout, fp->pc); + put_index(fout, fp->bc); + put_index(fout, fp->hc); + put_index(fout, fp->zc); + put_index(fout, fp->jc); + put_index(fout, fp->xc); + put_index(fout, fp->rc); + put_index(fout, fp->uc); + put_index(fout, fp->wc); + put_index(fout, fp->ic); + + fs_write(fp->av, 1, fp->ac, fout); + + for (i = 0; i < fp->dc; i++) sol_stor_dict(fout, fp->dv + i); + for (i = 0; i < fp->mc; i++) sol_stor_mtrl(fout, fp->mv + i); + for (i = 0; i < fp->vc; i++) sol_stor_vert(fout, fp->vv + i); + for (i = 0; i < fp->ec; i++) sol_stor_edge(fout, fp->ev + i); + for (i = 0; i < fp->sc; i++) sol_stor_side(fout, fp->sv + i); + for (i = 0; i < fp->tc; i++) sol_stor_texc(fout, fp->tv + i); + for (i = 0; i < fp->gc; i++) sol_stor_geom(fout, fp->gv + i); + for (i = 0; i < fp->lc; i++) sol_stor_lump(fout, fp->lv + i); + for (i = 0; i < fp->nc; i++) sol_stor_node(fout, fp->nv + i); + for (i = 0; i < fp->pc; i++) sol_stor_path(fout, fp->pv + i); + for (i = 0; i < fp->bc; i++) sol_stor_body(fout, fp->bv + i); + for (i = 0; i < fp->hc; i++) sol_stor_item(fout, fp->hv + i); + for (i = 0; i < fp->zc; i++) sol_stor_goal(fout, fp->zv + i); + for (i = 0; i < fp->jc; i++) sol_stor_jump(fout, fp->jv + i); + for (i = 0; i < fp->xc; i++) sol_stor_swch(fout, fp->xv + i); + for (i = 0; i < fp->rc; i++) sol_stor_bill(fout, fp->rv + i); + for (i = 0; i < fp->uc; i++) sol_stor_ball(fout, fp->uv + i); + for (i = 0; i < fp->wc; i++) sol_stor_view(fout, fp->wv + i); + for (i = 0; i < fp->ic; i++) put_index(fout, fp->iv[i]); +} + +int sol_stor_base(struct s_base *fp, const char *filename) +{ + fs_file fout; + + if ((fout = fs_open(filename, "w"))) + { + sol_stor_file(fout, fp); + fs_close(fout); + + return 1; + } + return 0; +} + +/*---------------------------------------------------------------------------*/ diff --git a/share/solid_base.h b/share/solid_base.h new file mode 100644 index 0000000..c041300 --- /dev/null +++ b/share/solid_base.h @@ -0,0 +1,329 @@ +/* + * Copyright (C) 2003 Robert Kooima + * + * NEVERBALL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2 of the License, + * or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#ifndef SOLID_BASE_H +#define SOLID_BASE_H + +#include "base_config.h" + +/* + * Some might be taken aback at the terseness of the names of the + * structure members and the variables used by the functions that + * access them. Yes, yes, I know: readability. I contend that once + * the naming convention is embraced, the names become more readable + * than any verbose alternative, and their brevity and uniformity do + * more to augment readability than longVariableNames ever could. + * + * Members and variables are named XY. X determines the type of + * structure to which the variable refers. Y determines the usage of + * the variable. + * + * The Xs are as documented by struct s_file: + * + * f File (struct s_file) + * m Material (struct s_mtrl) + * v Vertex (struct s_vert) + * e Edge (struct s_edge) + * s Side (struct s_side) + * t Texture coord (struct s_texc) + * g Geometry (struct s_geom) + * l Lump (struct s_lump) + * n Node (struct s_node) + * p Path (struct s_path) + * b Body (struct s_body) + * h Item (struct s_item) + * z Goal (struct s_goal) + * j Jump (struct s_jump) + * x Switch (struct s_swch) + * r Billboard (struct s_bill) + * u User (struct s_ball) + * w Viewpoint (struct s_view) + * d Dictionary (struct s_dict) + * i Index (int) + * a Text (char) + * + * The Ys are as follows: + * + * c Counter + * p Pointer + * v Vector (array) + * 0 Index of the first + * i Index + * j Subindex + * k Subsubindex + * + * Thus "up" is a pointer to a user structure. "lc" is the number of + * lumps. "ei" and "ej" are edge indices into some "ev" edge vector. + * An edge is defined by two vertices, so an edge structure consists + * of "vi" and "vj". And so on. + * + * Those members that do not conform to this convention are explicitly + * documented with a comment. + * + * These prefixes are still available: c k o q y. + */ + +/* + * Additionally, solid data is split into three main parts: static + * data (base), simulation data (vary), and rendering data (draw). + */ + +/*---------------------------------------------------------------------------*/ + +/* Material type flags */ + +#define M_OPAQUE 1 +#define M_TRANSPARENT 2 +#define M_REFLECTIVE 4 +#define M_ENVIRONMENT 8 +#define M_ADDITIVE 16 +#define M_CLAMPED 32 +#define M_DECAL 64 +#define M_TWO_SIDED 128 +#define M_SHADOWED 256 + +/* Billboard types. */ + +#define B_EDGE 1 +#define B_FLAT 2 +#define B_ADDITIVE 4 +#define B_NOFACE 8 + +/* Lump flags. */ + +#define L_DETAIL 1 + +/* Item types. */ + +#define ITEM_NONE 0 +#define ITEM_COIN 1 +#define ITEM_GROW 2 +#define ITEM_SHRINK 3 + +/* Path flags. */ + +#define P_ORIENTED 1 + +/*---------------------------------------------------------------------------*/ + +struct b_mtrl +{ + float d[4]; /* diffuse color */ + float a[4]; /* ambient color */ + float s[4]; /* specular color */ + float e[4]; /* emission color */ + float h[1]; /* specular exponent */ + float angle; + + int fl; /* material flags */ + + char f[PATHMAX]; /* texture file name */ +}; + +struct b_vert +{ + float p[3]; /* vertex position */ +}; + +struct b_edge +{ + int vi; + int vj; +}; + +struct b_side +{ + float n[3]; /* plane normal vector */ + float d; /* distance from origin */ +}; + +struct b_texc +{ + float u[2]; /* texture coordinate */ +}; + +struct b_geom +{ + int mi; + int ti, si, vi; + int tj, sj, vj; + int tk, sk, vk; +}; + +struct b_lump +{ + int fl; /* lump flags */ + int v0, vc; + int e0, ec; + int g0, gc; + int s0, sc; +}; + +struct b_node +{ + int si; + int ni; + int nj; + int l0; + int lc; +}; + +struct b_path +{ + float p[3]; /* starting position */ + float e[4]; /* orientation (quaternion) */ + float t; /* travel time */ + int tm; /* milliseconds */ + + int pi; + int f; /* enable flag */ + int s; /* smooth flag */ + + int fl; /* flags */ + + /* TODO: merge enable and smooth into flags. */ +}; + +struct b_body +{ + int pi; + int ni; + int l0; + int lc; + int g0; + int gc; +}; + +struct b_item +{ + float p[3]; /* position */ + int t; /* type */ + int n; /* value */ +}; + +struct b_goal +{ + float p[3]; /* position */ + float r; /* radius */ +}; + +struct b_swch +{ + float p[3]; /* position */ + float r; /* radius */ + int pi; /* the linked path */ + + float t; /* default timer */ + int tm; /* milliseconds */ + int f; /* default state */ + int i; /* is invisible? */ +}; + +struct b_bill +{ + int fl; + int mi; + float t; /* repeat time interval */ + float d; /* distance */ + + float w[3]; /* width coefficients */ + float h[3]; /* height coefficients */ + + float rx[3]; /* X rotation coefficients */ + float ry[3]; /* Y rotation coefficients */ + float rz[3]; /* Z rotation coefficients */ + + float p[3]; +}; + +struct b_jump +{ + float p[3]; /* position */ + float q[3]; /* target position */ + float r; /* radius */ +}; + +struct b_ball +{ + float p[3]; /* position vector */ + float r; /* radius */ +}; + +struct b_view +{ + float p[3]; + float q[3]; +}; + +struct b_dict +{ + int ai; + int aj; +}; + +struct s_base +{ + int ac; + int mc; + int vc; + int ec; + int sc; + int tc; + int gc; + int lc; + int nc; + int pc; + int bc; + int hc; + int zc; + int jc; + int xc; + int rc; + int uc; + int wc; + int dc; + int ic; + + char *av; + struct b_mtrl *mv; + struct b_vert *vv; + struct b_edge *ev; + struct b_side *sv; + struct b_texc *tv; + struct b_geom *gv; + struct b_lump *lv; + struct b_node *nv; + struct b_path *pv; + struct b_body *bv; + struct b_item *hv; + struct b_goal *zv; + struct b_jump *jv; + struct b_swch *xv; + struct b_bill *rv; + struct b_ball *uv; + struct b_view *wv; + struct b_dict *dv; + int *iv; +}; + +/*---------------------------------------------------------------------------*/ + +int sol_load_base(struct s_base *, const char *); +int sol_load_meta(struct s_base *, const char *); +void sol_free_base(struct s_base *); +int sol_stor_base(struct s_base *, const char *); + +/*---------------------------------------------------------------------------*/ + +#endif diff --git a/share/solid_draw.c b/share/solid_draw.c new file mode 100644 index 0000000..3ae47bb --- /dev/null +++ b/share/solid_draw.c @@ -0,0 +1,841 @@ +/* + * Copyright (C) 2003 Robert Kooima + * + * NEVERBALL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2 of the License, + * or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#include +#include + +#include +#include +#include +#include + +#include "glext.h" +#include "vec3.h" +#include "image.h" +#include "base_image.h" +#include "base_config.h" +#include "lang.h" + +#include "solid_draw.h" +#include "solid_all.h" + +/*---------------------------------------------------------------------------*/ + +static int sol_enum_mtrl(const struct s_base *base, + const struct b_body *bp, int mi) +{ + int li, gi, c = 0; + + /* Count all lump geoms with this material. */ + + for (li = 0; li < bp->lc; li++) + { + int g0 = base->lv[bp->l0 + li].g0; + int gc = base->lv[bp->l0 + li].gc; + + for (gi = 0; gi < gc; gi++) + if (base->gv[base->iv[g0 + gi]].mi == mi) + c++; + } + + /* Count all body geoms with this material. */ + + for (gi = 0; gi < bp->gc; gi++) + if (base->gv[base->iv[bp->g0 + gi]].mi == mi) + c++; + + return c; +} + +static int sol_enum_body(const struct s_base *base, + const struct b_body *bp, int fl) +{ + int mi, c = 0; + + /* Count all geoms with this flag. */ + + for (mi = 0; mi < base->mc; mi++) + if (base->mv[mi].fl & fl) + c = c + sol_enum_mtrl(base, bp, mi); + + return c; +} + +/*---------------------------------------------------------------------------*/ + +int sol_reflective(const struct s_draw *draw) +{ + int bi; + + for (bi = 0; bi < draw->bc; bi++) + if (draw->bv[bi].rl) + return 1; + + return 0; +} + +/*---------------------------------------------------------------------------*/ + +#define tobyte(f) ((GLubyte) (f * 255.0f)) + +#define color_cmp(a, b) (tobyte((a)[0]) == tobyte((b)[0]) && \ + tobyte((a)[1]) == tobyte((b)[1]) && \ + tobyte((a)[2]) == tobyte((b)[2]) && \ + tobyte((a)[3]) == tobyte((b)[3])) + +static struct b_mtrl default_base_mtrl = +{ + { 0.8f, 0.8f, 0.8f, 1.0f }, + { 0.2f, 0.2f, 0.2f, 1.0f }, + { 0.0f, 0.0f, 0.0f, 1.0f }, + { 0.0f, 0.0f, 0.0f, 1.0f }, + { 0.0f }, 0.0f, M_OPAQUE, "" +}; + +static struct d_mtrl default_draw_mtrl = +{ + &default_base_mtrl, 0 +}; + +static const struct d_mtrl *sol_draw_mtrl(const struct s_draw *draw, + const struct d_mtrl *mp_draw, + const struct d_mtrl *mq_draw) +{ + const struct b_mtrl *mp_base = mp_draw->base; + const struct b_mtrl *mq_base = mq_draw->base; + + /* Change material properties only as needed. */ + + if (!color_cmp(mp_base->a, mq_base->a)) + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, mp_base->a); + if (!color_cmp(mp_base->d, mq_base->d)) + glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp_base->d); + if (!color_cmp(mp_base->s, mq_base->s)) + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mp_base->s); + if (!color_cmp(mp_base->e, mq_base->e)) + glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, mp_base->e); + if (tobyte(mp_base->h[0]) != tobyte(mq_base->h[0])) + glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, mp_base->h); + + /* Bind the texture. */ + + if (mp_draw->o != mq_draw->o) + glBindTexture(GL_TEXTURE_2D, mp_draw->o); + + /* Enable environment mapping. */ + + if ((mp_base->fl & M_ENVIRONMENT) && !(mq_base->fl & M_ENVIRONMENT)) + { + glEnable(GL_TEXTURE_GEN_S); + glEnable(GL_TEXTURE_GEN_T); + + glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); + glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); + } + + /* Disable environment mapping. */ + + if ((mq_base->fl & M_ENVIRONMENT) && !(mp_base->fl & M_ENVIRONMENT)) + { + glDisable(GL_TEXTURE_GEN_S); + glDisable(GL_TEXTURE_GEN_T); + } + + /* Enable additive blending. */ + + if ((mp_base->fl & M_ADDITIVE) && !(mq_base->fl & M_ADDITIVE)) + glBlendFunc(GL_ONE, GL_ONE); + + /* Enable standard blending. */ + + if ((mq_base->fl & M_ADDITIVE) && !(mp_base->fl & M_ADDITIVE)) + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + /* Enable visibility-from-behind. */ + + if ((mp_base->fl & M_TWO_SIDED) && !(mq_base->fl & M_TWO_SIDED)) + { + glDisable(GL_CULL_FACE); + glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 1); + } + + /* Disable visibility-from-behind. */ + + if ((mq_base->fl & M_TWO_SIDED) && !(mp_base->fl & M_TWO_SIDED)) + { + glEnable(GL_CULL_FACE); + glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 0); + } + + /* Enable decal offset. */ + + if ((mp_base->fl & M_DECAL) && !(mq_base->fl & M_DECAL)) + { + glEnable(GL_POLYGON_OFFSET_FILL); + glPolygonOffset(-1.0f, -2.0f); + } + + /* Disable decal offset. */ + + if ((mq_base->fl & M_DECAL) && !(mp_base->fl & M_DECAL)) + glDisable(GL_POLYGON_OFFSET_FILL); + + return mp_draw; +} + +static const struct d_mtrl *sol_back_bill(const struct s_draw *draw, + const struct b_bill *rp, + const struct d_mtrl *mp, + float t) +{ + float T = (rp->t > 0.0f) ? (fmodf(t, rp->t) - rp->t / 2) : 0.0f; + + float w = rp->w[0] + rp->w[1] * T + rp->w[2] * T * T; + float h = rp->h[0] + rp->h[1] * T + rp->h[2] * T * T; + + if (w > 0 && h > 0) + { + float rx = rp->rx[0] + rp->rx[1] * T + rp->rx[2] * T * T; + float ry = rp->ry[0] + rp->ry[1] * T + rp->ry[2] * T * T; + float rz = rp->rz[0] + rp->rz[1] * T + rp->rz[2] * T * T; + + glPushMatrix(); + { + float y0 = (rp->fl & B_EDGE) ? 0 : -h / 2; + float y1 = (rp->fl & B_EDGE) ? h : +h / 2; + + glRotatef(ry, 0.0f, 1.0f, 0.0f); + glRotatef(rx, 1.0f, 0.0f, 0.0f); + glTranslatef(0.0f, 0.0f, -rp->d); + + if (rp->fl & B_FLAT) + { + glRotatef(-rx - 90.0f, 1.0f, 0.0f, 0.0f); + glRotatef(-ry, 0.0f, 0.0f, 1.0f); + } + if (rp->fl & B_EDGE) + glRotatef(-rx, 1.0f, 0.0f, 0.0f); + + glRotatef(rz, 0.0f, 0.0f, 1.0f); + + mp = sol_draw_mtrl(draw, draw->mv + rp->mi, mp); + + glBegin(GL_QUADS); + { + glTexCoord2f(0.0f, 0.0f); glVertex2f(-w / 2, y0); + glTexCoord2f(1.0f, 0.0f); glVertex2f(+w / 2, y0); + glTexCoord2f(1.0f, 1.0f); glVertex2f(+w / 2, y1); + glTexCoord2f(0.0f, 1.0f); glVertex2f(-w / 2, y1); + } + glEnd(); + } + glPopMatrix(); + } + + return mp; +} + +/*---------------------------------------------------------------------------*/ + +void sol_back(const struct s_draw *draw, float n, float f, float t) +{ + const struct d_mtrl *mp = &default_draw_mtrl; + + int ri; + + /* Render all billboards in the given range. */ + + glDisable(GL_LIGHTING); + glDepthMask(GL_FALSE); + { + for (ri = 0; ri < draw->base->rc; ri++) + if (n <= draw->base->rv[ri].d && draw->base->rv[ri].d < f) + mp = sol_back_bill(draw, draw->base->rv + ri, mp, t); + + mp = sol_draw_mtrl(draw, &default_draw_mtrl, mp); + } + glDepthMask(GL_TRUE); + glEnable(GL_LIGHTING); +} + +/*---------------------------------------------------------------------------*/ +/* + * The following code renders a body in a ludicrously inefficient + * manner. It iterates the materials and scans the data structure for + * geometry using each. This has the effect of absolutely minimizing + * material changes, texture bindings, and Begin/End pairs, but + * maximizing trips through the data. + * + * However, this is only done once for each level. The results are + * stored in display lists. Thus, it is well worth it. + */ + +static void sol_draw_geom(const struct s_base *base, + const struct b_geom *gp, int mi) +{ + if (gp->mi == mi) + { + const float *ui = base->tv[gp->ti].u; + const float *uj = base->tv[gp->tj].u; + const float *uk = base->tv[gp->tk].u; + + const float *ni = base->sv[gp->si].n; + const float *nj = base->sv[gp->sj].n; + const float *nk = base->sv[gp->sk].n; + + const float *vi = base->vv[gp->vi].p; + const float *vj = base->vv[gp->vj].p; + const float *vk = base->vv[gp->vk].p; + + glTexCoord2fv(ui); + glNormal3fv(ni); + glVertex3fv(vi); + + glTexCoord2fv(uj); + glNormal3fv(nj); + glVertex3fv(vj); + + glTexCoord2fv(uk); + glNormal3fv(nk); + glVertex3fv(vk); + } +} + +static void sol_draw_lump(const struct s_base *base, + const struct b_lump *lp, int mi) +{ + int i; + + for (i = 0; i < lp->gc; i++) + sol_draw_geom(base, base->gv + base->iv[lp->g0 + i], mi); +} + +static const struct d_mtrl *sol_draw_body(const struct s_draw *draw, + const struct b_body *bp, + const struct d_mtrl *mp, + int fl, int decal) +{ + const struct s_base *base = draw->base; + + int mi, li, gi; + + /* Iterate all materials of the correct opacity. */ + + for (mi = 0; mi < draw->mc; mi++) + { + struct d_mtrl *mq = draw->mv + mi; + + if ((mq->base->fl & fl) && (mq->base->fl & M_DECAL) == decal) + { + if (sol_enum_mtrl(draw->base, bp, mi)) + { + /* Set the material state. */ + + mp = sol_draw_mtrl(draw, mq, mp); + + /* Render all geometry of that material. */ + + glBegin(GL_TRIANGLES); + { + for (li = 0; li < bp->lc; li++) + sol_draw_lump(draw->base, + base->lv + bp->l0 + li, + mi); + for (gi = 0; gi < bp->gc; gi++) + sol_draw_geom(draw->base, + base->gv + base->iv[bp->g0 + gi], + mi); + } + glEnd(); + } + } + } + + return mp; +} + +static void sol_draw_list(const struct s_vary *vary, + const struct v_body *bp, GLuint list) +{ + float p[3], e[4], u[3], a; + + sol_body_p(p, vary, bp->pi, bp->t); + sol_body_e(e, vary, bp, 0); + + q_as_axisangle(e, u, &a); + a = V_DEG(a); + + glPushMatrix(); + { + /* Translate and rotate a moving body. */ + + glTranslatef(p[0], p[1], p[2]); + glRotatef(a, u[0], u[1], u[2]); + + /* Draw the body. */ + + glCallList(list); + } + glPopMatrix(); +} + +void sol_draw(const struct s_draw *draw, int depthmask, int depthtest) +{ + int bi; + + /* Render all opaque geometry into the color and depth buffers. */ + + for (bi = 0; bi < draw->bc; bi++) + if (draw->bv[bi].ol) + sol_draw_list(draw->vary, draw->vary->bv + bi, draw->bv[bi].ol); + + /* Render all translucent geometry into only the color buffer. */ + + if (depthtest == 0) glDisable(GL_DEPTH_TEST); + if (depthmask == 0) glDepthMask(GL_FALSE); + { + for (bi = 0; bi < draw->bc; bi++) + if (draw->bv[bi].tl) + sol_draw_list(draw->vary, draw->vary->bv + bi, draw->bv[bi].tl); + } + if (depthmask == 0) glDepthMask(GL_TRUE); + if (depthtest == 0) glEnable(GL_DEPTH_TEST); +} + +void sol_bill(const struct s_draw *draw, const float *M, float t) +{ + const struct d_mtrl *mp = &default_draw_mtrl; + + int ri; + + for (ri = 0; ri < draw->base->rc; ++ri) + { + const struct b_bill *rp = draw->base->rv + ri; + + float T = rp->t * t; + float S = fsinf(T); + + float w = rp->w [0] + rp->w [1] * T + rp->w [2] * S; + float h = rp->h [0] + rp->h [1] * T + rp->h [2] * S; + float rx = rp->rx[0] + rp->rx[1] * T + rp->rx[2] * S; + float ry = rp->ry[0] + rp->ry[1] * T + rp->ry[2] * S; + float rz = rp->rz[0] + rp->rz[1] * T + rp->rz[2] * S; + + mp = sol_draw_mtrl(draw, draw->mv + rp->mi, mp); + + glPushMatrix(); + { + glTranslatef(rp->p[0], rp->p[1], rp->p[2]); + + if (M && ((rp->fl & B_NOFACE) == 0)) glMultMatrixf(M); + + if (fabsf(rx) > 0.0f) glRotatef(rx, 1.0f, 0.0f, 0.0f); + if (fabsf(ry) > 0.0f) glRotatef(ry, 0.0f, 1.0f, 0.0f); + if (fabsf(rz) > 0.0f) glRotatef(rz, 0.0f, 0.0f, 1.0f); + + glBegin(GL_QUADS); + { + glTexCoord2f(0.0f, 0.0f); glVertex2f(-w / 2, -h / 2); + glTexCoord2f(1.0f, 0.0f); glVertex2f(+w / 2, -h / 2); + glTexCoord2f(1.0f, 1.0f); glVertex2f(+w / 2, +h / 2); + glTexCoord2f(0.0f, 1.0f); glVertex2f(-w / 2, +h / 2); + } + glEnd(); + } + glPopMatrix(); + } + + mp = sol_draw_mtrl(draw, &default_draw_mtrl, mp); +} + +void sol_refl(const struct s_draw *draw) +{ + int bi; + + /* Render all reflective geometry into the color and depth buffers. */ + + for (bi = 0; bi < draw->bc; bi++) + if (draw->bv[bi].rl) + sol_draw_list(draw->vary, draw->vary->bv + bi, draw->bv[bi].rl); +} + +/*---------------------------------------------------------------------------*/ + +static void sol_shad_geom(const struct s_base *base, + const struct b_geom *gp, int mi) +{ + if (gp->mi == mi) + { + const float *vi = base->vv[gp->vi].p; + const float *vj = base->vv[gp->vj].p; + const float *vk = base->vv[gp->vk].p; + + glTexCoord2f(vi[0], vi[2]); + glVertex3fv(vi); + + glTexCoord2f(vj[0], vj[2]); + glVertex3fv(vj); + + glTexCoord2f(vk[0], vk[2]); + glVertex3fv(vk); + } +} + +static void sol_shad_lump(const struct s_base *base, + const struct b_lump *lp, int mi) +{ + int i; + + for (i = 0; i < lp->gc; i++) + sol_shad_geom(base, base->gv + base->iv[lp->g0 + i], mi); +} + +static void sol_shad_body(const struct s_base *base, + const struct b_body *bp, + int fl, int decal) +{ + int mi, li, gi; + + if (decal) + { + glEnable(GL_POLYGON_OFFSET_FILL); + glPolygonOffset(-1.0f, -2.0f); + } + + glBegin(GL_TRIANGLES); + { + for (mi = 0; mi < base->mc; mi++) + { + struct b_mtrl *mp = base->mv + mi; + + if ((mp->fl & fl) && (mp->fl & M_DECAL) == decal) + { + for (li = 0; li < bp->lc; li++) + sol_shad_lump(base, base->lv + bp->l0 + li, mi); + for (gi = 0; gi < bp->gc; gi++) + sol_shad_geom(base, base->gv + base->iv[bp->g0 + gi], mi); + } + } + } + glEnd(); + + if (decal) + glDisable(GL_POLYGON_OFFSET_FILL); +} + +static void sol_shad_list(const struct s_vary *vary, + const struct v_body *bp, GLuint list) +{ + float p[3], e[4], u[3], a; + + sol_body_p(p, vary, bp->pi, bp->t); + sol_body_e(e, vary, bp, 0); + + q_as_axisangle(e, u, &a); + a = V_DEG(a); + + glPushMatrix(); + { + /* Translate and rotate a moving body. */ + + glTranslatef(p[0], p[1], p[2]); + glRotatef(a, u[0], u[1], u[2]); + + /* Translate the shadow on a moving body. */ + + glMatrixMode(GL_TEXTURE); + { + glPushMatrix(); + glTranslatef(p[0], p[2], 0.0f); + glRotatef(-a, u[0], u[2], u[1]); + } + glMatrixMode(GL_MODELVIEW); + + /* Draw the body. */ + + glCallList(list); + + /* Pop the shadow translation. */ + + glMatrixMode(GL_TEXTURE); + { + glPopMatrix(); + } + glMatrixMode(GL_MODELVIEW); + } + glPopMatrix(); +} + +void sol_shad(const struct s_draw *draw) +{ + int bi; + + /* Render all shadowed geometry. */ + + glDepthMask(GL_FALSE); + { + for (bi = 0; bi < draw->bc; bi++) + if (draw->bv[bi].sl) + sol_shad_list(draw->vary, draw->vary->bv + bi, draw->bv[bi].sl); + } + glDepthMask(GL_TRUE); +} + +/*---------------------------------------------------------------------------*/ + +static void sol_load_objects(struct s_draw *draw, int s) +{ + int i; + + /* Here we sort geometry into display lists by material type. */ + + for (i = 0; i < draw->bc; i++) + { + struct d_body *bp = draw->bv + i; + + int on = sol_enum_body(draw->base, bp->base, M_OPAQUE); + int tn = sol_enum_body(draw->base, bp->base, M_TRANSPARENT); + int rn = sol_enum_body(draw->base, bp->base, M_REFLECTIVE); + int dn = sol_enum_body(draw->base, bp->base, M_DECAL); + int sn = sol_enum_body(draw->base, bp->base, M_SHADOWED); + + /* Draw all opaque geometry, decals last. */ + + if (on) + { + bp->ol = glGenLists(1); + + glNewList(bp->ol, GL_COMPILE); + { + const struct d_mtrl *mp = &default_draw_mtrl; + + mp = sol_draw_body(draw, bp->base, mp, M_OPAQUE, 0); + mp = sol_draw_body(draw, bp->base, mp, M_OPAQUE, M_DECAL); + mp = sol_draw_mtrl(draw, &default_draw_mtrl, mp); + } + glEndList(); + } + else bp->ol = 0; + + /* Draw all translucent geometry, decals first. */ + + if (tn) + { + bp->tl = glGenLists(1); + + glNewList(bp->tl, GL_COMPILE); + { + const struct d_mtrl *mp = &default_draw_mtrl; + + mp = sol_draw_body(draw, bp->base, mp, M_TRANSPARENT, M_DECAL); + mp = sol_draw_body(draw, bp->base, mp, M_TRANSPARENT, 0); + mp = sol_draw_mtrl(draw, &default_draw_mtrl, mp); + } + glEndList(); + } + else bp->tl = 0; + + /* Draw all reflective geometry. */ + + if (rn) + { + bp->rl = glGenLists(1); + + glNewList(bp->rl, GL_COMPILE); + { + const struct d_mtrl *mp = &default_draw_mtrl; + + mp = sol_draw_body(draw, bp->base, mp, M_REFLECTIVE, 0); + mp = sol_draw_mtrl(draw, &default_draw_mtrl, mp); + } + glEndList(); + } + else bp->rl = 0; + + /* Draw all shadowed geometry. */ + + if (s && (on || rn || sn)) + { + bp->sl = glGenLists(1); + + glNewList(bp->sl, GL_COMPILE); + { + if (on) sol_shad_body(draw->base, bp->base, M_OPAQUE, 0); + if (rn) sol_shad_body(draw->base, bp->base, M_REFLECTIVE, 0); + if (dn) sol_shad_body(draw->base, bp->base, M_OPAQUE, M_DECAL); + if (sn) + { + /* Transparent shadowed geometry hack. */ + + if (dn) + sol_shad_body(draw->base, bp->base, M_SHADOWED, M_DECAL); + + sol_shad_body(draw->base, bp->base, M_SHADOWED, 0); + } + } + glEndList(); + } + else bp->sl = 0; + } +} + +static GLuint sol_find_texture(const char *name) +{ + char png[MAXSTR]; + char jpg[MAXSTR]; + + GLuint o; + + /* Prefer a lossless copy of the texture over a lossy compression. */ + + strncpy(png, name, PATHMAX); strcat(png, ".png"); + strncpy(jpg, name, PATHMAX); strcat(jpg, ".jpg"); + + /* Check for a PNG. */ + + if ((o = make_image_from_file(png))) + return o; + + /* Check for a JPG. */ + + if ((o = make_image_from_file(jpg))) + return o; + + return 0; +} + +static void sol_load_textures(struct s_draw *draw) +{ + int i; + + /* Load the image referenced by each material. */ + + for (i = 0; i < draw->mc; i++) + { + struct d_mtrl *mp = draw->mv + i; + + if ((mp->o = sol_find_texture(_(mp->base->f)))) + { + /* Set the texture to clamp or repeat based on material type. */ + + if (mp->base->fl & M_CLAMPED) + { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + } + else + { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + } + } + } +} + +/*---------------------------------------------------------------------------*/ + +int sol_load_draw(struct s_draw *draw, const struct s_vary *vary, int s) +{ + int i; + + memset(draw, 0, sizeof (*draw)); + + draw->vary = vary; + draw->base = draw->vary->base; + + if (draw->base->mc) + { + draw->mv = calloc(draw->base->mc, sizeof (*draw->mv)); + draw->mc = draw->base->mc; + + for (i = 0; i < draw->base->mc; i++) + { + struct d_mtrl *mp = draw->mv + i; + struct b_mtrl *mq = draw->base->mv + i; + + mp->base = mq; + } + } + + if (draw->base->bc) + { + draw->bv = calloc(draw->base->bc, sizeof (*draw->bv)); + draw->bc = draw->base->bc; + + for (i = 0; i < draw->base->bc; i++) + { + struct d_body *bp = draw->bv + i; + struct b_body *bq = draw->base->bv + i; + + bp->base = bq; + } + } + + sol_load_textures(draw); + sol_load_objects (draw, s); + + return 1; +} + +void sol_free_draw(struct s_draw *draw) +{ + int i; + + for (i = 0; i < draw->mc; i++) + { + if (glIsTexture(draw->mv[i].o)) + glDeleteTextures(1, &draw->mv[i].o); + } + + for (i = 0; i < draw->bc; i++) + { + if (glIsList(draw->bv[i].ol)) + glDeleteLists(draw->bv[i].ol, 1); + if (glIsList(draw->bv[i].tl)) + glDeleteLists(draw->bv[i].tl, 1); + if (glIsList(draw->bv[i].rl)) + glDeleteLists(draw->bv[i].rl, 1); + if (glIsList(draw->bv[i].sl)) + glDeleteLists(draw->bv[i].sl, 1); + } + + free(draw->mv); + free(draw->bv); + + memset(draw, 0, sizeof (*draw)); +} + +/*---------------------------------------------------------------------------*/ + +int sol_load_full(struct s_full *full, const char *filename, int s) +{ + if (sol_load_base(&full->base, filename)) + { + sol_load_vary(&full->vary, &full->base); + sol_load_draw(&full->draw, &full->vary, s); + + return 1; + } + + return 0; +} + +void sol_free_full(struct s_full *full) +{ + sol_free_draw(&full->draw); + sol_free_vary(&full->vary); + sol_free_base(&full->base); +} + +/*---------------------------------------------------------------------------*/ diff --git a/share/solid_draw.h b/share/solid_draw.h new file mode 100644 index 0000000..4e4525b --- /dev/null +++ b/share/solid_draw.h @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2003 Robert Kooima + * + * NEVERBALL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2 of the License, + * or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#ifndef SOLID_DRAW_H +#define SOLID_DRAW_H + +#include "solid_base.h" +#include "solid_vary.h" + +/* + * Rendered solid data. + */ + +/*---------------------------------------------------------------------------*/ + +struct d_mtrl +{ + const struct b_mtrl *base; + + GLuint o; /* OpenGL texture object */ +}; + +struct d_body +{ + const struct b_body *base; + + GLuint ol; /* opaque geometry list */ + GLuint tl; /* transparent geometry list */ + GLuint rl; /* reflective geometry list */ + GLuint sl; /* shadowed geometry list */ +}; + +struct s_draw +{ + const struct s_base *base; + const struct s_vary *vary; + + int mc; + int bc; + + struct d_mtrl *mv; + struct d_body *bv; +}; + +/*---------------------------------------------------------------------------*/ + +int sol_load_draw(struct s_draw *, const struct s_vary *, int); +void sol_free_draw(struct s_draw *); + +int sol_reflective(const struct s_draw *); + +void sol_back(const struct s_draw *, float, float, float); +void sol_refl(const struct s_draw *); +void sol_draw(const struct s_draw *, int, int); +void sol_bill(const struct s_draw *, const float *, float); +void sol_shad(const struct s_draw *); + +/*---------------------------------------------------------------------------*/ + +struct s_full +{ + struct s_base base; + struct s_vary vary; + struct s_draw draw; +}; + +int sol_load_full(struct s_full *, const char *, int); +void sol_free_full(struct s_full *); + +/*---------------------------------------------------------------------------*/ + +#endif diff --git a/share/solid_gl.c b/share/solid_gl.c deleted file mode 100644 index 6253257..0000000 --- a/share/solid_gl.c +++ /dev/null @@ -1,758 +0,0 @@ -/* - * Copyright (C) 2003 Robert Kooima - * - * NEVERBALL is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2 of the License, - * or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - */ - -#include -#include - -#include -#include -#include -#include - -#include "glext.h" -#include "vec3.h" -#include "image.h" -#include "base_image.h" -#include "solid_gl.h" -#include "solid_all.h" -#include "base_config.h" -#include "lang.h" - -/*---------------------------------------------------------------------------*/ - -static int sol_enum_mtrl(const struct s_file *fp, - const struct s_body *bp, int mi) -{ - int li, gi, c = 0; - - /* Count all lump geoms with this material. */ - - for (li = 0; li < bp->lc; li++) - { - int g0 = fp->lv[bp->l0 + li].g0; - int gc = fp->lv[bp->l0 + li].gc; - - for (gi = 0; gi < gc; gi++) - if (fp->gv[fp->iv[g0 + gi]].mi == mi) - c++; - } - - /* Count all body geoms with this material. */ - - for (gi = 0; gi < bp->gc; gi++) - if (fp->gv[fp->iv[bp->g0 + gi]].mi == mi) - c++; - - return c; -} - -static int sol_enum_body(const struct s_file *fp, - const struct s_body *bp, int fl) -{ - int mi, c = 0; - - /* Count all geoms with this flag. */ - - for (mi = 0; mi < fp->mc; mi++) - if (fp->mv[mi].fl & fl) - c = c + sol_enum_mtrl(fp, bp, mi); - - return c; -} - -/*---------------------------------------------------------------------------*/ - -int sol_reflective(const struct s_file *fp) -{ - int bi; - - for (bi = 0; bi < fp->bc; bi++) - if (fp->bv[bi].rl) - return 1; - - return 0; -} - -/*---------------------------------------------------------------------------*/ - -#define tobyte(f) ((GLubyte) (f * 255.0f)) - -#define color_cmp(a, b) (tobyte((a)[0]) == tobyte((b)[0]) && \ - tobyte((a)[1]) == tobyte((b)[1]) && \ - tobyte((a)[2]) == tobyte((b)[2]) && \ - tobyte((a)[3]) == tobyte((b)[3])) - -static struct s_mtrl default_mtrl = -{ - { 0.8f, 0.8f, 0.8f, 1.0f }, - { 0.2f, 0.2f, 0.2f, 1.0f }, - { 0.0f, 0.0f, 0.0f, 1.0f }, - { 0.0f, 0.0f, 0.0f, 1.0f }, - { 0.0f, }, 0.0f, M_OPAQUE, 0, "" -}; - -static const struct s_mtrl *sol_draw_mtrl(const struct s_file *fp, - const struct s_mtrl *mp, - const struct s_mtrl *mq) -{ - /* Change material properties only as needed. */ - - if (!color_cmp(mp->a, mq->a)) - glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, mp->a); - if (!color_cmp(mp->d, mq->d)) - glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->d); - if (!color_cmp(mp->s, mq->s)) - glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mp->s); - if (!color_cmp(mp->e, mq->e)) - glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, mp->e); - if (tobyte(mp->h[0]) != tobyte(mq->h[0])) - glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, mp->h); - - /* Bind the texture. */ - - if (mp->o != mq->o) - glBindTexture(GL_TEXTURE_2D, mp->o); - - /* Enable environment mapping. */ - - if ((mp->fl & M_ENVIRONMENT) && !(mq->fl & M_ENVIRONMENT)) - { - glEnable(GL_TEXTURE_GEN_S); - glEnable(GL_TEXTURE_GEN_T); - - glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); - glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); - } - - /* Disable environment mapping. */ - - if ((mq->fl & M_ENVIRONMENT) && !(mp->fl & M_ENVIRONMENT)) - { - glDisable(GL_TEXTURE_GEN_S); - glDisable(GL_TEXTURE_GEN_T); - } - - /* Enable additive blending. */ - - if ((mp->fl & M_ADDITIVE) && !(mq->fl & M_ADDITIVE)) - glBlendFunc(GL_ONE, GL_ONE); - - /* Enable standard blending. */ - - if ((mq->fl & M_ADDITIVE) && !(mp->fl & M_ADDITIVE)) - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - /* Enable visibility-from-behind. */ - - if ((mp->fl & M_TWO_SIDED) && !(mq->fl & M_TWO_SIDED)) - { - glDisable(GL_CULL_FACE); - glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 1); - } - - /* Disable visibility-from-behind. */ - - if ((mq->fl & M_TWO_SIDED) && !(mp->fl & M_TWO_SIDED)) - { - glEnable(GL_CULL_FACE); - glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 0); - } - - /* Enable decal offset. */ - - if ((mp->fl & M_DECAL) && !(mq->fl & M_DECAL)) - { - glEnable(GL_POLYGON_OFFSET_FILL); - glPolygonOffset(-1.0f, -2.0f); - } - - /* Disable decal offset. */ - - if ((mq->fl & M_DECAL) && !(mp->fl & M_DECAL)) - glDisable(GL_POLYGON_OFFSET_FILL); - - return mp; -} - -static const struct s_mtrl *sol_back_bill(const struct s_file *fp, - const struct s_bill *rp, - const struct s_mtrl *mp, float t) -{ - float T = (rp->t > 0.0f) ? (fmodf(t, rp->t) - rp->t / 2) : 0.0f; - - float w = rp->w[0] + rp->w[1] * T + rp->w[2] * T * T; - float h = rp->h[0] + rp->h[1] * T + rp->h[2] * T * T; - - if (w > 0 && h > 0) - { - float rx = rp->rx[0] + rp->rx[1] * T + rp->rx[2] * T * T; - float ry = rp->ry[0] + rp->ry[1] * T + rp->ry[2] * T * T; - float rz = rp->rz[0] + rp->rz[1] * T + rp->rz[2] * T * T; - - glPushMatrix(); - { - float y0 = (rp->fl & B_EDGE) ? 0 : -h / 2; - float y1 = (rp->fl & B_EDGE) ? h : +h / 2; - - glRotatef(ry, 0.0f, 1.0f, 0.0f); - glRotatef(rx, 1.0f, 0.0f, 0.0f); - glTranslatef(0.0f, 0.0f, -rp->d); - - if (rp->fl & B_FLAT) - { - glRotatef(-rx - 90.0f, 1.0f, 0.0f, 0.0f); - glRotatef(-ry, 0.0f, 0.0f, 1.0f); - } - if (rp->fl & B_EDGE) - glRotatef(-rx, 1.0f, 0.0f, 0.0f); - - glRotatef(rz, 0.0f, 0.0f, 1.0f); - - mp = sol_draw_mtrl(fp, fp->mv + rp->mi, mp); - - glBegin(GL_QUADS); - { - glTexCoord2f(0.0f, 0.0f); glVertex2f(-w / 2, y0); - glTexCoord2f(1.0f, 0.0f); glVertex2f(+w / 2, y0); - glTexCoord2f(1.0f, 1.0f); glVertex2f(+w / 2, y1); - glTexCoord2f(0.0f, 1.0f); glVertex2f(-w / 2, y1); - } - glEnd(); - } - glPopMatrix(); - } - - return mp; -} - -/*---------------------------------------------------------------------------*/ - -void sol_back(const struct s_file *fp, float n, float f, float t) -{ - const struct s_mtrl *mp = &default_mtrl; - - int ri; - - /* Render all billboards in the given range. */ - - glDisable(GL_LIGHTING); - glDepthMask(GL_FALSE); - { - for (ri = 0; ri < fp->rc; ri++) - if (n <= fp->rv[ri].d && fp->rv[ri].d < f) - mp = sol_back_bill(fp, fp->rv + ri, mp, t); - - mp = sol_draw_mtrl(fp, &default_mtrl, mp); - } - glDepthMask(GL_TRUE); - glEnable(GL_LIGHTING); -} - -/*---------------------------------------------------------------------------*/ -/* - * The following code renders a body in a ludicrously inefficient - * manner. It iterates the materials and scans the data structure for - * geometry using each. This has the effect of absolutely minimizing - * material changes, texture bindings, and Begin/End pairs, but - * maximizing trips through the data. - * - * However, this is only done once for each level. The results are - * stored in display lists. Thus, it is well worth it. - */ - -static void sol_draw_geom(const struct s_file *fp, - const struct s_geom *gp, int mi) -{ - if (gp->mi == mi) - { - const float *ui = fp->tv[gp->ti].u; - const float *uj = fp->tv[gp->tj].u; - const float *uk = fp->tv[gp->tk].u; - - const float *ni = fp->sv[gp->si].n; - const float *nj = fp->sv[gp->sj].n; - const float *nk = fp->sv[gp->sk].n; - - const float *vi = fp->vv[gp->vi].p; - const float *vj = fp->vv[gp->vj].p; - const float *vk = fp->vv[gp->vk].p; - - glTexCoord2fv(ui); - glNormal3fv(ni); - glVertex3fv(vi); - - glTexCoord2fv(uj); - glNormal3fv(nj); - glVertex3fv(vj); - - glTexCoord2fv(uk); - glNormal3fv(nk); - glVertex3fv(vk); - } -} - -static void sol_draw_lump(const struct s_file *fp, - const struct s_lump *lp, int mi) -{ - int i; - - for (i = 0; i < lp->gc; i++) - sol_draw_geom(fp, fp->gv + fp->iv[lp->g0 + i], mi); -} - -static const struct s_mtrl *sol_draw_body(const struct s_file *fp, - const struct s_body *bp, - const struct s_mtrl *mp, - int fl, int decal) -{ - int mi, li, gi; - - /* Iterate all materials of the correct opacity. */ - - for (mi = 0; mi < fp->mc; mi++) - if ((fp->mv[mi].fl & fl) && (fp->mv[mi].fl & M_DECAL) == decal) - { - if (sol_enum_mtrl(fp, bp, mi)) - { - /* Set the material state. */ - - mp = sol_draw_mtrl(fp, fp->mv + mi, mp); - - /* Render all geometry of that material. */ - - glBegin(GL_TRIANGLES); - { - for (li = 0; li < bp->lc; li++) - sol_draw_lump(fp, fp->lv + bp->l0 + li, mi); - for (gi = 0; gi < bp->gc; gi++) - sol_draw_geom(fp, fp->gv + fp->iv[bp->g0 + gi], mi); - } - glEnd(); - } - } - - return mp; -} - -static void sol_draw_list(const struct s_file *fp, - const struct s_body *bp, GLuint list) -{ - float p[3], e[4], u[3], a; - - sol_body_p(p, fp, bp->pi, bp->t); - sol_body_e(e, fp, bp, 0); - - q_as_axisangle(e, u, &a); - a = V_DEG(a); - - glPushMatrix(); - { - /* Translate and rotate a moving body. */ - - glTranslatef(p[0], p[1], p[2]); - glRotatef(a, u[0], u[1], u[2]); - - /* Draw the body. */ - - glCallList(list); - } - glPopMatrix(); -} - -void sol_draw(const struct s_file *fp, int depthmask, int depthtest) -{ - int bi; - - /* Render all opaque geometry into the color and depth buffers. */ - - for (bi = 0; bi < fp->bc; bi++) - if (fp->bv[bi].ol) - sol_draw_list(fp, fp->bv + bi, fp->bv[bi].ol); - - /* Render all translucent geometry into only the color buffer. */ - - if (depthtest == 0) glDisable(GL_DEPTH_TEST); - if (depthmask == 0) glDepthMask(GL_FALSE); - { - for (bi = 0; bi < fp->bc; bi++) - if (fp->bv[bi].tl) - sol_draw_list(fp, fp->bv + bi, fp->bv[bi].tl); - } - if (depthmask == 0) glDepthMask(GL_TRUE); - if (depthtest == 0) glEnable(GL_DEPTH_TEST); -} - -void sol_bill(const struct s_file *fp, const float *M, float t) -{ - const struct s_mtrl *mp = &default_mtrl; - - int ri; - - for (ri = 0; ri < fp->rc; ++ri) - { - const struct s_bill *rp = fp->rv + ri; - - float T = rp->t * t; - float S = fsinf(T); - - float w = rp->w [0] + rp->w [1] * T + rp->w [2] * S; - float h = rp->h [0] + rp->h [1] * T + rp->h [2] * S; - float rx = rp->rx[0] + rp->rx[1] * T + rp->rx[2] * S; - float ry = rp->ry[0] + rp->ry[1] * T + rp->ry[2] * S; - float rz = rp->rz[0] + rp->rz[1] * T + rp->rz[2] * S; - - mp = sol_draw_mtrl(fp, fp->mv + rp->mi, mp); - - glPushMatrix(); - { - glTranslatef(rp->p[0], rp->p[1], rp->p[2]); - - if (M && ((rp->fl & B_NOFACE) == 0)) glMultMatrixf(M); - - if (fabsf(rx) > 0.0f) glRotatef(rx, 1.0f, 0.0f, 0.0f); - if (fabsf(ry) > 0.0f) glRotatef(ry, 0.0f, 1.0f, 0.0f); - if (fabsf(rz) > 0.0f) glRotatef(rz, 0.0f, 0.0f, 1.0f); - - glBegin(GL_QUADS); - { - glTexCoord2f(0.0f, 0.0f); glVertex2f(-w / 2, -h / 2); - glTexCoord2f(1.0f, 0.0f); glVertex2f(+w / 2, -h / 2); - glTexCoord2f(1.0f, 1.0f); glVertex2f(+w / 2, +h / 2); - glTexCoord2f(0.0f, 1.0f); glVertex2f(-w / 2, +h / 2); - } - glEnd(); - } - glPopMatrix(); - } - - mp = sol_draw_mtrl(fp, &default_mtrl, mp); -} - -void sol_refl(const struct s_file *fp) -{ - int bi; - - /* Render all reflective geometry into the color and depth buffers. */ - - for (bi = 0; bi < fp->bc; bi++) - if (fp->bv[bi].rl) - sol_draw_list(fp, fp->bv + bi, fp->bv[bi].rl); -} - -/*---------------------------------------------------------------------------*/ - -static void sol_shad_geom(const struct s_file *fp, - const struct s_geom *gp, int mi) -{ - if (gp->mi == mi) - { - const float *vi = fp->vv[gp->vi].p; - const float *vj = fp->vv[gp->vj].p; - const float *vk = fp->vv[gp->vk].p; - - glTexCoord2f(vi[0], vi[2]); - glVertex3fv(vi); - - glTexCoord2f(vj[0], vj[2]); - glVertex3fv(vj); - - glTexCoord2f(vk[0], vk[2]); - glVertex3fv(vk); - } -} - -static void sol_shad_lump(const struct s_file *fp, - const struct s_lump *lp, int mi) -{ - int i; - - for (i = 0; i < lp->gc; i++) - sol_shad_geom(fp, fp->gv + fp->iv[lp->g0 + i], mi); -} - -static void sol_shad_body(const struct s_file *fp, - const struct s_body *bp, - int fl, int decal) -{ - int mi, li, gi; - - if (decal) - { - glEnable(GL_POLYGON_OFFSET_FILL); - glPolygonOffset(-1.0f, -2.0f); - } - - glBegin(GL_TRIANGLES); - { - for (mi = 0; mi < fp->mc; mi++) - if ((fp->mv[mi].fl & fl) && (fp->mv[mi].fl & M_DECAL) == decal) - { - for (li = 0; li < bp->lc; li++) - sol_shad_lump(fp, fp->lv + bp->l0 + li, mi); - for (gi = 0; gi < bp->gc; gi++) - sol_shad_geom(fp, fp->gv + fp->iv[bp->g0 + gi], mi); - } - } - glEnd(); - - if (decal) - glDisable(GL_POLYGON_OFFSET_FILL); -} - -static void sol_shad_list(const struct s_file *fp, - const struct s_body *bp, GLuint list) -{ - float p[3], e[4], u[3], a; - - sol_body_p(p, fp, bp->pi, bp->t); - sol_body_e(e, fp, bp, 0); - - q_as_axisangle(e, u, &a); - a = V_DEG(a); - - glPushMatrix(); - { - /* Translate and rotate a moving body. */ - - glTranslatef(p[0], p[1], p[2]); - glRotatef(a, u[0], u[1], u[2]); - - /* Translate the shadow on a moving body. */ - - glMatrixMode(GL_TEXTURE); - { - glPushMatrix(); - glTranslatef(p[0], p[2], 0.0f); - glRotatef(-a, u[0], u[2], u[1]); - } - glMatrixMode(GL_MODELVIEW); - - /* Draw the body. */ - - glCallList(list); - - /* Pop the shadow translation. */ - - glMatrixMode(GL_TEXTURE); - { - glPopMatrix(); - } - glMatrixMode(GL_MODELVIEW); - } - glPopMatrix(); -} - -void sol_shad(const struct s_file *fp) -{ - int bi; - - /* Render all shadowed geometry. */ - - glDepthMask(GL_FALSE); - { - for (bi = 0; bi < fp->bc; bi++) - if (fp->bv[bi].sl) - sol_shad_list(fp, fp->bv + bi, fp->bv[bi].sl); - } - glDepthMask(GL_TRUE); -} - -/*---------------------------------------------------------------------------*/ - -static void sol_load_objects(struct s_file *fp, int s) -{ - int i; - - /* Here we sort geometry into display lists by material type. */ - - for (i = 0; i < fp->bc; i++) - { - struct s_body *bp = fp->bv + i; - - int on = sol_enum_body(fp, bp, M_OPAQUE); - int tn = sol_enum_body(fp, bp, M_TRANSPARENT); - int rn = sol_enum_body(fp, bp, M_REFLECTIVE); - int dn = sol_enum_body(fp, bp, M_DECAL); - int sn = sol_enum_body(fp, bp, M_SHADOWED); - - /* Draw all opaque geometry, decals last. */ - - if (on) - { - fp->bv[i].ol = glGenLists(1); - - glNewList(fp->bv[i].ol, GL_COMPILE); - { - const struct s_mtrl *mp = &default_mtrl; - - mp = sol_draw_body(fp, fp->bv + i, mp, M_OPAQUE, 0); - mp = sol_draw_body(fp, fp->bv + i, mp, M_OPAQUE, M_DECAL); - mp = sol_draw_mtrl(fp, &default_mtrl, mp); - } - glEndList(); - } - else fp->bv[i].ol = 0; - - /* Draw all translucent geometry, decals first. */ - - if (tn) - { - fp->bv[i].tl = glGenLists(1); - - glNewList(fp->bv[i].tl, GL_COMPILE); - { - const struct s_mtrl *mp = &default_mtrl; - - mp = sol_draw_body(fp, fp->bv + i, mp, M_TRANSPARENT, M_DECAL); - mp = sol_draw_body(fp, fp->bv + i, mp, M_TRANSPARENT, 0); - mp = sol_draw_mtrl(fp, &default_mtrl, mp); - } - glEndList(); - } - else fp->bv[i].tl = 0; - - /* Draw all reflective geometry. */ - - if (rn) - { - fp->bv[i].rl = glGenLists(1); - - glNewList(fp->bv[i].rl, GL_COMPILE); - { - const struct s_mtrl *mp = &default_mtrl; - - mp = sol_draw_body(fp, fp->bv + i, mp, M_REFLECTIVE, 0); - mp = sol_draw_mtrl(fp, &default_mtrl, mp); - } - glEndList(); - } - else fp->bv[i].rl = 0; - - /* Draw all shadowed geometry. */ - - if (s && (on || rn || sn)) - { - fp->bv[i].sl = glGenLists(1); - - glNewList(fp->bv[i].sl, GL_COMPILE); - { - if (on) sol_shad_body(fp, fp->bv + i, M_OPAQUE, 0); - if (rn) sol_shad_body(fp, fp->bv + i, M_REFLECTIVE, 0); - if (dn) sol_shad_body(fp, fp->bv + i, M_OPAQUE, M_DECAL); - if (sn) - { - /* Transparent shadowed geometry hack. */ - - if (dn) - sol_shad_body(fp, fp->bv + i, M_SHADOWED, M_DECAL); - - sol_shad_body(fp, fp->bv + i, M_SHADOWED, 0); - } - } - glEndList(); - } - else fp->bv[i].sl = 0; - } -} - -static GLuint sol_find_texture(const char *name) -{ - char png[MAXSTR]; - char jpg[MAXSTR]; - - GLuint o; - - /* Prefer a lossless copy of the texture over a lossy compression. */ - - strncpy(png, name, PATHMAX); strcat(png, ".png"); - strncpy(jpg, name, PATHMAX); strcat(jpg, ".jpg"); - - /* Check for a PNG. */ - - if ((o = make_image_from_file(png))) - return o; - - /* Check for a JPG. */ - - if ((o = make_image_from_file(jpg))) - return o; - - return 0; -} - -static void sol_load_textures(struct s_file *fp) -{ - int i; - - /* Load the image referenced by each material. */ - - for (i = 0; i < fp->mc; i++) - if ((fp->mv[i].o = sol_find_texture(_(fp->mv[i].f)))) - { - /* Set the texture to clamp or repeat based on material type. */ - - if (fp->mv[i].fl & M_CLAMPED) - { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); - } - else - { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - } - } -} - -/*---------------------------------------------------------------------------*/ - -int sol_load_gl(struct s_file *fp, const char *filename, int s) -{ - if (sol_load_only_file(fp, filename)) - { - sol_load_textures(fp); - sol_load_objects (fp, s); - return 1; - } - return 0; -} - -/*---------------------------------------------------------------------------*/ - -void sol_free_gl(struct s_file *fp) -{ - int i; - - for (i = 0; i < fp->mc; i++) - { - if (glIsTexture(fp->mv[i].o)) - glDeleteTextures(1, &fp->mv[i].o); - } - - for (i = 0; i < fp->bc; i++) - { - if (glIsList(fp->bv[i].ol)) - glDeleteLists(fp->bv[i].ol, 1); - if (glIsList(fp->bv[i].tl)) - glDeleteLists(fp->bv[i].tl, 1); - if (glIsList(fp->bv[i].rl)) - glDeleteLists(fp->bv[i].rl, 1); - if (glIsList(fp->bv[i].sl)) - glDeleteLists(fp->bv[i].sl, 1); - } - - sol_free(fp); -} - -/*---------------------------------------------------------------------------*/ diff --git a/share/solid_gl.h b/share/solid_gl.h deleted file mode 100644 index f67fb29..0000000 --- a/share/solid_gl.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2003 Robert Kooima - * - * NEVERBALL is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2 of the License, - * or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - */ - -#ifndef SOL_GL_H -#define SOL_GL_H - -#include "solid.h" - -/*---------------------------------------------------------------------------*/ - -int sol_load_gl(struct s_file *, const char *, int); -void sol_free_gl(struct s_file *); - -int sol_reflective(const struct s_file *); - -void sol_back(const struct s_file *, float, float, float); -void sol_refl(const struct s_file *); -void sol_draw(const struct s_file *, int, int); -void sol_bill(const struct s_file *, const float *, float); -void sol_shad(const struct s_file *); - -/*---------------------------------------------------------------------------*/ - -#endif diff --git a/share/solid_sim.h b/share/solid_sim.h index f57b2b3..cc60720 100644 --- a/share/solid_sim.h +++ b/share/solid_sim.h @@ -12,17 +12,17 @@ * General Public License for more details. */ -#ifndef SOL_SIM_H -#define SOL_SIM_H +#ifndef SOLID_SIM_H +#define SOLID_SIM_H -#include "solid.h" +#include "solid_vary.h" /*---------------------------------------------------------------------------*/ -void sol_init_sim(struct s_file *); +void sol_init_sim(struct s_vary *); void sol_quit_sim(void); -float sol_step(struct s_file *, const float *, float, int, int *); +float sol_step(struct s_vary *, const float *, float, int, int *); /*---------------------------------------------------------------------------*/ diff --git a/share/solid_sim_sol.c b/share/solid_sim_sol.c index 8990867..c446c04 100644 --- a/share/solid_sim_sol.c +++ b/share/solid_sim_sol.c @@ -17,7 +17,7 @@ #include "vec3.h" #include "common.h" -#include "solid.h" +#include "solid_vary.h" #include "solid_sim.h" #include "solid_all.h" #include "solid_cmd.h" @@ -246,7 +246,7 @@ static float v_side(float Q[3], * Q gives the position of the point of impact and W gives the * velocity of the object being impacted. */ -static float sol_bounce(struct s_ball *up, +static float sol_bounce(struct v_ball *up, const float q[3], const float w[3], float dt) { @@ -283,8 +283,8 @@ static float sol_bounce(struct s_ball *up, static float sol_test_vert(float dt, float T[3], - const struct s_ball *up, - const struct s_vert *vp, + const struct v_ball *up, + const struct b_vert *vp, const float o[3], const float w[3]) { @@ -293,28 +293,27 @@ static float sol_test_vert(float dt, static float sol_test_edge(float dt, float T[3], - const struct s_ball *up, - const struct s_file *fp, - const struct s_edge *ep, + const struct v_ball *up, + const struct s_base *base, + const struct b_edge *ep, const float o[3], const float w[3]) { float q[3]; float u[3]; - v_cpy(q, fp->vv[ep->vi].p); - v_sub(u, fp->vv[ep->vj].p, - fp->vv[ep->vi].p); + v_cpy(q, base->vv[ep->vi].p); + v_sub(u, base->vv[ep->vj].p, base->vv[ep->vi].p); return v_edge(T, o, q, u, w, up->p, up->v, up->r); } static float sol_test_side(float dt, float T[3], - const struct s_ball *up, - const struct s_file *fp, - const struct s_lump *lp, - const struct s_side *sp, + const struct v_ball *up, + const struct s_base *base, + const struct b_lump *lp, + const struct b_side *sp, const float o[3], const float w[3]) { @@ -324,7 +323,7 @@ static float sol_test_side(float dt, if (t < dt) for (i = 0; i < lp->sc; i++) { - const struct s_side *sq = fp->sv + fp->iv[lp->s0 + i]; + const struct b_side *sq = base->sv + base->iv[lp->s0 + i]; if (sp != sq && v_dot(T, sq->n) - @@ -338,8 +337,8 @@ static float sol_test_side(float dt, /*---------------------------------------------------------------------------*/ static int sol_test_fore(float dt, - const struct s_ball *up, - const struct s_side *sp, + const struct v_ball *up, + const struct b_side *sp, const float o[3], const float w[3]) { @@ -367,8 +366,8 @@ static int sol_test_fore(float dt, } static int sol_test_back(float dt, - const struct s_ball *up, - const struct s_side *sp, + const struct v_ball *up, + const struct b_side *sp, const float o[3], const float w[3]) { @@ -399,9 +398,9 @@ static int sol_test_back(float dt, static float sol_test_lump(float dt, float T[3], - const struct s_ball *up, - const struct s_file *fp, - const struct s_lump *lp, + const struct v_ball *up, + const struct s_base *base, + const struct b_lump *lp, const float o[3], const float w[3]) { @@ -418,7 +417,7 @@ static float sol_test_lump(float dt, if (up->r > 0.0f) for (i = 0; i < lp->vc; i++) { - const struct s_vert *vp = fp->vv + fp->iv[lp->v0 + i]; + const struct b_vert *vp = base->vv + base->iv[lp->v0 + i]; if ((u = sol_test_vert(t, U, up, vp, o, w)) < t) { @@ -432,9 +431,9 @@ static float sol_test_lump(float dt, if (up->r > 0.0f) for (i = 0; i < lp->ec; i++) { - const struct s_edge *ep = fp->ev + fp->iv[lp->e0 + i]; + const struct b_edge *ep = base->ev + base->iv[lp->e0 + i]; - if ((u = sol_test_edge(t, U, up, fp, ep, o, w)) < t) + if ((u = sol_test_edge(t, U, up, base, ep, o, w)) < t) { v_cpy(T, U); t = u; @@ -445,9 +444,9 @@ static float sol_test_lump(float dt, for (i = 0; i < lp->sc; i++) { - const struct s_side *sp = fp->sv + fp->iv[lp->s0 + i]; + const struct b_side *sp = base->sv + base->iv[lp->s0 + i]; - if ((u = sol_test_side(t, U, up, fp, lp, sp, o, w)) < t) + if ((u = sol_test_side(t, U, up, base, lp, sp, o, w)) < t) { v_cpy(T, U); t = u; @@ -458,9 +457,9 @@ static float sol_test_lump(float dt, static float sol_test_node(float dt, float T[3], - const struct s_ball *up, - const struct s_file *fp, - const struct s_node *np, + const struct v_ball *up, + const struct s_base *base, + const struct b_node *np, const float o[3], const float w[3]) { @@ -471,9 +470,9 @@ static float sol_test_node(float dt, for (i = 0; i < np->lc; i++) { - const struct s_lump *lp = fp->lv + np->l0 + i; + const struct b_lump *lp = base->lv + np->l0 + i; - if ((u = sol_test_lump(t, U, up, fp, lp, o, w)) < t) + if ((u = sol_test_lump(t, U, up, base, lp, o, w)) < t) { v_cpy(T, U); t = u; @@ -482,11 +481,11 @@ static float sol_test_node(float dt, /* Test in front of this node */ - if (np->ni >= 0 && sol_test_fore(t, up, fp->sv + np->si, o, w)) + if (np->ni >= 0 && sol_test_fore(t, up, base->sv + np->si, o, w)) { - const struct s_node *nq = fp->nv + np->ni; + const struct b_node *nq = base->nv + np->ni; - if ((u = sol_test_node(t, U, up, fp, nq, o, w)) < t) + if ((u = sol_test_node(t, U, up, base, nq, o, w)) < t) { v_cpy(T, U); t = u; @@ -495,11 +494,11 @@ static float sol_test_node(float dt, /* Test behind this node */ - if (np->nj >= 0 && sol_test_back(t, up, fp->sv + np->si, o, w)) + if (np->nj >= 0 && sol_test_back(t, up, base->sv + np->si, o, w)) { - const struct s_node *nq = fp->nv + np->nj; + const struct b_node *nq = base->nv + np->nj; - if ((u = sol_test_node(t, U, up, fp, nq, o, w)) < t) + if ((u = sol_test_node(t, U, up, base, nq, o, w)) < t) { v_cpy(T, U); t = u; @@ -511,18 +510,18 @@ static float sol_test_node(float dt, static float sol_test_body(float dt, float T[3], float V[3], - const struct s_ball *up, - const struct s_file *fp, - const struct s_body *bp) + const struct v_ball *up, + const struct s_vary *vary, + const struct v_body *bp) { float U[3], O[3], E[4], W[3], A[3], u; - const struct s_node *np = fp->nv + bp->ni; + const struct b_node *np = vary->base->nv + bp->base->ni; - sol_body_p(O, fp, bp->pi, bp->t); - sol_body_v(W, fp, bp->pi, bp->t, dt); - sol_body_e(E, fp, bp, 0); - sol_body_w(A, fp, bp); + sol_body_p(O, vary, bp->pi, bp->t); + sol_body_v(W, vary, bp->pi, bp->t, dt); + sol_body_e(E, vary, bp, 0); + sol_body_w(A, vary, bp); /* * For rotating bodies, rather than rotate every normal and vertex @@ -539,7 +538,7 @@ static float sol_test_body(float dt, { /* The body has a non-identity orientation or it is rotating. */ - struct s_ball ball; + struct v_ball ball; float e[4], p0[3], p1[3]; const float z[3] = { 0 }; @@ -552,7 +551,7 @@ static float sol_test_body(float dt, v_mad(p1, p1, up->v, dt); v_mad(p1, p1, W, -dt); - sol_body_e(e, fp, bp, dt); + sol_body_e(e, vary, bp, dt); q_conj(e, e); q_rot(p1, e, p1); @@ -567,7 +566,7 @@ static float sol_test_body(float dt, v_sub(ball.v, p1, p0); v_scl(ball.v, ball.v, 1.0f / dt); - if ((u = sol_test_node(dt, U, &ball, fp, np, z, z)) < dt) + if ((u = sol_test_node(dt, U, &ball, vary->base, np, z, z)) < dt) { float d[4]; @@ -596,7 +595,7 @@ static float sol_test_body(float dt, } else { - if ((u = sol_test_node(dt, U, up, fp, np, O, W)) < dt) + if ((u = sol_test_node(dt, U, up, vary->base, np, O, W)) < dt) { v_cpy(T, U); v_cpy(V, W); @@ -608,17 +607,17 @@ static float sol_test_body(float dt, static float sol_test_file(float dt, float T[3], float V[3], - const struct s_ball *up, - const struct s_file *fp) + const struct v_ball *up, + const struct s_vary *vary) { float U[3], W[3], u, t = dt; int i; - for (i = 0; i < fp->bc; i++) + for (i = 0; i < vary->bc; i++) { - const struct s_body *bp = fp->bv + i; + const struct v_body *bp = vary->bv + i; - if ((u = sol_test_body(t, U, W, up, fp, bp)) < t) + if ((u = sol_test_body(t, U, W, up, vary, bp)) < t) { v_cpy(T, U); v_cpy(V, W); @@ -682,16 +681,16 @@ static int ms_peek(float dt) * iterations, punt it. */ -float sol_step(struct s_file *fp, const float *g, float dt, int ui, int *m) +float sol_step(struct s_vary *vary, const float *g, float dt, int ui, int *m) { float P[3], V[3], v[3], r[3], a[3], d, e, nt, b = 0.0f, tt = dt; int c; union cmd cmd; - if (ui < fp->uc) + if (ui < vary->uc) { - struct s_ball *up = fp->uv + ui; + struct v_ball *up = vary->uv + ui; /* If the ball is in contact with a surface, apply friction. */ @@ -699,7 +698,7 @@ float sol_step(struct s_file *fp, const float *g, float dt, int ui, int *m) v_cpy(v, up->v); v_cpy(up->v, g); - if (m && sol_test_file(tt, P, V, up, fp) < 0.0005f) + if (m && sol_test_file(tt, P, V, up, vary) < 0.0005f) { v_cpy(up->v, v); v_sub(r, P, up->p); @@ -745,26 +744,26 @@ float sol_step(struct s_file *fp, const float *g, float dt, int ui, int *m) st = tt; - for (bi = 0; bi < fp->bc; bi++) + for (bi = 0; bi < vary->bc; bi++) { - struct s_body *bp = fp->bv + bi; + struct v_body *bp = vary->bv + bi; if (bp->pi >= 0) { - struct s_path *pp = fp->pv + bp->pi; + struct v_path *pp = vary->pv + bp->pi; if (!pp->f) continue; - if (bp->tm + ms_peek(st) > pp->tm) - st = MS_TO_TIME(pp->tm - bp->tm); + if (bp->tm + ms_peek(st) > pp->base->tm) + st = MS_TO_TIME(pp->base->tm - bp->tm); } } /* Miss collisions if we reach the iteration limit. */ if (c > 1) - nt = sol_test_file(st, P, V, up, fp); + nt = sol_test_file(st, P, V, up, vary); else nt = tt; @@ -774,9 +773,9 @@ float sol_step(struct s_file *fp, const float *g, float dt, int ui, int *m) ms = ms_step(nt); - sol_body_step(fp, nt, ms); - sol_swch_step(fp, nt, ms); - sol_ball_step(fp, nt); + sol_body_step(vary, nt, ms); + sol_swch_step(vary, nt, ms); + sol_ball_step(vary, nt); if (nt < st) if (b < (d = sol_bounce(up, P, V, nt))) @@ -795,7 +794,7 @@ float sol_step(struct s_file *fp, const float *g, float dt, int ui, int *m) /*---------------------------------------------------------------------------*/ -void sol_init_sim(struct s_file *fp) +void sol_init_sim(struct s_vary *vary) { ms_init(); } diff --git a/share/solid_vary.c b/share/solid_vary.c new file mode 100644 index 0000000..033ee44 --- /dev/null +++ b/share/solid_vary.c @@ -0,0 +1,137 @@ +/* + * Copyright (C) 2003 Robert Kooima + * + * NEVERBALL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2 of the License, + * or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#include + +#include "solid_vary.h" +#include "common.h" +#include "vec3.h" + +/*---------------------------------------------------------------------------*/ + +int sol_load_vary(struct s_vary *fp, const struct s_base *base) +{ + int i; + + memset(fp, 0, sizeof (*fp)); + + fp->base = base; + + if (fp->base->pc) + { + fp->pv = calloc(fp->base->pc, sizeof (*fp->pv)); + fp->pc = fp->base->pc; + + for (i = 0; i < fp->base->pc; i++) + { + struct v_path *pp = fp->pv + i; + struct b_path *pq = fp->base->pv + i; + + pp->base = pq; + pp->f = pq->f; + } + } + + if (fp->base->bc) + { + fp->bv = calloc(fp->base->bc, sizeof (*fp->bv)); + fp->bc = fp->base->bc; + + for (i = 0; i < fp->base->bc; i++) + { + struct v_body *bp = fp->bv + i; + struct b_body *bq = fp->base->bv + i; + + bp->base = bq; + bp->pi = bq->pi; + } + } + + if (fp->base->hc) + { + fp->hv = calloc(fp->base->hc, sizeof (*fp->hv)); + fp->hc = fp->base->hc; + + for (i = 0; i < fp->base->hc; i++) + { + struct v_item *hp = fp->hv + i; + struct b_item *hq = fp->base->hv + i; + + v_cpy(hp->p, hq->p); + + hp->t = hq->t; + hp->n = hq->n; + } + } + + if (fp->base->xc) + { + fp->xv = calloc(fp->base->xc, sizeof (*fp->xv)); + fp->xc = fp->base->xc; + + for (i = 0; i < fp->base->xc; i++) + { + struct v_swch *xp = fp->xv + i; + struct b_swch *xq = fp->base->xv + i; + + xp->base = xq; + xp->t = xq->t; + xp->tm = xq->tm; + xp->f = xq->f; + } + } + + if (fp->base->uc) + { + fp->uv = calloc(fp->base->uc, sizeof (*fp->uv)); + fp->uc = fp->base->uc; + + for (i = 0; i < fp->base->uc; i++) + { + struct v_ball *up = fp->uv + i; + struct b_ball *uq = fp->base->uv + i; + + v_cpy(up->p, uq->p); + + up->r = uq->r; + + up->E[0][0] = up->e[0][0] = 1.0f; + up->E[0][1] = up->e[0][1] = 0.0f; + up->E[0][2] = up->e[0][2] = 0.0f; + + up->E[1][0] = up->e[1][0] = 0.0f; + up->E[1][1] = up->e[1][1] = 1.0f; + up->E[1][2] = up->e[1][2] = 0.0f; + + up->E[2][0] = up->e[2][0] = 0.0f; + up->E[2][1] = up->e[2][1] = 0.0f; + up->E[2][2] = up->e[2][2] = 1.0f; + } + } + + return 1; +} + +void sol_free_vary(struct s_vary *fp) +{ + if (fp->pv) free(fp->pv); + if (fp->bv) free(fp->bv); + if (fp->hv) free(fp->hv); + if (fp->xv) free(fp->xv); + if (fp->uv) free(fp->uv); + + memset(fp, 0, sizeof (*fp)); +} + +/*---------------------------------------------------------------------------*/ diff --git a/share/solid_vary.h b/share/solid_vary.h new file mode 100644 index 0000000..403099e --- /dev/null +++ b/share/solid_vary.h @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2003 Robert Kooima + * + * NEVERBALL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2 of the License, + * or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#ifndef SOLID_VARY_H +#define SOLID_VARY_H + +#include "base_config.h" +#include "solid_base.h" + +/* + * Varying solid data. + */ + +/*---------------------------------------------------------------------------*/ + +struct v_path +{ + const struct b_path *base; + + int f; /* enable flag */ +}; + +struct v_body +{ + const struct b_body *base; + + float t; /* time on current path */ + int tm; /* milliseconds */ + + int pi; +}; + +struct v_item +{ + float p[3]; /* position */ + int t; /* type */ + int n; /* value */ +}; + +struct v_swch +{ + const struct b_swch *base; + + float t; /* current timer */ + int tm; /* milliseconds */ + int f; /* current state */ + int e; /* is a ball inside it? */ +}; + +struct v_ball +{ + float e[3][3]; /* basis of orientation */ + float p[3]; /* position vector */ + float v[3]; /* velocity vector */ + float w[3]; /* angular velocity vector */ + float E[3][3]; /* basis of pendulum */ + float W[3]; /* angular pendulum velocity */ + float r; /* radius */ +}; + +struct s_vary +{ + const struct s_base *base; + + int pc; + int bc; + int hc; + int xc; + int uc; + + struct v_path *pv; + struct v_body *bv; + struct v_item *hv; + struct v_swch *xv; + struct v_ball *uv; +}; + +/*---------------------------------------------------------------------------*/ + +int sol_load_vary(struct s_vary *, const struct s_base *); +void sol_free_vary(struct s_vary *); + +/*---------------------------------------------------------------------------*/ + +#endif -- 1.7.9.5