static int drawball = 1; /* Should the ball be drawn? */
static int ball_b = 0; /* Is the ball a bonus ball? */
+static int grow = 0; /* Should the ball be changing size? */
+static float grow_orig = 0; /* the original ball size */
+static float grow_goal = 0; /* how big or small to get! */
+static float grow_t = 0.0; /* timer for the ball to grow... */
+static float grow_strt = 0; /* starting value for growth */
+static int got_orig = 0; /* Do we know original ball size? */
+
+#define GROW_TIME 0.5f /* sec for the ball to get to size. */
+#define GROW_BIG 1.5f /* large factor */
+#define GROW_SMALL 0.5f /* small factor */
+
/*---------------------------------------------------------------------------*/
-static void view_init(void)
+static void grow_set(const struct s_file *fp, int type)
+{
+ if (!got_orig)
+ {
+ grow_orig = fp->uv->r;
+ grow_goal = grow_orig;
+ grow_strt = grow_orig;
+ got_orig = 1;
+ }
+
+ if (type == ITEM_SHRINK)
+ {
+ if (grow_goal == grow_orig * GROW_SMALL)
+ return;
+ else if (grow_goal == grow_orig * GROW_BIG)
+ {
+ grow = 1;
+ grow_goal = grow_orig;
+ }
+ else
+ {
+ grow_goal = grow_orig * GROW_SMALL;
+ grow = 1;
+ }
+ }
+ if (type == ITEM_GROW)
+ {
+ if (grow_goal == grow_orig * GROW_BIG)
+ return;
+ else if (grow_goal == grow_orig * GROW_SMALL)
+ {
+ grow = 1;
+ grow_goal = grow_orig;
+ }
+ else
+ {
+ grow_goal = grow_orig * GROW_BIG;
+ grow = 1;
+ }
+ }
+
+ if (grow)
+ {
+ grow_t = 0.0;
+ grow_strt = fp->uv->r;
+ }
+}
+
+static void grow_ball(const struct s_file *fp, float dt)
{
- /* 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 :) */
+ float dr;
+
+ /* Calculate new size based on how long since you touched the coin... */
+
+ grow_t += dt;
+
+ if (grow_t >= GROW_TIME)
+ {
+ grow = 0;
+ grow_t = GROW_TIME;
+ }
+ dr = grow_strt + ((grow_goal-grow_strt) * (1.0f / (GROW_TIME / grow_t)));
+
+ /* No sinking through the floor! Keeps ball's bottom constant. */
+ fp->uv->p[1] += (dr - fp->uv->r);
+ fp->uv->r = dr;
+}
+
+static void view_init(void)
+{
+ view_a = 0.f;
view_ry = 0.f;
view_fov = (float) config_get_d(CONFIG_VIEW_FOV);
if (game_state)
game_free();
- if (!sol_load_gl(&file, level->file, config_get_d(CONFIG_TEXTURES),
+ if (!sol_load_gl(&file, config_data(level->file),
+ config_get_d(CONFIG_TEXTURES),
config_get_d(CONFIG_SHADOW)))
return (game_state = 0);
sol_load_gl(&back, config_data(level->back),
config_get_d(CONFIG_TEXTURES), 0);
+ /* Initialize ball size tracking... */
+
+ got_orig = 0;
+
return game_state;
}
coin_push();
{
for (ci = 0; ci < fp->cc; ci++)
+
if (fp->cv[ci].n > 0)
{
glPushMatrix();
}
}
coin_pull();
+
+}
+
+static void game_draw_items(const struct s_file *fp)
+{
+ float r = 360.f * SDL_GetTicks() / 1000.f;
+ int hi;
+
+ item_push();
+ item_push_text(ITEM_SHRINK);
+ {
+ for (hi = 0; hi < fp->hc; hi++)
+
+ if (fp->hv[hi].t == ITEM_SHRINK)
+ {
+ glPushMatrix();
+ {
+ glTranslatef(fp->hv[hi].p[0],
+ fp->hv[hi].p[1],
+ fp->hv[hi].p[2]);
+ glRotatef(r, 0.0f, 1.0f, 0.0f);
+ item_draw(fp->hv[hi].t, r);
+ }
+ glPopMatrix();
+ }
+ }
+ item_pull();
+
+ /* FIXME: there has got to be a better way than two seperate loops,
+ * once for each texture, but someone else is going to have to do
+ * it! */
+
+ item_push();
+ item_push_text(ITEM_GROW);
+ {
+ for (hi = 0; hi < fp->hc; hi++)
+
+ if (fp->hv[hi].t == ITEM_GROW)
+ {
+ glPushMatrix();
+ {
+ glTranslatef(fp->hv[hi].p[0],
+ fp->hv[hi].p[1],
+ fp->hv[hi].p[2]);
+ glRotatef(r, 0.0f, 1.0f, 0.0f);
+ item_draw(fp->hv[hi].t, r);
+ }
+ glPopMatrix();
+ }
+ }
+ item_pull();
}
static void game_draw_goals(const struct s_file *fp, float rx, float ry)
{
part_draw_coin(-rx * d, -ry);
game_draw_coins(&file);
+ game_draw_items(&file);
if (drawball)
game_draw_balls(&file);
}
float p[3];
float c[3];
int bt = state_value != NULL;
- int n;
+ int n, t;
struct s_goal *g;
/* Test for a coin grab. */
coin_color(c, n);
part_burst(p, c);
- coins += n;
+ /* Add coins if regular, change radius if not. */
+
+ if (n <= 10)
+ coins += n;
+ else
+ {
+ grow_set(fp, n);
+ n = 0;
+ }
+
/* Check for goal open. */
if (goal_c > 0)
{
audio_play(AUD_COIN, 1.f);
}
+ /* Test for an item. */
+ if (bt && (t = sol_item_test(fp, p, COIN_RADIUS)) != ITEM_NONE)
+ {
+ item_color(c, t);
+ part_burst(p, c);
+
+ grow_set(fp, t);
+
+ audio_play(AUD_COIN, 1.f);
+ }
+
/* Test for a switch. */
if (sol_swch_test(fp, 0))
audio_play(AUD_SWITCH, 1.f);
game_rz = game_iz;
}
+ if (grow)
+ grow_ball(fp, dt);
+
game_update_grav(h, g);
part_step(h, t);