-/*
+/*
* Copyright (C) 2003 Robert Kooima
*
* NEVERBALL is free software; you can redistribute it and/or modify
#include "glext.h"
#include "vec3.h"
-#include "geom.h"
-#include "image.h"
+#include "geom.h" /* Only for height constants! */
+#include "base_image.h"
#include "solid.h"
#include "base_config.h"
#include "binary.h"
-#define MAGIC 0x4F425251 /* Neverball sol file magic number (should not change) */
-#define SOL_VERSION 3 /* Neverball sol file format version (can change) */
+#define MAGIC 0x4F425251 /* SOL file magic number (should not change). */
+#define SOL_VERSION 5 /* SOL file format version (can change). */
#define LARGE 1.0e+5f
}
}
-static void sol_body_p(float p[3],
- const struct s_file *fp,
- const struct s_body *bp)
+void sol_body_p(float p[3],
+ const struct s_file *fp,
+ const struct s_body *bp)
{
float v[3];
/*---------------------------------------------------------------------------*/
-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;
-}
-
-/*---------------------------------------------------------------------------*/
-
-static void sol_draw_mtrl(const struct s_file *fp, int i)
-{
- const struct s_mtrl *mp = fp->mv + i;
-
- glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, mp->a);
- glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->d);
- glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mp->s);
- glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, mp->e);
- glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, mp->h);
-
- if (mp->fl & M_ENVIRONMENT)
- {
- glEnable(GL_TEXTURE_GEN_S);
- glEnable(GL_TEXTURE_GEN_T);
-
- glBindTexture(GL_TEXTURE_2D, mp->o);
-
- glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
- glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
- }
- else
- {
- glDisable(GL_TEXTURE_GEN_S);
- glDisable(GL_TEXTURE_GEN_T);
-
- glBindTexture(GL_TEXTURE_2D, mp->o);
- }
-
- if (mp->fl & M_ADDITIVE)
- glBlendFunc(GL_ONE, GL_ONE);
- else
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
-}
-
-static void sol_draw_bill(const struct s_file *fp,
- const struct s_bill *rp, float t)
-{
- float T = fmodf(t, rp->t) - rp->t / 2;
-
- 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);
-
- sol_draw_mtrl(fp, rp->mi);
-
- glBegin(GL_QUADS);
- {
- glTexCoord2f(0.0f, 1.0f); glVertex2f(-w / 2, y0);
- glTexCoord2f(1.0f, 1.0f); glVertex2f(+w / 2, y0);
- glTexCoord2f(1.0f, 0.0f); glVertex2f(+w / 2, y1);
- glTexCoord2f(0.0f, 0.0f); glVertex2f(-w / 2, y1);
- }
- glEnd();
- }
- glPopMatrix();
- }
-}
-
-void sol_back(const struct s_file *fp, float n, float f, float t)
-{
- int ri;
-
- glPushAttrib(GL_LIGHTING_BIT | GL_DEPTH_BUFFER_BIT);
- {
- /* 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)
- sol_draw_bill(fp, fp->rv + ri, t);
- }
- glPopAttrib();
-}
-
-/*---------------------------------------------------------------------------*/
-/*
- * 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 void sol_draw_body(const struct s_file *fp,
- const struct s_body *bp, int fl)
-{
- int mi, li, gi;
-
- /* Iterate all materials of the correct opacity. */
-
- for (mi = 0; mi < fp->mc; mi++)
- if (fp->mv[mi].fl & fl)
- {
- if (sol_enum_mtrl(fp, bp, mi))
- {
- /* Set the material state. */
-
- sol_draw_mtrl(fp, mi);
-
- /* 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();
- }
- }
-}
-
-static void sol_draw_list(const struct s_file *fp,
- const struct s_body *bp, GLuint list)
-{
- float p[3];
-
- sol_body_p(p, fp, bp);
-
- glPushMatrix();
- {
- /* Translate a moving body. */
-
- glTranslatef(p[0], p[1], p[2]);
-
- /* Draw the body. */
-
- glCallList(list);
- }
- glPopMatrix();
-}
-
-void sol_draw(const struct s_file *fp)
-{
- int bi;
-
- glPushAttrib(GL_TEXTURE_BIT |
- GL_LIGHTING_BIT |
- GL_COLOR_BUFFER_BIT |
- GL_DEPTH_BUFFER_BIT);
- {
- /* Render all obaque 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. */
-
- glDepthMask(GL_FALSE);
-
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
- for (bi = 0; bi < fp->bc; bi++)
- if (fp->bv[bi].tl)
- sol_draw_list(fp, fp->bv + bi, fp->bv[bi].tl);
- }
- glPopAttrib();
-}
-
-void sol_refl(const struct s_file *fp)
-{
- int bi;
-
- glPushAttrib(GL_LIGHTING_BIT);
- {
- /* Render all reflective geometry into the color and depth buffers. */
-
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
- for (bi = 0; bi < fp->bc; bi++)
- if (fp->bv[bi].rl)
- sol_draw_list(fp, fp->bv + bi, fp->bv[bi].rl);
- }
- glPopAttrib();
-}
-
-/*---------------------------------------------------------------------------*/
-
-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 mi, li, gi;
-
- glBegin(GL_TRIANGLES);
- {
- for (mi = 0; mi < fp->mc; mi++)
- if (fp->mv[mi].fl & fl)
- {
- 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();
-}
-
-static void sol_shad_list(const struct s_file *fp,
- const struct s_body *bp, GLuint list)
-{
- float p[3];
-
- sol_body_p(p, fp, bp);
-
- glPushMatrix();
- {
- /* Translate a moving body. */
-
- glTranslatef(p[0], p[1], p[2]);
-
- /* Translate the shadow on a moving body. */
-
- glMatrixMode(GL_TEXTURE);
- {
- glPushMatrix();
- glTranslatef(p[0], p[2], 0.0f);
- }
- 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;
-
- glPushAttrib(GL_DEPTH_BUFFER_BIT | GL_LIGHTING_BIT);
- {
- /* Render all shadowed geometry. */
-
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
- glDepthFunc(GL_LEQUAL);
- 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);
- }
- glPopAttrib();
-}
-
-/*---------------------------------------------------------------------------*/
-
-static void sol_load_objects(struct s_file *fp, int s)
-{
- int i;
-
- for (i = 0; i < fp->bc; i++)
- {
- struct s_body *bp = fp->bv + i;
-
- /* Draw all opaque geometry. */
-
- if (sol_enum_body(fp, bp, M_OPAQUE | M_ENVIRONMENT))
- {
- fp->bv[i].ol = glGenLists(1);
-
- glNewList(fp->bv[i].ol, GL_COMPILE);
- {
- sol_draw_body(fp, fp->bv + i, M_OPAQUE | M_ENVIRONMENT);
- }
- glEndList();
- }
- else fp->bv[i].ol = 0;
-
- /* Draw all translucent geometry. */
-
- if (sol_enum_body(fp, bp, M_TRANSPARENT))
- {
- fp->bv[i].tl = glGenLists(1);
-
- glNewList(fp->bv[i].tl, GL_COMPILE);
- {
- sol_draw_body(fp, fp->bv + i, M_TRANSPARENT);
- }
- glEndList();
- }
- else fp->bv[i].tl = 0;
-
- /* Draw all reflective geometry. */
-
- if (sol_enum_body(fp, bp, M_REFLECTIVE))
- {
- fp->bv[i].rl = glGenLists(1);
-
- glNewList(fp->bv[i].rl, GL_COMPILE);
- {
- sol_draw_body(fp, fp->bv + i, M_REFLECTIVE);
- }
- glEndList();
- }
- else fp->bv[i].rl = 0;
-
- /* Draw all shadowed geometry. */
-
- if (s && sol_enum_body(fp, bp, M_SHADOWED))
- {
- fp->bv[i].sl = glGenLists(1);
-
- glNewList(fp->bv[i].sl, GL_COMPILE);
- {
- sol_shad_body(fp, fp->bv + i, M_SHADOWED);
- }
- glEndList();
- }
- else fp->bv[i].sl = 0;
- }
-}
-
-static SDL_Surface *sol_find_texture(const char *name)
-{
- char png[MAXSTR];
- char tga[MAXSTR];
- char jpg[MAXSTR];
- SDL_Surface *s;
-
- /* Prefer a lossless copy of the texture over a lossy compression. */
-
- strncpy(png, name, PATHMAX); strcat(png, ".png");
- strncpy(tga, name, PATHMAX); strcat(tga, ".tga");
- strncpy(jpg, name, PATHMAX); strcat(jpg, ".jpg");
-
- /* Check for a PNG. */
-
- if ((s = IMG_Load(config_data(png))))
- return s;
-
- /* Check for a TGA, swapping channels if found. */
-
- if ((s = IMG_Load(config_data(tga))))
- {
- image_swab(s);
- return s;
- }
-
- /* Check for a JPG. */
-
- if ((s = IMG_Load(config_data(jpg))))
- return s;
-
- return NULL;
-}
-
-static void sol_load_textures(struct s_file *fp, int k)
-{
- SDL_Surface *s;
- SDL_Surface *d;
-
- int i;
-
- for (i = 0; i < fp->mc; i++)
- if ((s = sol_find_texture(fp->mv[i].f)))
- {
- GLenum f = (s->format->BitsPerPixel == 32) ? GL_RGBA : GL_RGB;
-
- glGenTextures(1, &fp->mv[i].o);
- glBindTexture(GL_TEXTURE_2D, fp->mv[i].o);
-
- if (k > 1)
- {
- /* Create a new buffer and copy the scaled image to it. */
-
- if ((d = image_scale(s, k)))
- {
- glTexImage2D(GL_TEXTURE_2D, 0, f, d->w, d->h, 0, f,
- GL_UNSIGNED_BYTE, d->pixels);
- SDL_FreeSurface(d);
- }
- }
- else
- glTexImage2D(GL_TEXTURE_2D, 0, f, s->w, s->h, 0, f,
- GL_UNSIGNED_BYTE, s->pixels);
-
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-
- /* 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);
- }
-
- SDL_FreeSurface(s);
- }
-}
-
-/*---------------------------------------------------------------------------*/
-
static void sol_load_mtrl(FILE *fin, struct s_mtrl *mp)
{
get_array(fin, mp->a, 4);
get_array(fin, zp->p, 3);
get_float(fin, &zp->r);
get_index(fin, &zp->s);
+ get_index(fin, &zp->c);
}
static void sol_load_swch(FILE *fin, struct s_swch *xp)
get_array(fin, bp->e[2], 3);
get_array(fin, bp->p, 3);
get_float(fin, &bp->r);
+ get_float(fin, &bp->a);
}
static void sol_load_view(FILE *fin, struct s_view *wp)
get_index(fin, &magic);
get_index(fin, &version);
+
if (magic != MAGIC || version != SOL_VERSION)
return 0;
for (i = 0; i < fp->ic; i++) get_index(fin, fp->iv + i);
if (fp->ac) fread(fp->av, 1, fp->ac, fin);
-
+
return 1;
}
return res;
}
-int sol_load(struct s_file *fp, const char *filename, int k, int s)
-{
- FILE *fin;
- int res = 0;
-
- if ((fin = fopen(filename, FMODE_RB)))
- {
- if (sol_load_file(fin, fp))
- {
- res = 1;
- sol_load_textures(fp, k);
- sol_load_objects (fp, s);
- }
-
- fclose(fin);
- }
- return res;
-}
-
/*---------------------------------------------------------------------------*/
static void sol_stor_mtrl(FILE *fout, struct s_mtrl *mp)
put_array(fout, zp->p, 3);
put_float(fout, &zp->r);
put_index(fout, &zp->s);
+ put_index(fout, &zp->c);
}
static void sol_stor_swch(FILE *fout, struct s_swch *xp)
put_array(fout, bp->e[2], 3);
put_array(fout, bp->p, 3);
put_float(fout, &bp->r);
+ put_float(fout, &bp->a);
}
static void sol_stor_view(FILE *fout, struct s_view *wp)
put_index(fin, &magic);
put_index(fin, &version);
-
+
put_index(fin, &fp->mc);
put_index(fin, &fp->vc);
put_index(fin, &fp->ec);
void sol_free(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 (fp->mv) free(fp->mv);
if (fp->vv) free(fp->vv);
if (fp->ev) free(fp->ev);
v_mad(u, w, n, -wn);
v_mad(v, v, n, -vn);
v_mad(v, v, u, +km * dt);
- v_mad(v, v, n, xn + yn);
+ v_mad(v, v, n, xn + yn);
v_mad(p, q, n, up->r);
const float o[3],
const float w[3])
{
- float U[3], u, t = dt;
+ float U[3] = {0.0f, 0.0f, 0.0f}; /* init value only to avoid gcc warnings */
+ float u, t = dt;
int i;
/* Short circuit a non-solid lump. */
t = u;
}
}
-
+
/* Test all edges */
if (up->r > 0.0f)
return 0;
}
-int sol_goal_test(struct s_file *fp, float *p, int ui)
+struct s_goal *sol_goal_test(struct s_file *fp, float *p, int ui)
{
const float *ball_p = fp->uv[ui].p;
const float ball_r = fp->uv[ui].r;
p[1] = fp->zv[zi].p[1];
p[2] = fp->zv[zi].p[2];
- return 1 + fp->zv[zi].s;
+ return &fp->zv[zi];
}
}
- return 0;
+ return NULL;
}
int sol_jump_test(struct s_file *fp, float *p, int ui)
+/* Test if the ball ui is inside a jump. */
+/* Return 1 if yes and fill p with the destination position. */
+/* Return 0 if no. */
+/* Return 2 if the ball is on the border of a jump. */
{
const float *ball_p = fp->uv[ui].p;
const float ball_r = fp->uv[ui].r;
int ji;
+ float l;
+ int res = 0;
for (ji = 0; ji < fp->jc; ji++)
{
r[1] = ball_p[2] - fp->jv[ji].p[2];
r[2] = 0;
- if (v_len(r) < fp->jv[ji].r - ball_r &&
+ l = v_len(r) - fp->jv[ji].r;
+ if (l < 0 &&
ball_p[1] > fp->jv[ji].p[1] &&
ball_p[1] < fp->jv[ji].p[1] + JUMP_HEIGHT / 2)
{
- p[0] = fp->jv[ji].q[0] + (ball_p[0] - fp->jv[ji].p[0]);
- p[1] = fp->jv[ji].q[1] + (ball_p[1] - fp->jv[ji].p[1]);
- p[2] = fp->jv[ji].q[2] + (ball_p[2] - fp->jv[ji].p[2]);
+ if (l < - ball_r )
+ {
+ p[0] = fp->jv[ji].q[0] + (ball_p[0] - fp->jv[ji].p[0]);
+ p[1] = fp->jv[ji].q[1] + (ball_p[1] - fp->jv[ji].p[1]);
+ p[2] = fp->jv[ji].q[2] + (ball_p[2] - fp->jv[ji].p[2]);
- return 1;
+ return 1;
+ }
+ else
+ res = 2;
}
}
- return 0;
+ return res;
}
-int sol_swch_test(struct s_file *fp, int flag, int ui)
+int sol_swch_test(struct s_file *fp, int ui)
+/* In the SOL fp, test and process the event the ball ui enters a switch.
+ * Return 1 if a visible switch is activated, return 0 otherwise (no switch is
+ * activated or only invisible switchs) */
{
const float *ball_p = fp->uv[ui].p;
const float ball_r = fp->uv[ui].r;
int xi;
- int f = 1;
+ float l;
+ int res = 0; /* result */
for (xi = 0; xi < fp->xc; xi++)
{
r[1] = ball_p[2] - xp->p[2];
r[2] = 0;
- if (v_len(r) < xp->r - ball_r &&
+ l = v_len(r) - xp->r;
+ if (l < ball_r &&
ball_p[1] > xp->p[1] &&
ball_p[1] < xp->p[1] + SWCH_HEIGHT / 2)
{
- if (flag)
+ if (!xp->e && l < - ball_r)
{
int pi = xp->pi;
int pj = xp->pi;
+ /* The ball enter */
+ if (xp->t0 == 0)
+ xp->e = 1;
+
/* Toggle the state, update the path. */
xp->f = xp->f ? 0 : 1;
if (xp->f != xp->f0)
xp->t = xp->t0;
+
+ /* If visible, set the result */
+ if (!xp->i)
+ res = 1;
}
- f = 0;
}
+ else if (xp->e)
+ /* A ball go out */
+ xp->e = 0;
}
}
- return f;
+ return res;
}
/*---------------------------------------------------------------------------*/