Group key config symbols together
[neverball] / share / solid.c
1 /*
2  * Copyright (C) 2003 Robert Kooima
3  *
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.
8  *
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.
13  */
14
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <string.h>
18
19 #include "solid.h"
20 #include "base_config.h"
21 #include "binary.h"
22 #include "fs.h"
23
24 #define MAGIC       0x4c4f53af
25 #define SOL_VERSION 6
26
27 /*---------------------------------------------------------------------------*/
28
29 static void sol_load_mtrl(fs_file fin, struct s_mtrl *mp)
30 {
31     get_array(fin,  mp->d, 4);
32     get_array(fin,  mp->a, 4);
33     get_array(fin,  mp->s, 4);
34     get_array(fin,  mp->e, 4);
35     get_array(fin,  mp->h, 1);
36     get_index(fin, &mp->fl);
37
38     fs_read(mp->f, 1, PATHMAX, fin);
39 }
40
41 static void sol_load_vert(fs_file fin, struct s_vert *vp)
42 {
43     get_array(fin,  vp->p, 3);
44 }
45
46 static void sol_load_edge(fs_file fin, struct s_edge *ep)
47 {
48     get_index(fin, &ep->vi);
49     get_index(fin, &ep->vj);
50 }
51
52 static void sol_load_side(fs_file fin, struct s_side *sp)
53 {
54     get_array(fin,  sp->n, 3);
55     get_float(fin, &sp->d);
56 }
57
58 static void sol_load_texc(fs_file fin, struct s_texc *tp)
59 {
60     get_array(fin,  tp->u, 2);
61 }
62
63 static void sol_load_geom(fs_file fin, struct s_geom *gp)
64 {
65     get_index(fin, &gp->mi);
66     get_index(fin, &gp->ti);
67     get_index(fin, &gp->si);
68     get_index(fin, &gp->vi);
69     get_index(fin, &gp->tj);
70     get_index(fin, &gp->sj);
71     get_index(fin, &gp->vj);
72     get_index(fin, &gp->tk);
73     get_index(fin, &gp->sk);
74     get_index(fin, &gp->vk);
75 }
76
77 static void sol_load_lump(fs_file fin, struct s_lump *lp)
78 {
79     get_index(fin, &lp->fl);
80     get_index(fin, &lp->v0);
81     get_index(fin, &lp->vc);
82     get_index(fin, &lp->e0);
83     get_index(fin, &lp->ec);
84     get_index(fin, &lp->g0);
85     get_index(fin, &lp->gc);
86     get_index(fin, &lp->s0);
87     get_index(fin, &lp->sc);
88 }
89
90 static void sol_load_node(fs_file fin, struct s_node *np)
91 {
92     get_index(fin, &np->si);
93     get_index(fin, &np->ni);
94     get_index(fin, &np->nj);
95     get_index(fin, &np->l0);
96     get_index(fin, &np->lc);
97 }
98
99 static void sol_load_path(fs_file fin, struct s_path *pp)
100 {
101     get_array(fin,  pp->p, 3);
102     get_float(fin, &pp->t);
103     get_index(fin, &pp->pi);
104     get_index(fin, &pp->f);
105     get_index(fin, &pp->s);
106 }
107
108 static void sol_load_body(fs_file fin, struct s_body *bp)
109 {
110     get_index(fin, &bp->pi);
111     get_index(fin, &bp->ni);
112     get_index(fin, &bp->l0);
113     get_index(fin, &bp->lc);
114     get_index(fin, &bp->g0);
115     get_index(fin, &bp->gc);
116 }
117
118 static void sol_load_item(fs_file fin, struct s_item *hp)
119 {
120     get_array(fin,  hp->p, 3);
121     get_index(fin, &hp->t);
122     get_index(fin, &hp->n);
123 }
124
125 static void sol_load_goal(fs_file fin, struct s_goal *zp)
126 {
127     get_array(fin,  zp->p, 3);
128     get_float(fin, &zp->r);
129 }
130
131 static void sol_load_swch(fs_file fin, struct s_swch *xp)
132 {
133     get_array(fin,  xp->p, 3);
134     get_float(fin, &xp->r);
135     get_index(fin, &xp->pi);
136     get_float(fin, &xp->t0);
137     get_float(fin, &xp->t);
138     get_index(fin, &xp->f0);
139     get_index(fin, &xp->f);
140     get_index(fin, &xp->i);
141 }
142
143 static void sol_load_bill(fs_file fin, struct s_bill *rp)
144 {
145     get_index(fin, &rp->fl);
146     get_index(fin, &rp->mi);
147     get_float(fin, &rp->t);
148     get_float(fin, &rp->d);
149     get_array(fin,  rp->w,  3);
150     get_array(fin,  rp->h,  3);
151     get_array(fin,  rp->rx, 3);
152     get_array(fin,  rp->ry, 3);
153     get_array(fin,  rp->rz, 3);
154     get_array(fin,  rp->p,  3);
155 }
156
157 static void sol_load_jump(fs_file fin, struct s_jump *jp)
158 {
159     get_array(fin,  jp->p, 3);
160     get_array(fin,  jp->q, 3);
161     get_float(fin, &jp->r);
162 }
163
164 static void sol_load_ball(fs_file fin, struct s_ball *bp)
165 {
166     get_array(fin,  bp->p, 3);
167     get_float(fin, &bp->r);
168
169     bp->e[0][0] = bp->E[0][0] = 1.0f;
170     bp->e[0][1] = bp->E[0][1] = 0.0f;
171     bp->e[0][2] = bp->E[0][2] = 0.0f;
172
173     bp->e[1][0] = bp->E[1][0] = 0.0f;
174     bp->e[1][1] = bp->E[1][1] = 1.0f;
175     bp->e[1][2] = bp->E[1][2] = 0.0f;
176
177     bp->e[2][0] = bp->E[2][0] = 0.0f;
178     bp->e[2][1] = bp->E[2][1] = 0.0f;
179     bp->e[2][2] = bp->E[2][2] = 1.0f;
180 }
181
182 static void sol_load_view(fs_file fin, struct s_view *wp)
183 {
184     get_array(fin,  wp->p, 3);
185     get_array(fin,  wp->q, 3);
186 }
187
188 static void sol_load_dict(fs_file fin, struct s_dict *dp)
189 {
190     get_index(fin, &dp->ai);
191     get_index(fin, &dp->aj);
192 }
193
194 static int sol_load_file(fs_file fin, struct s_file *fp)
195 {
196     int i;
197     int magic;
198     int version;
199
200     get_index(fin, &magic);
201     get_index(fin, &version);
202
203     if (magic != MAGIC || version != SOL_VERSION)
204         return 0;
205
206     get_index(fin, &fp->ac);
207     get_index(fin, &fp->dc);
208     get_index(fin, &fp->mc);
209     get_index(fin, &fp->vc);
210     get_index(fin, &fp->ec);
211     get_index(fin, &fp->sc);
212     get_index(fin, &fp->tc);
213     get_index(fin, &fp->gc);
214     get_index(fin, &fp->lc);
215     get_index(fin, &fp->nc);
216     get_index(fin, &fp->pc);
217     get_index(fin, &fp->bc);
218     get_index(fin, &fp->hc);
219     get_index(fin, &fp->zc);
220     get_index(fin, &fp->jc);
221     get_index(fin, &fp->xc);
222     get_index(fin, &fp->rc);
223     get_index(fin, &fp->uc);
224     get_index(fin, &fp->wc);
225     get_index(fin, &fp->ic);
226
227     if (fp->ac)
228         fp->av = (char          *) calloc(fp->ac, sizeof (char));
229     if (fp->mc)
230         fp->mv = (struct s_mtrl *) calloc(fp->mc, sizeof (struct s_mtrl));
231     if (fp->vc)
232         fp->vv = (struct s_vert *) calloc(fp->vc, sizeof (struct s_vert));
233     if (fp->ec)
234         fp->ev = (struct s_edge *) calloc(fp->ec, sizeof (struct s_edge));
235     if (fp->sc)
236         fp->sv = (struct s_side *) calloc(fp->sc, sizeof (struct s_side));
237     if (fp->tc)
238         fp->tv = (struct s_texc *) calloc(fp->tc, sizeof (struct s_texc));
239     if (fp->gc)
240         fp->gv = (struct s_geom *) calloc(fp->gc, sizeof (struct s_geom));
241     if (fp->lc)
242         fp->lv = (struct s_lump *) calloc(fp->lc, sizeof (struct s_lump));
243     if (fp->nc)
244         fp->nv = (struct s_node *) calloc(fp->nc, sizeof (struct s_node));
245     if (fp->pc)
246         fp->pv = (struct s_path *) calloc(fp->pc, sizeof (struct s_path));
247     if (fp->bc)
248         fp->bv = (struct s_body *) calloc(fp->bc, sizeof (struct s_body));
249     if (fp->hc)
250         fp->hv = (struct s_item *) calloc(fp->hc, sizeof (struct s_item));
251     if (fp->zc)
252         fp->zv = (struct s_goal *) calloc(fp->zc, sizeof (struct s_goal));
253     if (fp->jc)
254         fp->jv = (struct s_jump *) calloc(fp->jc, sizeof (struct s_jump));
255     if (fp->xc)
256         fp->xv = (struct s_swch *) calloc(fp->xc, sizeof (struct s_swch));
257     if (fp->rc)
258         fp->rv = (struct s_bill *) calloc(fp->rc, sizeof (struct s_bill));
259     if (fp->uc)
260         fp->uv = (struct s_ball *) calloc(fp->uc, sizeof (struct s_ball));
261     if (fp->wc)
262         fp->wv = (struct s_view *) calloc(fp->wc, sizeof (struct s_view));
263     if (fp->dc)
264         fp->dv = (struct s_dict *) calloc(fp->dc, sizeof (struct s_dict));
265     if (fp->ic)
266         fp->iv = (int           *) calloc(fp->ic, sizeof (int));
267
268     if (fp->ac)
269         fs_read(fp->av, 1, fp->ac, fin);
270
271     for (i = 0; i < fp->dc; i++) sol_load_dict(fin, fp->dv + i);
272     for (i = 0; i < fp->mc; i++) sol_load_mtrl(fin, fp->mv + i);
273     for (i = 0; i < fp->vc; i++) sol_load_vert(fin, fp->vv + i);
274     for (i = 0; i < fp->ec; i++) sol_load_edge(fin, fp->ev + i);
275     for (i = 0; i < fp->sc; i++) sol_load_side(fin, fp->sv + i);
276     for (i = 0; i < fp->tc; i++) sol_load_texc(fin, fp->tv + i);
277     for (i = 0; i < fp->gc; i++) sol_load_geom(fin, fp->gv + i);
278     for (i = 0; i < fp->lc; i++) sol_load_lump(fin, fp->lv + i);
279     for (i = 0; i < fp->nc; i++) sol_load_node(fin, fp->nv + i);
280     for (i = 0; i < fp->pc; i++) sol_load_path(fin, fp->pv + i);
281     for (i = 0; i < fp->bc; i++) sol_load_body(fin, fp->bv + i);
282     for (i = 0; i < fp->hc; i++) sol_load_item(fin, fp->hv + i);
283     for (i = 0; i < fp->zc; i++) sol_load_goal(fin, fp->zv + i);
284     for (i = 0; i < fp->jc; i++) sol_load_jump(fin, fp->jv + i);
285     for (i = 0; i < fp->xc; i++) sol_load_swch(fin, fp->xv + i);
286     for (i = 0; i < fp->rc; i++) sol_load_bill(fin, fp->rv + i);
287     for (i = 0; i < fp->uc; i++) sol_load_ball(fin, fp->uv + i);
288     for (i = 0; i < fp->wc; i++) sol_load_view(fin, fp->wv + i);
289     for (i = 0; i < fp->ic; i++) get_index(fin, fp->iv + i);
290
291     return 1;
292 }
293
294 static int sol_load_head(fs_file fin, struct s_file *fp)
295 {
296     int magic;
297     int version;
298
299     get_index(fin, &magic);
300     get_index(fin, &version);
301
302     if (magic != MAGIC || version != SOL_VERSION)
303         return 0;
304
305     get_index(fin, &fp->ac);
306     get_index(fin, &fp->dc);
307
308 #if 0
309     get_index(fin, &fp->mc);
310     get_index(fin, &fp->vc);
311     get_index(fin, &fp->ec);
312     get_index(fin, &fp->sc);
313     get_index(fin, &fp->tc);
314     get_index(fin, &fp->gc);
315     get_index(fin, &fp->lc);
316     get_index(fin, &fp->nc);
317     get_index(fin, &fp->pc);
318     get_index(fin, &fp->bc);
319     get_index(fin, &fp->hc);
320     get_index(fin, &fp->zc);
321     get_index(fin, &fp->jc);
322     get_index(fin, &fp->xc);
323     get_index(fin, &fp->rc);
324     get_index(fin, &fp->uc);
325     get_index(fin, &fp->wc);
326     get_index(fin, &fp->ic);
327 #endif
328     fs_seek(fin, 18 * 4, SEEK_CUR);
329
330     if (fp->ac)
331     {
332         fp->av = (char *) calloc(fp->ac, sizeof (char));
333         fs_read(fp->av, 1, fp->ac, fin);
334     }
335
336     if (fp->dc)
337     {
338         int i;
339
340         fp->dv = (struct s_dict *) calloc(fp->dc, sizeof (struct s_dict));
341
342         for (i = 0; i < fp->dc; i++)
343             sol_load_dict(fin, fp->dv + i);
344     }
345
346     return 1;
347 }
348
349 int sol_load_only_file(struct s_file *fp, const char *filename)
350 {
351     fs_file fin;
352     int res = 0;
353
354     if ((fin = fs_open(filename, "r")))
355     {
356         res = sol_load_file(fin, fp);
357         fs_close(fin);
358     }
359     return res;
360 }
361
362 int sol_load_only_head(struct s_file *fp, const char *filename)
363 {
364     fs_file fin;
365     int res = 0;
366
367     if ((fin = fs_open(filename, "r")))
368     {
369         res = sol_load_head(fin, fp);
370         fs_close(fin);
371     }
372     return res;
373 }
374
375 /*---------------------------------------------------------------------------*/
376
377 static void sol_stor_mtrl(fs_file fout, struct s_mtrl *mp)
378 {
379     put_array(fout,  mp->d, 4);
380     put_array(fout,  mp->a, 4);
381     put_array(fout,  mp->s, 4);
382     put_array(fout,  mp->e, 4);
383     put_array(fout,  mp->h, 1);
384     put_index(fout, &mp->fl);
385
386     fs_write(mp->f, 1, PATHMAX, fout);
387 }
388
389 static void sol_stor_vert(fs_file fout, struct s_vert *vp)
390 {
391     put_array(fout,  vp->p, 3);
392 }
393
394 static void sol_stor_edge(fs_file fout, struct s_edge *ep)
395 {
396     put_index(fout, &ep->vi);
397     put_index(fout, &ep->vj);
398 }
399
400 static void sol_stor_side(fs_file fout, struct s_side *sp)
401 {
402     put_array(fout,  sp->n, 3);
403     put_float(fout, &sp->d);
404 }
405
406 static void sol_stor_texc(fs_file fout, struct s_texc *tp)
407 {
408     put_array(fout,  tp->u, 2);
409 }
410
411 static void sol_stor_geom(fs_file fout, struct s_geom *gp)
412 {
413     put_index(fout, &gp->mi);
414     put_index(fout, &gp->ti);
415     put_index(fout, &gp->si);
416     put_index(fout, &gp->vi);
417     put_index(fout, &gp->tj);
418     put_index(fout, &gp->sj);
419     put_index(fout, &gp->vj);
420     put_index(fout, &gp->tk);
421     put_index(fout, &gp->sk);
422     put_index(fout, &gp->vk);
423 }
424
425 static void sol_stor_lump(fs_file fout, struct s_lump *lp)
426 {
427     put_index(fout, &lp->fl);
428     put_index(fout, &lp->v0);
429     put_index(fout, &lp->vc);
430     put_index(fout, &lp->e0);
431     put_index(fout, &lp->ec);
432     put_index(fout, &lp->g0);
433     put_index(fout, &lp->gc);
434     put_index(fout, &lp->s0);
435     put_index(fout, &lp->sc);
436 }
437
438 static void sol_stor_node(fs_file fout, struct s_node *np)
439 {
440     put_index(fout, &np->si);
441     put_index(fout, &np->ni);
442     put_index(fout, &np->nj);
443     put_index(fout, &np->l0);
444     put_index(fout, &np->lc);
445 }
446
447 static void sol_stor_path(fs_file fout, struct s_path *pp)
448 {
449     put_array(fout,  pp->p, 3);
450     put_float(fout, &pp->t);
451     put_index(fout, &pp->pi);
452     put_index(fout, &pp->f);
453     put_index(fout, &pp->s);
454 }
455
456 static void sol_stor_body(fs_file fout, struct s_body *bp)
457 {
458     put_index(fout, &bp->pi);
459     put_index(fout, &bp->ni);
460     put_index(fout, &bp->l0);
461     put_index(fout, &bp->lc);
462     put_index(fout, &bp->g0);
463     put_index(fout, &bp->gc);
464 }
465
466 static void sol_stor_item(fs_file fout, struct s_item *hp)
467 {
468     put_array(fout,  hp->p, 3);
469     put_index(fout, &hp->t);
470     put_index(fout, &hp->n);
471 }
472
473 static void sol_stor_goal(fs_file fout, struct s_goal *zp)
474 {
475     put_array(fout,  zp->p, 3);
476     put_float(fout, &zp->r);
477 }
478
479 static void sol_stor_swch(fs_file fout, struct s_swch *xp)
480 {
481     put_array(fout,  xp->p, 3);
482     put_float(fout, &xp->r);
483     put_index(fout, &xp->pi);
484     put_float(fout, &xp->t0);
485     put_float(fout, &xp->t);
486     put_index(fout, &xp->f0);
487     put_index(fout, &xp->f);
488     put_index(fout, &xp->i);
489 }
490
491 static void sol_stor_bill(fs_file fout, struct s_bill *rp)
492 {
493     put_index(fout, &rp->fl);
494     put_index(fout, &rp->mi);
495     put_float(fout, &rp->t);
496     put_float(fout, &rp->d);
497     put_array(fout,  rp->w,  3);
498     put_array(fout,  rp->h,  3);
499     put_array(fout,  rp->rx, 3);
500     put_array(fout,  rp->ry, 3);
501     put_array(fout,  rp->rz, 3);
502     put_array(fout,  rp->p,  3);
503 }
504
505 static void sol_stor_jump(fs_file fout, struct s_jump *jp)
506 {
507     put_array(fout,  jp->p, 3);
508     put_array(fout,  jp->q, 3);
509     put_float(fout, &jp->r);
510 }
511
512 static void sol_stor_ball(fs_file fout, struct s_ball *bp)
513 {
514     put_array(fout,  bp->p, 3);
515     put_float(fout, &bp->r);
516 }
517
518 static void sol_stor_view(fs_file fout, struct s_view *wp)
519 {
520     put_array(fout,  wp->p, 3);
521     put_array(fout,  wp->q, 3);
522 }
523
524 static void sol_stor_dict(fs_file fout, struct s_dict *dp)
525 {
526     put_index(fout, &dp->ai);
527     put_index(fout, &dp->aj);
528 }
529
530 static void sol_stor_file(fs_file fout, struct s_file *fp)
531 {
532     int i;
533     int magic   = MAGIC;
534     int version = SOL_VERSION;
535
536     put_index(fout, &magic);
537     put_index(fout, &version);
538
539     put_index(fout, &fp->ac);
540     put_index(fout, &fp->dc);
541     put_index(fout, &fp->mc);
542     put_index(fout, &fp->vc);
543     put_index(fout, &fp->ec);
544     put_index(fout, &fp->sc);
545     put_index(fout, &fp->tc);
546     put_index(fout, &fp->gc);
547     put_index(fout, &fp->lc);
548     put_index(fout, &fp->nc);
549     put_index(fout, &fp->pc);
550     put_index(fout, &fp->bc);
551     put_index(fout, &fp->hc);
552     put_index(fout, &fp->zc);
553     put_index(fout, &fp->jc);
554     put_index(fout, &fp->xc);
555     put_index(fout, &fp->rc);
556     put_index(fout, &fp->uc);
557     put_index(fout, &fp->wc);
558     put_index(fout, &fp->ic);
559
560     fs_write(fp->av, 1, fp->ac, fout);
561
562     for (i = 0; i < fp->dc; i++) sol_stor_dict(fout, fp->dv + i);
563     for (i = 0; i < fp->mc; i++) sol_stor_mtrl(fout, fp->mv + i);
564     for (i = 0; i < fp->vc; i++) sol_stor_vert(fout, fp->vv + i);
565     for (i = 0; i < fp->ec; i++) sol_stor_edge(fout, fp->ev + i);
566     for (i = 0; i < fp->sc; i++) sol_stor_side(fout, fp->sv + i);
567     for (i = 0; i < fp->tc; i++) sol_stor_texc(fout, fp->tv + i);
568     for (i = 0; i < fp->gc; i++) sol_stor_geom(fout, fp->gv + i);
569     for (i = 0; i < fp->lc; i++) sol_stor_lump(fout, fp->lv + i);
570     for (i = 0; i < fp->nc; i++) sol_stor_node(fout, fp->nv + i);
571     for (i = 0; i < fp->pc; i++) sol_stor_path(fout, fp->pv + i);
572     for (i = 0; i < fp->bc; i++) sol_stor_body(fout, fp->bv + i);
573     for (i = 0; i < fp->hc; i++) sol_stor_item(fout, fp->hv + i);
574     for (i = 0; i < fp->zc; i++) sol_stor_goal(fout, fp->zv + i);
575     for (i = 0; i < fp->jc; i++) sol_stor_jump(fout, fp->jv + i);
576     for (i = 0; i < fp->xc; i++) sol_stor_swch(fout, fp->xv + i);
577     for (i = 0; i < fp->rc; i++) sol_stor_bill(fout, fp->rv + i);
578     for (i = 0; i < fp->uc; i++) sol_stor_ball(fout, fp->uv + i);
579     for (i = 0; i < fp->wc; i++) sol_stor_view(fout, fp->wv + i);
580     for (i = 0; i < fp->ic; i++) put_index(fout, fp->iv + i);
581 }
582
583 /*---------------------------------------------------------------------------*/
584
585 int sol_stor(struct s_file *fp, const char *filename)
586 {
587     fs_file fout;
588
589     if ((fout = fs_open(filename, "w")))
590     {
591         sol_stor_file(fout, fp);
592         fs_close(fout);
593
594         return 1;
595     }
596     return 0;
597 }
598
599 void sol_free(struct s_file *fp)
600 {
601     if (fp->av) free(fp->av);
602     if (fp->mv) free(fp->mv);
603     if (fp->vv) free(fp->vv);
604     if (fp->ev) free(fp->ev);
605     if (fp->sv) free(fp->sv);
606     if (fp->tv) free(fp->tv);
607     if (fp->gv) free(fp->gv);
608     if (fp->lv) free(fp->lv);
609     if (fp->nv) free(fp->nv);
610     if (fp->pv) free(fp->pv);
611     if (fp->bv) free(fp->bv);
612     if (fp->hv) free(fp->hv);
613     if (fp->zv) free(fp->zv);
614     if (fp->jv) free(fp->jv);
615     if (fp->xv) free(fp->xv);
616     if (fp->rv) free(fp->rv);
617     if (fp->uv) free(fp->uv);
618     if (fp->wv) free(fp->wv);
619     if (fp->dv) free(fp->dv);
620     if (fp->iv) free(fp->iv);
621
622     memset(fp, 0, sizeof (struct s_file));
623 }
624
625 /*---------------------------------------------------------------------------*/