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"
32 #define SOL_VERSION_MIN SOL_VERSION_1_5
33 #define SOL_VERSION_CURR SOL_VERSION_DEV
35 #define SOL_MAGIC (0xAF | 'S' << 8 | 'O' << 16 | 'L' << 24)
37 /*---------------------------------------------------------------------------*/
39 static int sol_version
;
41 static int sol_file(fs_file fin
)
46 magic
= get_index(fin
);
47 version
= get_index(fin
);
49 if (magic
!= SOL_MAGIC
|| (version
< SOL_VERSION_MIN
||
50 version
> SOL_VERSION_CURR
))
53 sol_version
= version
;
58 static void sol_load_mtrl(fs_file fin
, struct b_mtrl
*mp
)
60 get_array(fin
, mp
->d
, 4);
61 get_array(fin
, mp
->a
, 4);
62 get_array(fin
, mp
->s
, 4);
63 get_array(fin
, mp
->e
, 4);
64 get_array(fin
, mp
->h
, 1);
66 mp
->fl
= get_index(fin
);
68 fs_read(mp
->f
, 1, PATHMAX
, fin
);
70 if (sol_version
>= SOL_VERSION_DEV
)
72 if (mp
->fl
& M_ALPHA_TEST
)
74 mp
->alpha_func
= get_index(fin
);
75 mp
->alpha_ref
= get_float(fin
);
79 /* Convert 1.5.4 material flags. */
81 if (sol_version
== SOL_VERSION_1_5
)
83 static const int flags
[][2] = {
86 { 4, M_REFLECTIVE
| M_SHADOWED
},
89 { 32, M_CLAMP_S
| M_CLAMP_T
},
90 { 64, M_DECAL
| M_SHADOWED
},
98 for (f
= 0, i
= 0; i
< ARRAYSIZE(flags
); i
++)
99 if (mp
->fl
& flags
[i
][0])
106 /* Must be "mtrl/invisible". */
108 mp
->fl
= M_TRANSPARENT
;
114 static void sol_load_vert(fs_file fin
, struct b_vert
*vp
)
116 get_array(fin
, vp
->p
, 3);
119 static void sol_load_edge(fs_file fin
, struct b_edge
*ep
)
121 ep
->vi
= get_index(fin
);
122 ep
->vj
= get_index(fin
);
125 static void sol_load_side(fs_file fin
, struct b_side
*sp
)
127 get_array(fin
, sp
->n
, 3);
129 sp
->d
= get_float(fin
);
132 static void sol_load_texc(fs_file fin
, struct b_texc
*tp
)
134 get_array(fin
, tp
->u
, 2);
137 static void sol_load_offs(fs_file fin
, struct b_offs
*op
)
139 op
->ti
= get_index(fin
);
140 op
->si
= get_index(fin
);
141 op
->vi
= get_index(fin
);
144 static void sol_load_geom(fs_file fin
, struct b_geom
*gp
, struct s_base
*fp
)
146 gp
->mi
= get_index(fin
);
148 if (sol_version
>= SOL_VERSION_DEV
)
150 gp
->oi
= get_index(fin
);
151 gp
->oj
= get_index(fin
);
152 gp
->ok
= get_index(fin
);
162 for (i
= 0; i
< 3; i
++)
164 ov
[i
].ti
= get_index(fin
);
165 ov
[i
].si
= get_index(fin
);
166 ov
[i
].vi
= get_index(fin
);
170 for (j
= 0; j
< fp
->oc
; j
++)
171 if (ov
[i
].ti
== fp
->ov
[j
].ti
&&
172 ov
[i
].si
== fp
->ov
[j
].si
&&
173 ov
[i
].vi
== fp
->ov
[j
].vi
)
183 if (oc
&& (p
= realloc(fp
->ov
, sizeof (struct b_offs
) * (fp
->oc
+ oc
))))
187 for (i
= 0; i
< 3; i
++)
190 fp
->ov
[fp
->oc
] = ov
[i
];
201 static void sol_load_lump(fs_file fin
, struct b_lump
*lp
)
203 lp
->fl
= get_index(fin
);
204 lp
->v0
= get_index(fin
);
205 lp
->vc
= get_index(fin
);
206 lp
->e0
= get_index(fin
);
207 lp
->ec
= get_index(fin
);
208 lp
->g0
= get_index(fin
);
209 lp
->gc
= get_index(fin
);
210 lp
->s0
= get_index(fin
);
211 lp
->sc
= get_index(fin
);
214 static void sol_load_node(fs_file fin
, struct b_node
*np
)
216 np
->si
= get_index(fin
);
217 np
->ni
= get_index(fin
);
218 np
->nj
= get_index(fin
);
219 np
->l0
= get_index(fin
);
220 np
->lc
= get_index(fin
);
223 static void sol_load_path(fs_file fin
, struct b_path
*pp
)
225 get_array(fin
, pp
->p
, 3);
227 pp
->t
= get_float(fin
);
228 pp
->pi
= get_index(fin
);
229 pp
->f
= get_index(fin
);
230 pp
->s
= get_index(fin
);
232 pp
->tm
= TIME_TO_MS(pp
->t
);
233 pp
->t
= MS_TO_TIME(pp
->tm
);
235 if (sol_version
>= SOL_VERSION_DEV
)
236 pp
->fl
= get_index(fin
);
243 if (pp
->fl
& P_ORIENTED
)
244 get_array(fin
, pp
->e
, 4);
247 static void sol_load_body(fs_file fin
, struct b_body
*bp
)
249 bp
->pi
= get_index(fin
);
251 if (sol_version
>= SOL_VERSION_DEV
)
253 bp
->pj
= get_index(fin
);
261 bp
->ni
= get_index(fin
);
262 bp
->l0
= get_index(fin
);
263 bp
->lc
= get_index(fin
);
264 bp
->g0
= get_index(fin
);
265 bp
->gc
= get_index(fin
);
268 static void sol_load_item(fs_file fin
, struct b_item
*hp
)
270 get_array(fin
, hp
->p
, 3);
272 hp
->t
= get_index(fin
);
273 hp
->n
= get_index(fin
);
276 static void sol_load_goal(fs_file fin
, struct b_goal
*zp
)
278 get_array(fin
, zp
->p
, 3);
280 zp
->r
= get_float(fin
);
283 static void sol_load_swch(fs_file fin
, struct b_swch
*xp
)
285 get_array(fin
, xp
->p
, 3);
287 xp
->r
= get_float(fin
);
288 xp
->pi
= get_index(fin
);
289 xp
->t
= get_float(fin
);
290 (void) get_float(fin
);
291 xp
->f
= get_index(fin
);
292 (void) get_index(fin
);
293 xp
->i
= get_index(fin
);
295 xp
->tm
= TIME_TO_MS(xp
->t
);
296 xp
->t
= MS_TO_TIME(xp
->tm
);
299 static void sol_load_bill(fs_file fin
, struct b_bill
*rp
)
301 rp
->fl
= get_index(fin
);
302 rp
->mi
= get_index(fin
);
303 rp
->t
= get_float(fin
);
304 rp
->d
= get_float(fin
);
306 get_array(fin
, rp
->w
, 3);
307 get_array(fin
, rp
->h
, 3);
308 get_array(fin
, rp
->rx
, 3);
309 get_array(fin
, rp
->ry
, 3);
310 get_array(fin
, rp
->rz
, 3);
311 get_array(fin
, rp
->p
, 3);
314 static void sol_load_jump(fs_file fin
, struct b_jump
*jp
)
316 get_array(fin
, jp
->p
, 3);
317 get_array(fin
, jp
->q
, 3);
319 jp
->r
= get_float(fin
);
322 static void sol_load_ball(fs_file fin
, struct b_ball
*up
)
324 get_array(fin
, up
->p
, 3);
326 up
->r
= get_float(fin
);
329 static void sol_load_view(fs_file fin
, struct b_view
*wp
)
331 get_array(fin
, wp
->p
, 3);
332 get_array(fin
, wp
->q
, 3);
335 static void sol_load_dict(fs_file fin
, struct b_dict
*dp
)
337 dp
->ai
= get_index(fin
);
338 dp
->aj
= get_index(fin
);
341 static void sol_load_indx(fs_file fin
, struct s_base
*fp
)
343 fp
->ac
= get_index(fin
);
344 fp
->dc
= get_index(fin
);
345 fp
->mc
= get_index(fin
);
346 fp
->vc
= get_index(fin
);
347 fp
->ec
= get_index(fin
);
348 fp
->sc
= get_index(fin
);
349 fp
->tc
= get_index(fin
);
351 if (sol_version
>= SOL_VERSION_DEV
)
352 fp
->oc
= get_index(fin
);
354 fp
->gc
= get_index(fin
);
355 fp
->lc
= get_index(fin
);
356 fp
->nc
= get_index(fin
);
357 fp
->pc
= get_index(fin
);
358 fp
->bc
= get_index(fin
);
359 fp
->hc
= get_index(fin
);
360 fp
->zc
= get_index(fin
);
361 fp
->jc
= get_index(fin
);
362 fp
->xc
= get_index(fin
);
363 fp
->rc
= get_index(fin
);
364 fp
->uc
= get_index(fin
);
365 fp
->wc
= get_index(fin
);
366 fp
->ic
= get_index(fin
);
369 static int sol_load_file(fs_file fin
, struct s_base
*fp
)
376 sol_load_indx(fin
, fp
);
379 fp
->av
= (char *) calloc(fp
->ac
, sizeof (*fp
->av
));
381 fp
->mv
= (struct b_mtrl
*) calloc(fp
->mc
, sizeof (*fp
->mv
));
383 fp
->vv
= (struct b_vert
*) calloc(fp
->vc
, sizeof (*fp
->vv
));
385 fp
->ev
= (struct b_edge
*) calloc(fp
->ec
, sizeof (*fp
->ev
));
387 fp
->sv
= (struct b_side
*) calloc(fp
->sc
, sizeof (*fp
->sv
));
389 fp
->tv
= (struct b_texc
*) calloc(fp
->tc
, sizeof (*fp
->tv
));
391 fp
->ov
= (struct b_offs
*) calloc(fp
->oc
, sizeof (*fp
->ov
));
393 fp
->gv
= (struct b_geom
*) calloc(fp
->gc
, sizeof (*fp
->gv
));
395 fp
->lv
= (struct b_lump
*) calloc(fp
->lc
, sizeof (*fp
->lv
));
397 fp
->nv
= (struct b_node
*) calloc(fp
->nc
, sizeof (*fp
->nv
));
399 fp
->pv
= (struct b_path
*) calloc(fp
->pc
, sizeof (*fp
->pv
));
401 fp
->bv
= (struct b_body
*) calloc(fp
->bc
, sizeof (*fp
->bv
));
403 fp
->hv
= (struct b_item
*) calloc(fp
->hc
, sizeof (*fp
->hv
));
405 fp
->zv
= (struct b_goal
*) calloc(fp
->zc
, sizeof (*fp
->zv
));
407 fp
->jv
= (struct b_jump
*) calloc(fp
->jc
, sizeof (*fp
->jv
));
409 fp
->xv
= (struct b_swch
*) calloc(fp
->xc
, sizeof (*fp
->xv
));
411 fp
->rv
= (struct b_bill
*) calloc(fp
->rc
, sizeof (*fp
->rv
));
413 fp
->uv
= (struct b_ball
*) calloc(fp
->uc
, sizeof (*fp
->uv
));
415 fp
->wv
= (struct b_view
*) calloc(fp
->wc
, sizeof (*fp
->wv
));
417 fp
->dv
= (struct b_dict
*) calloc(fp
->dc
, sizeof (*fp
->dv
));
419 fp
->iv
= (int *) calloc(fp
->ic
, sizeof (*fp
->iv
));
422 fs_read(fp
->av
, 1, fp
->ac
, fin
);
424 for (i
= 0; i
< fp
->dc
; i
++) sol_load_dict(fin
, fp
->dv
+ i
);
425 for (i
= 0; i
< fp
->mc
; i
++) sol_load_mtrl(fin
, fp
->mv
+ i
);
426 for (i
= 0; i
< fp
->vc
; i
++) sol_load_vert(fin
, fp
->vv
+ i
);
427 for (i
= 0; i
< fp
->ec
; i
++) sol_load_edge(fin
, fp
->ev
+ i
);
428 for (i
= 0; i
< fp
->sc
; i
++) sol_load_side(fin
, fp
->sv
+ i
);
429 for (i
= 0; i
< fp
->tc
; i
++) sol_load_texc(fin
, fp
->tv
+ i
);
430 for (i
= 0; i
< fp
->oc
; i
++) sol_load_offs(fin
, fp
->ov
+ i
);
431 for (i
= 0; i
< fp
->gc
; i
++) sol_load_geom(fin
, fp
->gv
+ i
, fp
);
432 for (i
= 0; i
< fp
->lc
; i
++) sol_load_lump(fin
, fp
->lv
+ i
);
433 for (i
= 0; i
< fp
->nc
; i
++) sol_load_node(fin
, fp
->nv
+ i
);
434 for (i
= 0; i
< fp
->pc
; i
++) sol_load_path(fin
, fp
->pv
+ i
);
435 for (i
= 0; i
< fp
->bc
; i
++) sol_load_body(fin
, fp
->bv
+ i
);
436 for (i
= 0; i
< fp
->hc
; i
++) sol_load_item(fin
, fp
->hv
+ i
);
437 for (i
= 0; i
< fp
->zc
; i
++) sol_load_goal(fin
, fp
->zv
+ i
);
438 for (i
= 0; i
< fp
->jc
; i
++) sol_load_jump(fin
, fp
->jv
+ i
);
439 for (i
= 0; i
< fp
->xc
; i
++) sol_load_swch(fin
, fp
->xv
+ i
);
440 for (i
= 0; i
< fp
->rc
; i
++) sol_load_bill(fin
, fp
->rv
+ i
);
441 for (i
= 0; i
< fp
->uc
; i
++) sol_load_ball(fin
, fp
->uv
+ i
);
442 for (i
= 0; i
< fp
->wc
; i
++) sol_load_view(fin
, fp
->wv
+ i
);
443 for (i
= 0; i
< fp
->ic
; i
++) fp
->iv
[i
] = get_index(fin
);
445 /* Magically "fix" all of our code. */
450 fp
->uv
= (struct b_ball
*) calloc(fp
->uc
, sizeof (*fp
->uv
));
456 static int sol_load_head(fs_file fin
, struct s_base
*fp
)
461 sol_load_indx(fin
, fp
);
465 fp
->av
= (char *) calloc(fp
->ac
, sizeof (*fp
->av
));
466 fs_read(fp
->av
, 1, fp
->ac
, fin
);
473 fp
->dv
= (struct b_dict
*) calloc(fp
->dc
, sizeof (*fp
->dv
));
475 for (i
= 0; i
< fp
->dc
; i
++)
476 sol_load_dict(fin
, fp
->dv
+ i
);
482 int sol_load_base(struct s_base
*fp
, const char *filename
)
487 memset(fp
, 0, sizeof (*fp
));
489 if ((fin
= fs_open(filename
, "r")))
491 res
= sol_load_file(fin
, fp
);
497 int sol_load_meta(struct s_base
*fp
, const char *filename
)
502 memset(fp
, 0, sizeof (*fp
));
504 if ((fin
= fs_open(filename
, "r")))
506 res
= sol_load_head(fin
, fp
);
512 void sol_free_base(struct s_base
*fp
)
514 if (fp
->av
) free(fp
->av
);
515 if (fp
->mv
) free(fp
->mv
);
516 if (fp
->vv
) free(fp
->vv
);
517 if (fp
->ev
) free(fp
->ev
);
518 if (fp
->sv
) free(fp
->sv
);
519 if (fp
->tv
) free(fp
->tv
);
520 if (fp
->ov
) free(fp
->ov
);
521 if (fp
->gv
) free(fp
->gv
);
522 if (fp
->lv
) free(fp
->lv
);
523 if (fp
->nv
) free(fp
->nv
);
524 if (fp
->pv
) free(fp
->pv
);
525 if (fp
->bv
) free(fp
->bv
);
526 if (fp
->hv
) free(fp
->hv
);
527 if (fp
->zv
) free(fp
->zv
);
528 if (fp
->jv
) free(fp
->jv
);
529 if (fp
->xv
) free(fp
->xv
);
530 if (fp
->rv
) free(fp
->rv
);
531 if (fp
->uv
) free(fp
->uv
);
532 if (fp
->wv
) free(fp
->wv
);
533 if (fp
->dv
) free(fp
->dv
);
534 if (fp
->iv
) free(fp
->iv
);
536 memset(fp
, 0, sizeof (*fp
));
539 /*---------------------------------------------------------------------------*/
541 static void sol_stor_mtrl(fs_file fout
, struct b_mtrl
*mp
)
543 put_array(fout
, mp
->d
, 4);
544 put_array(fout
, mp
->a
, 4);
545 put_array(fout
, mp
->s
, 4);
546 put_array(fout
, mp
->e
, 4);
547 put_array(fout
, mp
->h
, 1);
548 put_index(fout
, mp
->fl
);
550 fs_write(mp
->f
, 1, PATHMAX
, fout
);
552 if (mp
->fl
& M_ALPHA_TEST
)
554 put_index(fout
, mp
->alpha_func
);
555 put_float(fout
, mp
->alpha_ref
);
559 static void sol_stor_vert(fs_file fout
, struct b_vert
*vp
)
561 put_array(fout
, vp
->p
, 3);
564 static void sol_stor_edge(fs_file fout
, struct b_edge
*ep
)
566 put_index(fout
, ep
->vi
);
567 put_index(fout
, ep
->vj
);
570 static void sol_stor_side(fs_file fout
, struct b_side
*sp
)
572 put_array(fout
, sp
->n
, 3);
573 put_float(fout
, sp
->d
);
576 static void sol_stor_texc(fs_file fout
, struct b_texc
*tp
)
578 put_array(fout
, tp
->u
, 2);
581 static void sol_stor_offs(fs_file fout
, struct b_offs
*op
)
583 put_index(fout
, op
->ti
);
584 put_index(fout
, op
->si
);
585 put_index(fout
, op
->vi
);
588 static void sol_stor_geom(fs_file fout
, struct b_geom
*gp
)
590 put_index(fout
, gp
->mi
);
591 put_index(fout
, gp
->oi
);
592 put_index(fout
, gp
->oj
);
593 put_index(fout
, gp
->ok
);
596 static void sol_stor_lump(fs_file fout
, struct b_lump
*lp
)
598 put_index(fout
, lp
->fl
);
599 put_index(fout
, lp
->v0
);
600 put_index(fout
, lp
->vc
);
601 put_index(fout
, lp
->e0
);
602 put_index(fout
, lp
->ec
);
603 put_index(fout
, lp
->g0
);
604 put_index(fout
, lp
->gc
);
605 put_index(fout
, lp
->s0
);
606 put_index(fout
, lp
->sc
);
609 static void sol_stor_node(fs_file fout
, struct b_node
*np
)
611 put_index(fout
, np
->si
);
612 put_index(fout
, np
->ni
);
613 put_index(fout
, np
->nj
);
614 put_index(fout
, np
->l0
);
615 put_index(fout
, np
->lc
);
618 static void sol_stor_path(fs_file fout
, struct b_path
*pp
)
620 put_array(fout
, pp
->p
, 3);
621 put_float(fout
, pp
->t
);
622 put_index(fout
, pp
->pi
);
623 put_index(fout
, pp
->f
);
624 put_index(fout
, pp
->s
);
625 put_index(fout
, pp
->fl
);
627 if (pp
->fl
& P_ORIENTED
)
628 put_array(fout
, pp
->e
, 4);
631 static void sol_stor_body(fs_file fout
, struct b_body
*bp
)
633 put_index(fout
, bp
->pi
);
634 put_index(fout
, bp
->pj
);
635 put_index(fout
, bp
->ni
);
636 put_index(fout
, bp
->l0
);
637 put_index(fout
, bp
->lc
);
638 put_index(fout
, bp
->g0
);
639 put_index(fout
, bp
->gc
);
642 static void sol_stor_item(fs_file fout
, struct b_item
*hp
)
644 put_array(fout
, hp
->p
, 3);
645 put_index(fout
, hp
->t
);
646 put_index(fout
, hp
->n
);
649 static void sol_stor_goal(fs_file fout
, struct b_goal
*zp
)
651 put_array(fout
, zp
->p
, 3);
652 put_float(fout
, zp
->r
);
655 static void sol_stor_swch(fs_file fout
, struct b_swch
*xp
)
657 put_array(fout
, xp
->p
, 3);
658 put_float(fout
, xp
->r
);
659 put_index(fout
, xp
->pi
);
660 put_float(fout
, xp
->t
);
661 put_float(fout
, xp
->t
);
662 put_index(fout
, xp
->f
);
663 put_index(fout
, xp
->f
);
664 put_index(fout
, xp
->i
);
667 static void sol_stor_bill(fs_file fout
, struct b_bill
*rp
)
669 put_index(fout
, rp
->fl
);
670 put_index(fout
, rp
->mi
);
671 put_float(fout
, rp
->t
);
672 put_float(fout
, rp
->d
);
673 put_array(fout
, rp
->w
, 3);
674 put_array(fout
, rp
->h
, 3);
675 put_array(fout
, rp
->rx
, 3);
676 put_array(fout
, rp
->ry
, 3);
677 put_array(fout
, rp
->rz
, 3);
678 put_array(fout
, rp
->p
, 3);
681 static void sol_stor_jump(fs_file fout
, struct b_jump
*jp
)
683 put_array(fout
, jp
->p
, 3);
684 put_array(fout
, jp
->q
, 3);
685 put_float(fout
, jp
->r
);
688 static void sol_stor_ball(fs_file fout
, struct b_ball
*bp
)
690 put_array(fout
, bp
->p
, 3);
691 put_float(fout
, bp
->r
);
694 static void sol_stor_view(fs_file fout
, struct b_view
*wp
)
696 put_array(fout
, wp
->p
, 3);
697 put_array(fout
, wp
->q
, 3);
700 static void sol_stor_dict(fs_file fout
, struct b_dict
*dp
)
702 put_index(fout
, dp
->ai
);
703 put_index(fout
, dp
->aj
);
706 static void sol_stor_file(fs_file fout
, struct s_base
*fp
)
709 int magic
= SOL_MAGIC
;
710 int version
= SOL_VERSION_CURR
;
712 put_index(fout
, magic
);
713 put_index(fout
, version
);
715 put_index(fout
, fp
->ac
);
716 put_index(fout
, fp
->dc
);
717 put_index(fout
, fp
->mc
);
718 put_index(fout
, fp
->vc
);
719 put_index(fout
, fp
->ec
);
720 put_index(fout
, fp
->sc
);
721 put_index(fout
, fp
->tc
);
722 put_index(fout
, fp
->oc
);
723 put_index(fout
, fp
->gc
);
724 put_index(fout
, fp
->lc
);
725 put_index(fout
, fp
->nc
);
726 put_index(fout
, fp
->pc
);
727 put_index(fout
, fp
->bc
);
728 put_index(fout
, fp
->hc
);
729 put_index(fout
, fp
->zc
);
730 put_index(fout
, fp
->jc
);
731 put_index(fout
, fp
->xc
);
732 put_index(fout
, fp
->rc
);
733 put_index(fout
, fp
->uc
);
734 put_index(fout
, fp
->wc
);
735 put_index(fout
, fp
->ic
);
737 fs_write(fp
->av
, 1, fp
->ac
, fout
);
739 for (i
= 0; i
< fp
->dc
; i
++) sol_stor_dict(fout
, fp
->dv
+ i
);
740 for (i
= 0; i
< fp
->mc
; i
++) sol_stor_mtrl(fout
, fp
->mv
+ i
);
741 for (i
= 0; i
< fp
->vc
; i
++) sol_stor_vert(fout
, fp
->vv
+ i
);
742 for (i
= 0; i
< fp
->ec
; i
++) sol_stor_edge(fout
, fp
->ev
+ i
);
743 for (i
= 0; i
< fp
->sc
; i
++) sol_stor_side(fout
, fp
->sv
+ i
);
744 for (i
= 0; i
< fp
->tc
; i
++) sol_stor_texc(fout
, fp
->tv
+ i
);
745 for (i
= 0; i
< fp
->oc
; i
++) sol_stor_offs(fout
, fp
->ov
+ i
);
746 for (i
= 0; i
< fp
->gc
; i
++) sol_stor_geom(fout
, fp
->gv
+ i
);
747 for (i
= 0; i
< fp
->lc
; i
++) sol_stor_lump(fout
, fp
->lv
+ i
);
748 for (i
= 0; i
< fp
->nc
; i
++) sol_stor_node(fout
, fp
->nv
+ i
);
749 for (i
= 0; i
< fp
->pc
; i
++) sol_stor_path(fout
, fp
->pv
+ i
);
750 for (i
= 0; i
< fp
->bc
; i
++) sol_stor_body(fout
, fp
->bv
+ i
);
751 for (i
= 0; i
< fp
->hc
; i
++) sol_stor_item(fout
, fp
->hv
+ i
);
752 for (i
= 0; i
< fp
->zc
; i
++) sol_stor_goal(fout
, fp
->zv
+ i
);
753 for (i
= 0; i
< fp
->jc
; i
++) sol_stor_jump(fout
, fp
->jv
+ i
);
754 for (i
= 0; i
< fp
->xc
; i
++) sol_stor_swch(fout
, fp
->xv
+ i
);
755 for (i
= 0; i
< fp
->rc
; i
++) sol_stor_bill(fout
, fp
->rv
+ i
);
756 for (i
= 0; i
< fp
->uc
; i
++) sol_stor_ball(fout
, fp
->uv
+ i
);
757 for (i
= 0; i
< fp
->wc
; i
++) sol_stor_view(fout
, fp
->wv
+ i
);
758 for (i
= 0; i
< fp
->ic
; i
++) put_index(fout
, fp
->iv
[i
]);
761 int sol_stor_base(struct s_base
*fp
, const char *filename
)
765 if ((fout
= fs_open(filename
, "w")))
767 sol_stor_file(fout
, fp
);
775 /*---------------------------------------------------------------------------*/
777 const struct path tex_paths
[4] = {
778 { "textures/", ".png" },
779 { "textures/", ".jpg" },
784 const struct path mtrl_paths
[2] = {
789 /*---------------------------------------------------------------------------*/
792 * This has to match up with mtrl_func_syms in mtrl.c.
794 static const char mtrl_func_names
[8][16] = {
810 { "additive", M_ADDITIVE
},
811 { "clamp-s", M_CLAMP_S
},
812 { "clamp-t", M_CLAMP_T
},
813 { "decal", M_DECAL
},
814 { "environment", M_ENVIRONMENT
},
815 { "reflective", M_REFLECTIVE
},
816 { "shadowed", M_SHADOWED
},
817 { "transparent", M_TRANSPARENT
},
818 { "two-sided", M_TWO_SIDED
},
819 { "particle", M_PARTICLE
},
822 int mtrl_read(struct b_mtrl
*mp
, const char *name
)
824 static char line
[MAXSTR
];
825 static char word
[MAXSTR
];
830 if (mp
&& name
&& *name
)
832 SAFECPY(mp
->f
, name
);
834 mp
->a
[0] = mp
->a
[1] = mp
->a
[2] = 0.2f
;
835 mp
->d
[0] = mp
->d
[1] = mp
->d
[2] = 0.8f
;
836 mp
->s
[0] = mp
->s
[1] = mp
->s
[2] = 0.0f
;
837 mp
->e
[0] = mp
->e
[1] = mp
->e
[2] = 0.0f
;
838 mp
->a
[3] = mp
->d
[3] = mp
->s
[3] = mp
->e
[3] = 1.0f
;
844 mp
->alpha_ref
= 0.0f
;
848 for (i
= 0; i
< ARRAYSIZE(mtrl_paths
); i
++)
850 CONCAT_PATH(line
, &mtrl_paths
[i
], name
);
852 if ((fp
= fs_open(line
, "r")))
860 while (fs_gets(line
, sizeof (line
), fp
))
862 char *p
= strip_newline(line
);
864 if (sscanf(p
, "diffuse %f %f %f %f",
865 &mp
->d
[0], &mp
->d
[1],
866 &mp
->d
[2], &mp
->d
[3]) == 4)
869 else if (sscanf(p
, "ambient %f %f %f %f",
870 &mp
->a
[0], &mp
->a
[1],
871 &mp
->a
[2], &mp
->a
[3]) == 4)
874 else if (sscanf(p
, "specular %f %f %f %f",
875 &mp
->s
[0], &mp
->s
[1],
876 &mp
->s
[2], &mp
->s
[3]) == 4)
879 else if (sscanf(p
, "emissive %f %f %f %f",
880 &mp
->e
[0], &mp
->e
[1],
881 &mp
->e
[2], &mp
->e
[3]) == 4)
884 else if (sscanf(p
, "shininess %f", &mp
->h
[0]) == 1)
887 else if (strncmp(p
, "flags ", 6) == 0)
894 while (sscanf(p
, "%s%n", word
, &n
) > 0)
896 for (i
= 0; i
< ARRAYSIZE(mtrl_flags
); i
++)
897 if (strcmp(word
, mtrl_flags
[i
].name
) == 0)
899 f
|= mtrl_flags
[i
].flag
;
908 else if (sscanf(p
, "angle %f", &mp
->angle
) == 1)
911 else if (sscanf(p
, "alpha-test %15s %f",
912 str
, &mp
->alpha_ref
) == 2)
914 mp
->fl
|= M_ALPHA_TEST
;
916 for (i
= 0; i
< ARRAYSIZE(mtrl_func_names
); i
++)
917 if (strcmp(str
, mtrl_func_names
[i
]) == 0)
923 else /* Unknown directive */;
929 else /* Unknown material */;
934 /*---------------------------------------------------------------------------*/