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_PATH_FLAGS
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);
68 static void sol_load_vert(fs_file fin, struct b_vert *vp)
70 get_array(fin, vp->p, 3);
73 static void sol_load_edge(fs_file fin, struct b_edge *ep)
75 get_index(fin, &ep->vi);
76 get_index(fin, &ep->vj);
79 static void sol_load_side(fs_file fin, struct b_side *sp)
81 get_array(fin, sp->n, 3);
82 get_float(fin, &sp->d);
85 static void sol_load_texc(fs_file fin, struct b_texc *tp)
87 get_array(fin, tp->u, 2);
90 static void sol_load_geom(fs_file fin, struct b_geom *gp)
92 get_index(fin, &gp->mi);
93 get_index(fin, &gp->ti);
94 get_index(fin, &gp->si);
95 get_index(fin, &gp->vi);
96 get_index(fin, &gp->tj);
97 get_index(fin, &gp->sj);
98 get_index(fin, &gp->vj);
99 get_index(fin, &gp->tk);
100 get_index(fin, &gp->sk);
101 get_index(fin, &gp->vk);
104 static void sol_load_lump(fs_file fin, struct b_lump *lp)
106 get_index(fin, &lp->fl);
107 get_index(fin, &lp->v0);
108 get_index(fin, &lp->vc);
109 get_index(fin, &lp->e0);
110 get_index(fin, &lp->ec);
111 get_index(fin, &lp->g0);
112 get_index(fin, &lp->gc);
113 get_index(fin, &lp->s0);
114 get_index(fin, &lp->sc);
117 static void sol_load_node(fs_file fin, struct b_node *np)
119 get_index(fin, &np->si);
120 get_index(fin, &np->ni);
121 get_index(fin, &np->nj);
122 get_index(fin, &np->l0);
123 get_index(fin, &np->lc);
126 static void sol_load_path(fs_file fin, struct b_path *pp)
128 get_array(fin, pp->p, 3);
129 get_float(fin, &pp->t);
130 get_index(fin, &pp->pi);
131 get_index(fin, &pp->f);
132 get_index(fin, &pp->s);
134 pp->tm = TIME_TO_MS(pp->t);
135 pp->t = MS_TO_TIME(pp->tm);
137 if (sol_version >= SOL_VER_PATH_FLAGS)
138 get_index(fin, &pp->fl);
145 if (pp->fl & P_ORIENTED)
146 get_array(fin, pp->e, 4);
149 static void sol_load_body(fs_file fin, struct b_body *bp)
151 get_index(fin, &bp->pi);
152 get_index(fin, &bp->ni);
153 get_index(fin, &bp->l0);
154 get_index(fin, &bp->lc);
155 get_index(fin, &bp->g0);
156 get_index(fin, &bp->gc);
159 static void sol_load_item(fs_file fin, struct b_item *hp)
161 get_array(fin, hp->p, 3);
162 get_index(fin, &hp->t);
163 get_index(fin, &hp->n);
166 static void sol_load_goal(fs_file fin, struct b_goal *zp)
168 get_array(fin, zp->p, 3);
169 get_float(fin, &zp->r);
172 static void sol_load_swch(fs_file fin, struct b_swch *xp)
177 get_array(fin, xp->p, 3);
178 get_float(fin, &xp->r);
179 get_index(fin, &xp->pi);
180 get_float(fin, &xp->t);
182 get_index(fin, &xp->f);
184 get_index(fin, &xp->i);
186 xp->tm = TIME_TO_MS(xp->t);
187 xp->t = MS_TO_TIME(xp->tm);
190 static void sol_load_bill(fs_file fin, struct b_bill *rp)
192 get_index(fin, &rp->fl);
193 get_index(fin, &rp->mi);
194 get_float(fin, &rp->t);
195 get_float(fin, &rp->d);
196 get_array(fin, rp->w, 3);
197 get_array(fin, rp->h, 3);
198 get_array(fin, rp->rx, 3);
199 get_array(fin, rp->ry, 3);
200 get_array(fin, rp->rz, 3);
201 get_array(fin, rp->p, 3);
204 static void sol_load_jump(fs_file fin, struct b_jump *jp)
206 get_array(fin, jp->p, 3);
207 get_array(fin, jp->q, 3);
208 get_float(fin, &jp->r);
211 static void sol_load_ball(fs_file fin, struct b_ball *bp)
213 get_array(fin, bp->p, 3);
214 get_float(fin, &bp->r);
217 static void sol_load_view(fs_file fin, struct b_view *wp)
219 get_array(fin, wp->p, 3);
220 get_array(fin, wp->q, 3);
223 static void sol_load_dict(fs_file fin, struct b_dict *dp)
225 get_index(fin, &dp->ai);
226 get_index(fin, &dp->aj);
229 static void sol_load_indx(fs_file fin, struct s_base *fp)
231 get_index(fin, &fp->ac);
232 get_index(fin, &fp->dc);
233 get_index(fin, &fp->mc);
234 get_index(fin, &fp->vc);
235 get_index(fin, &fp->ec);
236 get_index(fin, &fp->sc);
237 get_index(fin, &fp->tc);
238 get_index(fin, &fp->gc);
239 get_index(fin, &fp->lc);
240 get_index(fin, &fp->nc);
241 get_index(fin, &fp->pc);
242 get_index(fin, &fp->bc);
243 get_index(fin, &fp->hc);
244 get_index(fin, &fp->zc);
245 get_index(fin, &fp->jc);
246 get_index(fin, &fp->xc);
247 get_index(fin, &fp->rc);
248 get_index(fin, &fp->uc);
249 get_index(fin, &fp->wc);
250 get_index(fin, &fp->ic);
253 static int sol_load_file(fs_file fin, struct s_base *fp)
260 sol_load_indx(fin, fp);
263 fp->av = (char *) calloc(fp->ac, sizeof (*fp->av));
265 fp->mv = (struct b_mtrl *) calloc(fp->mc, sizeof (*fp->mv));
267 fp->vv = (struct b_vert *) calloc(fp->vc, sizeof (*fp->vv));
269 fp->ev = (struct b_edge *) calloc(fp->ec, sizeof (*fp->ev));
271 fp->sv = (struct b_side *) calloc(fp->sc, sizeof (*fp->sv));
273 fp->tv = (struct b_texc *) calloc(fp->tc, sizeof (*fp->tv));
275 fp->gv = (struct b_geom *) calloc(fp->gc, sizeof (*fp->gv));
277 fp->lv = (struct b_lump *) calloc(fp->lc, sizeof (*fp->lv));
279 fp->nv = (struct b_node *) calloc(fp->nc, sizeof (*fp->nv));
281 fp->pv = (struct b_path *) calloc(fp->pc, sizeof (*fp->pv));
283 fp->bv = (struct b_body *) calloc(fp->bc, sizeof (*fp->bv));
285 fp->hv = (struct b_item *) calloc(fp->hc, sizeof (*fp->hv));
287 fp->zv = (struct b_goal *) calloc(fp->zc, sizeof (*fp->zv));
289 fp->jv = (struct b_jump *) calloc(fp->jc, sizeof (*fp->jv));
291 fp->xv = (struct b_swch *) calloc(fp->xc, sizeof (*fp->xv));
293 fp->rv = (struct b_bill *) calloc(fp->rc, sizeof (*fp->rv));
295 fp->uv = (struct b_ball *) calloc(fp->uc, sizeof (*fp->uv));
297 fp->wv = (struct b_view *) calloc(fp->wc, sizeof (*fp->wv));
299 fp->dv = (struct b_dict *) calloc(fp->dc, sizeof (*fp->dv));
301 fp->iv = (int *) calloc(fp->ic, sizeof (*fp->iv));
304 fs_read(fp->av, 1, fp->ac, fin);
306 for (i = 0; i < fp->dc; i++) sol_load_dict(fin, fp->dv + i);
307 for (i = 0; i < fp->mc; i++) sol_load_mtrl(fin, fp->mv + i);
308 for (i = 0; i < fp->vc; i++) sol_load_vert(fin, fp->vv + i);
309 for (i = 0; i < fp->ec; i++) sol_load_edge(fin, fp->ev + i);
310 for (i = 0; i < fp->sc; i++) sol_load_side(fin, fp->sv + i);
311 for (i = 0; i < fp->tc; i++) sol_load_texc(fin, fp->tv + i);
312 for (i = 0; i < fp->gc; i++) sol_load_geom(fin, fp->gv + i);
313 for (i = 0; i < fp->lc; i++) sol_load_lump(fin, fp->lv + i);
314 for (i = 0; i < fp->nc; i++) sol_load_node(fin, fp->nv + i);
315 for (i = 0; i < fp->pc; i++) sol_load_path(fin, fp->pv + i);
316 for (i = 0; i < fp->bc; i++) sol_load_body(fin, fp->bv + i);
317 for (i = 0; i < fp->hc; i++) sol_load_item(fin, fp->hv + i);
318 for (i = 0; i < fp->zc; i++) sol_load_goal(fin, fp->zv + i);
319 for (i = 0; i < fp->jc; i++) sol_load_jump(fin, fp->jv + i);
320 for (i = 0; i < fp->xc; i++) sol_load_swch(fin, fp->xv + i);
321 for (i = 0; i < fp->rc; i++) sol_load_bill(fin, fp->rv + i);
322 for (i = 0; i < fp->uc; i++) sol_load_ball(fin, fp->uv + i);
323 for (i = 0; i < fp->wc; i++) sol_load_view(fin, fp->wv + i);
324 for (i = 0; i < fp->ic; i++) get_index(fin, fp->iv + i);
329 static int sol_load_head(fs_file fin, struct s_base *fp)
334 sol_load_indx(fin, fp);
338 fp->av = (char *) calloc(fp->ac, sizeof (*fp->av));
339 fs_read(fp->av, 1, fp->ac, fin);
346 fp->dv = (struct b_dict *) calloc(fp->dc, sizeof (*fp->dv));
348 for (i = 0; i < fp->dc; i++)
349 sol_load_dict(fin, fp->dv + i);
355 int sol_load_base(struct s_base *fp, const char *filename)
360 memset(fp, 0, sizeof (*fp));
362 if ((fin = fs_open(filename, "r")))
364 res = sol_load_file(fin, fp);
370 int sol_load_meta(struct s_base *fp, const char *filename)
375 if ((fin = fs_open(filename, "r")))
377 res = sol_load_head(fin, fp);
383 void sol_free_base(struct s_base *fp)
385 if (fp->av) free(fp->av);
386 if (fp->mv) free(fp->mv);
387 if (fp->vv) free(fp->vv);
388 if (fp->ev) free(fp->ev);
389 if (fp->sv) free(fp->sv);
390 if (fp->tv) free(fp->tv);
391 if (fp->gv) free(fp->gv);
392 if (fp->lv) free(fp->lv);
393 if (fp->nv) free(fp->nv);
394 if (fp->pv) free(fp->pv);
395 if (fp->bv) free(fp->bv);
396 if (fp->hv) free(fp->hv);
397 if (fp->zv) free(fp->zv);
398 if (fp->jv) free(fp->jv);
399 if (fp->xv) free(fp->xv);
400 if (fp->rv) free(fp->rv);
401 if (fp->uv) free(fp->uv);
402 if (fp->wv) free(fp->wv);
403 if (fp->dv) free(fp->dv);
404 if (fp->iv) free(fp->iv);
406 memset(fp, 0, sizeof (*fp));
409 /*---------------------------------------------------------------------------*/
411 static void sol_stor_mtrl(fs_file fout, struct b_mtrl *mp)
413 put_array(fout, mp->d, 4);
414 put_array(fout, mp->a, 4);
415 put_array(fout, mp->s, 4);
416 put_array(fout, mp->e, 4);
417 put_array(fout, mp->h, 1);
418 put_index(fout, mp->fl);
420 fs_write(mp->f, 1, PATHMAX, fout);
423 static void sol_stor_vert(fs_file fout, struct b_vert *vp)
425 put_array(fout, vp->p, 3);
428 static void sol_stor_edge(fs_file fout, struct b_edge *ep)
430 put_index(fout, ep->vi);
431 put_index(fout, ep->vj);
434 static void sol_stor_side(fs_file fout, struct b_side *sp)
436 put_array(fout, sp->n, 3);
437 put_float(fout, sp->d);
440 static void sol_stor_texc(fs_file fout, struct b_texc *tp)
442 put_array(fout, tp->u, 2);
445 static void sol_stor_geom(fs_file fout, struct b_geom *gp)
447 put_index(fout, gp->mi);
448 put_index(fout, gp->ti);
449 put_index(fout, gp->si);
450 put_index(fout, gp->vi);
451 put_index(fout, gp->tj);
452 put_index(fout, gp->sj);
453 put_index(fout, gp->vj);
454 put_index(fout, gp->tk);
455 put_index(fout, gp->sk);
456 put_index(fout, gp->vk);
459 static void sol_stor_lump(fs_file fout, struct b_lump *lp)
461 put_index(fout, lp->fl);
462 put_index(fout, lp->v0);
463 put_index(fout, lp->vc);
464 put_index(fout, lp->e0);
465 put_index(fout, lp->ec);
466 put_index(fout, lp->g0);
467 put_index(fout, lp->gc);
468 put_index(fout, lp->s0);
469 put_index(fout, lp->sc);
472 static void sol_stor_node(fs_file fout, struct b_node *np)
474 put_index(fout, np->si);
475 put_index(fout, np->ni);
476 put_index(fout, np->nj);
477 put_index(fout, np->l0);
478 put_index(fout, np->lc);
481 static void sol_stor_path(fs_file fout, struct b_path *pp)
483 put_array(fout, pp->p, 3);
484 put_float(fout, pp->t);
485 put_index(fout, pp->pi);
486 put_index(fout, pp->f);
487 put_index(fout, pp->s);
488 put_index(fout, pp->fl);
490 if (pp->fl & P_ORIENTED)
491 put_array(fout, pp->e, 4);
494 static void sol_stor_body(fs_file fout, struct b_body *bp)
496 put_index(fout, bp->pi);
497 put_index(fout, bp->ni);
498 put_index(fout, bp->l0);
499 put_index(fout, bp->lc);
500 put_index(fout, bp->g0);
501 put_index(fout, bp->gc);
504 static void sol_stor_item(fs_file fout, struct b_item *hp)
506 put_array(fout, hp->p, 3);
507 put_index(fout, hp->t);
508 put_index(fout, hp->n);
511 static void sol_stor_goal(fs_file fout, struct b_goal *zp)
513 put_array(fout, zp->p, 3);
514 put_float(fout, zp->r);
517 static void sol_stor_swch(fs_file fout, struct b_swch *xp)
519 put_array(fout, xp->p, 3);
520 put_float(fout, xp->r);
521 put_index(fout, xp->pi);
522 put_float(fout, xp->t);
523 put_float(fout, xp->t);
524 put_index(fout, xp->f);
525 put_index(fout, xp->f);
526 put_index(fout, xp->i);
529 static void sol_stor_bill(fs_file fout, struct b_bill *rp)
531 put_index(fout, rp->fl);
532 put_index(fout, rp->mi);
533 put_float(fout, rp->t);
534 put_float(fout, rp->d);
535 put_array(fout, rp->w, 3);
536 put_array(fout, rp->h, 3);
537 put_array(fout, rp->rx, 3);
538 put_array(fout, rp->ry, 3);
539 put_array(fout, rp->rz, 3);
540 put_array(fout, rp->p, 3);
543 static void sol_stor_jump(fs_file fout, struct b_jump *jp)
545 put_array(fout, jp->p, 3);
546 put_array(fout, jp->q, 3);
547 put_float(fout, jp->r);
550 static void sol_stor_ball(fs_file fout, struct b_ball *bp)
552 put_array(fout, bp->p, 3);
553 put_float(fout, bp->r);
556 static void sol_stor_view(fs_file fout, struct b_view *wp)
558 put_array(fout, wp->p, 3);
559 put_array(fout, wp->q, 3);
562 static void sol_stor_dict(fs_file fout, struct b_dict *dp)
564 put_index(fout, dp->ai);
565 put_index(fout, dp->aj);
568 static void sol_stor_file(fs_file fout, struct s_base *fp)
571 int magic = SOL_MAGIC;
572 int version = SOL_VER_CURRENT;
574 put_index(fout, magic);
575 put_index(fout, version);
577 put_index(fout, fp->ac);
578 put_index(fout, fp->dc);
579 put_index(fout, fp->mc);
580 put_index(fout, fp->vc);
581 put_index(fout, fp->ec);
582 put_index(fout, fp->sc);
583 put_index(fout, fp->tc);
584 put_index(fout, fp->gc);
585 put_index(fout, fp->lc);
586 put_index(fout, fp->nc);
587 put_index(fout, fp->pc);
588 put_index(fout, fp->bc);
589 put_index(fout, fp->hc);
590 put_index(fout, fp->zc);
591 put_index(fout, fp->jc);
592 put_index(fout, fp->xc);
593 put_index(fout, fp->rc);
594 put_index(fout, fp->uc);
595 put_index(fout, fp->wc);
596 put_index(fout, fp->ic);
598 fs_write(fp->av, 1, fp->ac, fout);
600 for (i = 0; i < fp->dc; i++) sol_stor_dict(fout, fp->dv + i);
601 for (i = 0; i < fp->mc; i++) sol_stor_mtrl(fout, fp->mv + i);
602 for (i = 0; i < fp->vc; i++) sol_stor_vert(fout, fp->vv + i);
603 for (i = 0; i < fp->ec; i++) sol_stor_edge(fout, fp->ev + i);
604 for (i = 0; i < fp->sc; i++) sol_stor_side(fout, fp->sv + i);
605 for (i = 0; i < fp->tc; i++) sol_stor_texc(fout, fp->tv + i);
606 for (i = 0; i < fp->gc; i++) sol_stor_geom(fout, fp->gv + i);
607 for (i = 0; i < fp->lc; i++) sol_stor_lump(fout, fp->lv + i);
608 for (i = 0; i < fp->nc; i++) sol_stor_node(fout, fp->nv + i);
609 for (i = 0; i < fp->pc; i++) sol_stor_path(fout, fp->pv + i);
610 for (i = 0; i < fp->bc; i++) sol_stor_body(fout, fp->bv + i);
611 for (i = 0; i < fp->hc; i++) sol_stor_item(fout, fp->hv + i);
612 for (i = 0; i < fp->zc; i++) sol_stor_goal(fout, fp->zv + i);
613 for (i = 0; i < fp->jc; i++) sol_stor_jump(fout, fp->jv + i);
614 for (i = 0; i < fp->xc; i++) sol_stor_swch(fout, fp->xv + i);
615 for (i = 0; i < fp->rc; i++) sol_stor_bill(fout, fp->rv + i);
616 for (i = 0; i < fp->uc; i++) sol_stor_ball(fout, fp->uv + i);
617 for (i = 0; i < fp->wc; i++) sol_stor_view(fout, fp->wv + i);
618 for (i = 0; i < fp->ic; i++) put_index(fout, fp->iv[i]);
621 int sol_stor_base(struct s_base *fp, const char *filename)
625 if ((fout = fs_open(filename, "w")))
627 sol_stor_file(fout, fp);
635 /*---------------------------------------------------------------------------*/