#include "part.h"
#include "image.h"
#include "audio.h"
-#include "solid.h"
+#include "solid_gl.h"
#include "config.h"
#include "binary.h"
#include "level.h"
static int coins = 0; /* Collected coins */
static int goal_c = 0; /* Goal coins remaining (0 = open) */
static float goal_k = 0; /* Goal animation */
-static int swch_e = 1; /* Switching enabled flag */
static int jump_e = 1; /* Jumping enabled flag */
static int jump_b = 0; /* Jump-in-progress flag */
static float jump_dt; /* Jump duration */
static float jump_p[3]; /* Jump destination */
static float fade_k = 0.0; /* Fade in/out level */
static float fade_d = 0.0; /* Fade in/out direction */
+static int drawball = 1; /* Should the ball be drawn? */
+static int ball_b = 0; /* Is the ball a bonus ball? */
/*---------------------------------------------------------------------------*/
static void view_init(void)
{
- view_a = 0.f;
+ /* Get the initial orientation angle */
+ if (file.uc > 0)
+ view_a = file.uv->a - 90.f; /* angle is in the sol */
+ else
+ view_a = 0.f; /* default is north :) */
+
view_ry = 0.f;
view_fov = (float) config_get_d(CONFIG_VIEW_FOV);
view_e[2][2] = 1.f;
}
-int game_init(const struct level * level, int t, int g)
+int game_init(const struct level *level, int t, int g)
{
clock = (float) t / 100.f;
clock_down = (t > 0);
if (game_state)
game_free();
+ if (!sol_load_gl(&file, level->file, config_get_d(CONFIG_TEXTURES),
+ config_get_d(CONFIG_SHADOW)))
+ return (game_state = 0);
+
+ game_state = 1;
+
game_ix = 0.f;
game_iz = 0.f;
game_rx = 0.f;
game_rz = 0.f;
+ drawball = 1;
+
/* Initialize jump and goal states. */
jump_e = 1;
goal_c = g;
goal_k = (g == 0) ? 1.0f : 0.0f;
+ ball_b = level->is_bonus;
+
/* Initialise the level, background, particles, fade, and view. */
fade_k = 1.0f;
view_init();
back_init(level->grad, config_get_d(CONFIG_GEOMETRY));
- if (sol_load(&back, config_data(level->back),
- config_get_d(CONFIG_TEXTURES), 0) &&
- sol_load(&file, level->file,
- config_get_d(CONFIG_TEXTURES), config_get_d(CONFIG_SHADOW)))
- return (game_state = 1);
- else
- return (game_state = 0);
+ sol_load_gl(&back, config_data(level->back),
+ config_get_d(CONFIG_TEXTURES), 0);
+
+ return game_state;
}
void game_free(void)
{
if (game_state)
{
- sol_free(&file);
- sol_free(&back);
+ sol_free_gl(&file);
+ sol_free_gl(&back);
back_free();
}
game_state = 0;
return goal_c;
}
-char *curr_intro(void)
-{
- return (file.ac > 0) ? file.av : NULL;
-}
-
/*---------------------------------------------------------------------------*/
static void game_draw_balls(const struct s_file *fp)
glColor4fv(c);
- ball_draw();
+ ball_draw(ball_b);
}
glPopMatrix();
}
fp->zv[zi].p[1],
fp->zv[zi].p[2]);
- part_draw_goal(rx, ry, fp->zv[zi].r, goal_k);
+ part_draw_goal(rx, ry, fp->zv[zi].r, goal_k, fp->zv[zi].c);
glScalef(fp->zv[zi].r, goal_k, fp->zv[zi].r);
goal_draw();
fp->jv[ji].p[2]);
glScalef(fp->jv[ji].r, 1.f, fp->jv[ji].r);
- jump_draw();
+ jump_draw(!jump_e);
}
glPopMatrix();
}
for (xi = 0; xi < fp->xc; xi++)
{
+ if (fp->xv[xi].i)
+ continue;
glPushMatrix();
{
glTranslatef(fp->xv[xi].p[0],
fp->xv[xi].p[2]);
glScalef(fp->xv[xi].r, 1.f, fp->xv[xi].r);
- swch_draw(fp->xv[xi].f);
+ swch_draw(fp->xv[xi].f, fp->xv[xi].e);
}
glPopMatrix();
}
sol_draw(&file);
- if (config_get_d(CONFIG_SHADOW))
+ if (config_get_d(CONFIG_SHADOW) && drawball)
{
shad_draw_set(ball_p, ball_r);
sol_shad(&file);
{
part_draw_coin(-rx * d, -ry);
game_draw_coins(&file);
- game_draw_balls(&file);
+ if (drawball)
+ game_draw_balls(&file);
}
game_draw_goals(&file, -rx * d, -ry);
game_draw_jumps(&file);
}
}
-static int game_update_state(int bt)
+static int game_update_state(int *state_value)
{
struct s_file *fp = &file;
float p[3];
float c[3];
- int n, e = swch_e;
+ int bt = state_value != NULL;
+ int n;
+ struct s_goal *g;
/* Test for a coin grab. */
coin_color(c, n);
part_burst(p, c);
- coins += n;
- /* Check for goal open. */
- if (goal_c > 0)
- {
- goal_c = goal_c - n;
- if (goal_c <= 0)
- {
- audio_play(AUD_SWITCH, 1.f);
- goal_c = 0;
- }
- else
- audio_play(AUD_COIN, 1.f);
- }
- else
- audio_play(AUD_COIN, 1.f);
+ coins += n;
+ /* Check for goal open. */
+ if (goal_c > 0)
+ {
+ goal_c = goal_c - n;
+ if (goal_c <= 0)
+ {
+ audio_play(AUD_SWITCH, 1.f);
+ goal_c = 0;
+ }
+ else
+ audio_play(AUD_COIN, 1.f);
+ }
+ else
+ audio_play(AUD_COIN, 1.f);
}
/* Test for a switch. */
-
- if ((swch_e = sol_swch_test(fp, swch_e, 0)) != e && e)
+ if (sol_swch_test(fp, 0))
audio_play(AUD_SWITCH, 1.f);
/* Test for a jump. */
/* Test for a goal. */
- if (bt && goal_c == 0 && sol_goal_test(fp, p, 0))
+ if (bt && goal_c == 0 && (g = sol_goal_test(fp, p, 0)))
{
- audio_play(AUD_GOAL, 1.0f);
- return GAME_GOAL;
+ *state_value = g->s;
+ audio_play(AUD_GOAL, 1.0f);
+ return g->c ? GAME_SPEC : GAME_GOAL;
}
/* Test for time-out. */
if (bt && clock_down && clock <= 0.f)
+ {
+ const GLfloat *p = fp->uv->p;
+ const GLfloat c[5] = {1.0f, 1.0f, 0.0f, 0.0f, 1.0f};
+ part_burst(p, c);
+ part_burst(p, c+1);
+ part_burst(p, c+2);
+ part_burst(p, c);
+ part_burst(p, c+1);
+ part_burst(p, c+2);
+ drawball = 0;
+ audio_play(AUD_TIME, 1.0f);
return GAME_TIME;
+ }
/* Test for fall-out. */
if (bt && fp->uv[0].p[1] < fp->vv[0].p[1])
+ {
+ audio_play(AUD_FALL, 1.0f);
return GAME_FALL;
+ }
return GAME_NONE;
}
* graphics frame rate.
*/
-int game_step(const float g[3], float dt, int bt)
+int game_step(const float g[3], float dt, int *state_value)
{
struct s_file *fp = &file;
game_update_grav(h, g);
part_step(h, t);
- if (jump_b)
+ if (!drawball)
+ /* nothing */;
+ else if (jump_b)
{
jump_dt += t;
game_step_fade(dt);
game_update_view(dt);
- game_update_time(dt, bt);
+ game_update_time(dt, state_value != NULL);
- return game_update_state(bt);
+ return game_update_state(state_value);
}
return GAME_NONE;
}
float max = game_ix * game_ix + game_iz * game_iz;
if (max > ANGLE_BOUND * ANGLE_BOUND)
{
- max = ANGLE_BOUND / sqrt(max);
- game_ix *= max;
- game_iz *= max;
+ max = ANGLE_BOUND / sqrt(max);
+ game_ix *= max;
+ game_iz *= max;
}
}
float p1[3] = { 0.f, 0.f, 0.f };
float v[3];
+ z[0] = fsinf(V_RAD(view_a));
+ z[2] = fcosf(V_RAD(view_a));
+
v_cpy(view_e[0], x);
v_cpy(view_e[1], y);
v_cpy(view_e[2], z);