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