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.
20 #include "base_config.h"
29 SOL_VER_CURRENT = SOL_VER_PATH_FLAGS
32 #define SOL_MAGIC (0xAF | 'S' << 8 | 'O' << 16 | 'L' << 24)
34 /*---------------------------------------------------------------------------*/
36 static int sol_version;
38 static int sol_file(fs_file fin)
43 get_index(fin, &magic);
44 get_index(fin, &version);
46 if (magic != SOL_MAGIC || (version < SOL_VER_MINIMUM ||
47 version > SOL_VER_CURRENT))
50 sol_version = version;
55 static void sol_load_mtrl(fs_file fin, struct s_mtrl *mp)
57 get_array(fin, mp->d, 4);
58 get_array(fin, mp->a, 4);
59 get_array(fin, mp->s, 4);
60 get_array(fin, mp->e, 4);
61 get_array(fin, mp->h, 1);
62 get_index(fin, &mp->fl);
64 fs_read(mp->f, 1, PATHMAX, fin);
67 static void sol_load_vert(fs_file fin, struct s_vert *vp)
69 get_array(fin, vp->p, 3);
72 static void sol_load_edge(fs_file fin, struct s_edge *ep)
74 get_index(fin, &ep->vi);
75 get_index(fin, &ep->vj);
78 static void sol_load_side(fs_file fin, struct s_side *sp)
80 get_array(fin, sp->n, 3);
81 get_float(fin, &sp->d);
84 static void sol_load_texc(fs_file fin, struct s_texc *tp)
86 get_array(fin, tp->u, 2);
89 static void sol_load_geom(fs_file fin, struct s_geom *gp)
91 get_index(fin, &gp->mi);
92 get_index(fin, &gp->ti);
93 get_index(fin, &gp->si);
94 get_index(fin, &gp->vi);
95 get_index(fin, &gp->tj);
96 get_index(fin, &gp->sj);
97 get_index(fin, &gp->vj);
98 get_index(fin, &gp->tk);
99 get_index(fin, &gp->sk);
100 get_index(fin, &gp->vk);
103 static void sol_load_lump(fs_file fin, struct s_lump *lp)
105 get_index(fin, &lp->fl);
106 get_index(fin, &lp->v0);
107 get_index(fin, &lp->vc);
108 get_index(fin, &lp->e0);
109 get_index(fin, &lp->ec);
110 get_index(fin, &lp->g0);
111 get_index(fin, &lp->gc);
112 get_index(fin, &lp->s0);
113 get_index(fin, &lp->sc);
116 static void sol_load_node(fs_file fin, struct s_node *np)
118 get_index(fin, &np->si);
119 get_index(fin, &np->ni);
120 get_index(fin, &np->nj);
121 get_index(fin, &np->l0);
122 get_index(fin, &np->lc);
125 static void sol_load_path(fs_file fin, struct s_path *pp)
127 get_array(fin, pp->p, 3);
128 get_float(fin, &pp->t);
129 get_index(fin, &pp->pi);
130 get_index(fin, &pp->f);
131 get_index(fin, &pp->s);
133 pp->tm = TIME_TO_MS(pp->t);
134 pp->t = MS_TO_TIME(pp->tm);
136 if (sol_version >= SOL_VER_PATH_FLAGS)
137 get_index(fin, &pp->fl);
144 if (pp->fl & P_ORIENTED)
145 get_array(fin, pp->e, 4);
148 static void sol_load_body(fs_file fin, struct s_body *bp)
150 get_index(fin, &bp->pi);
151 get_index(fin, &bp->ni);
152 get_index(fin, &bp->l0);
153 get_index(fin, &bp->lc);
154 get_index(fin, &bp->g0);
155 get_index(fin, &bp->gc);
158 static void sol_load_item(fs_file fin, struct s_item *hp)
160 get_array(fin, hp->p, 3);
161 get_index(fin, &hp->t);
162 get_index(fin, &hp->n);
165 static void sol_load_goal(fs_file fin, struct s_goal *zp)
167 get_array(fin, zp->p, 3);
168 get_float(fin, &zp->r);
171 static void sol_load_swch(fs_file fin, struct s_swch *xp)
173 get_array(fin, xp->p, 3);
174 get_float(fin, &xp->r);
175 get_index(fin, &xp->pi);
176 get_float(fin, &xp->t0);
177 get_float(fin, &xp->t);
178 get_index(fin, &xp->f0);
179 get_index(fin, &xp->f);
180 get_index(fin, &xp->i);
182 xp->t0m = TIME_TO_MS(xp->t0);
183 xp->tm = TIME_TO_MS(xp->t);
185 xp->t0 = MS_TO_TIME(xp->t0m);
186 xp->t = MS_TO_TIME(xp->tm);
189 static void sol_load_bill(fs_file fin, struct s_bill *rp)
191 get_index(fin, &rp->fl);
192 get_index(fin, &rp->mi);
193 get_float(fin, &rp->t);
194 get_float(fin, &rp->d);
195 get_array(fin, rp->w, 3);
196 get_array(fin, rp->h, 3);
197 get_array(fin, rp->rx, 3);
198 get_array(fin, rp->ry, 3);
199 get_array(fin, rp->rz, 3);
200 get_array(fin, rp->p, 3);
203 static void sol_load_jump(fs_file fin, struct s_jump *jp)
205 get_array(fin, jp->p, 3);
206 get_array(fin, jp->q, 3);
207 get_float(fin, &jp->r);
210 static void sol_load_ball(fs_file fin, struct s_ball *bp)
212 get_array(fin, bp->p, 3);
213 get_float(fin, &bp->r);
215 bp->e[0][0] = bp->E[0][0] = 1.0f;
216 bp->e[0][1] = bp->E[0][1] = 0.0f;
217 bp->e[0][2] = bp->E[0][2] = 0.0f;
219 bp->e[1][0] = bp->E[1][0] = 0.0f;
220 bp->e[1][1] = bp->E[1][1] = 1.0f;
221 bp->e[1][2] = bp->E[1][2] = 0.0f;
223 bp->e[2][0] = bp->E[2][0] = 0.0f;
224 bp->e[2][1] = bp->E[2][1] = 0.0f;
225 bp->e[2][2] = bp->E[2][2] = 1.0f;
228 static void sol_load_view(fs_file fin, struct s_view *wp)
230 get_array(fin, wp->p, 3);
231 get_array(fin, wp->q, 3);
234 static void sol_load_dict(fs_file fin, struct s_dict *dp)
236 get_index(fin, &dp->ai);
237 get_index(fin, &dp->aj);
240 static void sol_load_indx(fs_file fin, struct s_file *fp)
242 get_index(fin, &fp->ac);
243 get_index(fin, &fp->dc);
244 get_index(fin, &fp->mc);
245 get_index(fin, &fp->vc);
246 get_index(fin, &fp->ec);
247 get_index(fin, &fp->sc);
248 get_index(fin, &fp->tc);
249 get_index(fin, &fp->gc);
250 get_index(fin, &fp->lc);
251 get_index(fin, &fp->nc);
252 get_index(fin, &fp->pc);
253 get_index(fin, &fp->bc);
254 get_index(fin, &fp->hc);
255 get_index(fin, &fp->zc);
256 get_index(fin, &fp->jc);
257 get_index(fin, &fp->xc);
258 get_index(fin, &fp->rc);
259 get_index(fin, &fp->uc);
260 get_index(fin, &fp->wc);
261 get_index(fin, &fp->ic);
264 static int sol_load_file(fs_file fin, struct s_file *fp)
271 sol_load_indx(fin, fp);
274 fp->av = (char *) calloc(fp->ac, sizeof (char));
276 fp->mv = (struct s_mtrl *) calloc(fp->mc, sizeof (struct s_mtrl));
278 fp->vv = (struct s_vert *) calloc(fp->vc, sizeof (struct s_vert));
280 fp->ev = (struct s_edge *) calloc(fp->ec, sizeof (struct s_edge));
282 fp->sv = (struct s_side *) calloc(fp->sc, sizeof (struct s_side));
284 fp->tv = (struct s_texc *) calloc(fp->tc, sizeof (struct s_texc));
286 fp->gv = (struct s_geom *) calloc(fp->gc, sizeof (struct s_geom));
288 fp->lv = (struct s_lump *) calloc(fp->lc, sizeof (struct s_lump));
290 fp->nv = (struct s_node *) calloc(fp->nc, sizeof (struct s_node));
292 fp->pv = (struct s_path *) calloc(fp->pc, sizeof (struct s_path));
294 fp->bv = (struct s_body *) calloc(fp->bc, sizeof (struct s_body));
296 fp->hv = (struct s_item *) calloc(fp->hc, sizeof (struct s_item));
298 fp->zv = (struct s_goal *) calloc(fp->zc, sizeof (struct s_goal));
300 fp->jv = (struct s_jump *) calloc(fp->jc, sizeof (struct s_jump));
302 fp->xv = (struct s_swch *) calloc(fp->xc, sizeof (struct s_swch));
304 fp->rv = (struct s_bill *) calloc(fp->rc, sizeof (struct s_bill));
306 fp->uv = (struct s_ball *) calloc(fp->uc, sizeof (struct s_ball));
308 fp->wv = (struct s_view *) calloc(fp->wc, sizeof (struct s_view));
310 fp->dv = (struct s_dict *) calloc(fp->dc, sizeof (struct s_dict));
312 fp->iv = (int *) calloc(fp->ic, sizeof (int));
315 fs_read(fp->av, 1, fp->ac, fin);
317 for (i = 0; i < fp->dc; i++) sol_load_dict(fin, fp->dv + i);
318 for (i = 0; i < fp->mc; i++) sol_load_mtrl(fin, fp->mv + i);
319 for (i = 0; i < fp->vc; i++) sol_load_vert(fin, fp->vv + i);
320 for (i = 0; i < fp->ec; i++) sol_load_edge(fin, fp->ev + i);
321 for (i = 0; i < fp->sc; i++) sol_load_side(fin, fp->sv + i);
322 for (i = 0; i < fp->tc; i++) sol_load_texc(fin, fp->tv + i);
323 for (i = 0; i < fp->gc; i++) sol_load_geom(fin, fp->gv + i);
324 for (i = 0; i < fp->lc; i++) sol_load_lump(fin, fp->lv + i);
325 for (i = 0; i < fp->nc; i++) sol_load_node(fin, fp->nv + i);
326 for (i = 0; i < fp->pc; i++) sol_load_path(fin, fp->pv + i);
327 for (i = 0; i < fp->bc; i++) sol_load_body(fin, fp->bv + i);
328 for (i = 0; i < fp->hc; i++) sol_load_item(fin, fp->hv + i);
329 for (i = 0; i < fp->zc; i++) sol_load_goal(fin, fp->zv + i);
330 for (i = 0; i < fp->jc; i++) sol_load_jump(fin, fp->jv + i);
331 for (i = 0; i < fp->xc; i++) sol_load_swch(fin, fp->xv + i);
332 for (i = 0; i < fp->rc; i++) sol_load_bill(fin, fp->rv + i);
333 for (i = 0; i < fp->uc; i++) sol_load_ball(fin, fp->uv + i);
334 for (i = 0; i < fp->wc; i++) sol_load_view(fin, fp->wv + i);
335 for (i = 0; i < fp->ic; i++) get_index(fin, fp->iv + i);
340 static int sol_load_head(fs_file fin, struct s_file *fp)
345 sol_load_indx(fin, fp);
349 fp->av = (char *) calloc(fp->ac, sizeof (char));
350 fs_read(fp->av, 1, fp->ac, fin);
357 fp->dv = (struct s_dict *) calloc(fp->dc, sizeof (struct s_dict));
359 for (i = 0; i < fp->dc; i++)
360 sol_load_dict(fin, fp->dv + i);
366 int sol_load_only_file(struct s_file *fp, const char *filename)
371 if ((fin = fs_open(filename, "r")))
373 res = sol_load_file(fin, fp);
379 int sol_load_only_head(struct s_file *fp, const char *filename)
384 if ((fin = fs_open(filename, "r")))
386 res = sol_load_head(fin, fp);
392 /*---------------------------------------------------------------------------*/
394 static void sol_stor_mtrl(fs_file fout, struct s_mtrl *mp)
396 put_array(fout, mp->d, 4);
397 put_array(fout, mp->a, 4);
398 put_array(fout, mp->s, 4);
399 put_array(fout, mp->e, 4);
400 put_array(fout, mp->h, 1);
401 put_index(fout, mp->fl);
403 fs_write(mp->f, 1, PATHMAX, fout);
406 static void sol_stor_vert(fs_file fout, struct s_vert *vp)
408 put_array(fout, vp->p, 3);
411 static void sol_stor_edge(fs_file fout, struct s_edge *ep)
413 put_index(fout, ep->vi);
414 put_index(fout, ep->vj);
417 static void sol_stor_side(fs_file fout, struct s_side *sp)
419 put_array(fout, sp->n, 3);
420 put_float(fout, sp->d);
423 static void sol_stor_texc(fs_file fout, struct s_texc *tp)
425 put_array(fout, tp->u, 2);
428 static void sol_stor_geom(fs_file fout, struct s_geom *gp)
430 put_index(fout, gp->mi);
431 put_index(fout, gp->ti);
432 put_index(fout, gp->si);
433 put_index(fout, gp->vi);
434 put_index(fout, gp->tj);
435 put_index(fout, gp->sj);
436 put_index(fout, gp->vj);
437 put_index(fout, gp->tk);
438 put_index(fout, gp->sk);
439 put_index(fout, gp->vk);
442 static void sol_stor_lump(fs_file fout, struct s_lump *lp)
444 put_index(fout, lp->fl);
445 put_index(fout, lp->v0);
446 put_index(fout, lp->vc);
447 put_index(fout, lp->e0);
448 put_index(fout, lp->ec);
449 put_index(fout, lp->g0);
450 put_index(fout, lp->gc);
451 put_index(fout, lp->s0);
452 put_index(fout, lp->sc);
455 static void sol_stor_node(fs_file fout, struct s_node *np)
457 put_index(fout, np->si);
458 put_index(fout, np->ni);
459 put_index(fout, np->nj);
460 put_index(fout, np->l0);
461 put_index(fout, np->lc);
464 static void sol_stor_path(fs_file fout, struct s_path *pp)
466 put_array(fout, pp->p, 3);
467 put_float(fout, pp->t);
468 put_index(fout, pp->pi);
469 put_index(fout, pp->f);
470 put_index(fout, pp->s);
471 put_index(fout, pp->fl);
473 if (pp->fl & P_ORIENTED)
474 put_array(fout, pp->e, 4);
477 static void sol_stor_body(fs_file fout, struct s_body *bp)
479 put_index(fout, bp->pi);
480 put_index(fout, bp->ni);
481 put_index(fout, bp->l0);
482 put_index(fout, bp->lc);
483 put_index(fout, bp->g0);
484 put_index(fout, bp->gc);
487 static void sol_stor_item(fs_file fout, struct s_item *hp)
489 put_array(fout, hp->p, 3);
490 put_index(fout, hp->t);
491 put_index(fout, hp->n);
494 static void sol_stor_goal(fs_file fout, struct s_goal *zp)
496 put_array(fout, zp->p, 3);
497 put_float(fout, zp->r);
500 static void sol_stor_swch(fs_file fout, struct s_swch *xp)
502 put_array(fout, xp->p, 3);
503 put_float(fout, xp->r);
504 put_index(fout, xp->pi);
505 put_float(fout, xp->t0);
506 put_float(fout, xp->t);
507 put_index(fout, xp->f0);
508 put_index(fout, xp->f);
509 put_index(fout, xp->i);
512 static void sol_stor_bill(fs_file fout, struct s_bill *rp)
514 put_index(fout, rp->fl);
515 put_index(fout, rp->mi);
516 put_float(fout, rp->t);
517 put_float(fout, rp->d);
518 put_array(fout, rp->w, 3);
519 put_array(fout, rp->h, 3);
520 put_array(fout, rp->rx, 3);
521 put_array(fout, rp->ry, 3);
522 put_array(fout, rp->rz, 3);
523 put_array(fout, rp->p, 3);
526 static void sol_stor_jump(fs_file fout, struct s_jump *jp)
528 put_array(fout, jp->p, 3);
529 put_array(fout, jp->q, 3);
530 put_float(fout, jp->r);
533 static void sol_stor_ball(fs_file fout, struct s_ball *bp)
535 put_array(fout, bp->p, 3);
536 put_float(fout, bp->r);
539 static void sol_stor_view(fs_file fout, struct s_view *wp)
541 put_array(fout, wp->p, 3);
542 put_array(fout, wp->q, 3);
545 static void sol_stor_dict(fs_file fout, struct s_dict *dp)
547 put_index(fout, dp->ai);
548 put_index(fout, dp->aj);
551 static void sol_stor_file(fs_file fout, struct s_file *fp)
554 int magic = SOL_MAGIC;
555 int version = SOL_VER_CURRENT;
557 put_index(fout, magic);
558 put_index(fout, version);
560 put_index(fout, fp->ac);
561 put_index(fout, fp->dc);
562 put_index(fout, fp->mc);
563 put_index(fout, fp->vc);
564 put_index(fout, fp->ec);
565 put_index(fout, fp->sc);
566 put_index(fout, fp->tc);
567 put_index(fout, fp->gc);
568 put_index(fout, fp->lc);
569 put_index(fout, fp->nc);
570 put_index(fout, fp->pc);
571 put_index(fout, fp->bc);
572 put_index(fout, fp->hc);
573 put_index(fout, fp->zc);
574 put_index(fout, fp->jc);
575 put_index(fout, fp->xc);
576 put_index(fout, fp->rc);
577 put_index(fout, fp->uc);
578 put_index(fout, fp->wc);
579 put_index(fout, fp->ic);
581 fs_write(fp->av, 1, fp->ac, fout);
583 for (i = 0; i < fp->dc; i++) sol_stor_dict(fout, fp->dv + i);
584 for (i = 0; i < fp->mc; i++) sol_stor_mtrl(fout, fp->mv + i);
585 for (i = 0; i < fp->vc; i++) sol_stor_vert(fout, fp->vv + i);
586 for (i = 0; i < fp->ec; i++) sol_stor_edge(fout, fp->ev + i);
587 for (i = 0; i < fp->sc; i++) sol_stor_side(fout, fp->sv + i);
588 for (i = 0; i < fp->tc; i++) sol_stor_texc(fout, fp->tv + i);
589 for (i = 0; i < fp->gc; i++) sol_stor_geom(fout, fp->gv + i);
590 for (i = 0; i < fp->lc; i++) sol_stor_lump(fout, fp->lv + i);
591 for (i = 0; i < fp->nc; i++) sol_stor_node(fout, fp->nv + i);
592 for (i = 0; i < fp->pc; i++) sol_stor_path(fout, fp->pv + i);
593 for (i = 0; i < fp->bc; i++) sol_stor_body(fout, fp->bv + i);
594 for (i = 0; i < fp->hc; i++) sol_stor_item(fout, fp->hv + i);
595 for (i = 0; i < fp->zc; i++) sol_stor_goal(fout, fp->zv + i);
596 for (i = 0; i < fp->jc; i++) sol_stor_jump(fout, fp->jv + i);
597 for (i = 0; i < fp->xc; i++) sol_stor_swch(fout, fp->xv + i);
598 for (i = 0; i < fp->rc; i++) sol_stor_bill(fout, fp->rv + i);
599 for (i = 0; i < fp->uc; i++) sol_stor_ball(fout, fp->uv + i);
600 for (i = 0; i < fp->wc; i++) sol_stor_view(fout, fp->wv + i);
601 for (i = 0; i < fp->ic; i++) put_index(fout, fp->iv[i]);
604 /*---------------------------------------------------------------------------*/
606 int sol_stor(struct s_file *fp, const char *filename)
610 if ((fout = fs_open(filename, "w")))
612 sol_stor_file(fout, fp);
620 void sol_free(struct s_file *fp)
622 if (fp->av) free(fp->av);
623 if (fp->mv) free(fp->mv);
624 if (fp->vv) free(fp->vv);
625 if (fp->ev) free(fp->ev);
626 if (fp->sv) free(fp->sv);
627 if (fp->tv) free(fp->tv);
628 if (fp->gv) free(fp->gv);
629 if (fp->lv) free(fp->lv);
630 if (fp->nv) free(fp->nv);
631 if (fp->pv) free(fp->pv);
632 if (fp->bv) free(fp->bv);
633 if (fp->hv) free(fp->hv);
634 if (fp->zv) free(fp->zv);
635 if (fp->jv) free(fp->jv);
636 if (fp->xv) free(fp->xv);
637 if (fp->rv) free(fp->rv);
638 if (fp->uv) free(fp->uv);
639 if (fp->wv) free(fp->wv);
640 if (fp->dv) free(fp->dv);
641 if (fp->iv) free(fp->iv);
643 memset(fp, 0, sizeof (struct s_file));
646 /*---------------------------------------------------------------------------*/