1*d86ed7fbStbbdev /*
2*d86ed7fbStbbdev     Copyright (c) 2005-2020 Intel Corporation
3*d86ed7fbStbbdev 
4*d86ed7fbStbbdev     Licensed under the Apache License, Version 2.0 (the "License");
5*d86ed7fbStbbdev     you may not use this file except in compliance with the License.
6*d86ed7fbStbbdev     You may obtain a copy of the License at
7*d86ed7fbStbbdev 
8*d86ed7fbStbbdev         http://www.apache.org/licenses/LICENSE-2.0
9*d86ed7fbStbbdev 
10*d86ed7fbStbbdev     Unless required by applicable law or agreed to in writing, software
11*d86ed7fbStbbdev     distributed under the License is distributed on an "AS IS" BASIS,
12*d86ed7fbStbbdev     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*d86ed7fbStbbdev     See the License for the specific language governing permissions and
14*d86ed7fbStbbdev     limitations under the License.
15*d86ed7fbStbbdev */
16*d86ed7fbStbbdev 
17*d86ed7fbStbbdev /*
18*d86ed7fbStbbdev     The original source for this example is
19*d86ed7fbStbbdev     Copyright (c) 1994-2008 John E. Stone
20*d86ed7fbStbbdev     All rights reserved.
21*d86ed7fbStbbdev 
22*d86ed7fbStbbdev     Redistribution and use in source and binary forms, with or without
23*d86ed7fbStbbdev     modification, are permitted provided that the following conditions
24*d86ed7fbStbbdev     are met:
25*d86ed7fbStbbdev     1. Redistributions of source code must retain the above copyright
26*d86ed7fbStbbdev        notice, this list of conditions and the following disclaimer.
27*d86ed7fbStbbdev     2. Redistributions in binary form must reproduce the above copyright
28*d86ed7fbStbbdev        notice, this list of conditions and the following disclaimer in the
29*d86ed7fbStbbdev        documentation and/or other materials provided with the distribution.
30*d86ed7fbStbbdev     3. The name of the author may not be used to endorse or promote products
31*d86ed7fbStbbdev        derived from this software without specific prior written permission.
32*d86ed7fbStbbdev 
33*d86ed7fbStbbdev     THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
34*d86ed7fbStbbdev     OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
35*d86ed7fbStbbdev     WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
36*d86ed7fbStbbdev     ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
37*d86ed7fbStbbdev     DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
38*d86ed7fbStbbdev     DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
39*d86ed7fbStbbdev     OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
40*d86ed7fbStbbdev     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
41*d86ed7fbStbbdev     LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
42*d86ed7fbStbbdev     OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
43*d86ed7fbStbbdev     SUCH DAMAGE.
44*d86ed7fbStbbdev */
45*d86ed7fbStbbdev 
46*d86ed7fbStbbdev /*
47*d86ed7fbStbbdev  * parse.cpp - an UltraLame (tm) parser for simple data files...
48*d86ed7fbStbbdev  */
49*d86ed7fbStbbdev 
50*d86ed7fbStbbdev // Try preventing lots of GCC warnings about ignored results of fscanf etc.
51*d86ed7fbStbbdev #ifdef __GNUC__
52*d86ed7fbStbbdev // Starting from 4.5, GCC has a suppression option
53*d86ed7fbStbbdev #pragma GCC diagnostic ignored "-Wunused-result"
54*d86ed7fbStbbdev #endif
55*d86ed7fbStbbdev 
56*d86ed7fbStbbdev #include <cstdio>
57*d86ed7fbStbbdev #include <cmath>
58*d86ed7fbStbbdev #include <cstring>
59*d86ed7fbStbbdev #include <cstdlib>
60*d86ed7fbStbbdev #include <cctype> /* needed for toupper(), macro.. */
61*d86ed7fbStbbdev 
62*d86ed7fbStbbdev #include "types.hpp"
63*d86ed7fbStbbdev #include "api.hpp" /* rendering API */
64*d86ed7fbStbbdev 
65*d86ed7fbStbbdev #define PARSE_INTERNAL
66*d86ed7fbStbbdev #include "parse.hpp" /* self protos */
67*d86ed7fbStbbdev #undef PARSE_INTERNAL
68*d86ed7fbStbbdev 
69*d86ed7fbStbbdev static texentry textable[NUMTEXS]; /* texture lookup table */
70*d86ed7fbStbbdev static texentry defaulttex; /* The default texture when a lookup fails */
71*d86ed7fbStbbdev static int numtextures; /* number of TEXDEF textures */
72*d86ed7fbStbbdev static int numobjectsparsed; /* total number of objects parsed so far */
73*d86ed7fbStbbdev static color scenebackcol; /* scene background color */
74*d86ed7fbStbbdev 
75*d86ed7fbStbbdev static int stringcmp(const char *a, const char *b) {
76*d86ed7fbStbbdev     std::size_t i, s, l;
77*d86ed7fbStbbdev 
78*d86ed7fbStbbdev     s = strlen(a);
79*d86ed7fbStbbdev     l = strlen(b);
80*d86ed7fbStbbdev 
81*d86ed7fbStbbdev     if (s != l)
82*d86ed7fbStbbdev         return 1;
83*d86ed7fbStbbdev 
84*d86ed7fbStbbdev     for (i = 0; i < s; i++) {
85*d86ed7fbStbbdev         if (toupper(a[i]) != toupper(b[i])) {
86*d86ed7fbStbbdev             return 1;
87*d86ed7fbStbbdev         }
88*d86ed7fbStbbdev     }
89*d86ed7fbStbbdev     return 0;
90*d86ed7fbStbbdev }
91*d86ed7fbStbbdev 
92*d86ed7fbStbbdev static void reset_tex_table(void) {
93*d86ed7fbStbbdev     apitexture apitex;
94*d86ed7fbStbbdev 
95*d86ed7fbStbbdev     numtextures = 0;
96*d86ed7fbStbbdev     memset(&textable, 0, sizeof(textable));
97*d86ed7fbStbbdev 
98*d86ed7fbStbbdev     apitex.col.r = 1.0;
99*d86ed7fbStbbdev     apitex.col.g = 1.0;
100*d86ed7fbStbbdev     apitex.col.b = 1.0;
101*d86ed7fbStbbdev     apitex.ambient = 0.1;
102*d86ed7fbStbbdev     apitex.diffuse = 0.9;
103*d86ed7fbStbbdev     apitex.specular = 0.0;
104*d86ed7fbStbbdev     apitex.opacity = 1.0;
105*d86ed7fbStbbdev     apitex.texturefunc = 0;
106*d86ed7fbStbbdev 
107*d86ed7fbStbbdev     defaulttex.tex = rt_texture(&apitex);
108*d86ed7fbStbbdev }
109*d86ed7fbStbbdev 
110*d86ed7fbStbbdev static errcode add_texture(void *tex, char name[TEXNAMELEN]) {
111*d86ed7fbStbbdev     textable[numtextures].tex = tex;
112*d86ed7fbStbbdev     strcpy(textable[numtextures].name, name);
113*d86ed7fbStbbdev 
114*d86ed7fbStbbdev     numtextures++;
115*d86ed7fbStbbdev     if (numtextures > NUMTEXS) {
116*d86ed7fbStbbdev         fprintf(stderr, "Parse: %d textures allocated, texture slots full!\n", numtextures);
117*d86ed7fbStbbdev         numtextures--; /* keep writing over last texture if we've run out.. */
118*d86ed7fbStbbdev         return PARSEALLOCERR;
119*d86ed7fbStbbdev     }
120*d86ed7fbStbbdev 
121*d86ed7fbStbbdev     return PARSENOERR;
122*d86ed7fbStbbdev }
123*d86ed7fbStbbdev 
124*d86ed7fbStbbdev static void *find_texture(char name[TEXNAMELEN]) {
125*d86ed7fbStbbdev     int i;
126*d86ed7fbStbbdev 
127*d86ed7fbStbbdev     for (i = 0; i < numtextures; i++) {
128*d86ed7fbStbbdev         if (strcmp(name, textable[i].name) == 0)
129*d86ed7fbStbbdev             return textable[i].tex;
130*d86ed7fbStbbdev     }
131*d86ed7fbStbbdev     fprintf(stderr, "Undefined texture '%s', using default. \n", name);
132*d86ed7fbStbbdev     return (defaulttex.tex);
133*d86ed7fbStbbdev }
134*d86ed7fbStbbdev 
135*d86ed7fbStbbdev apiflt degtorad(apiflt deg) {
136*d86ed7fbStbbdev     apiflt tmp;
137*d86ed7fbStbbdev     tmp = deg * 3.1415926 / 180.0;
138*d86ed7fbStbbdev     return tmp;
139*d86ed7fbStbbdev }
140*d86ed7fbStbbdev 
141*d86ed7fbStbbdev static void degvectoradvec(vector *degvec) {
142*d86ed7fbStbbdev     vector tmp;
143*d86ed7fbStbbdev 
144*d86ed7fbStbbdev     tmp.x = degtorad(degvec->x);
145*d86ed7fbStbbdev     tmp.y = degtorad(degvec->y);
146*d86ed7fbStbbdev     tmp.z = degtorad(degvec->z);
147*d86ed7fbStbbdev     *degvec = tmp;
148*d86ed7fbStbbdev }
149*d86ed7fbStbbdev 
150*d86ed7fbStbbdev static void InitRot3d(RotMat *rot, apiflt x, apiflt y, apiflt z) {
151*d86ed7fbStbbdev     rot->rx1 = cos(y) * cos(z);
152*d86ed7fbStbbdev     rot->rx2 = sin(x) * sin(y) * cos(z) - cos(x) * sin(z);
153*d86ed7fbStbbdev     rot->rx3 = sin(x) * sin(z) + cos(x) * cos(z) * sin(y);
154*d86ed7fbStbbdev 
155*d86ed7fbStbbdev     rot->ry1 = cos(y) * sin(z);
156*d86ed7fbStbbdev     rot->ry2 = cos(x) * cos(z) + sin(x) * sin(y) * sin(z);
157*d86ed7fbStbbdev     rot->ry3 = cos(x) * sin(y) * sin(z) - sin(x) * cos(z);
158*d86ed7fbStbbdev 
159*d86ed7fbStbbdev     rot->rz1 = sin(y);
160*d86ed7fbStbbdev     rot->rz2 = sin(x) * cos(y);
161*d86ed7fbStbbdev     rot->rz3 = cos(x) * cos(y);
162*d86ed7fbStbbdev }
163*d86ed7fbStbbdev 
164*d86ed7fbStbbdev static void Rotate3d(RotMat *rot, vector *vec) {
165*d86ed7fbStbbdev     vector tmp;
166*d86ed7fbStbbdev     tmp.x = (vec->x * (rot->rx1) + vec->y * (rot->rx2) + vec->z * (rot->rx3));
167*d86ed7fbStbbdev     tmp.y = (vec->x * (rot->ry1) + vec->y * (rot->ry2) + vec->z * (rot->ry3));
168*d86ed7fbStbbdev     tmp.z = (vec->x * (rot->rz1) + vec->y * (rot->rz2) + vec->z * (rot->rz3));
169*d86ed7fbStbbdev     *vec = tmp;
170*d86ed7fbStbbdev }
171*d86ed7fbStbbdev 
172*d86ed7fbStbbdev static void Scale3d(vector *scale, vector *vec) {
173*d86ed7fbStbbdev     vec->x = vec->x * scale->x;
174*d86ed7fbStbbdev     vec->y = vec->y * scale->y;
175*d86ed7fbStbbdev     vec->z = vec->z * scale->z;
176*d86ed7fbStbbdev }
177*d86ed7fbStbbdev 
178*d86ed7fbStbbdev static void Trans3d(vector *trans, vector *vec) {
179*d86ed7fbStbbdev     vec->x += trans->x;
180*d86ed7fbStbbdev     vec->y += trans->y;
181*d86ed7fbStbbdev     vec->z += trans->z;
182*d86ed7fbStbbdev }
183*d86ed7fbStbbdev 
184*d86ed7fbStbbdev static errcode GetString(FILE *dfile, const char *string) {
185*d86ed7fbStbbdev     char data[255];
186*d86ed7fbStbbdev 
187*d86ed7fbStbbdev     fscanf(dfile, "%s", data);
188*d86ed7fbStbbdev     if (stringcmp(data, string) != 0) {
189*d86ed7fbStbbdev         fprintf(stderr, "parse: Expected %s, got %s \n", string, data);
190*d86ed7fbStbbdev         fprintf(stderr, "parse: Error while parsing object: %d \n", numobjectsparsed);
191*d86ed7fbStbbdev         return PARSEBADSYNTAX;
192*d86ed7fbStbbdev     }
193*d86ed7fbStbbdev 
194*d86ed7fbStbbdev     return PARSENOERR;
195*d86ed7fbStbbdev }
196*d86ed7fbStbbdev 
197*d86ed7fbStbbdev unsigned int readmodel(char *modelfile, SceneHandle scene) {
198*d86ed7fbStbbdev     FILE *dfile;
199*d86ed7fbStbbdev     errcode rc;
200*d86ed7fbStbbdev 
201*d86ed7fbStbbdev     reset_tex_table();
202*d86ed7fbStbbdev     dfile = nullptr;
203*d86ed7fbStbbdev 
204*d86ed7fbStbbdev     dfile = fopen(modelfile, "r");
205*d86ed7fbStbbdev     if (dfile == nullptr) {
206*d86ed7fbStbbdev         return PARSEBADFILE;
207*d86ed7fbStbbdev     }
208*d86ed7fbStbbdev 
209*d86ed7fbStbbdev     rc = GetScenedefs(dfile, scene);
210*d86ed7fbStbbdev     if (rc != PARSENOERR) {
211*d86ed7fbStbbdev         fclose(dfile);
212*d86ed7fbStbbdev         return rc;
213*d86ed7fbStbbdev     }
214*d86ed7fbStbbdev 
215*d86ed7fbStbbdev     scenebackcol.r = 0.0; /* default background is black */
216*d86ed7fbStbbdev     scenebackcol.g = 0.0;
217*d86ed7fbStbbdev     scenebackcol.b = 0.0;
218*d86ed7fbStbbdev 
219*d86ed7fbStbbdev     numobjectsparsed = 0;
220*d86ed7fbStbbdev     while ((rc = GetObject(dfile, scene)) == PARSENOERR) {
221*d86ed7fbStbbdev         numobjectsparsed++;
222*d86ed7fbStbbdev     }
223*d86ed7fbStbbdev     fclose(dfile);
224*d86ed7fbStbbdev 
225*d86ed7fbStbbdev     if (rc == PARSEEOF)
226*d86ed7fbStbbdev         rc = PARSENOERR;
227*d86ed7fbStbbdev 
228*d86ed7fbStbbdev     rt_background(scene, scenebackcol);
229*d86ed7fbStbbdev 
230*d86ed7fbStbbdev     return rc;
231*d86ed7fbStbbdev }
232*d86ed7fbStbbdev 
233*d86ed7fbStbbdev static errcode GetScenedefs(FILE *dfile, SceneHandle scene) {
234*d86ed7fbStbbdev     vector Ccenter, Cview, Cup;
235*d86ed7fbStbbdev     apiflt zoom, aspectratio;
236*d86ed7fbStbbdev     int raydepth, antialiasing;
237*d86ed7fbStbbdev     char outfilename[200];
238*d86ed7fbStbbdev     int xres, yres, verbose;
239*d86ed7fbStbbdev     float a, b, c;
240*d86ed7fbStbbdev     errcode rc = PARSENOERR;
241*d86ed7fbStbbdev 
242*d86ed7fbStbbdev     rc |= GetString(dfile, "BEGIN_SCENE");
243*d86ed7fbStbbdev 
244*d86ed7fbStbbdev     rc |= GetString(dfile, "OUTFILE");
245*d86ed7fbStbbdev     fscanf(dfile, "%s", outfilename);
246*d86ed7fbStbbdev #ifdef _WIN32
247*d86ed7fbStbbdev     if (strcmp(outfilename, "/dev/null") == 0) {
248*d86ed7fbStbbdev         strcpy(outfilename, "NUL:");
249*d86ed7fbStbbdev     }
250*d86ed7fbStbbdev #endif
251*d86ed7fbStbbdev 
252*d86ed7fbStbbdev     rc |= GetString(dfile, "RESOLUTION");
253*d86ed7fbStbbdev     fscanf(dfile, "%d %d", &xres, &yres);
254*d86ed7fbStbbdev 
255*d86ed7fbStbbdev     rc |= GetString(dfile, "VERBOSE");
256*d86ed7fbStbbdev     fscanf(dfile, "%d", &verbose);
257*d86ed7fbStbbdev 
258*d86ed7fbStbbdev     rt_scenesetup(scene, outfilename, xres, yres, verbose);
259*d86ed7fbStbbdev 
260*d86ed7fbStbbdev     rc |= GetString(dfile, "CAMERA");
261*d86ed7fbStbbdev 
262*d86ed7fbStbbdev     rc |= GetString(dfile, "ZOOM");
263*d86ed7fbStbbdev     fscanf(dfile, "%f", &a);
264*d86ed7fbStbbdev     zoom = a;
265*d86ed7fbStbbdev 
266*d86ed7fbStbbdev     rc |= GetString(dfile, "ASPECTRATIO");
267*d86ed7fbStbbdev     fscanf(dfile, "%f", &b);
268*d86ed7fbStbbdev     aspectratio = b;
269*d86ed7fbStbbdev 
270*d86ed7fbStbbdev     rc |= GetString(dfile, "ANTIALIASING");
271*d86ed7fbStbbdev     fscanf(dfile, "%d", &antialiasing);
272*d86ed7fbStbbdev 
273*d86ed7fbStbbdev     rc |= GetString(dfile, "RAYDEPTH");
274*d86ed7fbStbbdev     fscanf(dfile, "%d", &raydepth);
275*d86ed7fbStbbdev 
276*d86ed7fbStbbdev     rc |= GetString(dfile, "CENTER");
277*d86ed7fbStbbdev     fscanf(dfile, "%f %f %f", &a, &b, &c);
278*d86ed7fbStbbdev     Ccenter.x = a;
279*d86ed7fbStbbdev     Ccenter.y = b;
280*d86ed7fbStbbdev     Ccenter.z = c;
281*d86ed7fbStbbdev 
282*d86ed7fbStbbdev     rc |= GetString(dfile, "VIEWDIR");
283*d86ed7fbStbbdev     fscanf(dfile, "%f %f %f", &a, &b, &c);
284*d86ed7fbStbbdev     Cview.x = a;
285*d86ed7fbStbbdev     Cview.y = b;
286*d86ed7fbStbbdev     Cview.z = c;
287*d86ed7fbStbbdev 
288*d86ed7fbStbbdev     rc |= GetString(dfile, "UPDIR");
289*d86ed7fbStbbdev     fscanf(dfile, "%f %f %f", &a, &b, &c);
290*d86ed7fbStbbdev     Cup.x = a;
291*d86ed7fbStbbdev     Cup.y = b;
292*d86ed7fbStbbdev     Cup.z = c;
293*d86ed7fbStbbdev 
294*d86ed7fbStbbdev     rc |= GetString(dfile, "END_CAMERA");
295*d86ed7fbStbbdev 
296*d86ed7fbStbbdev     rt_camerasetup(scene, zoom, aspectratio, antialiasing, raydepth, Ccenter, Cview, Cup);
297*d86ed7fbStbbdev 
298*d86ed7fbStbbdev     return rc;
299*d86ed7fbStbbdev }
300*d86ed7fbStbbdev 
301*d86ed7fbStbbdev static errcode GetObject(FILE *dfile, SceneHandle scene) {
302*d86ed7fbStbbdev     char objtype[80];
303*d86ed7fbStbbdev 
304*d86ed7fbStbbdev     fscanf(dfile, "%s", objtype);
305*d86ed7fbStbbdev     if (!stringcmp(objtype, "END_SCENE")) {
306*d86ed7fbStbbdev         return PARSEEOF; /* end parsing */
307*d86ed7fbStbbdev     }
308*d86ed7fbStbbdev     if (!stringcmp(objtype, "TEXDEF")) {
309*d86ed7fbStbbdev         return GetTexDef(dfile);
310*d86ed7fbStbbdev     }
311*d86ed7fbStbbdev     if (!stringcmp(objtype, "TEXALIAS")) {
312*d86ed7fbStbbdev         return GetTexAlias(dfile);
313*d86ed7fbStbbdev     }
314*d86ed7fbStbbdev     if (!stringcmp(objtype, "BACKGROUND")) {
315*d86ed7fbStbbdev         return GetBackGnd(dfile);
316*d86ed7fbStbbdev     }
317*d86ed7fbStbbdev     if (!stringcmp(objtype, "CYLINDER")) {
318*d86ed7fbStbbdev         return GetCylinder(dfile);
319*d86ed7fbStbbdev     }
320*d86ed7fbStbbdev     if (!stringcmp(objtype, "FCYLINDER")) {
321*d86ed7fbStbbdev         return GetFCylinder(dfile);
322*d86ed7fbStbbdev     }
323*d86ed7fbStbbdev     if (!stringcmp(objtype, "POLYCYLINDER")) {
324*d86ed7fbStbbdev         return GetPolyCylinder(dfile);
325*d86ed7fbStbbdev     }
326*d86ed7fbStbbdev     if (!stringcmp(objtype, "SPHERE")) {
327*d86ed7fbStbbdev         return GetSphere(dfile);
328*d86ed7fbStbbdev     }
329*d86ed7fbStbbdev     if (!stringcmp(objtype, "PLANE")) {
330*d86ed7fbStbbdev         return GetPlane(dfile);
331*d86ed7fbStbbdev     }
332*d86ed7fbStbbdev     if (!stringcmp(objtype, "RING")) {
333*d86ed7fbStbbdev         return GetRing(dfile);
334*d86ed7fbStbbdev     }
335*d86ed7fbStbbdev     if (!stringcmp(objtype, "BOX")) {
336*d86ed7fbStbbdev         return GetBox(dfile);
337*d86ed7fbStbbdev     }
338*d86ed7fbStbbdev     if (!stringcmp(objtype, "SCALARVOL")) {
339*d86ed7fbStbbdev         return GetVol(dfile);
340*d86ed7fbStbbdev     }
341*d86ed7fbStbbdev     if (!stringcmp(objtype, "TRI")) {
342*d86ed7fbStbbdev         return GetTri(dfile);
343*d86ed7fbStbbdev     }
344*d86ed7fbStbbdev     if (!stringcmp(objtype, "STRI")) {
345*d86ed7fbStbbdev         return GetSTri(dfile);
346*d86ed7fbStbbdev     }
347*d86ed7fbStbbdev     if (!stringcmp(objtype, "LIGHT")) {
348*d86ed7fbStbbdev         return GetLight(dfile);
349*d86ed7fbStbbdev     }
350*d86ed7fbStbbdev     if (!stringcmp(objtype, "SCAPE")) {
351*d86ed7fbStbbdev         return GetLandScape(dfile);
352*d86ed7fbStbbdev     }
353*d86ed7fbStbbdev     if (!stringcmp(objtype, "TPOLYFILE")) {
354*d86ed7fbStbbdev         return GetTPolyFile(dfile);
355*d86ed7fbStbbdev     }
356*d86ed7fbStbbdev 
357*d86ed7fbStbbdev     fprintf(stderr, "Found bad token: %s expected an object type\n", objtype);
358*d86ed7fbStbbdev     return PARSEBADSYNTAX;
359*d86ed7fbStbbdev }
360*d86ed7fbStbbdev 
361*d86ed7fbStbbdev static errcode GetVector(FILE *dfile, vector *v1) {
362*d86ed7fbStbbdev     float a, b, c;
363*d86ed7fbStbbdev 
364*d86ed7fbStbbdev     fscanf(dfile, "%f %f %f", &a, &b, &c);
365*d86ed7fbStbbdev     v1->x = a;
366*d86ed7fbStbbdev     v1->y = b;
367*d86ed7fbStbbdev     v1->z = c;
368*d86ed7fbStbbdev 
369*d86ed7fbStbbdev     return PARSENOERR;
370*d86ed7fbStbbdev }
371*d86ed7fbStbbdev 
372*d86ed7fbStbbdev static errcode GetColor(FILE *dfile, color *c1) {
373*d86ed7fbStbbdev     float r, g, b;
374*d86ed7fbStbbdev     int rc;
375*d86ed7fbStbbdev 
376*d86ed7fbStbbdev     rc = GetString(dfile, "COLOR");
377*d86ed7fbStbbdev     fscanf(dfile, "%f %f %f", &r, &g, &b);
378*d86ed7fbStbbdev     c1->r = r;
379*d86ed7fbStbbdev     c1->g = g;
380*d86ed7fbStbbdev     c1->b = b;
381*d86ed7fbStbbdev 
382*d86ed7fbStbbdev     return rc;
383*d86ed7fbStbbdev }
384*d86ed7fbStbbdev 
385*d86ed7fbStbbdev static errcode GetTexDef(FILE *dfile) {
386*d86ed7fbStbbdev     char texname[TEXNAMELEN];
387*d86ed7fbStbbdev 
388*d86ed7fbStbbdev     fscanf(dfile, "%s", texname);
389*d86ed7fbStbbdev     add_texture(GetTexBody(dfile), texname);
390*d86ed7fbStbbdev 
391*d86ed7fbStbbdev     return PARSENOERR;
392*d86ed7fbStbbdev }
393*d86ed7fbStbbdev 
394*d86ed7fbStbbdev static errcode GetTexAlias(FILE *dfile) {
395*d86ed7fbStbbdev     char texname[TEXNAMELEN];
396*d86ed7fbStbbdev     char aliasname[TEXNAMELEN];
397*d86ed7fbStbbdev 
398*d86ed7fbStbbdev     fscanf(dfile, "%s", texname);
399*d86ed7fbStbbdev     fscanf(dfile, "%s", aliasname);
400*d86ed7fbStbbdev     add_texture(find_texture(aliasname), texname);
401*d86ed7fbStbbdev 
402*d86ed7fbStbbdev     return PARSENOERR;
403*d86ed7fbStbbdev }
404*d86ed7fbStbbdev 
405*d86ed7fbStbbdev static errcode GetTexture(FILE *dfile, void **tex) {
406*d86ed7fbStbbdev     char tmp[255];
407*d86ed7fbStbbdev     errcode rc = PARSENOERR;
408*d86ed7fbStbbdev 
409*d86ed7fbStbbdev     fscanf(dfile, "%s", tmp);
410*d86ed7fbStbbdev     if (!stringcmp("TEXTURE", tmp)) {
411*d86ed7fbStbbdev         *tex = GetTexBody(dfile);
412*d86ed7fbStbbdev     }
413*d86ed7fbStbbdev     else
414*d86ed7fbStbbdev         *tex = find_texture(tmp);
415*d86ed7fbStbbdev 
416*d86ed7fbStbbdev     return rc;
417*d86ed7fbStbbdev }
418*d86ed7fbStbbdev 
419*d86ed7fbStbbdev void *GetTexBody(FILE *dfile) {
420*d86ed7fbStbbdev     char tmp[255];
421*d86ed7fbStbbdev     float a, b, c, d, phong, phongexp, phongtype;
422*d86ed7fbStbbdev     apitexture tex;
423*d86ed7fbStbbdev     void *voidtex;
424*d86ed7fbStbbdev     errcode rc;
425*d86ed7fbStbbdev 
426*d86ed7fbStbbdev     rc = GetString(dfile, "AMBIENT");
427*d86ed7fbStbbdev     fscanf(dfile, "%f", &a);
428*d86ed7fbStbbdev     tex.ambient = a;
429*d86ed7fbStbbdev 
430*d86ed7fbStbbdev     rc |= GetString(dfile, "DIFFUSE");
431*d86ed7fbStbbdev     fscanf(dfile, "%f", &b);
432*d86ed7fbStbbdev     tex.diffuse = b;
433*d86ed7fbStbbdev 
434*d86ed7fbStbbdev     rc |= GetString(dfile, "SPECULAR");
435*d86ed7fbStbbdev     fscanf(dfile, "%f", &c);
436*d86ed7fbStbbdev     tex.specular = c;
437*d86ed7fbStbbdev 
438*d86ed7fbStbbdev     rc |= GetString(dfile, "OPACITY");
439*d86ed7fbStbbdev     fscanf(dfile, "%f", &d);
440*d86ed7fbStbbdev     tex.opacity = d;
441*d86ed7fbStbbdev 
442*d86ed7fbStbbdev     fscanf(dfile, "%s", tmp);
443*d86ed7fbStbbdev     if (!stringcmp("PHONG", tmp)) {
444*d86ed7fbStbbdev         fscanf(dfile, "%s", tmp);
445*d86ed7fbStbbdev         if (!stringcmp("METAL", tmp)) {
446*d86ed7fbStbbdev             phongtype = RT_PHONG_METAL;
447*d86ed7fbStbbdev         }
448*d86ed7fbStbbdev         else if (!stringcmp("PLASTIC", tmp)) {
449*d86ed7fbStbbdev             phongtype = RT_PHONG_PLASTIC;
450*d86ed7fbStbbdev         }
451*d86ed7fbStbbdev         else {
452*d86ed7fbStbbdev             phongtype = RT_PHONG_PLASTIC;
453*d86ed7fbStbbdev         }
454*d86ed7fbStbbdev 
455*d86ed7fbStbbdev         fscanf(dfile, "%f", &phong);
456*d86ed7fbStbbdev         GetString(dfile, "PHONG_SIZE");
457*d86ed7fbStbbdev         fscanf(dfile, "%f", &phongexp);
458*d86ed7fbStbbdev         fscanf(dfile, "%s", tmp);
459*d86ed7fbStbbdev     }
460*d86ed7fbStbbdev     else {
461*d86ed7fbStbbdev         phong = 0.0;
462*d86ed7fbStbbdev         phongexp = 100.0;
463*d86ed7fbStbbdev         phongtype = RT_PHONG_PLASTIC;
464*d86ed7fbStbbdev     }
465*d86ed7fbStbbdev 
466*d86ed7fbStbbdev     fscanf(dfile, "%f %f %f", &a, &b, &c);
467*d86ed7fbStbbdev     tex.col.r = a;
468*d86ed7fbStbbdev     tex.col.g = b;
469*d86ed7fbStbbdev     tex.col.b = c;
470*d86ed7fbStbbdev 
471*d86ed7fbStbbdev     rc |= GetString(dfile, "TEXFUNC");
472*d86ed7fbStbbdev     fscanf(dfile, "%d", &tex.texturefunc);
473*d86ed7fbStbbdev     if (tex.texturefunc >= 7) { /* if its an image map, we need a filename */
474*d86ed7fbStbbdev         fscanf(dfile, "%s", tex.imap);
475*d86ed7fbStbbdev     }
476*d86ed7fbStbbdev     if (tex.texturefunc != 0) {
477*d86ed7fbStbbdev         rc |= GetString(dfile, "CENTER");
478*d86ed7fbStbbdev         rc |= GetVector(dfile, &tex.ctr);
479*d86ed7fbStbbdev         rc |= GetString(dfile, "ROTATE");
480*d86ed7fbStbbdev         rc |= GetVector(dfile, &tex.rot);
481*d86ed7fbStbbdev         rc |= GetString(dfile, "SCALE");
482*d86ed7fbStbbdev         rc |= GetVector(dfile, &tex.scale);
483*d86ed7fbStbbdev     }
484*d86ed7fbStbbdev     if (tex.texturefunc == 9) {
485*d86ed7fbStbbdev         rc |= GetString(dfile, "UAXIS");
486*d86ed7fbStbbdev         rc |= GetVector(dfile, &tex.uaxs);
487*d86ed7fbStbbdev         rc |= GetString(dfile, "VAXIS");
488*d86ed7fbStbbdev         rc |= GetVector(dfile, &tex.vaxs);
489*d86ed7fbStbbdev     }
490*d86ed7fbStbbdev 
491*d86ed7fbStbbdev     voidtex = rt_texture(&tex);
492*d86ed7fbStbbdev     rt_tex_phong(voidtex, phong, phongexp, (int)phongtype);
493*d86ed7fbStbbdev 
494*d86ed7fbStbbdev     return voidtex;
495*d86ed7fbStbbdev }
496*d86ed7fbStbbdev 
497*d86ed7fbStbbdev static errcode GetLight(FILE *dfile) {
498*d86ed7fbStbbdev     apiflt rad;
499*d86ed7fbStbbdev     vector ctr;
500*d86ed7fbStbbdev     apitexture tex;
501*d86ed7fbStbbdev     float a;
502*d86ed7fbStbbdev     errcode rc;
503*d86ed7fbStbbdev 
504*d86ed7fbStbbdev     memset(&tex, 0, sizeof(apitexture));
505*d86ed7fbStbbdev 
506*d86ed7fbStbbdev     rc = GetString(dfile, "CENTER");
507*d86ed7fbStbbdev     rc |= GetVector(dfile, &ctr);
508*d86ed7fbStbbdev     rc |= GetString(dfile, "RAD");
509*d86ed7fbStbbdev     fscanf(dfile, "%f", &a); /* read in radius */
510*d86ed7fbStbbdev     rad = a;
511*d86ed7fbStbbdev 
512*d86ed7fbStbbdev     rc |= GetColor(dfile, &tex.col);
513*d86ed7fbStbbdev 
514*d86ed7fbStbbdev     rt_light(rt_texture(&tex), ctr, rad);
515*d86ed7fbStbbdev 
516*d86ed7fbStbbdev     return rc;
517*d86ed7fbStbbdev }
518*d86ed7fbStbbdev 
519*d86ed7fbStbbdev static errcode GetBackGnd(FILE *dfile) {
520*d86ed7fbStbbdev     float r, g, b;
521*d86ed7fbStbbdev 
522*d86ed7fbStbbdev     fscanf(dfile, "%f %f %f", &r, &g, &b);
523*d86ed7fbStbbdev 
524*d86ed7fbStbbdev     scenebackcol.r = r;
525*d86ed7fbStbbdev     scenebackcol.g = g;
526*d86ed7fbStbbdev     scenebackcol.b = b;
527*d86ed7fbStbbdev 
528*d86ed7fbStbbdev     return PARSENOERR;
529*d86ed7fbStbbdev }
530*d86ed7fbStbbdev 
531*d86ed7fbStbbdev static errcode GetCylinder(FILE *dfile) {
532*d86ed7fbStbbdev     apiflt rad;
533*d86ed7fbStbbdev     vector ctr, axis;
534*d86ed7fbStbbdev     void *tex;
535*d86ed7fbStbbdev     float a;
536*d86ed7fbStbbdev     errcode rc;
537*d86ed7fbStbbdev 
538*d86ed7fbStbbdev     rc = GetString(dfile, "CENTER");
539*d86ed7fbStbbdev     rc |= GetVector(dfile, &ctr);
540*d86ed7fbStbbdev     rc |= GetString(dfile, "AXIS");
541*d86ed7fbStbbdev     rc |= GetVector(dfile, &axis);
542*d86ed7fbStbbdev     rc |= GetString(dfile, "RAD");
543*d86ed7fbStbbdev     fscanf(dfile, "%f", &a);
544*d86ed7fbStbbdev     rad = a;
545*d86ed7fbStbbdev 
546*d86ed7fbStbbdev     rc |= GetTexture(dfile, &tex);
547*d86ed7fbStbbdev     rt_cylinder(tex, ctr, axis, rad);
548*d86ed7fbStbbdev 
549*d86ed7fbStbbdev     return rc;
550*d86ed7fbStbbdev }
551*d86ed7fbStbbdev 
552*d86ed7fbStbbdev static errcode GetFCylinder(FILE *dfile) {
553*d86ed7fbStbbdev     apiflt rad;
554*d86ed7fbStbbdev     vector ctr, axis;
555*d86ed7fbStbbdev     vector pnt1, pnt2;
556*d86ed7fbStbbdev     void *tex;
557*d86ed7fbStbbdev     float a;
558*d86ed7fbStbbdev     errcode rc;
559*d86ed7fbStbbdev 
560*d86ed7fbStbbdev     rc = GetString(dfile, "BASE");
561*d86ed7fbStbbdev     rc |= GetVector(dfile, &pnt1);
562*d86ed7fbStbbdev     rc |= GetString(dfile, "APEX");
563*d86ed7fbStbbdev     rc |= GetVector(dfile, &pnt2);
564*d86ed7fbStbbdev 
565*d86ed7fbStbbdev     ctr = pnt1;
566*d86ed7fbStbbdev     axis.x = pnt2.x - pnt1.x;
567*d86ed7fbStbbdev     axis.y = pnt2.y - pnt1.y;
568*d86ed7fbStbbdev     axis.z = pnt2.z - pnt1.z;
569*d86ed7fbStbbdev 
570*d86ed7fbStbbdev     rc |= GetString(dfile, "RAD");
571*d86ed7fbStbbdev     fscanf(dfile, "%f", &a);
572*d86ed7fbStbbdev     rad = a;
573*d86ed7fbStbbdev 
574*d86ed7fbStbbdev     rc |= GetTexture(dfile, &tex);
575*d86ed7fbStbbdev     rt_fcylinder(tex, ctr, axis, rad);
576*d86ed7fbStbbdev 
577*d86ed7fbStbbdev     return rc;
578*d86ed7fbStbbdev }
579*d86ed7fbStbbdev 
580*d86ed7fbStbbdev static errcode GetPolyCylinder(FILE *dfile) {
581*d86ed7fbStbbdev     apiflt rad;
582*d86ed7fbStbbdev     vector *temp;
583*d86ed7fbStbbdev     void *tex;
584*d86ed7fbStbbdev     float a;
585*d86ed7fbStbbdev     int numpts, i;
586*d86ed7fbStbbdev     errcode rc;
587*d86ed7fbStbbdev 
588*d86ed7fbStbbdev     rc = GetString(dfile, "POINTS");
589*d86ed7fbStbbdev     fscanf(dfile, "%d", &numpts);
590*d86ed7fbStbbdev 
591*d86ed7fbStbbdev     temp = (vector *)malloc(numpts * sizeof(vector));
592*d86ed7fbStbbdev 
593*d86ed7fbStbbdev     for (i = 0; i < numpts; i++) {
594*d86ed7fbStbbdev         rc |= GetVector(dfile, &temp[i]);
595*d86ed7fbStbbdev     }
596*d86ed7fbStbbdev 
597*d86ed7fbStbbdev     rc |= GetString(dfile, "RAD");
598*d86ed7fbStbbdev     fscanf(dfile, "%f", &a);
599*d86ed7fbStbbdev     rad = a;
600*d86ed7fbStbbdev 
601*d86ed7fbStbbdev     rc |= GetTexture(dfile, &tex);
602*d86ed7fbStbbdev     rt_polycylinder(tex, temp, numpts, rad);
603*d86ed7fbStbbdev 
604*d86ed7fbStbbdev     free(temp);
605*d86ed7fbStbbdev 
606*d86ed7fbStbbdev     return rc;
607*d86ed7fbStbbdev }
608*d86ed7fbStbbdev 
609*d86ed7fbStbbdev static errcode GetSphere(FILE *dfile) {
610*d86ed7fbStbbdev     apiflt rad;
611*d86ed7fbStbbdev     vector ctr;
612*d86ed7fbStbbdev     void *tex;
613*d86ed7fbStbbdev     float a;
614*d86ed7fbStbbdev     errcode rc;
615*d86ed7fbStbbdev 
616*d86ed7fbStbbdev     rc = GetString(dfile, "CENTER");
617*d86ed7fbStbbdev     rc |= GetVector(dfile, &ctr);
618*d86ed7fbStbbdev     rc |= GetString(dfile, "RAD");
619*d86ed7fbStbbdev     fscanf(dfile, "%f", &a);
620*d86ed7fbStbbdev     rad = a;
621*d86ed7fbStbbdev 
622*d86ed7fbStbbdev     rc |= GetTexture(dfile, &tex);
623*d86ed7fbStbbdev 
624*d86ed7fbStbbdev     rt_sphere(tex, ctr, rad);
625*d86ed7fbStbbdev 
626*d86ed7fbStbbdev     return rc;
627*d86ed7fbStbbdev }
628*d86ed7fbStbbdev 
629*d86ed7fbStbbdev static errcode GetPlane(FILE *dfile) {
630*d86ed7fbStbbdev     vector normal;
631*d86ed7fbStbbdev     vector ctr;
632*d86ed7fbStbbdev     void *tex;
633*d86ed7fbStbbdev     errcode rc;
634*d86ed7fbStbbdev 
635*d86ed7fbStbbdev     rc = GetString(dfile, "CENTER");
636*d86ed7fbStbbdev     rc |= GetVector(dfile, &ctr);
637*d86ed7fbStbbdev     rc |= GetString(dfile, "NORMAL");
638*d86ed7fbStbbdev     rc |= GetVector(dfile, &normal);
639*d86ed7fbStbbdev     rc |= GetTexture(dfile, &tex);
640*d86ed7fbStbbdev 
641*d86ed7fbStbbdev     rt_plane(tex, ctr, normal);
642*d86ed7fbStbbdev 
643*d86ed7fbStbbdev     return rc;
644*d86ed7fbStbbdev }
645*d86ed7fbStbbdev 
646*d86ed7fbStbbdev static errcode GetVol(FILE *dfile) {
647*d86ed7fbStbbdev     vector min, max;
648*d86ed7fbStbbdev     int x, y, z;
649*d86ed7fbStbbdev     char fname[255];
650*d86ed7fbStbbdev     void *tex;
651*d86ed7fbStbbdev     errcode rc;
652*d86ed7fbStbbdev 
653*d86ed7fbStbbdev     rc = GetString(dfile, "MIN");
654*d86ed7fbStbbdev     rc |= GetVector(dfile, &min);
655*d86ed7fbStbbdev     rc |= GetString(dfile, "MAX");
656*d86ed7fbStbbdev     rc |= GetVector(dfile, &max);
657*d86ed7fbStbbdev     rc |= GetString(dfile, "DIM");
658*d86ed7fbStbbdev     fscanf(dfile, "%d %d %d ", &x, &y, &z);
659*d86ed7fbStbbdev     rc |= GetString(dfile, "FILE");
660*d86ed7fbStbbdev     fscanf(dfile, "%s", fname);
661*d86ed7fbStbbdev     rc |= GetTexture(dfile, &tex);
662*d86ed7fbStbbdev 
663*d86ed7fbStbbdev     rt_scalarvol(tex, min, max, x, y, z, fname, nullptr);
664*d86ed7fbStbbdev 
665*d86ed7fbStbbdev     return rc;
666*d86ed7fbStbbdev }
667*d86ed7fbStbbdev 
668*d86ed7fbStbbdev static errcode GetBox(FILE *dfile) {
669*d86ed7fbStbbdev     vector min, max;
670*d86ed7fbStbbdev     void *tex;
671*d86ed7fbStbbdev     errcode rc;
672*d86ed7fbStbbdev 
673*d86ed7fbStbbdev     rc = GetString(dfile, "MIN");
674*d86ed7fbStbbdev     rc |= GetVector(dfile, &min);
675*d86ed7fbStbbdev     rc |= GetString(dfile, "MAX");
676*d86ed7fbStbbdev     rc |= GetVector(dfile, &max);
677*d86ed7fbStbbdev     rc |= GetTexture(dfile, &tex);
678*d86ed7fbStbbdev 
679*d86ed7fbStbbdev     rt_box(tex, min, max);
680*d86ed7fbStbbdev 
681*d86ed7fbStbbdev     return rc;
682*d86ed7fbStbbdev }
683*d86ed7fbStbbdev 
684*d86ed7fbStbbdev static errcode GetRing(FILE *dfile) {
685*d86ed7fbStbbdev     vector normal;
686*d86ed7fbStbbdev     vector ctr;
687*d86ed7fbStbbdev     void *tex;
688*d86ed7fbStbbdev     float a, b;
689*d86ed7fbStbbdev     errcode rc;
690*d86ed7fbStbbdev 
691*d86ed7fbStbbdev     rc = GetString(dfile, "CENTER");
692*d86ed7fbStbbdev     rc |= GetVector(dfile, &ctr);
693*d86ed7fbStbbdev     rc |= GetString(dfile, "NORMAL");
694*d86ed7fbStbbdev     rc |= GetVector(dfile, &normal);
695*d86ed7fbStbbdev     rc |= GetString(dfile, "INNER");
696*d86ed7fbStbbdev     fscanf(dfile, " %f ", &a);
697*d86ed7fbStbbdev     rc |= GetString(dfile, "OUTER");
698*d86ed7fbStbbdev     fscanf(dfile, " %f ", &b);
699*d86ed7fbStbbdev     rc |= GetTexture(dfile, &tex);
700*d86ed7fbStbbdev 
701*d86ed7fbStbbdev     rt_ring(tex, ctr, normal, a, b);
702*d86ed7fbStbbdev 
703*d86ed7fbStbbdev     return rc;
704*d86ed7fbStbbdev }
705*d86ed7fbStbbdev 
706*d86ed7fbStbbdev static errcode GetTri(FILE *dfile) {
707*d86ed7fbStbbdev     vector v0, v1, v2;
708*d86ed7fbStbbdev     void *tex;
709*d86ed7fbStbbdev     errcode rc;
710*d86ed7fbStbbdev 
711*d86ed7fbStbbdev     rc = GetString(dfile, "V0");
712*d86ed7fbStbbdev     rc |= GetVector(dfile, &v0);
713*d86ed7fbStbbdev 
714*d86ed7fbStbbdev     rc |= GetString(dfile, "V1");
715*d86ed7fbStbbdev     rc |= GetVector(dfile, &v1);
716*d86ed7fbStbbdev 
717*d86ed7fbStbbdev     rc |= GetString(dfile, "V2");
718*d86ed7fbStbbdev     rc |= GetVector(dfile, &v2);
719*d86ed7fbStbbdev 
720*d86ed7fbStbbdev     rc |= GetTexture(dfile, &tex);
721*d86ed7fbStbbdev 
722*d86ed7fbStbbdev     rt_tri(tex, v0, v1, v2);
723*d86ed7fbStbbdev 
724*d86ed7fbStbbdev     return rc;
725*d86ed7fbStbbdev }
726*d86ed7fbStbbdev 
727*d86ed7fbStbbdev static errcode GetSTri(FILE *dfile) {
728*d86ed7fbStbbdev     vector v0, v1, v2, n0, n1, n2;
729*d86ed7fbStbbdev     void *tex;
730*d86ed7fbStbbdev     errcode rc;
731*d86ed7fbStbbdev 
732*d86ed7fbStbbdev     rc = GetString(dfile, "V0");
733*d86ed7fbStbbdev     rc |= GetVector(dfile, &v0);
734*d86ed7fbStbbdev 
735*d86ed7fbStbbdev     rc |= GetString(dfile, "V1");
736*d86ed7fbStbbdev     rc |= GetVector(dfile, &v1);
737*d86ed7fbStbbdev 
738*d86ed7fbStbbdev     rc |= GetString(dfile, "V2");
739*d86ed7fbStbbdev     rc |= GetVector(dfile, &v2);
740*d86ed7fbStbbdev 
741*d86ed7fbStbbdev     rc |= GetString(dfile, "N0");
742*d86ed7fbStbbdev     rc |= GetVector(dfile, &n0);
743*d86ed7fbStbbdev 
744*d86ed7fbStbbdev     rc |= GetString(dfile, "N1");
745*d86ed7fbStbbdev     rc |= GetVector(dfile, &n1);
746*d86ed7fbStbbdev 
747*d86ed7fbStbbdev     rc |= GetString(dfile, "N2");
748*d86ed7fbStbbdev     rc |= GetVector(dfile, &n2);
749*d86ed7fbStbbdev 
750*d86ed7fbStbbdev     rc |= GetTexture(dfile, &tex);
751*d86ed7fbStbbdev 
752*d86ed7fbStbbdev     rt_stri(tex, v0, v1, v2, n0, n1, n2);
753*d86ed7fbStbbdev 
754*d86ed7fbStbbdev     return rc;
755*d86ed7fbStbbdev }
756*d86ed7fbStbbdev 
757*d86ed7fbStbbdev static errcode GetLandScape(FILE *dfile) {
758*d86ed7fbStbbdev     void *tex;
759*d86ed7fbStbbdev     vector ctr;
760*d86ed7fbStbbdev     apiflt wx, wy;
761*d86ed7fbStbbdev     int m, n;
762*d86ed7fbStbbdev     float a, b;
763*d86ed7fbStbbdev     errcode rc;
764*d86ed7fbStbbdev 
765*d86ed7fbStbbdev     rc = GetString(dfile, "RES");
766*d86ed7fbStbbdev     fscanf(dfile, "%d %d", &m, &n);
767*d86ed7fbStbbdev 
768*d86ed7fbStbbdev     rc |= GetString(dfile, "SCALE");
769*d86ed7fbStbbdev     fscanf(dfile, "%f %f", &a, &b);
770*d86ed7fbStbbdev     wx = a;
771*d86ed7fbStbbdev     wy = b;
772*d86ed7fbStbbdev 
773*d86ed7fbStbbdev     rc |= GetString(dfile, "CENTER");
774*d86ed7fbStbbdev     rc |= GetVector(dfile, &ctr);
775*d86ed7fbStbbdev 
776*d86ed7fbStbbdev     rc |= GetTexture(dfile, &tex);
777*d86ed7fbStbbdev 
778*d86ed7fbStbbdev     rt_landscape(tex, m, n, ctr, wx, wy);
779*d86ed7fbStbbdev 
780*d86ed7fbStbbdev     return rc;
781*d86ed7fbStbbdev }
782*d86ed7fbStbbdev 
783*d86ed7fbStbbdev static errcode GetTPolyFile(FILE *dfile) {
784*d86ed7fbStbbdev     void *tex;
785*d86ed7fbStbbdev     vector ctr, rot, scale;
786*d86ed7fbStbbdev     vector v1, v2, v0;
787*d86ed7fbStbbdev     char ifname[255];
788*d86ed7fbStbbdev     FILE *ifp;
789*d86ed7fbStbbdev     int v, totalpolys;
790*d86ed7fbStbbdev     RotMat RotA;
791*d86ed7fbStbbdev     errcode rc;
792*d86ed7fbStbbdev 
793*d86ed7fbStbbdev     totalpolys = 0;
794*d86ed7fbStbbdev 
795*d86ed7fbStbbdev     rc = GetString(dfile, "SCALE");
796*d86ed7fbStbbdev     rc |= GetVector(dfile, &scale);
797*d86ed7fbStbbdev 
798*d86ed7fbStbbdev     rc |= GetString(dfile, "ROT");
799*d86ed7fbStbbdev     rc |= GetVector(dfile, &rot);
800*d86ed7fbStbbdev 
801*d86ed7fbStbbdev     degvectoradvec(&rot);
802*d86ed7fbStbbdev     InitRot3d(&RotA, rot.x, rot.y, rot.z);
803*d86ed7fbStbbdev 
804*d86ed7fbStbbdev     rc |= GetString(dfile, "CENTER");
805*d86ed7fbStbbdev     rc |= GetVector(dfile, &ctr);
806*d86ed7fbStbbdev 
807*d86ed7fbStbbdev     rc |= GetString(dfile, "FILE");
808*d86ed7fbStbbdev     fscanf(dfile, "%s", ifname);
809*d86ed7fbStbbdev 
810*d86ed7fbStbbdev     rc |= GetTexture(dfile, &tex);
811*d86ed7fbStbbdev 
812*d86ed7fbStbbdev     if ((ifp = fopen(ifname, "r")) == nullptr) {
813*d86ed7fbStbbdev         fprintf(stderr, "Can't open data file %s for input!! Aborting...\n", ifname);
814*d86ed7fbStbbdev         return PARSEBADSUBFILE;
815*d86ed7fbStbbdev     }
816*d86ed7fbStbbdev 
817*d86ed7fbStbbdev     while (!feof(ifp)) {
818*d86ed7fbStbbdev         fscanf(ifp, "%d", &v);
819*d86ed7fbStbbdev         if (v != 3) {
820*d86ed7fbStbbdev             break;
821*d86ed7fbStbbdev         }
822*d86ed7fbStbbdev 
823*d86ed7fbStbbdev         totalpolys++;
824*d86ed7fbStbbdev         v = 0;
825*d86ed7fbStbbdev 
826*d86ed7fbStbbdev         rc |= GetVector(ifp, &v0);
827*d86ed7fbStbbdev         rc |= GetVector(ifp, &v1);
828*d86ed7fbStbbdev         rc |= GetVector(ifp, &v2);
829*d86ed7fbStbbdev 
830*d86ed7fbStbbdev         Scale3d(&scale, &v0);
831*d86ed7fbStbbdev         Scale3d(&scale, &v1);
832*d86ed7fbStbbdev         Scale3d(&scale, &v2);
833*d86ed7fbStbbdev 
834*d86ed7fbStbbdev         Rotate3d(&RotA, &v0);
835*d86ed7fbStbbdev         Rotate3d(&RotA, &v1);
836*d86ed7fbStbbdev         Rotate3d(&RotA, &v2);
837*d86ed7fbStbbdev 
838*d86ed7fbStbbdev         Trans3d(&ctr, &v0);
839*d86ed7fbStbbdev         Trans3d(&ctr, &v1);
840*d86ed7fbStbbdev         Trans3d(&ctr, &v2);
841*d86ed7fbStbbdev 
842*d86ed7fbStbbdev         rt_tri(tex, v1, v0, v2);
843*d86ed7fbStbbdev     }
844*d86ed7fbStbbdev 
845*d86ed7fbStbbdev     fclose(ifp);
846*d86ed7fbStbbdev 
847*d86ed7fbStbbdev     return rc;
848*d86ed7fbStbbdev }
849