X-Git-Url: http://vcs.maemo.org/git/?a=blobdiff_plain;f=putt%2Fgame.c;h=9318ceb616ed30ae7090133e444290df990558e0;hb=aad3149acf32a98c85766e779e115dfb88afe4ff;hp=27aaa25712806a8beffc1ea0f9df8de71f5f9ccc;hpb=26c7eaa698e76ed25f0ef3667dbcd9b6288bf0df;p=neverball diff --git a/putt/game.c b/putt/game.c index 27aaa25..9318ceb 100644 --- a/putt/game.c +++ b/putt/game.c @@ -1,4 +1,4 @@ -/* +/* * Copyright (C) 2003 Robert Kooima * * NEVERPUTT is free software; you can redistribute it and/or modify @@ -19,17 +19,22 @@ #include "game.h" #include "vec3.h" #include "geom.h" +#include "ball.h" #include "back.h" #include "hole.h" #include "hud.h" #include "image.h" #include "audio.h" -#include "solid.h" #include "config.h" +#include "video.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 */ @@ -48,6 +53,8 @@ static float jump_b = 0; /* Jump-in-progress flag */ static float jump_dt; /* Jump duration */ static float jump_p[3]; /* Jump destination */ +static float idle_t; /* Idling timeout */ + /*---------------------------------------------------------------------------*/ static void view_init(void) @@ -79,22 +86,41 @@ static void view_init(void) void game_init(const char *s) { + int i; + jump_e = 1; jump_b = 0; + idle_t = 1.0f; + view_init(); - sol_load(&file, config_data(s), config_get_d(CONFIG_TEXTURES), - config_get_d(CONFIG_SHADOW)); + sol_load_full(&file, s, config_get_d(CONFIG_SHADOW)); + sol_init_sim(&file.vary); + + for (i = 0; i < file.base.dc; i++) + { + 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) + { + sscanf(v, "%f", &idle_t); + + if (idle_t < 1.0f) + idle_t = 1.0f; + } + } } void game_free(void) { - sol_free(&file); + sol_quit_sim(); + 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]; @@ -106,7 +132,7 @@ static void game_draw_vect_prim(const struct s_file *fp, GLenum mode) v_cpy(z, view_e[2]); r = fp->uv[ball].r; - + glBegin(mode); { glColor4f(1.0f, 1.0f, 0.5f, 0.5f); @@ -127,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) { @@ -154,7 +180,8 @@ 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] = { { 1.0f, 1.0f, 1.0f, 0.7f }, @@ -164,28 +191,31 @@ static void game_draw_balls(const struct s_file *fp) { 1.0f, 1.0f, 0.0f, 1.0f }, }; - float M[16]; int ui; + glEnable(GL_COLOR_MATERIAL); + for (ui = curr_party(); ui > 0; ui--) { if (ui == ball) { + float ball_M[16]; + float pend_M[16]; + + m_basis(ball_M, fp->uv[ui].e[0], fp->uv[ui].e[1], fp->uv[ui].e[2]); + m_basis(pend_M, fp->uv[ui].E[0], fp->uv[ui].E[1], fp->uv[ui].E[2]); + glPushMatrix(); { - m_basis(M, fp->uv[ui].e[0], fp->uv[ui].e[1], fp->uv[ui].e[2]); - glTranslatef(fp->uv[ui].p[0], fp->uv[ui].p[1] + BALL_FUDGE, fp->uv[ui].p[2]); - glMultMatrixf(M); glScalef(fp->uv[ui].r, fp->uv[ui].r, fp->uv[ui].r); glColor4fv(color[ui]); - - ball_draw(); + ball_draw(ball_M, pend_M, bill_M, t); } glPopMatrix(); } @@ -209,9 +239,12 @@ static void game_draw_balls(const struct s_file *fp) glPopMatrix(); } } + + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + glDisable(GL_COLOR_MATERIAL); } -static void game_draw_goals(const struct s_file *fp, float rx, float ry) +static void game_draw_goals(const struct s_base *fp) { int zi; @@ -228,7 +261,7 @@ static void game_draw_goals(const struct s_file *fp, float rx, float ry) } } -static void game_draw_jumps(const struct s_file *fp) +static void game_draw_jumps(const struct s_base *fp) { int ji; @@ -247,20 +280,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++) { + 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(); } @@ -268,21 +306,29 @@ static void game_draw_swchs(const struct s_file *fp) /*---------------------------------------------------------------------------*/ -void game_draw(int pose) +void game_draw(int pose, float t) { - const float light_p[4] = { 8.f, 32.f, 8.f, 1.f }; + static const float a[4] = { 0.2f, 0.2f, 0.2f, 1.0f }; + static const float s[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; + static const float e[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + static const float h[1] = { 0.0f }; + + const float light_p[4] = { 8.f, 32.f, 8.f, 0.f }; + + const struct s_draw *fp = &file.draw; - const struct s_file *fp = &file; - float fov = FOV; if (jump_b) fov *= 2.0f * fabsf(jump_dt - 0.5f); - config_push_persp(fov, 0.1f, FAR_DIST); + video_push_persp(fov, 0.1f, FAR_DIST); glPushAttrib(GL_LIGHTING_BIT); glPushMatrix(); { - float v[3], rx, ry; + float T[16], M[16], v[3], rx, ry; + + m_view(T, view_c, view_p, view_e[1]); + m_xps(M, T); v_sub(v, view_c, view_p); @@ -290,8 +336,7 @@ void game_draw(int pose) ry = V_DEG(fatan2f(+v[0], -v[2])); glTranslatef(0.f, 0.f, -v_len(v)); - glRotatef(rx, 1.f, 0.f, 0.f); - glRotatef(ry, 0.f, 1.f, 0.f); + glMultMatrixf(M); glTranslatef(-view_c[0], -view_c[1], -view_c[2]); /* Center the skybox about the position of the camera. */ @@ -308,12 +353,12 @@ void game_draw(int pose) /* Draw the floor. */ - sol_draw(fp); + sol_draw(fp, 0, 1); if (config_get_d(CONFIG_SHADOW) && !pose) { - shad_draw_set(fp->uv[ball].p, fp->uv[ball].r); - sol_shad(fp); + shad_draw_set(); + sol_shad(fp, ball); shad_draw_clr(); } @@ -324,17 +369,30 @@ void game_draw(int pose) if (pose == 0) { - game_draw_balls(fp); - game_draw_vect(fp); + game_draw_balls(fp->vary, T, t); + game_draw_vect(fp->vary); } - game_draw_goals(fp, -rx, -ry); - game_draw_jumps(fp); - game_draw_swchs(fp); + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, a); + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, s); + glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, e); + glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, h); + + glEnable(GL_COLOR_MATERIAL); + glDisable(GL_LIGHTING); + glDepthMask(GL_FALSE); + { + game_draw_goals(fp->base); + game_draw_jumps(fp->base); + game_draw_swchs(fp->vary); + } + glDepthMask(GL_TRUE); + glEnable(GL_LIGHTING); + glDisable(GL_COLOR_MATERIAL); } glPopMatrix(); glPopAttrib(); - config_pop_matrix(); + video_pop_matrix(); } /*---------------------------------------------------------------------------*/ @@ -352,8 +410,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)) { @@ -410,7 +468,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) @@ -420,21 +478,25 @@ static int game_update_state(float dt) /* Test for a switch. */ - if (sol_swch_test(fp, ball)) + if (sol_swch_test(fp, ball) == 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, ball) == 1) + if (jump_e == 1 && jump_b == 0 && (sol_jump_test(fp, jump_p, ball) == + JUMP_TRIGGER)) { jump_b = 1; jump_e = 0; jump_dt = 0.f; - + audio_play(AUD_JUMP, 1.f); } - if (jump_e == 0 && jump_b == 0 && sol_jump_test(fp, jump_p, ball) == 0) + if (jump_e == 0 && jump_b == 0 && (sol_jump_test(fp, jump_p, ball) == + JUMP_OUTSIDE)) + { jump_e = 1; + } /* Test for fall-out. */ @@ -443,14 +505,16 @@ static int game_update_state(float dt) /* Test for a goal or stop. */ - if (t > 1.f) + if (t > 1.f && sol_goal_test(fp, p, ball)) { t = 0.f; + return GAME_GOAL; + } - if (sol_goal_test(fp, p, ball)) - return GAME_GOAL; - else - return GAME_STOP; + if (t > idle_t) + { + t = 0.f; + return GAME_STOP; } return GAME_NONE; @@ -467,13 +531,13 @@ static int game_update_state(float dt) * the measured frame time exceeds this maximum, we cut the time step in * half, and do two updates. If THIS time step exceeds the maximum, we do * four updates. And so on. In this way, the physics system is allowed to - * seek an optimal update rate independant of, yet in integral sync with, the + * seek an optimal update rate independent of, yet in integral sync with, the * graphics frame rate. */ 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; @@ -514,7 +578,7 @@ int game_step(const float g[3], float dt) for (i = 0; i < n; i++) { d = sol_step(fp, g, t, ball, &m); - + if (b < d) b = d; if (m) @@ -539,9 +603,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; } @@ -568,7 +632,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 }; @@ -581,7 +645,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); @@ -605,18 +669,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. */ @@ -647,32 +711,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]); } /*---------------------------------------------------------------------------*/