2 * Copyright (C) 2003 Robert Kooima
4 * NEVERBALL is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published
6 * by the Free Software Foundation; either version 2 of the License,
7 * or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
19 #include "solid_base.h"
20 #include "base_config.h"
30 SOL_VER_CURRENT = SOL_VER_GLES
33 #define SOL_MAGIC (0xAF | 'S' << 8 | 'O' << 16 | 'L' << 24)
35 /*---------------------------------------------------------------------------*/
37 static int sol_version;
39 static int sol_file(fs_file fin)
44 get_index(fin, &magic);
45 get_index(fin, &version);
47 if (magic != SOL_MAGIC || (version < SOL_VER_MINIMUM ||
48 version > SOL_VER_CURRENT))
51 sol_version = version;
56 static void sol_load_mtrl(fs_file fin, struct b_mtrl *mp)
58 get_array(fin, mp->d, 4);
59 get_array(fin, mp->a, 4);
60 get_array(fin, mp->s, 4);
61 get_array(fin, mp->e, 4);
62 get_array(fin, mp->h, 1);
63 get_index(fin, &mp->fl);
65 fs_read(mp->f, 1, PATHMAX, fin);
67 if (sol_version < SOL_VER_GLES)
69 static const int flags[][2] = {
72 { 4, M_REFLECTIVE | M_SHADOWED },
75 { 32, M_CLAMP_S | M_CLAMP_T },
80 /* Convert 1.5.4 material flags. */
86 for (f = 0, i = 0; i < ARRAYSIZE(flags); i++)
87 if (mp->fl & flags[i][0])
94 /* Must be "mtrl/invisible". */
96 mp->fl = M_TRANSPARENT;
102 static void sol_load_vert(fs_file fin, struct b_vert *vp)
104 get_array(fin, vp->p, 3);
107 static void sol_load_edge(fs_file fin, struct b_edge *ep)
109 get_index(fin, &ep->vi);
110 get_index(fin, &ep->vj);
113 static void sol_load_side(fs_file fin, struct b_side *sp)
115 get_array(fin, sp->n, 3);
116 get_float(fin, &sp->d);
119 static void sol_load_texc(fs_file fin, struct b_texc *tp)
121 get_array(fin, tp->u, 2);
124 static void sol_load_offs(fs_file fin, struct b_offs *op)
126 get_index(fin, &op->ti);
127 get_index(fin, &op->si);
128 get_index(fin, &op->vi);
131 static void sol_load_geom(fs_file fin, struct b_geom *gp, struct s_base *fp)
133 get_index(fin, &gp->mi);
135 if (sol_version >= SOL_VER_GLES)
137 get_index(fin, &gp->oi);
138 get_index(fin, &gp->oj);
139 get_index(fin, &gp->ok);
149 for (i = 0; i < 3; i++)
151 get_index(fin, &ov[i].ti);
152 get_index(fin, &ov[i].si);
153 get_index(fin, &ov[i].vi);
157 for (j = 0; j < fp->oc; j++)
158 if (ov[i].ti == fp->ov[j].ti &&
159 ov[i].si == fp->ov[j].si &&
160 ov[i].vi == fp->ov[j].vi)
170 if (oc && (p = realloc(fp->ov, sizeof (struct b_offs) * (fp->oc + oc))))
174 for (i = 0; i < 3; i++)
177 fp->ov[fp->oc] = ov[i];
188 static void sol_load_lump(fs_file fin, struct b_lump *lp)
190 get_index(fin, &lp->fl);
191 get_index(fin, &lp->v0);
192 get_index(fin, &lp->vc);
193 get_index(fin, &lp->e0);
194 get_index(fin, &lp->ec);
195 get_index(fin, &lp->g0);
196 get_index(fin, &lp->gc);
197 get_index(fin, &lp->s0);
198 get_index(fin, &lp->sc);
201 static void sol_load_node(fs_file fin, struct b_node *np)
203 get_index(fin, &np->si);
204 get_index(fin, &np->ni);
205 get_index(fin, &np->nj);
206 get_index(fin, &np->l0);
207 get_index(fin, &np->lc);
210 static void sol_load_path(fs_file fin, struct b_path *pp)
212 get_array(fin, pp->p, 3);
213 get_float(fin, &pp->t);
214 get_index(fin, &pp->pi);
215 get_index(fin, &pp->f);
216 get_index(fin, &pp->s);
218 pp->tm = TIME_TO_MS(pp->t);
219 pp->t = MS_TO_TIME(pp->tm);
221 if (sol_version >= SOL_VER_GLES)
222 get_index(fin, &pp->fl);
229 if (pp->fl & P_ORIENTED)
230 get_array(fin, pp->e, 4);
233 static void sol_load_body(fs_file fin, struct b_body *bp)
235 get_index(fin, &bp->pi);
236 get_index(fin, &bp->ni);
237 get_index(fin, &bp->l0);
238 get_index(fin, &bp->lc);
239 get_index(fin, &bp->g0);
240 get_index(fin, &bp->gc);
243 static void sol_load_item(fs_file fin, struct b_item *hp)
245 get_array(fin, hp->p, 3);
246 get_index(fin, &hp->t);
247 get_index(fin, &hp->n);
250 static void sol_load_goal(fs_file fin, struct b_goal *zp)
252 get_array(fin, zp->p, 3);
253 get_float(fin, &zp->r);
256 static void sol_load_swch(fs_file fin, struct b_swch *xp)
261 get_array(fin, xp->p, 3);
262 get_float(fin, &xp->r);
263 get_index(fin, &xp->pi);
264 get_float(fin, &xp->t);
266 get_index(fin, &xp->f);
268 get_index(fin, &xp->i);
270 xp->tm = TIME_TO_MS(xp->t);
271 xp->t = MS_TO_TIME(xp->tm);
274 static void sol_load_bill(fs_file fin, struct b_bill *rp)
276 get_index(fin, &rp->fl);
277 get_index(fin, &rp->mi);
278 get_float(fin, &rp->t);
279 get_float(fin, &rp->d);
280 get_array(fin, rp->w, 3);
281 get_array(fin, rp->h, 3);
282 get_array(fin, rp->rx, 3);
283 get_array(fin, rp->ry, 3);
284 get_array(fin, rp->rz, 3);
285 get_array(fin, rp->p, 3);
288 static void sol_load_jump(fs_file fin, struct b_jump *jp)
290 get_array(fin, jp->p, 3);
291 get_array(fin, jp->q, 3);
292 get_float(fin, &jp->r);
295 static void sol_load_ball(fs_file fin, struct b_ball *up)
297 get_array(fin, up->p, 3);
298 get_float(fin, &up->r);
301 static void sol_load_view(fs_file fin, struct b_view *wp)
303 get_array(fin, wp->p, 3);
304 get_array(fin, wp->q, 3);
307 static void sol_load_dict(fs_file fin, struct b_dict *dp)
309 get_index(fin, &dp->ai);
310 get_index(fin, &dp->aj);
313 static void sol_load_indx(fs_file fin, struct s_base *fp)
315 get_index(fin, &fp->ac);
316 get_index(fin, &fp->dc);
317 get_index(fin, &fp->mc);
318 get_index(fin, &fp->vc);
319 get_index(fin, &fp->ec);
320 get_index(fin, &fp->sc);
321 get_index(fin, &fp->tc);
323 if (sol_version >= SOL_VER_GLES)
324 get_index(fin, &fp->oc);
326 get_index(fin, &fp->gc);
327 get_index(fin, &fp->lc);
328 get_index(fin, &fp->nc);
329 get_index(fin, &fp->pc);
330 get_index(fin, &fp->bc);
331 get_index(fin, &fp->hc);
332 get_index(fin, &fp->zc);
333 get_index(fin, &fp->jc);
334 get_index(fin, &fp->xc);
335 get_index(fin, &fp->rc);
336 get_index(fin, &fp->uc);
337 get_index(fin, &fp->wc);
338 get_index(fin, &fp->ic);
341 static int sol_load_file(fs_file fin, struct s_base *fp)
348 sol_load_indx(fin, fp);
351 fp->av = (char *) calloc(fp->ac, sizeof (*fp->av));
353 fp->mv = (struct b_mtrl *) calloc(fp->mc, sizeof (*fp->mv));
355 fp->vv = (struct b_vert *) calloc(fp->vc, sizeof (*fp->vv));
357 fp->ev = (struct b_edge *) calloc(fp->ec, sizeof (*fp->ev));
359 fp->sv = (struct b_side *) calloc(fp->sc, sizeof (*fp->sv));
361 fp->tv = (struct b_texc *) calloc(fp->tc, sizeof (*fp->tv));
363 fp->ov = (struct b_offs *) calloc(fp->oc, sizeof (*fp->ov));
365 fp->gv = (struct b_geom *) calloc(fp->gc, sizeof (*fp->gv));
367 fp->lv = (struct b_lump *) calloc(fp->lc, sizeof (*fp->lv));
369 fp->nv = (struct b_node *) calloc(fp->nc, sizeof (*fp->nv));
371 fp->pv = (struct b_path *) calloc(fp->pc, sizeof (*fp->pv));
373 fp->bv = (struct b_body *) calloc(fp->bc, sizeof (*fp->bv));
375 fp->hv = (struct b_item *) calloc(fp->hc, sizeof (*fp->hv));
377 fp->zv = (struct b_goal *) calloc(fp->zc, sizeof (*fp->zv));
379 fp->jv = (struct b_jump *) calloc(fp->jc, sizeof (*fp->jv));
381 fp->xv = (struct b_swch *) calloc(fp->xc, sizeof (*fp->xv));
383 fp->rv = (struct b_bill *) calloc(fp->rc, sizeof (*fp->rv));
385 fp->uv = (struct b_ball *) calloc(fp->uc, sizeof (*fp->uv));
387 fp->wv = (struct b_view *) calloc(fp->wc, sizeof (*fp->wv));
389 fp->dv = (struct b_dict *) calloc(fp->dc, sizeof (*fp->dv));
391 fp->iv = (int *) calloc(fp->ic, sizeof (*fp->iv));
394 fs_read(fp->av, 1, fp->ac, fin);
396 for (i = 0; i < fp->dc; i++) sol_load_dict(fin, fp->dv + i);
397 for (i = 0; i < fp->mc; i++) sol_load_mtrl(fin, fp->mv + i);
398 for (i = 0; i < fp->vc; i++) sol_load_vert(fin, fp->vv + i);
399 for (i = 0; i < fp->ec; i++) sol_load_edge(fin, fp->ev + i);
400 for (i = 0; i < fp->sc; i++) sol_load_side(fin, fp->sv + i);
401 for (i = 0; i < fp->tc; i++) sol_load_texc(fin, fp->tv + i);
402 for (i = 0; i < fp->oc; i++) sol_load_offs(fin, fp->ov + i);
403 for (i = 0; i < fp->gc; i++) sol_load_geom(fin, fp->gv + i, fp);
404 for (i = 0; i < fp->lc; i++) sol_load_lump(fin, fp->lv + i);
405 for (i = 0; i < fp->nc; i++) sol_load_node(fin, fp->nv + i);
406 for (i = 0; i < fp->pc; i++) sol_load_path(fin, fp->pv + i);
407 for (i = 0; i < fp->bc; i++) sol_load_body(fin, fp->bv + i);
408 for (i = 0; i < fp->hc; i++) sol_load_item(fin, fp->hv + i);
409 for (i = 0; i < fp->zc; i++) sol_load_goal(fin, fp->zv + i);
410 for (i = 0; i < fp->jc; i++) sol_load_jump(fin, fp->jv + i);
411 for (i = 0; i < fp->xc; i++) sol_load_swch(fin, fp->xv + i);
412 for (i = 0; i < fp->rc; i++) sol_load_bill(fin, fp->rv + i);
413 for (i = 0; i < fp->uc; i++) sol_load_ball(fin, fp->uv + i);
414 for (i = 0; i < fp->wc; i++) sol_load_view(fin, fp->wv + i);
415 for (i = 0; i < fp->ic; i++) get_index(fin, fp->iv + i);
417 /* Magically "fix" all of our code. */
422 fp->uv = (struct b_ball *) calloc(fp->uc, sizeof (*fp->uv));
428 static int sol_load_head(fs_file fin, struct s_base *fp)
433 sol_load_indx(fin, fp);
437 fp->av = (char *) calloc(fp->ac, sizeof (*fp->av));
438 fs_read(fp->av, 1, fp->ac, fin);
445 fp->dv = (struct b_dict *) calloc(fp->dc, sizeof (*fp->dv));
447 for (i = 0; i < fp->dc; i++)
448 sol_load_dict(fin, fp->dv + i);
454 int sol_load_base(struct s_base *fp, const char *filename)
459 memset(fp, 0, sizeof (*fp));
461 if ((fin = fs_open(filename, "r")))
463 res = sol_load_file(fin, fp);
469 int sol_load_meta(struct s_base *fp, const char *filename)
474 if ((fin = fs_open(filename, "r")))
476 res = sol_load_head(fin, fp);
482 void sol_free_base(struct s_base *fp)
484 if (fp->av) free(fp->av);
485 if (fp->mv) free(fp->mv);
486 if (fp->vv) free(fp->vv);
487 if (fp->ev) free(fp->ev);
488 if (fp->sv) free(fp->sv);
489 if (fp->tv) free(fp->tv);
490 if (fp->ov) free(fp->ov);
491 if (fp->gv) free(fp->gv);
492 if (fp->lv) free(fp->lv);
493 if (fp->nv) free(fp->nv);
494 if (fp->pv) free(fp->pv);
495 if (fp->bv) free(fp->bv);
496 if (fp->hv) free(fp->hv);
497 if (fp->zv) free(fp->zv);
498 if (fp->jv) free(fp->jv);
499 if (fp->xv) free(fp->xv);
500 if (fp->rv) free(fp->rv);
501 if (fp->uv) free(fp->uv);
502 if (fp->wv) free(fp->wv);
503 if (fp->dv) free(fp->dv);
504 if (fp->iv) free(fp->iv);
506 memset(fp, 0, sizeof (*fp));
509 /*---------------------------------------------------------------------------*/
511 static void sol_stor_mtrl(fs_file fout, struct b_mtrl *mp)
513 put_array(fout, mp->d, 4);
514 put_array(fout, mp->a, 4);
515 put_array(fout, mp->s, 4);
516 put_array(fout, mp->e, 4);
517 put_array(fout, mp->h, 1);
518 put_index(fout, mp->fl);
520 fs_write(mp->f, 1, PATHMAX, fout);
523 static void sol_stor_vert(fs_file fout, struct b_vert *vp)
525 put_array(fout, vp->p, 3);
528 static void sol_stor_edge(fs_file fout, struct b_edge *ep)
530 put_index(fout, ep->vi);
531 put_index(fout, ep->vj);
534 static void sol_stor_side(fs_file fout, struct b_side *sp)
536 put_array(fout, sp->n, 3);
537 put_float(fout, sp->d);
540 static void sol_stor_texc(fs_file fout, struct b_texc *tp)
542 put_array(fout, tp->u, 2);
545 static void sol_stor_offs(fs_file fout, struct b_offs *op)
547 put_index(fout, op->ti);
548 put_index(fout, op->si);
549 put_index(fout, op->vi);
552 static void sol_stor_geom(fs_file fout, struct b_geom *gp)
554 put_index(fout, gp->mi);
555 put_index(fout, gp->oi);
556 put_index(fout, gp->oj);
557 put_index(fout, gp->ok);
560 static void sol_stor_lump(fs_file fout, struct b_lump *lp)
562 put_index(fout, lp->fl);
563 put_index(fout, lp->v0);
564 put_index(fout, lp->vc);
565 put_index(fout, lp->e0);
566 put_index(fout, lp->ec);
567 put_index(fout, lp->g0);
568 put_index(fout, lp->gc);
569 put_index(fout, lp->s0);
570 put_index(fout, lp->sc);
573 static void sol_stor_node(fs_file fout, struct b_node *np)
575 put_index(fout, np->si);
576 put_index(fout, np->ni);
577 put_index(fout, np->nj);
578 put_index(fout, np->l0);
579 put_index(fout, np->lc);
582 static void sol_stor_path(fs_file fout, struct b_path *pp)
584 put_array(fout, pp->p, 3);
585 put_float(fout, pp->t);
586 put_index(fout, pp->pi);
587 put_index(fout, pp->f);
588 put_index(fout, pp->s);
589 put_index(fout, pp->fl);
591 if (pp->fl & P_ORIENTED)
592 put_array(fout, pp->e, 4);
595 static void sol_stor_body(fs_file fout, struct b_body *bp)
597 put_index(fout, bp->pi);
598 put_index(fout, bp->ni);
599 put_index(fout, bp->l0);
600 put_index(fout, bp->lc);
601 put_index(fout, bp->g0);
602 put_index(fout, bp->gc);
605 static void sol_stor_item(fs_file fout, struct b_item *hp)
607 put_array(fout, hp->p, 3);
608 put_index(fout, hp->t);
609 put_index(fout, hp->n);
612 static void sol_stor_goal(fs_file fout, struct b_goal *zp)
614 put_array(fout, zp->p, 3);
615 put_float(fout, zp->r);
618 static void sol_stor_swch(fs_file fout, struct b_swch *xp)
620 put_array(fout, xp->p, 3);
621 put_float(fout, xp->r);
622 put_index(fout, xp->pi);
623 put_float(fout, xp->t);
624 put_float(fout, xp->t);
625 put_index(fout, xp->f);
626 put_index(fout, xp->f);
627 put_index(fout, xp->i);
630 static void sol_stor_bill(fs_file fout, struct b_bill *rp)
632 put_index(fout, rp->fl);
633 put_index(fout, rp->mi);
634 put_float(fout, rp->t);
635 put_float(fout, rp->d);
636 put_array(fout, rp->w, 3);
637 put_array(fout, rp->h, 3);
638 put_array(fout, rp->rx, 3);
639 put_array(fout, rp->ry, 3);
640 put_array(fout, rp->rz, 3);
641 put_array(fout, rp->p, 3);
644 static void sol_stor_jump(fs_file fout, struct b_jump *jp)
646 put_array(fout, jp->p, 3);
647 put_array(fout, jp->q, 3);
648 put_float(fout, jp->r);
651 static void sol_stor_ball(fs_file fout, struct b_ball *bp)
653 put_array(fout, bp->p, 3);
654 put_float(fout, bp->r);
657 static void sol_stor_view(fs_file fout, struct b_view *wp)
659 put_array(fout, wp->p, 3);
660 put_array(fout, wp->q, 3);
663 static void sol_stor_dict(fs_file fout, struct b_dict *dp)
665 put_index(fout, dp->ai);
666 put_index(fout, dp->aj);
669 static void sol_stor_file(fs_file fout, struct s_base *fp)
672 int magic = SOL_MAGIC;
673 int version = SOL_VER_CURRENT;
675 put_index(fout, magic);
676 put_index(fout, version);
678 put_index(fout, fp->ac);
679 put_index(fout, fp->dc);
680 put_index(fout, fp->mc);
681 put_index(fout, fp->vc);
682 put_index(fout, fp->ec);
683 put_index(fout, fp->sc);
684 put_index(fout, fp->tc);
685 put_index(fout, fp->oc);
686 put_index(fout, fp->gc);
687 put_index(fout, fp->lc);
688 put_index(fout, fp->nc);
689 put_index(fout, fp->pc);
690 put_index(fout, fp->bc);
691 put_index(fout, fp->hc);
692 put_index(fout, fp->zc);
693 put_index(fout, fp->jc);
694 put_index(fout, fp->xc);
695 put_index(fout, fp->rc);
696 put_index(fout, fp->uc);
697 put_index(fout, fp->wc);
698 put_index(fout, fp->ic);
700 fs_write(fp->av, 1, fp->ac, fout);
702 for (i = 0; i < fp->dc; i++) sol_stor_dict(fout, fp->dv + i);
703 for (i = 0; i < fp->mc; i++) sol_stor_mtrl(fout, fp->mv + i);
704 for (i = 0; i < fp->vc; i++) sol_stor_vert(fout, fp->vv + i);
705 for (i = 0; i < fp->ec; i++) sol_stor_edge(fout, fp->ev + i);
706 for (i = 0; i < fp->sc; i++) sol_stor_side(fout, fp->sv + i);
707 for (i = 0; i < fp->tc; i++) sol_stor_texc(fout, fp->tv + i);
708 for (i = 0; i < fp->oc; i++) sol_stor_offs(fout, fp->ov + i);
709 for (i = 0; i < fp->gc; i++) sol_stor_geom(fout, fp->gv + i);
710 for (i = 0; i < fp->lc; i++) sol_stor_lump(fout, fp->lv + i);
711 for (i = 0; i < fp->nc; i++) sol_stor_node(fout, fp->nv + i);
712 for (i = 0; i < fp->pc; i++) sol_stor_path(fout, fp->pv + i);
713 for (i = 0; i < fp->bc; i++) sol_stor_body(fout, fp->bv + i);
714 for (i = 0; i < fp->hc; i++) sol_stor_item(fout, fp->hv + i);
715 for (i = 0; i < fp->zc; i++) sol_stor_goal(fout, fp->zv + i);
716 for (i = 0; i < fp->jc; i++) sol_stor_jump(fout, fp->jv + i);
717 for (i = 0; i < fp->xc; i++) sol_stor_swch(fout, fp->xv + i);
718 for (i = 0; i < fp->rc; i++) sol_stor_bill(fout, fp->rv + i);
719 for (i = 0; i < fp->uc; i++) sol_stor_ball(fout, fp->uv + i);
720 for (i = 0; i < fp->wc; i++) sol_stor_view(fout, fp->wv + i);
721 for (i = 0; i < fp->ic; i++) put_index(fout, fp->iv[i]);
724 int sol_stor_base(struct s_base *fp, const char *filename)
728 if ((fout = fs_open(filename, "w")))
730 sol_stor_file(fout, fp);
738 /*---------------------------------------------------------------------------*/