Subversion Repositories eduke32

Rev

Rev 5040 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
99 terminx 1
/*
2
 * Definitions file parser for Build
2456 hendricks2 3
 * by Jonathon Fowler (jf@jonof.id.au)
99 terminx 4
 * Remixed substantially by Ken Silverman
5
 * See the included license file "BUILDLIC.TXT" for license info.
6
 */
7
 
8
#include "build.h"
9
#include "compat.h"
1782 plagman 10
#include "engine_priv.h"
99 terminx 11
#include "baselayer.h"
12
#include "scriptfile.h"
5 Plagman 13
#include "cache1d.h"
544 terminx 14
#include "kplib.h"
4316 hendricks2 15
#include "lz4.h"
2554 helixhorne 16
#include "common.h"
3467 helixhorne 17
#include "mdsprite.h"  // md3model_t
5 Plagman 18
 
1677 terminx 19
enum scripttoken_t
584 terminx 20
{
109 terminx 21
    T_INCLUDE = 0,
22
    T_DEFINE,
23
    T_DEFINETEXTURE,
24
    T_DEFINESKYBOX,
25
    T_DEFINETINT,
26
    T_DEFINEMODEL,
27
    T_DEFINEMODELFRAME,
28
    T_DEFINEMODELANIM,
29
    T_DEFINEMODELSKIN,
30
    T_SELECTMODELSKIN,
31
    T_DEFINEVOXEL,
32
    T_DEFINEVOXELTILES,
33
    T_MODEL,
34
    T_FILE,
35
    T_SCALE,
36
    T_SHADE,
37
    T_FRAME,
531 Plagman 38
    T_SMOOTHDURATION,
109 terminx 39
    T_ANIM,
40
    T_SKIN,
41
    T_SURF,
42
    T_TILE,
43
    T_TILE0,
44
    T_TILE1,
45
    T_FRAME0,
46
    T_FRAME1,
47
    T_FPS,
48
    T_FLAGS,
49
    T_PAL,
1782 plagman 50
    T_BASEPAL,
459 Plagman 51
    T_DETAIL,
497 Plagman 52
    T_GLOW,
1350 terminx 53
    T_SPECULAR,
54
    T_NORMAL,
501 Plagman 55
    T_PARAM,
109 terminx 56
    T_HUD,
57
    T_XADD,
58
    T_YADD,
59
    T_ZADD,
60
    T_ANGADD,
1814 plagman 61
    T_FOV,
109 terminx 62
    T_FLIPPED,
63
    T_HIDE,
64
    T_NOBOB,
65
    T_NODEPTH,
66
    T_VOXEL,
67
    T_SKYBOX,
68
    T_FRONT,T_RIGHT,T_BACK,T_LEFT,T_TOP,T_BOTTOM,
1748 plagman 69
    T_HIGHPALOOKUP,
2568 helixhorne 70
    T_TINT,
71
    T_MAKEPALOOKUP, T_REMAPPAL, T_REMAPSELF,
72
    T_RED,T_GREEN,T_BLUE,
1278 plagman 73
    T_TEXTURE,T_ALPHACUT,T_XSCALE,T_YSCALE,T_SPECPOWER,T_SPECFACTOR,T_NOCOMPRESS,T_NODOWNSIZE,
4062 terminx 74
    T_ORIGSIZEX,T_ORIGSIZEY,
109 terminx 75
    T_UNDEFMODEL,T_UNDEFMODELRANGE,T_UNDEFMODELOF,T_UNDEFTEXTURE,T_UNDEFTEXTURERANGE,
76
    T_ALPHAHACK,T_ALPHAHACKRANGE,
77
    T_SPRITECOL,T_2DCOL,
78
    T_FOGPAL,
79
    T_LOADGRP,
224 terminx 80
    T_DUMMYTILE,T_DUMMYTILERANGE,
665 terminx 81
    T_SETUPTILE,T_SETUPTILERANGE,
928 hnt_ts 82
    T_ANIMTILERANGE,
587 terminx 83
    T_CACHESIZE,
1150 terminx 84
    T_IMPORTTILE,
587 terminx 85
    T_MUSIC,T_ID,T_SOUND,
3230 helixhorne 86
    T_TILEFROMTEXTURE, T_XOFFSET, T_YOFFSET, T_TEXHITSCAN, T_NOFULLBRIGHT,
2242 helixhorne 87
    T_INCLUDEDEFAULT,
88
    T_ANIMSOUNDS,
4987 terminx 89
    T_CUTSCENE,
2587 helixhorne 90
    T_NOFLOORPALRANGE,
3078 helixhorne 91
    T_TEXHITSCANRANGE,
3230 helixhorne 92
    T_NOFULLBRIGHTRANGE,
3309 hendricks2 93
    T_MAPINFO, T_MAPFILE, T_MAPTITLE, T_MAPMD4, T_MHKFILE,
2435 hendricks2 94
    T_ECHO,
5056 hendricks2 95
    T_GLOBALFLAGS,
99 terminx 96
};
97
 
1205 terminx 98
static int32_t lastmodelid = -1, lastvoxid = -1, modelskin = -1, lastmodelskin = -1, seenframe = 0;
4225 helixhorne 99
static int32_t nextvoxid = 0;
4637 terminx 100
static char *faketilebuffer = NULL;
101
static int32_t faketilebuffersiz = 0;
99 terminx 102
 
1820 terminx 103
#ifdef USE_OPENGL
5 Plagman 104
extern float alphahackarray[MAXTILES];
163 terminx 105
#endif
5 Plagman 106
 
584 terminx 107
static const char *skyfaces[6] =
108
{
109
    "front face", "right face", "back face",
110
    "left face", "top face", "bottom face"
111
};
99 terminx 112
 
1937 hendricks2 113
static int32_t defsparser(scriptfile *script);
114
 
2588 helixhorne 115
static void defsparser_include(const char *fn, const scriptfile *script, const char *cmdtokptr)
1937 hendricks2 116
{
117
    scriptfile *included;
118
 
119
    included = scriptfile_fromfile(fn);
4680 terminx 120
    if (EDUKE32_PREDICT_FALSE(!included))
1937 hendricks2 121
    {
2588 helixhorne 122
        if (!cmdtokptr)
4061 helixhorne 123
            initprintf("Warning: Failed including %s as module\n", fn);
1937 hendricks2 124
        else
4061 helixhorne 125
            initprintf("Warning: Failed including %s on line %s:%d\n",
1937 hendricks2 126
                       fn, script->filename,scriptfile_getlinum(script,cmdtokptr));
127
    }
128
    else
129
    {
3621 hendricks2 130
        if (!cmdtokptr)
131
        {
132
            flushlogwindow = 1;
4061 helixhorne 133
            initprintf("Loading module \"%s\"\n",fn);
3621 hendricks2 134
            flushlogwindow = 0;
135
        }
136
 
1937 hendricks2 137
        defsparser(included);
138
        scriptfile_close(included);
139
    }
140
}
141
 
2588 helixhorne 142
 
143
static int32_t check_tile_range(const char *defcmd, int32_t *tilebeg, int32_t *tileend,
144
                                const scriptfile *script, const char *cmdtokptr)
145
{
4680 terminx 146
    if (EDUKE32_PREDICT_FALSE(*tileend < *tilebeg))
2588 helixhorne 147
    {
4061 helixhorne 148
        initprintf("Warning: %s: backwards tile range on line %s:%d\n", defcmd,
2588 helixhorne 149
                   script->filename, scriptfile_getlinum(script,cmdtokptr));
150
        swaplong(tilebeg, tileend);
151
    }
152
 
4680 terminx 153
    if (EDUKE32_PREDICT_FALSE((unsigned)*tilebeg >= MAXUSERTILES || (unsigned)*tileend >= MAXUSERTILES))
2588 helixhorne 154
    {
4061 helixhorne 155
        initprintf("Error: %s: Invalid tile range on line %s:%d\n", defcmd,
2588 helixhorne 156
                   script->filename, scriptfile_getlinum(script,cmdtokptr));
157
        return 1;
158
    }
159
 
160
    return 0;
161
}
162
 
4186 helixhorne 163
static int32_t check_tile(const char *defcmd, int32_t tile, const scriptfile *script,
2588 helixhorne 164
                          const char *cmdtokptr)
165
{
4680 terminx 166
    if (EDUKE32_PREDICT_FALSE((unsigned)tile >= MAXUSERTILES))
2588 helixhorne 167
    {
4061 helixhorne 168
        initprintf("Error: %s: Invalid tile number on line %s:%d\n", defcmd,
2588 helixhorne 169
                   script->filename, scriptfile_getlinum(script,cmdtokptr));
170
        return 1;
171
    }
172
 
173
    return 0;
174
}
175
 
4680 terminx 176
extern void getclosestcol_flush(void);
177
 
2588 helixhorne 178
static void tile_from_truecolpic(int32_t tile, const palette_t *picptr, int32_t alphacut)
179
{
4637 terminx 180
    const vec2_t siz = tilesiz[tile];
181
    int32_t i, j, tsiz = siz.x * siz.y;
2588 helixhorne 182
 
4637 terminx 183
    if (tsiz > faketilebuffersiz)
184
    {
185
        faketilebuffer = (char *) Xrealloc(faketilebuffer, tsiz);
186
        faketilebuffersiz = tsiz;
187
    }
2588 helixhorne 188
 
4680 terminx 189
    getclosestcol_flush();
190
 
4637 terminx 191
    faketiledata[tile] = (char *)Xmalloc(tsiz + 32);
2588 helixhorne 192
 
4637 terminx 193
    for (i=siz.x-1; i>=0; i--)
2588 helixhorne 194
    {
4637 terminx 195
        uint32_t ofs = i * siz.y;
196
 
197
        for (j=siz.y-1; j>=0; j--)
2588 helixhorne 198
        {
4637 terminx 199
            const palette_t *col = &picptr[j*siz.x+i];
200
            if (col->f < alphacut) { faketilebuffer[ofs+j] = 255; continue; }
201
            faketilebuffer[ofs+j] = getclosestcol(col->b>>2, col->g>>2, col->r>>2);
2588 helixhorne 202
        }
4061 helixhorne 203
        //                initprintf(" %d %d %d %d\n",col->r,col->g,col->b,col->f);
2588 helixhorne 204
    }
205
 
4637 terminx 206
    faketilesiz[tile] = LZ4_compress(faketilebuffer, faketiledata[tile], tsiz);
2588 helixhorne 207
}
208
 
3827 helixhorne 209
#undef USE_DEF_PROGRESS
210
#if defined _WIN32 || defined HAVE_GTK2
211
# define USE_DEF_PROGRESS
212
#endif
213
 
1205 terminx 214
static int32_t defsparser(scriptfile *script)
99 terminx 215
{
1205 terminx 216
    int32_t tokn;
109 terminx 217
    char *cmdtokptr;
3827 helixhorne 218
#ifdef USE_DEF_PROGRESS
3801 terminx 219
    static uint32_t iter = 0;
3827 helixhorne 220
#endif
1677 terminx 221
 
222
    static const tokenlist basetokens[] =
223
    {
224
        { "include",         T_INCLUDE          },
225
        { "#include",        T_INCLUDE          },
1909 terminx 226
        { "includedefault",  T_INCLUDEDEFAULT   },
227
        { "#includedefault", T_INCLUDEDEFAULT   },
1677 terminx 228
        { "define",          T_DEFINE           },
229
        { "#define",         T_DEFINE           },
230
 
231
        // deprecated style
232
        { "definetexture",   T_DEFINETEXTURE    },
233
        { "defineskybox",    T_DEFINESKYBOX     },
234
        { "definetint",      T_DEFINETINT       },
235
        { "definemodel",     T_DEFINEMODEL      },
236
        { "definemodelframe",T_DEFINEMODELFRAME },
237
        { "definemodelanim", T_DEFINEMODELANIM  },
238
        { "definemodelskin", T_DEFINEMODELSKIN  },
239
        { "selectmodelskin", T_SELECTMODELSKIN  },
240
        { "definevoxel",     T_DEFINEVOXEL      },
241
        { "definevoxeltiles",T_DEFINEVOXELTILES },
242
 
243
        // new style
244
        { "model",           T_MODEL            },
245
        { "voxel",           T_VOXEL            },
246
        { "skybox",          T_SKYBOX           },
1748 plagman 247
        { "highpalookup",    T_HIGHPALOOKUP     },
1677 terminx 248
        { "tint",            T_TINT             },
2568 helixhorne 249
        { "makepalookup",    T_MAKEPALOOKUP     },
1677 terminx 250
        { "texture",         T_TEXTURE          },
251
        { "tile",            T_TEXTURE          },
252
        { "music",           T_MUSIC            },
253
        { "sound",           T_SOUND            },
2242 helixhorne 254
        { "animsounds",      T_ANIMSOUNDS       },  // dummy
4987 terminx 255
        { "cutscene",        T_CUTSCENE         },
4811 helixhorne 256
        { "nofloorpalrange", T_NOFLOORPALRANGE  },
3078 helixhorne 257
        { "texhitscanrange", T_TEXHITSCANRANGE  },
3230 helixhorne 258
        { "nofullbrightrange", T_NOFULLBRIGHTRANGE },
1677 terminx 259
        // other stuff
260
        { "undefmodel",      T_UNDEFMODEL       },
261
        { "undefmodelrange", T_UNDEFMODELRANGE  },
262
        { "undefmodelof",    T_UNDEFMODELOF     },
263
        { "undeftexture",    T_UNDEFTEXTURE     },
264
        { "undeftexturerange", T_UNDEFTEXTURERANGE },
265
        { "alphahack",       T_ALPHAHACK                },
266
        { "alphahackrange",  T_ALPHAHACKRANGE   },
267
        { "spritecol",       T_SPRITECOL                },
268
        { "2dcol",               T_2DCOL                        },
269
        { "fogpal",              T_FOGPAL                       },
270
        { "loadgrp",             T_LOADGRP                      },
271
        { "dummytile",           T_DUMMYTILE            },
272
        { "dummytilerange",  T_DUMMYTILERANGE   },
273
        { "setuptile",       T_SETUPTILE        },
274
        { "setuptilerange",  T_SETUPTILERANGE   },
275
        { "animtilerange",   T_ANIMTILERANGE    },
276
        { "cachesize",       T_CACHESIZE        },
277
        { "dummytilefrompic",T_IMPORTTILE       },
278
        { "tilefromtexture", T_TILEFROMTEXTURE  },
4884 hendricks2 279
        { "mapinfo",         T_MAPINFO          },
2435 hendricks2 280
        { "echo",            T_ECHO             },
5056 hendricks2 281
        { "globalflags",     T_GLOBALFLAGS      },
1677 terminx 282
    };
283
 
584 terminx 284
    while (1)
285
    {
3827 helixhorne 286
#ifdef USE_DEF_PROGRESS
3801 terminx 287
        if (++iter >= 50)
288
        {
289
            flushlogwindow = 1;
290
            initprintf(".");
291
            flushlogwindow = 0;
292
            iter = 0;
293
        }
3827 helixhorne 294
#endif
4637 terminx 295
        handleevents();
993 terminx 296
        if (quitevent) return 0;
4385 terminx 297
        tokn = getatoken(script,basetokens,ARRAY_SIZE(basetokens));
109 terminx 298
        cmdtokptr = script->ltextptr;
584 terminx 299
        switch (tokn)
300
        {
109 terminx 301
        case T_ERROR:
4061 helixhorne 302
            initprintf("Error on line %s:%d.\n", script->filename,scriptfile_getlinum(script,cmdtokptr));
109 terminx 303
            break;
304
        case T_EOF:
305
            return(0);
306
        case T_INCLUDE:
331 terminx 307
        {
308
            char *fn;
584 terminx 309
            if (!scriptfile_getstring(script,&fn))
1937 hendricks2 310
                defsparser_include(fn, script, cmdtokptr);
331 terminx 311
            break;
312
        }
1909 terminx 313
        case T_INCLUDEDEFAULT:
314
        {
2726 hendricks2 315
            defsparser_include(G_DefaultDefFile(), script, cmdtokptr);
1909 terminx 316
            break;
317
        }
109 terminx 318
        case T_DEFINE:
331 terminx 319
        {
320
            char *name;
1205 terminx 321
            int32_t number;
99 terminx 322
 
331 terminx 323
            if (scriptfile_getstring(script,&name)) break;
324
            if (scriptfile_getsymbol(script,&number)) break;
99 terminx 325
 
4680 terminx 326
            if (EDUKE32_PREDICT_FALSE(scriptfile_addsymbolvalue(name,number) < 0))
4061 helixhorne 327
                initprintf("Warning: Symbol %s was NOT redefined to %d on line %s:%d\n",
331 terminx 328
                           name,number,script->filename,scriptfile_getlinum(script,cmdtokptr));
329
            break;
330
        }
99 terminx 331
 
331 terminx 332
        // OLD (DEPRECATED) DEFINITION SYNTAX
109 terminx 333
        case T_DEFINETEXTURE:
331 terminx 334
        {
2554 helixhorne 335
            int32_t tile,pal,fnoo;
336
            char *fn;
99 terminx 337
 
331 terminx 338
            if (scriptfile_getsymbol(script,&tile)) break;
339
            if (scriptfile_getsymbol(script,&pal))  break;
340
            if (scriptfile_getnumber(script,&fnoo)) break; //x-center
341
            if (scriptfile_getnumber(script,&fnoo)) break; //y-center
342
            if (scriptfile_getnumber(script,&fnoo)) break; //x-size
343
            if (scriptfile_getnumber(script,&fnoo)) break; //y-size
344
            if (scriptfile_getstring(script,&fn))  break;
326 terminx 345
 
2554 helixhorne 346
            if (check_file_exist(fn))
347
                break;
544 terminx 348
 
3382 hendricks2 349
#ifdef USE_OPENGL
1278 plagman 350
            hicsetsubsttex(tile,pal,fn,-1.0,1.0,1.0,1.0,1.0,0);
3382 hendricks2 351
#endif
331 terminx 352
        }
353
        break;
109 terminx 354
        case T_DEFINESKYBOX:
331 terminx 355
        {
2554 helixhorne 356
            int32_t tile,pal,i;
357
            char *fn[6],happy=1;
99 terminx 358
 
331 terminx 359
            if (scriptfile_getsymbol(script,&tile)) break;
360
            if (scriptfile_getsymbol(script,&pal)) break;
361
            if (scriptfile_getsymbol(script,&i)) break; //future expansion
1229 terminx 362
            for (i=0; i<6; i++)
584 terminx 363
            {
331 terminx 364
                if (scriptfile_getstring(script,&fn[i])) break; //grab the 6 faces
544 terminx 365
 
2554 helixhorne 366
                if (check_file_exist(fn[i]))
367
                    happy = 0;
109 terminx 368
            }
331 terminx 369
            if (i < 6 || !happy) break;
3382 hendricks2 370
#ifdef USE_OPENGL
5010 terminx 371
            hicsetskybox(tile,pal,fn, 0);
3382 hendricks2 372
#endif
331 terminx 373
        }
374
        break;
109 terminx 375
        case T_DEFINETINT:
331 terminx 376
        {
1205 terminx 377
            int32_t pal, r,g,b,f;
99 terminx 378
 
331 terminx 379
            if (scriptfile_getsymbol(script,&pal)) break;
380
            if (scriptfile_getnumber(script,&r)) break;
381
            if (scriptfile_getnumber(script,&g)) break;
382
            if (scriptfile_getnumber(script,&b)) break;
383
            if (scriptfile_getnumber(script,&f)) break; //effects
3382 hendricks2 384
#ifdef USE_OPENGL
331 terminx 385
            hicsetpalettetint(pal,r,g,b,f);
3382 hendricks2 386
#endif
331 terminx 387
        }
388
        break;
109 terminx 389
        case T_ALPHAHACK:
331 terminx 390
        {
1205 terminx 391
            int32_t tile;
331 terminx 392
            double alpha;
99 terminx 393
 
331 terminx 394
            if (scriptfile_getsymbol(script,&tile)) break;
395
            if (scriptfile_getdouble(script,&alpha)) break;
1820 terminx 396
#ifdef USE_OPENGL
2553 helixhorne 397
            if ((uint32_t)tile < MAXTILES)
398
                alphahackarray[tile] = alpha;
163 terminx 399
#endif
331 terminx 400
        }
401
        break;
109 terminx 402
        case T_ALPHAHACKRANGE:
331 terminx 403
        {
3382 hendricks2 404
            int32_t tilenume1,tilenume2;
331 terminx 405
            double alpha;
3382 hendricks2 406
#ifdef USE_OPENGL
407
            int32_t i;
408
#endif
99 terminx 409
 
331 terminx 410
            if (scriptfile_getsymbol(script,&tilenume1)) break;
411
            if (scriptfile_getsymbol(script,&tilenume2)) break;
412
            if (scriptfile_getdouble(script,&alpha)) break;
2588 helixhorne 413
 
414
            if (check_tile_range("alphahackrange", &tilenume1, &tilenume2, script, cmdtokptr))
415
                break;
416
 
1820 terminx 417
#ifdef USE_OPENGL
2588 helixhorne 418
            for (i=tilenume1; i<=tilenume2; i++)
419
                alphahackarray[i] = alpha;
163 terminx 420
#endif
331 terminx 421
        }
422
        break;
109 terminx 423
        case T_SPRITECOL:
331 terminx 424
        {
1205 terminx 425
            int32_t tile,col,col2;
331 terminx 426
 
427
            if (scriptfile_getsymbol(script,&tile)) break;
428
            if (scriptfile_getnumber(script,&col)) break;
429
            if (scriptfile_getnumber(script,&col2)) break;
1205 terminx 430
            if ((uint32_t)tile < MAXTILES)
109 terminx 431
            {
331 terminx 432
                spritecol2d[tile][0] = col;
433
                spritecol2d[tile][1] = col2;
109 terminx 434
            }
331 terminx 435
        }
436
        break;
109 terminx 437
        case T_2DCOL:
331 terminx 438
        {
1205 terminx 439
            int32_t col,b,g,r;
99 terminx 440
 
331 terminx 441
            if (scriptfile_getnumber(script,&col)) break;
442
            if (scriptfile_getnumber(script,&r)) break;
443
            if (scriptfile_getnumber(script,&g)) break;
444
            if (scriptfile_getnumber(script,&b)) break;
99 terminx 445
 
2500 helixhorne 446
            if ((unsigned)col < 256)
584 terminx 447
            {
4232 helixhorne 448
                r = clamp(r, 0, 63);
449
                g = clamp(g, 0, 63);
450
                b = clamp(b, 0, 63);
451
 
331 terminx 452
                vgapal16[col*4+0] = b; // blue
453
                vgapal16[col*4+1] = g; // green
454
                vgapal16[col*4+2] = r; // red
109 terminx 455
            }
331 terminx 456
        }
457
        break;
109 terminx 458
        case T_FOGPAL:
331 terminx 459
        {
2569 helixhorne 460
            int32_t p,r,g,b;
5 Plagman 461
 
331 terminx 462
            if (scriptfile_getnumber(script,&p)) break;
463
            if (scriptfile_getnumber(script,&r)) break;
464
            if (scriptfile_getnumber(script,&g)) break;
465
            if (scriptfile_getnumber(script,&b)) break;
5 Plagman 466
 
2568 helixhorne 467
            r = clamp(r, 0, 63);
468
            g = clamp(g, 0, 63);
469
            b = clamp(b, 0, 63);
470
 
2569 helixhorne 471
            makepalookup(p, NULL, r, g, b, 1);
331 terminx 472
        }
473
        break;
4811 helixhorne 474
        case T_NOFLOORPALRANGE:
475
        {
476
            int32_t b,e,i;
477
 
478
            if (scriptfile_getnumber(script,&b)) break;
479
            if (scriptfile_getnumber(script,&e)) break;
480
 
481
            b = max(b, 1);
482
            e = min(e, MAXPALOOKUPS-1);
483
 
484
            for (i=b; i<=e; i++)
485
                g_noFloorPal[i] = 1;
486
        }
487
        break;
109 terminx 488
        case T_LOADGRP:
331 terminx 489
        {
490
            char *bs;
491
            scriptfile_getstring(script,&bs);
492
        }
493
        break;
441 terminx 494
        case T_CACHESIZE:
495
        {
1205 terminx 496
            int32_t j;
584 terminx 497
 
441 terminx 498
            if (scriptfile_getnumber(script,&j)) break;
499
        }
500
        break;
665 terminx 501
        case T_SETUPTILE:
502
        {
1205 terminx 503
            int32_t tile, tmp;
665 terminx 504
 
505
            if (scriptfile_getsymbol(script,&tile)) break;
4225 helixhorne 506
            if ((unsigned)tile >= MAXUSERTILES) break;
2588 helixhorne 507
            if (scriptfile_getsymbol(script,&h_xsize[tile])) break;  // XXX
665 terminx 508
            if (scriptfile_getsymbol(script,&h_ysize[tile])) break;
509
            if (scriptfile_getsymbol(script,&tmp)) break;
510
            h_xoffs[tile]=tmp;
511
            if (scriptfile_getsymbol(script,&tmp)) break;
512
            h_yoffs[tile]=tmp;
513
            break;
514
        }
515
        case T_SETUPTILERANGE:
516
        {
1205 terminx 517
            int32_t tile1,tile2,xsiz,ysiz,xoffs,yoffs,i;
665 terminx 518
 
519
            if (scriptfile_getnumber(script,&tile1)) break;
520
            if (scriptfile_getnumber(script,&tile2)) break;
521
            if (scriptfile_getnumber(script,&xsiz)) break;
522
            if (scriptfile_getnumber(script,&ysiz)) break;
523
            if (scriptfile_getsymbol(script,&xoffs)) break;
524
            if (scriptfile_getsymbol(script,&yoffs)) break;
2553 helixhorne 525
 
2588 helixhorne 526
            if (check_tile_range("setuptilerange", &tile1, &tile2, script, cmdtokptr))
527
                break;
528
 
529
            for (i=tile1; i<=tile2; i++)
665 terminx 530
            {
2588 helixhorne 531
                h_xsize[i] = xsiz;
532
                h_ysize[i] = ysiz;
533
                h_xoffs[i] = xoffs;
534
                h_yoffs[i] = yoffs;
665 terminx 535
            }
2553 helixhorne 536
 
665 terminx 537
            break;
538
        }
928 hnt_ts 539
        case T_ANIMTILERANGE:
540
        {
2588 helixhorne 541
            int32_t tile1, tile2, spd, type;
928 hnt_ts 542
 
543
            if (scriptfile_getsymbol(script,&tile1)) break;
544
            if (scriptfile_getsymbol(script,&tile2)) break;
545
            if (scriptfile_getsymbol(script,&spd)) break;
546
            if (scriptfile_getsymbol(script,&type)) break;
2588 helixhorne 547
 
548
            if (check_tile_range("animtilerange", &tile1, &tile2, script, cmdtokptr))
549
                break;
550
 
4680 terminx 551
            if (EDUKE32_PREDICT_FALSE(tile2-tile1 > 255))
928 hnt_ts 552
            {
4061 helixhorne 553
                initprintf("Error: animtilerange: tile difference can be at most 255 on line %s:%d\n",
2588 helixhorne 554
                           script->filename, scriptfile_getlinum(script,cmdtokptr));
555
                break;
928 hnt_ts 556
            }
2553 helixhorne 557
 
2588 helixhorne 558
            spd = clamp(spd, 0, 15);
4680 terminx 559
            if (EDUKE32_PREDICT_FALSE(type&~3))
3202 helixhorne 560
            {
4061 helixhorne 561
                initprintf("Error: animtilerange: animation type must be 0, 1, 2 or 3 on line %s:%d\n",
3202 helixhorne 562
                           script->filename, scriptfile_getlinum(script,cmdtokptr));
563
            }
2553 helixhorne 564
 
3202 helixhorne 565
            // set anim speed
566
            picanm[tile1].sf &= ~PICANM_ANIMSPEED_MASK;
567
            picanm[tile1].sf |= spd;
568
            // set anim type
569
            picanm[tile1].sf &= ~PICANM_ANIMTYPE_MASK;
570
            picanm[tile1].sf |= type<<PICANM_ANIMTYPE_SHIFT;
571
            // set anim number
572
            picanm[tile1].num = tile2-tile1;
2588 helixhorne 573
 
928 hnt_ts 574
            break;
575
        }
1151 terminx 576
        case T_TILEFROMTEXTURE:
577
        {
2588 helixhorne 578
            char *texturetokptr = script->ltextptr, *textureend, *fn = NULL;
3973 hendricks2 579
            int32_t tile = -1;
580
            int32_t alphacut = 255, flags = 0;
4402 helixhorne 581
            int32_t havexoffset = 0, haveyoffset = 0;
582
            int32_t xoffset = 0, yoffset = 0;
1151 terminx 583
 
1677 terminx 584
            static const tokenlist tilefromtexturetokens[] =
585
            {
586
                { "file",            T_FILE },
587
                { "name",            T_FILE },
588
                { "alphacut",        T_ALPHACUT },
589
                { "xoffset",         T_XOFFSET },
590
                { "xoff",            T_XOFFSET },
591
                { "yoffset",         T_YOFFSET },
592
                { "yoff",            T_YOFFSET },
3078 helixhorne 593
                { "texhitscan",      T_TEXHITSCAN },
3230 helixhorne 594
                { "nofullbright",    T_NOFULLBRIGHT },
1677 terminx 595
            };
596
 
1151 terminx 597
            if (scriptfile_getsymbol(script,&tile)) break;
598
            if (scriptfile_getbraces(script,&textureend)) break;
599
            while (script->textptr < textureend)
600
            {
4385 terminx 601
                int32_t token = getatoken(script,tilefromtexturetokens,ARRAY_SIZE(tilefromtexturetokens));
1151 terminx 602
                switch (token)
603
                {
604
                case T_FILE:
605
                    scriptfile_getstring(script,&fn); break;
606
                case T_ALPHACUT:
607
                    scriptfile_getsymbol(script,&alphacut); break;
1188 terminx 608
                case T_XOFFSET:
4402 helixhorne 609
                    havexoffset = 1;
1188 terminx 610
                    scriptfile_getsymbol(script,&xoffset); break;
611
                case T_YOFFSET:
4402 helixhorne 612
                    haveyoffset = 1;
1188 terminx 613
                    scriptfile_getsymbol(script,&yoffset); break;
3078 helixhorne 614
                case T_TEXHITSCAN:
3973 hendricks2 615
                    flags |= PICANM_TEXHITSCAN_BIT;
3078 helixhorne 616
                    break;
3973 hendricks2 617
                case T_NOFULLBRIGHT:
618
                    flags |= PICANM_NOFULLBRIGHT_BIT;
619
                    break;
1151 terminx 620
                default:
621
                    break;
622
                }
623
            }
624
 
4680 terminx 625
            if (EDUKE32_PREDICT_FALSE((unsigned)tile >= MAXUSERTILES))
1151 terminx 626
            {
4061 helixhorne 627
                initprintf("Error: missing or invalid 'tile number' for texture definition near line %s:%d\n",
1151 terminx 628
                           script->filename, scriptfile_getlinum(script,texturetokptr));
629
                break;
630
            }
631
 
3078 helixhorne 632
            if (!fn)
1151 terminx 633
            {
3973 hendricks2 634
                // tilefromtexture <tile> { texhitscan }  sets the bit but doesn't change tile data
635
                picanm[tile].sf |= flags;
4402 helixhorne 636
                if (havexoffset)
3973 hendricks2 637
                    picanm[tile].xofs = clamp(xoffset, -128, 127);
4402 helixhorne 638
                if (haveyoffset)
3973 hendricks2 639
                    picanm[tile].yofs = clamp(yoffset, -128, 127);
3230 helixhorne 640
 
4680 terminx 641
                if (EDUKE32_PREDICT_FALSE(flags == 0 && !havexoffset && !haveyoffset))
3835 hendricks2 642
                    initprintf("\nError: missing 'file name' for tilefromtexture definition near line %s:%d",
3078 helixhorne 643
                               script->filename, scriptfile_getlinum(script,texturetokptr));
644
                break;
645
            }
646
 
647
            if (check_file_exist(fn))
648
                break;
649
 
650
            alphacut = clamp(alphacut, 0, 255);
651
 
652
            {
2588 helixhorne 653
                int32_t xsiz, ysiz, j;
654
                palette_t *picptr = NULL;
1151 terminx 655
 
656
                kpzload(fn, (intptr_t *)&picptr, &j, &xsiz, &ysiz);
4061 helixhorne 657
//                initprintf("got bpl %d xsiz %d ysiz %d\n",bpl,xsiz,ysiz);
1151 terminx 658
 
2588 helixhorne 659
                if (!picptr)
660
                    break;
1151 terminx 661
 
2588 helixhorne 662
                if (xsiz <= 0 || ysiz <= 0)
663
                    break;
1151 terminx 664
 
3202 helixhorne 665
                set_tilesiz(tile, xsiz, ysiz);
4402 helixhorne 666
                picanm[tile].xofs = havexoffset ? clamp(xoffset, -128, 127) : 0;
667
                picanm[tile].yofs = haveyoffset ? clamp(yoffset, -128, 127) : 0;
3973 hendricks2 668
                picanm[tile].sf |= flags;
1151 terminx 669
 
2588 helixhorne 670
                tile_from_truecolpic(tile, picptr, alphacut);
1541 terminx 671
 
1151 terminx 672
                Bfree(picptr);
673
            }
674
        }
675
        break;
1150 terminx 676
        case T_IMPORTTILE:
677
        {
2588 helixhorne 678
            int32_t tile, xsiz, ysiz;
679
            palette_t *picptr = NULL;
1205 terminx 680
            int32_t bpl;
2588 helixhorne 681
            char *fn;
1150 terminx 682
 
683
            if (scriptfile_getsymbol(script,&tile)) break;
684
            if (scriptfile_getstring(script,&fn))  break;
685
 
686
            kpzload(fn, (intptr_t *)&picptr, &bpl, &xsiz, &ysiz);
4061 helixhorne 687
//            initprintf("got bpl %d xsiz %d ysiz %d\n",bpl,xsiz,ysiz);
1150 terminx 688
 
2588 helixhorne 689
            if (!picptr)
690
                break;  // TODO: message
1150 terminx 691
 
2588 helixhorne 692
            if (xsiz <= 0 || ysiz <= 0)  // XXX: kpzload isn't robust against that!
693
                break;
1150 terminx 694
 
4186 helixhorne 695
            if (check_tile("importtile", tile, script, cmdtokptr))
2588 helixhorne 696
                break;
1150 terminx 697
 
3202 helixhorne 698
            set_tilesiz(tile, xsiz, ysiz);
699
            Bmemset(&picanm[tile], 0, sizeof(picanm_t));
1150 terminx 700
 
2588 helixhorne 701
            tile_from_truecolpic(tile, picptr, 255);
702
 
1151 terminx 703
            Bfree(picptr);
1150 terminx 704
            break;
705
        }
116 terminx 706
        case T_DUMMYTILE:
331 terminx 707
        {
2588 helixhorne 708
            int32_t tile, xsiz, ysiz;
331 terminx 709
 
710
            if (scriptfile_getsymbol(script,&tile)) break;
711
            if (scriptfile_getsymbol(script,&xsiz)) break;
712
            if (scriptfile_getsymbol(script,&ysiz)) break;
713
 
714
            if (xsiz > 0 && ysiz > 0)
116 terminx 715
            {
3202 helixhorne 716
                set_tilesiz(tile, xsiz, ysiz);
717
                Bmemset(&picanm[tile], 0, sizeof(picanm_t));
1541 terminx 718
                faketilesiz[tile] = -1;
331 terminx 719
            }
116 terminx 720
 
331 terminx 721
            break;
722
        }
723
        case T_DUMMYTILERANGE:
724
        {
2588 helixhorne 725
            int32_t tile1,tile2,xsiz,ysiz,i;
257 terminx 726
 
331 terminx 727
            if (scriptfile_getnumber(script,&tile1)) break;
728
            if (scriptfile_getnumber(script,&tile2)) break;
729
            if (scriptfile_getnumber(script,&xsiz)) break;
730
            if (scriptfile_getnumber(script,&ysiz)) break;
2588 helixhorne 731
 
732
            if (check_tile_range("dummytilerange", &tile1, &tile2, script, cmdtokptr))
733
                break;
734
 
735
            if (xsiz <= 0 || ysiz <= 0)
736
                break;  // TODO: message
737
 
738
            for (i=tile1; i<=tile2; i++)
584 terminx 739
            {
3202 helixhorne 740
                set_tilesiz(i, xsiz, ysiz);
741
                Bmemset(&picanm[i], 0, sizeof(picanm_t));
2588 helixhorne 742
                faketilesiz[i] = -1;
116 terminx 743
            }
330 terminx 744
 
331 terminx 745
            break;
746
        }
116 terminx 747
 
109 terminx 748
        case T_DEFINEMODEL:
331 terminx 749
        {
750
            char *modelfn;
751
            double scale;
1205 terminx 752
            int32_t shadeoffs;
99 terminx 753
 
331 terminx 754
            if (scriptfile_getstring(script,&modelfn)) break;
755
            if (scriptfile_getdouble(script,&scale)) break;
756
            if (scriptfile_getnumber(script,&shadeoffs)) break;
99 terminx 757
 
1820 terminx 758
#ifdef USE_OPENGL
331 terminx 759
            lastmodelid = md_loadmodel(modelfn);
4680 terminx 760
            if (EDUKE32_PREDICT_FALSE(lastmodelid < 0))
584 terminx 761
            {
4061 helixhorne 762
                initprintf("Warning: Failed loading MD2/MD3 model \"%s\"\n", modelfn);
331 terminx 763
                break;
764
            }
2264 hendricks2 765
            md_setmisc(lastmodelid,(float)scale, shadeoffs,0.0,0.0,0);
3467 helixhorne 766
# ifdef POLYMER
3784 terminx 767
            if (glrendmode == REND_POLYMER)
1910 helixhorne 768
                md3postload_polymer((md3model_t *)models[lastmodelid]);
3467 helixhorne 769
# endif
99 terminx 770
#endif
331 terminx 771
            modelskin = lastmodelskin = 0;
772
            seenframe = 0;
773
        }
774
        break;
109 terminx 775
        case T_DEFINEMODELFRAME:
331 terminx 776
        {
895 terminx 777
            char *framename;
1820 terminx 778
#ifdef USE_OPENGL
895 terminx 779
            char happy=1;
3382 hendricks2 780
            int32_t tilex;
895 terminx 781
#endif
3382 hendricks2 782
            int32_t ftilenume, ltilenume;
99 terminx 783
 
331 terminx 784
            if (scriptfile_getstring(script,&framename)) break;
785
            if (scriptfile_getnumber(script,&ftilenume)) break; //first tile number
786
            if (scriptfile_getnumber(script,&ltilenume)) break; //last tile number (inclusive)
99 terminx 787
 
2588 helixhorne 788
            if (check_tile_range("definemodelframe", &ftilenume, &ltilenume, script, cmdtokptr))
789
                break;
790
 
4680 terminx 791
            if (EDUKE32_PREDICT_FALSE(lastmodelid < 0))
584 terminx 792
            {
2288 helixhorne 793
#ifdef USE_OPENGL
4061 helixhorne 794
                initprintf("Warning: Ignoring frame definition.\n");
2288 helixhorne 795
#endif
331 terminx 796
                break;
797
            }
1820 terminx 798
#ifdef USE_OPENGL
584 terminx 799
            for (tilex = ftilenume; tilex <= ltilenume && happy; tilex++)
800
            {
587 terminx 801
                switch (md_defineframe(lastmodelid, framename, tilex, max(0,modelskin), 0.0f,0))
584 terminx 802
                {
331 terminx 803
                case -1:
804
                    happy = 0; break; // invalid model id!?
805
                case -2:
4061 helixhorne 806
                    initprintf("Invalid tile number on line %s:%d\n",
331 terminx 807
                               script->filename, scriptfile_getlinum(script,cmdtokptr));
808
                    happy = 0;
809
                    break;
810
                case -3:
4061 helixhorne 811
                    initprintf("Invalid frame name on line %s:%d\n",
331 terminx 812
                               script->filename, scriptfile_getlinum(script,cmdtokptr));
813
                    happy = 0;
814
                    break;
1910 helixhorne 815
                default:
816
                    break;
109 terminx 817
                }
331 terminx 818
            }
99 terminx 819
#endif
331 terminx 820
            seenframe = 1;
821
        }
822
        break;
109 terminx 823
        case T_DEFINEMODELANIM:
331 terminx 824
        {
825
            char *startframe, *endframe;
1205 terminx 826
            int32_t flags;
331 terminx 827
            double dfps;
99 terminx 828
 
331 terminx 829
            if (scriptfile_getstring(script,&startframe)) break;
830
            if (scriptfile_getstring(script,&endframe)) break;
831
            if (scriptfile_getdouble(script,&dfps)) break; //animation frame rate
832
            if (scriptfile_getnumber(script,&flags)) break;
99 terminx 833
 
4680 terminx 834
            if (EDUKE32_PREDICT_FALSE(lastmodelid < 0))
584 terminx 835
            {
2288 helixhorne 836
#ifdef USE_OPENGL
4061 helixhorne 837
                initprintf("Warning: Ignoring animation definition.\n");
2288 helixhorne 838
#endif
331 terminx 839
                break;
840
            }
1820 terminx 841
#ifdef USE_OPENGL
1205 terminx 842
            switch (md_defineanimation(lastmodelid, startframe, endframe, (int32_t)(dfps*(65536.0*.001)), flags))
584 terminx 843
            {
331 terminx 844
            case 0:
845
                break;
846
            case -1:
847
                break; // invalid model id!?
848
            case -2:
4061 helixhorne 849
                initprintf("Invalid starting frame name on line %s:%d\n",
331 terminx 850
                           script->filename, scriptfile_getlinum(script,cmdtokptr));
851
                break;
852
            case -3:
4061 helixhorne 853
                initprintf("Invalid ending frame name on line %s:%d\n",
331 terminx 854
                           script->filename, scriptfile_getlinum(script,cmdtokptr));
855
                break;
856
            case -4:
4061 helixhorne 857
                initprintf("Out of memory on line %s:%d\n",
331 terminx 858
                           script->filename, scriptfile_getlinum(script,cmdtokptr));
859
                break;
860
            }
99 terminx 861
#endif
331 terminx 862
        }
863
        break;
109 terminx 864
        case T_DEFINEMODELSKIN:
331 terminx 865
        {
2554 helixhorne 866
            int32_t palnum;
867
            char *skinfn;
99 terminx 868
 
331 terminx 869
            if (scriptfile_getsymbol(script,&palnum)) break;
870
            if (scriptfile_getstring(script,&skinfn)) break; //skin filename
99 terminx 871
 
331 terminx 872
            // if we see a sequence of definemodelskin, then a sequence of definemodelframe,
873
            // and then a definemodelskin, we need to increment the skin counter.
874
            //
875
            // definemodel "mymodel.md2" 1 1
876
            // definemodelskin 0 "normal.png"   // skin 0
877
            // definemodelskin 21 "normal21.png"
878
            // definemodelframe "foo" 1000 1002   // these use skin 0
879
            // definemodelskin 0 "wounded.png"   // skin 1
880
            // definemodelskin 21 "wounded21.png"
881
            // definemodelframe "foo2" 1003 1004   // these use skin 1
882
            // selectmodelskin 0         // resets to skin 0
883
            // definemodelframe "foo3" 1005 1006   // these use skin 0
584 terminx 884
            if (seenframe) { modelskin = ++lastmodelskin; }
331 terminx 885
            seenframe = 0;
109 terminx 886
 
2554 helixhorne 887
            if (check_file_exist(skinfn))
888
                break;
2436 hendricks2 889
 
1820 terminx 890
#ifdef USE_OPENGL
1279 plagman 891
            switch (md_defineskin(lastmodelid, skinfn, palnum, max(0,modelskin), 0, 0.0f, 1.0f, 1.0f))
584 terminx 892
            {
331 terminx 893
            case 0:
894
                break;
895
            case -1:
896
                break; // invalid model id!?
897
            case -2:
4061 helixhorne 898
                initprintf("Invalid skin filename on line %s:%d\n",
331 terminx 899
                           script->filename, scriptfile_getlinum(script,cmdtokptr));
900
                break;
901
            case -3:
4061 helixhorne 902
                initprintf("Invalid palette number on line %s:%d\n",
331 terminx 903
                           script->filename, scriptfile_getlinum(script,cmdtokptr));
904
                break;
905
            case -4:
4061 helixhorne 906
                initprintf("Out of memory on line %s:%d\n",
331 terminx 907
                           script->filename, scriptfile_getlinum(script,cmdtokptr));
908
                break;
109 terminx 909
            }
331 terminx 910
#endif
911
        }
912
        break;
109 terminx 913
        case T_SELECTMODELSKIN:
331 terminx 914
        {
915
            if (scriptfile_getsymbol(script,&modelskin)) break;
916
        }
917
        break;
109 terminx 918
        case T_DEFINEVOXEL:
331 terminx 919
        {
920
            char *fn;
99 terminx 921
 
4834 helixhorne 922
            if (EDUKE32_PREDICT_FALSE(scriptfile_getstring(script,&fn)))
923
                break; //voxel filename
99 terminx 924
 
4680 terminx 925
            if (EDUKE32_PREDICT_FALSE(nextvoxid == MAXVOXELS))
584 terminx 926
            {
4835 helixhorne 927
                initprintf("Maximum number of voxels (%d) already defined.\n", MAXVOXELS);
331 terminx 928
                break;
929
            }
99 terminx 930
 
4680 terminx 931
            if (EDUKE32_PREDICT_FALSE(qloadkvx(nextvoxid, fn)))
584 terminx 932
            {
4061 helixhorne 933
                initprintf("Failure loading voxel file \"%s\"\n",fn);
331 terminx 934
                break;
935
            }
99 terminx 936
 
331 terminx 937
            lastvoxid = nextvoxid++;
938
        }
939
        break;
109 terminx 940
        case T_DEFINEVOXELTILES:
331 terminx 941
        {
1205 terminx 942
            int32_t ftilenume, ltilenume, tilex;
99 terminx 943
 
331 terminx 944
            if (scriptfile_getnumber(script,&ftilenume)) break; //1st tile #
945
            if (scriptfile_getnumber(script,&ltilenume)) break; //last tile #
99 terminx 946
 
2588 helixhorne 947
            if (check_tile_range("definevoxeltiles", &ftilenume, &ltilenume, script, cmdtokptr))
331 terminx 948
                break;
99 terminx 949
 
4680 terminx 950
            if (EDUKE32_PREDICT_FALSE(lastvoxid < 0))
584 terminx 951
            {
4061 helixhorne 952
                initprintf("Warning: Ignoring voxel tiles definition.\n");
331 terminx 953
                break;
954
            }
1820 terminx 955
 
584 terminx 956
            for (tilex = ftilenume; tilex <= ltilenume; tilex++)
331 terminx 957
                tiletovox[tilex] = lastvoxid;
958
        }
959
        break;
99 terminx 960
 
331 terminx 961
        // NEW (ENCOURAGED) DEFINITION SYNTAX
109 terminx 962
        case T_MODEL:
331 terminx 963
        {
964
            char *modelend, *modelfn;
2264 hendricks2 965
            double scale=1.0, mzadd=0.0, myoffset=0.0;
1205 terminx 966
            int32_t shadeoffs=0, pal=0, flags=0;
1910 helixhorne 967
            uint8_t usedframebitmap[1024>>3];
99 terminx 968
 
2237 helixhorne 969
            int32_t model_ok = 1;
970
 
1677 terminx 971
            static const tokenlist modeltokens[] =
972
            {
973
                { "scale",    T_SCALE    },
974
                { "shade",    T_SHADE    },
975
                { "zadd",     T_ZADD     },
2264 hendricks2 976
                { "yoffset",  T_YOFFSET  },
1677 terminx 977
                { "frame",    T_FRAME    },
978
                { "anim",     T_ANIM     },
979
                { "skin",     T_SKIN     },
980
                { "detail",   T_DETAIL   },
981
                { "glow",     T_GLOW     },
982
                { "specular", T_SPECULAR },
983
                { "normal",   T_NORMAL   },
984
                { "hud",      T_HUD      },
985
                { "flags",    T_FLAGS    },
986
            };
987
 
1925 helixhorne 988
            Bmemset(usedframebitmap, 0, sizeof(usedframebitmap));
989
 
331 terminx 990
            modelskin = lastmodelskin = 0;
991
            seenframe = 0;
99 terminx 992
 
331 terminx 993
            if (scriptfile_getstring(script,&modelfn)) break;
875 terminx 994
            if (scriptfile_getbraces(script,&modelend)) break;
1820 terminx 995
#ifdef USE_OPENGL
331 terminx 996
            lastmodelid = md_loadmodel(modelfn);
4680 terminx 997
            if (EDUKE32_PREDICT_FALSE(lastmodelid < 0))
584 terminx 998
            {
4061 helixhorne 999
                initprintf("Warning: Failed loading MD2/MD3 model \"%s\"\n", modelfn);
875 terminx 1000
                script->textptr = modelend+1;
331 terminx 1001
                break;
1002
            }
99 terminx 1003
#endif
584 terminx 1004
            while (script->textptr < modelend)
1005
            {
4385 terminx 1006
                int32_t token = getatoken(script,modeltokens,ARRAY_SIZE(modeltokens));
584 terminx 1007
                switch (token)
1008
                {
4061 helixhorne 1009
                    //case T_ERROR: initprintf("Error on line %s:%d in model tokens\n", script->filename,script->linenum); break;
331 terminx 1010
                case T_SCALE:
1011
                    scriptfile_getdouble(script,&scale); break;
1012
                case T_SHADE:
1013
                    scriptfile_getnumber(script,&shadeoffs); break;
1014
                case T_ZADD:
1015
                    scriptfile_getdouble(script,&mzadd); break;
2264 hendricks2 1016
                case T_YOFFSET:
1017
                    scriptfile_getdouble(script,&myoffset); break;
587 terminx 1018
                case T_FLAGS:
1019
                    scriptfile_getnumber(script,&flags); break;
331 terminx 1020
                case T_FRAME:
1021
                {
1022
                    char *frametokptr = script->ltextptr;
3382 hendricks2 1023
                    char *frameend, *framename = 0;
1024
#ifdef USE_OPENGL
1025
                    char happy=1;
1026
                    int32_t tilex = 0, framei;
1027
#endif
1028
                    int32_t ftilenume = -1, ltilenume = -1;
1178 terminx 1029
                    double smoothduration = 0.1f;
99 terminx 1030
 
1677 terminx 1031
                    static const tokenlist modelframetokens[] =
1032
                    {
1033
                        { "pal",              T_PAL               },
1034
                        { "frame",            T_FRAME             },
1035
                        { "name",             T_FRAME             },
1036
                        { "tile",             T_TILE              },
1037
                        { "tile0",            T_TILE0             },
1038
                        { "tile1",            T_TILE1             },
1039
                        { "smoothduration",   T_SMOOTHDURATION    },
1040
                    };
1041
 
331 terminx 1042
                    if (scriptfile_getbraces(script,&frameend)) break;
584 terminx 1043
                    while (script->textptr < frameend)
1044
                    {
4385 terminx 1045
                        switch (getatoken(script,modelframetokens,ARRAY_SIZE(modelframetokens)))
584 terminx 1046
                        {
587 terminx 1047
                        case T_PAL:
1048
                            scriptfile_getnumber(script,&pal); break;
331 terminx 1049
                        case T_FRAME:
1050
                            scriptfile_getstring(script,&framename); break;
1051
                        case T_TILE:
1052
                            scriptfile_getsymbol(script,&ftilenume); ltilenume = ftilenume; break;
1053
                        case T_TILE0:
1054
                            scriptfile_getsymbol(script,&ftilenume); break; //first tile number
1055
                        case T_TILE1:
1056
                            scriptfile_getsymbol(script,&ltilenume); break; //last tile number (inclusive)
531 Plagman 1057
                        case T_SMOOTHDURATION:
1058
                            scriptfile_getdouble(script,&smoothduration); break;
331 terminx 1059
                        }
1060
                    }
99 terminx 1061
 
2588 helixhorne 1062
                    if (check_tile_range("model: frame", &ftilenume, &ltilenume, script, frametokptr))
584 terminx 1063
                    {
2588 helixhorne 1064
                        model_ok = 0;
1065
                        break;
331 terminx 1066
                    }
99 terminx 1067
 
4680 terminx 1068
                    if (EDUKE32_PREDICT_FALSE(lastmodelid < 0))
584 terminx 1069
                    {
2288 helixhorne 1070
#ifdef USE_OPENGL
4061 helixhorne 1071
                        initprintf("Warning: Ignoring frame definition.\n");
2288 helixhorne 1072
#endif
331 terminx 1073
                        break;
1074
                    }
1820 terminx 1075
#ifdef USE_OPENGL
584 terminx 1076
                    for (tilex = ftilenume; tilex <= ltilenume && happy; tilex++)
1077
                    {
1910 helixhorne 1078
                        framei = md_defineframe(lastmodelid, framename, tilex, max(0,modelskin), smoothduration,pal);
1079
                        switch (framei)
584 terminx 1080
                        {
331 terminx 1081
                        case -1:
1082
                            happy = 0; break; // invalid model id!?
1083
                        case -2:
4061 helixhorne 1084
                            initprintf("Invalid tile number on line %s:%d\n",
331 terminx 1085
                                       script->filename, scriptfile_getlinum(script,frametokptr));
1086
                            happy = 0;
1087
                            break;
1088
                        case -3:
4061 helixhorne 1089
                            initprintf("Invalid frame name on line %s:%d\n",
331 terminx 1090
                                       script->filename, scriptfile_getlinum(script,frametokptr));
1091
                            happy = 0;
1092
                            break;
1910 helixhorne 1093
                        default:
1094
                            if (framei >= 0 && framei<1024)
1095
                                usedframebitmap[framei>>3] |= (1<<(framei&7));
331 terminx 1096
                        }
2237 helixhorne 1097
 
1098
                        model_ok &= happy;
331 terminx 1099
                    }
99 terminx 1100
#endif
331 terminx 1101
                    seenframe = 1;
1102
                }
1103
                break;
1104
                case T_ANIM:
1105
                {
1106
                    char *animtokptr = script->ltextptr;
1107
                    char *animend, *startframe = 0, *endframe = 0, happy=1;
1205 terminx 1108
                    int32_t flags = 0;
331 terminx 1109
                    double dfps = 1.0;
1110
 
1677 terminx 1111
                    static const tokenlist modelanimtokens[] =
1112
                    {
1113
                        { "frame0", T_FRAME0 },
1114
                        { "frame1", T_FRAME1 },
1115
                        { "fps",    T_FPS    },
1116
                        { "flags",  T_FLAGS  },
1117
                    };
1118
 
331 terminx 1119
                    if (scriptfile_getbraces(script,&animend)) break;
584 terminx 1120
                    while (script->textptr < animend)
1121
                    {
4385 terminx 1122
                        switch (getatoken(script,modelanimtokens,ARRAY_SIZE(modelanimtokens)))
584 terminx 1123
                        {
331 terminx 1124
                        case T_FRAME0:
1125
                            scriptfile_getstring(script,&startframe); break;
1126
                        case T_FRAME1:
1127
                            scriptfile_getstring(script,&endframe); break;
1128
                        case T_FPS:
1129
                            scriptfile_getdouble(script,&dfps); break; //animation frame rate
1130
                        case T_FLAGS:
1131
                            scriptfile_getsymbol(script,&flags); break;
109 terminx 1132
                        }
331 terminx 1133
                    }
99 terminx 1134
 
4680 terminx 1135
                    if (EDUKE32_PREDICT_FALSE(!startframe)) initprintf("Error: missing 'start frame' for anim definition near line %s:%d\n", script->filename, scriptfile_getlinum(script,animtokptr)), happy = 0;
1136
                    if (EDUKE32_PREDICT_FALSE(!endframe)) initprintf("Error: missing 'end frame' for anim definition near line %s:%d\n", script->filename, scriptfile_getlinum(script,animtokptr)), happy = 0;
2237 helixhorne 1137
                    model_ok &= happy;
4680 terminx 1138
                    if (EDUKE32_PREDICT_FALSE(!happy)) break;
99 terminx 1139
 
4680 terminx 1140
                    if (EDUKE32_PREDICT_FALSE(lastmodelid < 0))
584 terminx 1141
                    {
2288 helixhorne 1142
#ifdef USE_OPENGL
4061 helixhorne 1143
                        initprintf("Warning: Ignoring animation definition.\n");
2288 helixhorne 1144
#endif
331 terminx 1145
                        break;
1146
                    }
1820 terminx 1147
#ifdef USE_OPENGL
1205 terminx 1148
                    switch (md_defineanimation(lastmodelid, startframe, endframe, (int32_t)(dfps*(65536.0*.001)), flags))
584 terminx 1149
                    {
331 terminx 1150
                    case 0:
1151
                        break;
1152
                    case -1:
1153
                        break; // invalid model id!?
1154
                    case -2:
4061 helixhorne 1155
                        initprintf("Invalid starting frame name on line %s:%d\n",
331 terminx 1156
                                   script->filename, scriptfile_getlinum(script,animtokptr));
2237 helixhorne 1157
                        model_ok = 0;
331 terminx 1158
                        break;
1159
                    case -3:
4061 helixhorne 1160
                        initprintf("Invalid ending frame name on line %s:%d\n",
331 terminx 1161
                                   script->filename, scriptfile_getlinum(script,animtokptr));
2237 helixhorne 1162
                        model_ok = 0;
331 terminx 1163
                        break;
1164
                    case -4:
4061 helixhorne 1165
                        initprintf("Out of memory on line %s:%d\n",
331 terminx 1166
                                   script->filename, scriptfile_getlinum(script,animtokptr));
2237 helixhorne 1167
                        model_ok = 0;
331 terminx 1168
                        break;
1169
                    }
99 terminx 1170
#endif
584 terminx 1171
                }
1172
                break;
1350 terminx 1173
                case T_SKIN: case T_DETAIL: case T_GLOW: case T_SPECULAR: case T_NORMAL:
331 terminx 1174
                {
1175
                    char *skintokptr = script->ltextptr;
2554 helixhorne 1176
                    char *skinend, *skinfn = 0;
1177
                    int32_t palnum = 0, surfnum = 0;
1279 plagman 1178
                    double param = 1.0, specpower = 1.0, specfactor = 1.0;
99 terminx 1179
 
1677 terminx 1180
                    static const tokenlist modelskintokens[] =
1181
                    {
1182
                        { "pal",           T_PAL        },
1183
                        { "file",          T_FILE       },
1184
                        { "surf",          T_SURF       },
1185
                        { "surface",       T_SURF       },
1186
                        { "intensity",     T_PARAM      },
1187
                        { "scale",         T_PARAM      },
1188
                        { "detailscale",   T_PARAM      },
2539 hendricks2 1189
                        { "specpower",     T_SPECPOWER  }, { "specularpower",  T_SPECPOWER  }, { "parallaxscale", T_SPECPOWER },
1190
                        { "specfactor",    T_SPECFACTOR }, { "specularfactor", T_SPECFACTOR }, { "parallaxbias", T_SPECFACTOR },
5010 terminx 1191
 
1677 terminx 1192
                    };
1193
 
331 terminx 1194
                    if (scriptfile_getbraces(script,&skinend)) break;
584 terminx 1195
                    while (script->textptr < skinend)
1196
                    {
4385 terminx 1197
                        switch (getatoken(script,modelskintokens,ARRAY_SIZE(modelskintokens)))
584 terminx 1198
                        {
331 terminx 1199
                        case T_PAL:
1200
                            scriptfile_getsymbol(script,&palnum); break;
501 Plagman 1201
                        case T_PARAM:
1202
                            scriptfile_getdouble(script,&param); break;
1279 plagman 1203
                        case T_SPECPOWER:
1204
                            scriptfile_getdouble(script,&specpower); break;
1205
                        case T_SPECFACTOR:
1206
                            scriptfile_getdouble(script,&specfactor); break;
331 terminx 1207
                        case T_FILE:
1208
                            scriptfile_getstring(script,&skinfn); break; //skin filename
1209
                        case T_SURF:
1210
                            scriptfile_getnumber(script,&surfnum); break;
1211
                        }
1212
                    }
99 terminx 1213
 
4680 terminx 1214
                    if (EDUKE32_PREDICT_FALSE(!skinfn))
584 terminx 1215
                    {
4061 helixhorne 1216
                        initprintf("Error: missing 'skin filename' for skin definition near line %s:%d\n", script->filename, scriptfile_getlinum(script,skintokptr));
2237 helixhorne 1217
                        model_ok = 0;
331 terminx 1218
                        break;
1219
                    }
99 terminx 1220
 
331 terminx 1221
                    if (seenframe) { modelskin = ++lastmodelskin; }
1222
                    seenframe = 0;
99 terminx 1223
 
587 terminx 1224
                    switch (token)
501 Plagman 1225
                    {
587 terminx 1226
                    case T_DETAIL:
501 Plagman 1227
                        palnum = DETAILPAL;
1228
                        param = 1.0f / param;
587 terminx 1229
                        break;
1230
                    case T_GLOW:
1231
                        palnum = GLOWPAL;
1232
                        break;
1350 terminx 1233
                    case T_SPECULAR:
1234
                        palnum = SPECULARPAL;
1235
                        break;
1236
                    case T_NORMAL:
1237
                        palnum = NORMALPAL;
1238
                        break;
501 Plagman 1239
                    }
1240
 
2554 helixhorne 1241
                    if (check_file_exist(skinfn))
1242
                        break;
2436 hendricks2 1243
 
1820 terminx 1244
#ifdef USE_OPENGL
1279 plagman 1245
                    switch (md_defineskin(lastmodelid, skinfn, palnum, max(0,modelskin), surfnum, param, specpower, specfactor))
584 terminx 1246
                    {
331 terminx 1247
                    case 0:
1248
                        break;
1249
                    case -1:
1250
                        break; // invalid model id!?
1251
                    case -2:
4061 helixhorne 1252
                        initprintf("Invalid skin filename on line %s:%d\n",
331 terminx 1253
                                   script->filename, scriptfile_getlinum(script,skintokptr));
2237 helixhorne 1254
                        model_ok = 0;
331 terminx 1255
                        break;
1256
                    case -3:
4061 helixhorne 1257
                        initprintf("Invalid palette number on line %s:%d\n",
331 terminx 1258
                                   script->filename, scriptfile_getlinum(script,skintokptr));
2237 helixhorne 1259
                        model_ok = 0;
331 terminx 1260
                        break;
1261
                    case -4:
4061 helixhorne 1262
                        initprintf("Out of memory on line %s:%d\n",
331 terminx 1263
                                   script->filename, scriptfile_getlinum(script,skintokptr));
2237 helixhorne 1264
                        model_ok = 0;
331 terminx 1265
                        break;
1266
                    }
99 terminx 1267
#endif
584 terminx 1268
                }
1269
                break;
331 terminx 1270
                case T_HUD:
1271
                {
1272
                    char *hudtokptr = script->ltextptr;
3382 hendricks2 1273
                    char *frameend;
1274
#ifdef USE_OPENGL
1275
                    char happy=1;
1276
                    int32_t tilex = 0;
1277
#endif
4607 terminx 1278
                    int32_t ftilenume = -1, ltilenume = -1, flags = 0, fov = -1, angadd = 0;
1279
                    double xadd = 0.0, yadd = 0.0, zadd = 0.0;
99 terminx 1280
 
1677 terminx 1281
                    static const tokenlist modelhudtokens[] =
1282
                    {
1283
                        { "tile",   T_TILE   },
1284
                        { "tile0",  T_TILE0  },
1285
                        { "tile1",  T_TILE1  },
1286
                        { "xadd",   T_XADD   },
1287
                        { "yadd",   T_YADD   },
1288
                        { "zadd",   T_ZADD   },
1289
                        { "angadd", T_ANGADD },
1814 plagman 1290
                        { "fov",    T_FOV    },
1677 terminx 1291
                        { "hide",   T_HIDE   },
1292
                        { "nobob",  T_NOBOB  },
1293
                        { "flipped",T_FLIPPED},
1294
                        { "nodepth",T_NODEPTH},
1295
                    };
1296
 
331 terminx 1297
                    if (scriptfile_getbraces(script,&frameend)) break;
584 terminx 1298
                    while (script->textptr < frameend)
1299
                    {
4385 terminx 1300
                        switch (getatoken(script,modelhudtokens,ARRAY_SIZE(modelhudtokens)))
584 terminx 1301
                        {
331 terminx 1302
                        case T_TILE:
1303
                            scriptfile_getsymbol(script,&ftilenume); ltilenume = ftilenume; break;
1304
                        case T_TILE0:
1305
                            scriptfile_getsymbol(script,&ftilenume); break; //first tile number
1306
                        case T_TILE1:
1307
                            scriptfile_getsymbol(script,&ltilenume); break; //last tile number (inclusive)
1308
                        case T_XADD:
1309
                            scriptfile_getdouble(script,&xadd); break;
1310
                        case T_YADD:
1311
                            scriptfile_getdouble(script,&yadd); break;
1312
                        case T_ZADD:
1313
                            scriptfile_getdouble(script,&zadd); break;
1314
                        case T_ANGADD:
4607 terminx 1315
                            scriptfile_getsymbol(script,&angadd); break;
1814 plagman 1316
                        case T_FOV:
1317
                            scriptfile_getsymbol(script,&fov); break;
331 terminx 1318
                        case T_HIDE:
4174 helixhorne 1319
                            flags |= HUDFLAG_HIDE; break;
331 terminx 1320
                        case T_NOBOB:
4174 helixhorne 1321
                            flags |= HUDFLAG_NOBOB; break;
331 terminx 1322
                        case T_FLIPPED:
4174 helixhorne 1323
                            flags |= HUDFLAG_FLIPPED; break;
331 terminx 1324
                        case T_NODEPTH:
4174 helixhorne 1325
                            flags |= HUDFLAG_NODEPTH; break;
331 terminx 1326
                        }
1327
                    }
99 terminx 1328
 
4680 terminx 1329
                    if (EDUKE32_PREDICT_FALSE(check_tile_range("hud", &ftilenume, &ltilenume, script, hudtokptr)))
584 terminx 1330
                    {
2588 helixhorne 1331
                        model_ok = 0;
1332
                        break;
331 terminx 1333
                    }
99 terminx 1334
 
4680 terminx 1335
                    if (EDUKE32_PREDICT_FALSE(lastmodelid < 0))
584 terminx 1336
                    {
2288 helixhorne 1337
#ifdef USE_OPENGL
4061 helixhorne 1338
                        initprintf("Warning: Ignoring frame definition.\n");
2288 helixhorne 1339
#endif
331 terminx 1340
                        break;
1341
                    }
1820 terminx 1342
#ifdef USE_OPENGL
584 terminx 1343
                    for (tilex = ftilenume; tilex <= ltilenume && happy; tilex++)
1344
                    {
1814 plagman 1345
                        switch (md_definehud(lastmodelid, tilex, xadd, yadd, zadd, angadd, flags, fov))
584 terminx 1346
                        {
331 terminx 1347
                        case 0:
1348
                            break;
1349
                        case -1:
1350
                            happy = 0; break; // invalid model id!?
1351
                        case -2:
4061 helixhorne 1352
                            initprintf("Invalid tile number on line %s:%d\n",
331 terminx 1353
                                       script->filename, scriptfile_getlinum(script,hudtokptr));
1354
                            happy = 0;
1355
                            break;
1356
                        case -3:
4061 helixhorne 1357
                            initprintf("Invalid frame name on line %s:%d\n",
331 terminx 1358
                                       script->filename, scriptfile_getlinum(script,hudtokptr));
1359
                            happy = 0;
1360
                            break;
1361
                        }
2237 helixhorne 1362
 
1363
                        model_ok &= happy;
331 terminx 1364
                    }
99 terminx 1365
#endif
109 terminx 1366
                }
584 terminx 1367
                break;
1368
                }
331 terminx 1369
            }
99 terminx 1370
 
2287 helixhorne 1371
#ifdef USE_OPENGL
4680 terminx 1372
            if (EDUKE32_PREDICT_FALSE(!model_ok))
2237 helixhorne 1373
            {
1374
                if (lastmodelid >= 0)
1375
                {
4061 helixhorne 1376
                    initprintf("Removing model %d due to errors.\n", lastmodelid);
2237 helixhorne 1377
                    md_undefinemodel(lastmodelid);
1378
                    nextmodelid--;
1379
                }
1380
                break;
1381
            }
1382
 
2264 hendricks2 1383
            md_setmisc(lastmodelid,(float)scale,shadeoffs,(float)mzadd,(float)myoffset,flags);
1910 helixhorne 1384
 
1385
            // thin out the loaded model by throwing away unused frames
2251 helixhorne 1386
            // FIXME: CURRENTLY DISABLED: interpolation may access frames we consider 'unused'?
1387
# if 0
1910 helixhorne 1388
            if (models[lastmodelid]->mdnum==3 && ((md3model_t *)models[lastmodelid])->numframes <= 1024)
1389
            {
2251 helixhorne 1390
#  ifdef DEBUG_MODEL_MEM
1910 helixhorne 1391
                md3model_t *m = (md3model_t *)models[lastmodelid];
1392
                int32_t i, onumframes;
1393
                onumframes = m->numframes;
2079 helixhorne 1394
                i =
2251 helixhorne 1395
#  endif
2079 helixhorne 1396
                md_thinoutmodel(lastmodelid, usedframebitmap);
2251 helixhorne 1397
#  ifdef DEBUG_MODEL_MEM
1910 helixhorne 1398
                if (i>=0 && i<onumframes)
4061 helixhorne 1399
                    initprintf("used %d/%d frames: %s\n", i, onumframes, modelfn);
1910 helixhorne 1400
                else if (i<0)
4061 helixhorne 1401
                    initprintf("md_thinoutmodel returned %d: %s\n", i, modelfn);
2251 helixhorne 1402
#  endif
1910 helixhorne 1403
            }
2251 helixhorne 1404
# endif
99 terminx 1405
 
3784 terminx 1406
            if (glrendmode == REND_POLYMER)
1910 helixhorne 1407
                md3postload_polymer((md3model_t *)models[lastmodelid]);
1408
#endif
1409
 
331 terminx 1410
            modelskin = lastmodelskin = 0;
1411
            seenframe = 0;
99 terminx 1412
 
331 terminx 1413
        }
1414
        break;
109 terminx 1415
        case T_VOXEL:
331 terminx 1416
        {
1417
            char *voxeltokptr = script->ltextptr;
1418
            char *fn, *modelend;
1205 terminx 1419
            int32_t tile0 = MAXTILES, tile1 = -1, tilex = -1;
99 terminx 1420
 
1677 terminx 1421
            static const tokenlist voxeltokens[] =
1422
            {
1423
                { "tile",   T_TILE   },
1424
                { "tile0",  T_TILE0  },
1425
                { "tile1",  T_TILE1  },
1426
                { "scale",  T_SCALE  },
1427
            };
1428
 
4835 helixhorne 1429
            if (EDUKE32_PREDICT_FALSE(scriptfile_getstring(script,&fn)))
1430
                break; //voxel filename
1431
 
1432
            if (EDUKE32_PREDICT_FALSE(nextvoxid == MAXVOXELS))
1433
            {
1434
                initprintf("Maximum number of voxels (%d) already defined.\n", MAXVOXELS);
1435
                break;
1436
            }
1437
 
1438
            if (EDUKE32_PREDICT_FALSE(qloadkvx(nextvoxid, fn)))
1439
            {
1440
                initprintf("Failure loading voxel file \"%s\"\n",fn);
1441
                break;
1442
            }
1443
 
331 terminx 1444
            lastvoxid = nextvoxid++;
99 terminx 1445
 
331 terminx 1446
            if (scriptfile_getbraces(script,&modelend)) break;
584 terminx 1447
            while (script->textptr < modelend)
1448
            {
4834 helixhorne 1449
                switch (getatoken(script, voxeltokens, ARRAY_SIZE(voxeltokens)))
584 terminx 1450
                {
4061 helixhorne 1451
                    //case T_ERROR: initprintf("Error on line %s:%d in voxel tokens\n", script->filename,linenum); break;
331 terminx 1452
                case T_TILE:
1453
                    scriptfile_getsymbol(script,&tilex);
2588 helixhorne 1454
 
4186 helixhorne 1455
                    if (check_tile("voxel", tilex, script, voxeltokptr))
2588 helixhorne 1456
                        break;
1457
 
1458
                    tiletovox[tilex] = lastvoxid;
331 terminx 1459
                    break;
2588 helixhorne 1460
 
331 terminx 1461
                case T_TILE0:
2588 helixhorne 1462
                    scriptfile_getsymbol(script,&tile0);
1463
                    break; //1st tile #
1464
 
331 terminx 1465
                case T_TILE1:
1466
                    scriptfile_getsymbol(script,&tile1);
2588 helixhorne 1467
 
3329 helixhorne 1468
                    if (check_tile_range("voxel", &tile0, &tile1, script, voxeltokptr))
2588 helixhorne 1469
                        break;
1470
 
1471
                    for (tilex=tile0; tilex<=tile1; tilex++)
1472
                        tiletovox[tilex] = lastvoxid;
331 terminx 1473
                    break; //last tile number (inclusive)
2588 helixhorne 1474
 
584 terminx 1475
                case T_SCALE:
1476
                {
331 terminx 1477
                    double scale=1.0;
1478
                    scriptfile_getdouble(script,&scale);
1205 terminx 1479
                    voxscale[lastvoxid] = (int32_t)(65536*scale);
1908 helixhorne 1480
#ifdef USE_OPENGL
1481
                    if (voxmodels[lastvoxid])
1482
                        voxmodels[lastvoxid]->scale = scale;
1483
#endif
331 terminx 1484
                    break;
109 terminx 1485
                }
331 terminx 1486
                }
109 terminx 1487
            }
331 terminx 1488
            lastvoxid = -1;
1489
        }
1490
        break;
109 terminx 1491
        case T_SKYBOX:
331 terminx 1492
        {
1493
            char *skyboxtokptr = script->ltextptr;
2554 helixhorne 1494
            char *fn[6] = {0,0,0,0,0,0};
1495
            char *modelend;
5040 hendricks2 1496
            int32_t i, tile = -1, pal = 0, happy = 1;
1497
#ifdef USE_OPENGL
1498
            int32_t flags = 0;
1499
#endif
99 terminx 1500
 
1677 terminx 1501
            static const tokenlist skyboxtokens[] =
1502
            {
1503
                { "tile"   ,T_TILE   },
1504
                { "pal"    ,T_PAL    },
1505
                { "ft"     ,T_FRONT  },{ "front"  ,T_FRONT  },{ "forward",T_FRONT  },
1506
                { "rt"     ,T_RIGHT  },{ "right"  ,T_RIGHT  },
1507
                { "bk"     ,T_BACK   },{ "back"   ,T_BACK   },
1508
                { "lf"     ,T_LEFT   },{ "left"   ,T_LEFT   },{ "lt"     ,T_LEFT   },
1509
                { "up"     ,T_TOP    },{ "top"    ,T_TOP    },{ "ceiling",T_TOP    },{ "ceil"   ,T_TOP    },
5010 terminx 1510
                { "dn"     ,T_BOTTOM },{ "bottom" ,T_BOTTOM },{ "floor"  ,T_BOTTOM },{ "down"   ,T_BOTTOM },
1511
                { "nocompress", T_NOCOMPRESS },
1512
                { "nodownsize", T_NODOWNSIZE },
1677 terminx 1513
            };
1514
 
331 terminx 1515
            if (scriptfile_getbraces(script,&modelend)) break;
584 terminx 1516
            while (script->textptr < modelend)
1517
            {
4385 terminx 1518
                switch (getatoken(script,skyboxtokens,ARRAY_SIZE(skyboxtokens)))
584 terminx 1519
                {
4061 helixhorne 1520
                    //case T_ERROR: initprintf("Error on line %s:%d in skybox tokens\n",script->filename,linenum); break;
331 terminx 1521
                case T_TILE:
584 terminx 1522
                    scriptfile_getsymbol(script,&tile); break;
331 terminx 1523
                case T_PAL:
584 terminx 1524
                    scriptfile_getsymbol(script,&pal); break;
331 terminx 1525
                case T_FRONT:
1526
                    scriptfile_getstring(script,&fn[0]); break;
1527
                case T_RIGHT:
1528
                    scriptfile_getstring(script,&fn[1]); break;
1529
                case T_BACK:
1530
                    scriptfile_getstring(script,&fn[2]); break;
1531
                case T_LEFT:
1532
                    scriptfile_getstring(script,&fn[3]); break;
1533
                case T_TOP:
1534
                    scriptfile_getstring(script,&fn[4]); break;
1535
                case T_BOTTOM:
1536
                    scriptfile_getstring(script,&fn[5]); break;
5010 terminx 1537
#ifdef USE_OPENGL
1538
                case T_NOCOMPRESS:
1539
                    flags |= 1; break;
1540
                case T_NODOWNSIZE:
1541
                    flags |= 16; break;
1542
#endif
109 terminx 1543
                }
331 terminx 1544
            }
99 terminx 1545
 
4680 terminx 1546
            if (EDUKE32_PREDICT_FALSE(tile < 0)) initprintf("Error: skybox: missing 'tile number' near line %s:%d\n", script->filename, scriptfile_getlinum(script,skyboxtokptr)), happy=0;
1229 terminx 1547
            for (i=0; i<6; i++)
584 terminx 1548
            {
4680 terminx 1549
                if (EDUKE32_PREDICT_FALSE(!fn[i])) initprintf("Error: skybox: missing '%s filename' near line %s:%d\n", skyfaces[i], script->filename, scriptfile_getlinum(script,skyboxtokptr)), happy = 0;
1736 helixhorne 1550
                // FIXME?
2554 helixhorne 1551
                if (check_file_exist(fn[i]))
1552
                    happy = 0;
331 terminx 1553
            }
1554
            if (!happy) break;
99 terminx 1555
 
3382 hendricks2 1556
#ifdef USE_OPENGL
5010 terminx 1557
            hicsetskybox(tile,pal,fn, flags);
3382 hendricks2 1558
#endif
331 terminx 1559
        }
1560
        break;
1748 plagman 1561
        case T_HIGHPALOOKUP:
1562
        {
1563
            char *highpaltokptr = script->ltextptr;
2554 helixhorne 1564
            int32_t basepal=-1, pal=-1;
1565
            char *fn = NULL;
1748 plagman 1566
            char *highpalend;
1778 helixhorne 1567
#ifdef POLYMER
1568
            int32_t fd;
1748 plagman 1569
            char *highpaldata;
1778 helixhorne 1570
#endif
1748 plagman 1571
            static const tokenlist highpaltokens[] =
1572
            {
1782 plagman 1573
                { "basepal",   T_BASEPAL },
1748 plagman 1574
                { "pal",   T_PAL },
1575
                { "file",  T_FILE }
1576
            };
1577
 
1578
            if (scriptfile_getbraces(script,&highpalend)) break;
1579
            while (script->textptr < highpalend)
1580
            {
4385 terminx 1581
                switch (getatoken(script,highpaltokens,ARRAY_SIZE(highpaltokens)))
1748 plagman 1582
                {
1782 plagman 1583
                case T_BASEPAL:
1584
                    scriptfile_getsymbol(script,&basepal);   break;
1748 plagman 1585
                case T_PAL:
1586
                    scriptfile_getsymbol(script,&pal);   break;
1587
                case T_FILE:
1588
                    scriptfile_getstring(script,&fn); break;
1589
                }
1590
            }
4680 terminx 1591
            if (EDUKE32_PREDICT_FALSE((unsigned)basepal >= ((unsigned)basepalcount)))
1782 plagman 1592
            {
4061 helixhorne 1593
                initprintf("Error: missing or invalid 'base palette number' for highpalookup definition "
1594
                           "near line %s:%d\n", script->filename, scriptfile_getlinum(script,highpaltokptr));
1782 plagman 1595
                break;
1596
            }
1748 plagman 1597
 
4680 terminx 1598
            if (EDUKE32_PREDICT_FALSE((unsigned)pal >= MAXPALOOKUPS - RESERVEDPALS))
1748 plagman 1599
            {
4061 helixhorne 1600
                initprintf("Error: missing or invalid 'palette number' for highpalookup definition near "
1601
                           "line %s:%d\n", script->filename, scriptfile_getlinum(script,highpaltokptr));
1748 plagman 1602
                break;
1603
            }
1782 plagman 1604
 
4680 terminx 1605
            if (EDUKE32_PREDICT_FALSE(!fn))
1748 plagman 1606
            {
4061 helixhorne 1607
                initprintf("Error: missing 'file name' for highpalookup definition near line %s:%d\n",
1748 plagman 1608
                           script->filename, scriptfile_getlinum(script,highpaltokptr));
1609
                break;
1610
            }
1762 terminx 1611
 
2554 helixhorne 1612
            if (check_file_exist(fn))
1613
                break;
1748 plagman 1614
 
1778 helixhorne 1615
#ifdef POLYMER
1748 plagman 1616
            fd = kopen4load(fn, 0);
1617
 
1751 helixhorne 1618
            // load the highpalookup and send it to polymer
4491 helixhorne 1619
            highpaldata = (char *)Xmalloc(PR_HIGHPALOOKUP_DATA_SIZE);
1749 helixhorne 1620
 
1621
            {
1751 helixhorne 1622
                char *filebuf;
1749 helixhorne 1623
                int32_t xsiz, ysiz, filesize, i;
1624
 
1625
                filesize = kfilelength(fd);
1626
 
4491 helixhorne 1627
                filebuf = (char *)Xmalloc(filesize);
1749 helixhorne 1628
 
1629
                klseek(fd, 0, SEEK_SET);
1630
                if (kread(fd, filebuf, filesize)!=filesize)
4061 helixhorne 1631
                    { kclose(fd); Bfree(highpaldata); initprintf("Error: didn't read all of \"%s\".\n", fn); break; }
1749 helixhorne 1632
 
1633
                kclose(fd);
1634
                kpgetdim(filebuf, filesize, &xsiz, &ysiz);
1635
 
4680 terminx 1636
                if (EDUKE32_PREDICT_FALSE(xsiz != PR_HIGHPALOOKUP_DIM*PR_HIGHPALOOKUP_DIM || ysiz != PR_HIGHPALOOKUP_DIM))
1749 helixhorne 1637
                {
4061 helixhorne 1638
                    initprintf("Error: image dimensions of \"%s\" must be %dx%d.\n",
1751 helixhorne 1639
                               fn, PR_HIGHPALOOKUP_DIM*PR_HIGHPALOOKUP_DIM, PR_HIGHPALOOKUP_DIM);
1749 helixhorne 1640
                    Bfree(filebuf); Bfree(highpaldata);
1748 plagman 1641
                    break;
1749 helixhorne 1642
                }
1643
 
4637 terminx 1644
                i = kprender(filebuf, filesize, (intptr_t)highpaldata, xsiz*sizeof(coltype), xsiz, ysiz);
1749 helixhorne 1645
                Bfree(filebuf);
4680 terminx 1646
                if (EDUKE32_PREDICT_FALSE(i))
4061 helixhorne 1647
                    { Bfree(highpaldata); initprintf("Error: failed rendering \"%s\".\n", fn); break; }
1748 plagman 1648
            }
1749 helixhorne 1649
 
1782 plagman 1650
            polymer_definehighpalookup(basepal, pal, highpaldata);
1748 plagman 1651
 
1652
            Bfree(highpaldata);
1778 helixhorne 1653
#endif
1748 plagman 1654
        }
1655
        break;
109 terminx 1656
        case T_TINT:
331 terminx 1657
        {
1658
            char *tinttokptr = script->ltextptr;
1205 terminx 1659
            int32_t red=255, green=255, blue=255, pal=-1, flags=0;
331 terminx 1660
            char *tintend;
99 terminx 1661
 
1677 terminx 1662
            static const tokenlist tinttokens[] =
1663
            {
1664
                { "pal",   T_PAL },
1665
                { "red",   T_RED   },{ "r", T_RED },
1666
                { "green", T_GREEN },{ "g", T_GREEN },
1667
                { "blue",  T_BLUE  },{ "b", T_BLUE },
1668
                { "flags", T_FLAGS }
1669
            };
1670
 
331 terminx 1671
            if (scriptfile_getbraces(script,&tintend)) break;
584 terminx 1672
            while (script->textptr < tintend)
1673
            {
4385 terminx 1674
                switch (getatoken(script,tinttokens,ARRAY_SIZE(tinttokens)))
584 terminx 1675
                {
331 terminx 1676
                case T_PAL:
1677
                    scriptfile_getsymbol(script,&pal);   break;
1678
                case T_RED:
1679
                    scriptfile_getnumber(script,&red);   red   = min(255,max(0,red));   break;
1680
                case T_GREEN:
1681
                    scriptfile_getnumber(script,&green); green = min(255,max(0,green)); break;
1682
                case T_BLUE:
1683
                    scriptfile_getnumber(script,&blue);  blue  = min(255,max(0,blue));  break;
1684
                case T_FLAGS:
1685
                    scriptfile_getsymbol(script,&flags); break;
109 terminx 1686
                }
331 terminx 1687
            }
99 terminx 1688
 
4680 terminx 1689
            if (EDUKE32_PREDICT_FALSE(pal < 0))
584 terminx 1690
            {
4061 helixhorne 1691
                initprintf("Error: tint: missing 'palette number' near line %s:%d\n",
2568 helixhorne 1692
                           script->filename, scriptfile_getlinum(script,tinttokptr));
331 terminx 1693
                break;
1694
            }
99 terminx 1695
 
3382 hendricks2 1696
#ifdef USE_OPENGL
331 terminx 1697
            hicsetpalettetint(pal,red,green,blue,flags);
3382 hendricks2 1698
#endif
331 terminx 1699
        }
1700
        break;
2568 helixhorne 1701
        case T_MAKEPALOOKUP:
1702
        {
1703
            char *const starttokptr = script->ltextptr;
1704
            int32_t red=0, green=0, blue=0, pal=-1;
1705
            int32_t havepal=0, remappal=0;
1706
            char *endtextptr;
1707
 
1708
            static const tokenlist palookuptokens[] =
1709
            {
1710
                { "pal",   T_PAL },
1711
                { "red",   T_RED   }, { "r", T_RED },
1712
                { "green", T_GREEN }, { "g", T_GREEN },
1713
                { "blue",  T_BLUE  }, { "b", T_BLUE },
1714
                { "remappal", T_REMAPPAL },
1715
                { "remapself", T_REMAPSELF },
1716
            };
1717
 
4813 helixhorne 1718
            enum {
1719
                HAVE_PAL = 1,
1720
                HAVE_REMAPPAL = 2,
1721
                HAVE_REMAPSELF = 4,
1722
 
1723
                HAVEPAL_SPECIAL = HAVE_REMAPPAL | HAVE_REMAPSELF,
1724
                HAVEPAL_ERROR = 8,
1725
            };
1726
 
2568 helixhorne 1727
            if (scriptfile_getbraces(script,&endtextptr)) break;
1728
            while (script->textptr < endtextptr)
1729
            {
4385 terminx 1730
                switch (getatoken(script, palookuptokens, ARRAY_SIZE(palookuptokens)))
2568 helixhorne 1731
                {
1732
                case T_PAL:
1733
                    scriptfile_getsymbol(script, &pal);
4813 helixhorne 1734
                    havepal |= HAVE_PAL;
2568 helixhorne 1735
                    break;
1736
                case T_RED:
1737
                    scriptfile_getnumber(script,&red);
1738
                    red = clamp(red, 0, 63);
1739
                    break;
1740
                case T_GREEN:
1741
                    scriptfile_getnumber(script,&green);
1742
                    green = clamp(green, 0, 63);
1743
                    break;
1744
                case T_BLUE:
1745
                    scriptfile_getnumber(script,&blue);
1746
                    blue = clamp(blue, 0, 63);
1747
                    break;
1748
                case T_REMAPPAL:
1749
                    scriptfile_getsymbol(script,&remappal);
4813 helixhorne 1750
                    if (havepal & HAVEPAL_SPECIAL)
1751
                        havepal |= HAVEPAL_ERROR;
1752
                    havepal |= HAVE_REMAPPAL;
2568 helixhorne 1753
                    break;
1754
                case T_REMAPSELF:
4813 helixhorne 1755
                    if (havepal & HAVEPAL_SPECIAL)
1756
                        havepal |= HAVEPAL_ERROR;
1757
                    havepal |= HAVE_REMAPSELF;
2568 helixhorne 1758
                    break;
1759
                }
1760
            }
1761
 
1762
            {
1763
                char msgend[BMAX_PATH+64];
1764
 
1765
                Bsprintf(msgend, "for palookup definition near line %s:%d",
1766
                         script->filename, scriptfile_getlinum(script,starttokptr));
1767
 
4813 helixhorne 1768
                if (EDUKE32_PREDICT_FALSE((havepal & HAVE_PAL)==0))
2568 helixhorne 1769
                {
4061 helixhorne 1770
                    initprintf("Error: missing 'palette number' %s\n", msgend);
2568 helixhorne 1771
                    break;
1772
                }
4680 terminx 1773
                else if (EDUKE32_PREDICT_FALSE(pal==0 || (unsigned)pal >= MAXPALOOKUPS-RESERVEDPALS))
2568 helixhorne 1774
                {
4061 helixhorne 1775
                    initprintf("Error: 'palette number' out of range (1 .. %d) %s\n",
2568 helixhorne 1776
                               MAXPALOOKUPS-RESERVEDPALS-1, msgend);
1777
                    break;
1778
                }
4813 helixhorne 1779
 
1780
                if (EDUKE32_PREDICT_FALSE(havepal & HAVEPAL_ERROR))
2568 helixhorne 1781
                {
1782
                    // will also disallow multiple remappals or remapselfs
4061 helixhorne 1783
                    initprintf("Error: must have exactly one of either 'remappal' or 'remapself' %s\n", msgend);
2568 helixhorne 1784
                    break;
1785
                }
4813 helixhorne 1786
                else if (EDUKE32_PREDICT_FALSE((havepal & HAVE_REMAPPAL)
1787
                                               && (unsigned)remappal >= MAXPALOOKUPS-RESERVEDPALS))
2568 helixhorne 1788
                {
4061 helixhorne 1789
                    initprintf("Error: 'remap palette number' out of range (max=%d) %s\n",
2568 helixhorne 1790
                               MAXPALOOKUPS-RESERVEDPALS-1, msgend);
1791
                    break;
1792
                }
1793
 
4813 helixhorne 1794
                if (havepal & HAVE_REMAPSELF)
2568 helixhorne 1795
                    remappal = pal;
1796
            }
1797
 
1798
            // NOTE: all palookups are initialized, i.e. non-NULL!
1799
            // NOTE2: aliasing (pal==remappal) is OK
4812 helixhorne 1800
            makepalookup(pal, palookup[remappal], red, green, blue,
1801
                         remappal==0 ? 1 : g_noFloorPal[remappal]);
2568 helixhorne 1802
        }
1803
        break;
109 terminx 1804
        case T_TEXTURE:
331 terminx 1805
        {
1806
            char *texturetokptr = script->ltextptr, *textureend;
1205 terminx 1807
            int32_t tile=-1, token;
99 terminx 1808
 
1677 terminx 1809
            static const tokenlist texturetokens[] =
1810
            {
1811
                { "pal",     T_PAL  },
1812
                { "detail",  T_DETAIL },
1813
                { "glow",    T_GLOW },
1814
                { "specular",T_SPECULAR },
1815
                { "normal",  T_NORMAL },
1816
            };
1817
 
331 terminx 1818
            if (scriptfile_getsymbol(script,&tile)) break;
1819
            if (scriptfile_getbraces(script,&textureend)) break;
584 terminx 1820
            while (script->textptr < textureend)
1821
            {
4385 terminx 1822
                token = getatoken(script,texturetokens,ARRAY_SIZE(texturetokens));
584 terminx 1823
                switch (token)
1824
                {
1825
                case T_PAL:
1826
                {
331 terminx 1827
                    char *paltokptr = script->ltextptr, *palend;
4062 terminx 1828
                    int32_t pal=-1, xsiz = 0, ysiz = 0;
2554 helixhorne 1829
                    char *fn = NULL;
1526 plagman 1830
                    double alphacut = -1.0, xscale = 1.0, yscale = 1.0, specpower = 1.0, specfactor = 1.0;
3382 hendricks2 1831
#ifdef USE_OPENGL
331 terminx 1832
                    char flags = 0;
3382 hendricks2 1833
#endif
99 terminx 1834
 
1677 terminx 1835
                    static const tokenlist texturetokens_pal[] =
1836
                    {
1837
                        { "file",            T_FILE },{ "name", T_FILE },
1838
                        { "alphacut",        T_ALPHACUT },
1839
                        { "detailscale",     T_XSCALE }, { "scale",  T_XSCALE }, { "xscale",  T_XSCALE }, { "intensity",  T_XSCALE },
1840
                        { "yscale",          T_YSCALE },
2539 hendricks2 1841
                        { "specpower",       T_SPECPOWER }, { "specularpower", T_SPECPOWER }, { "parallaxscale", T_SPECPOWER },
1842
                        { "specfactor",      T_SPECFACTOR }, { "specularfactor", T_SPECFACTOR }, { "parallaxbias", T_SPECFACTOR },
1677 terminx 1843
                        { "nocompress",      T_NOCOMPRESS },
1844
                        { "nodownsize",      T_NODOWNSIZE },
4062 terminx 1845
                        { "orig_sizex",      T_ORIGSIZEX }, { "orig_sizey", T_ORIGSIZEY }
1677 terminx 1846
                    };
1847
 
331 terminx 1848
                    if (scriptfile_getsymbol(script,&pal)) break;
1849
                    if (scriptfile_getbraces(script,&palend)) break;
584 terminx 1850
                    while (script->textptr < palend)
1851
                    {
4385 terminx 1852
                        switch (getatoken(script,texturetokens_pal,ARRAY_SIZE(texturetokens_pal)))
584 terminx 1853
                        {
331 terminx 1854
                        case T_FILE:
1855
                            scriptfile_getstring(script,&fn); break;
1856
                        case T_ALPHACUT:
1857
                            scriptfile_getdouble(script,&alphacut); break;
504 Plagman 1858
                        case T_XSCALE:
1859
                            scriptfile_getdouble(script,&xscale); break;
1860
                        case T_YSCALE:
1861
                            scriptfile_getdouble(script,&yscale); break;
1526 plagman 1862
                        case T_SPECPOWER:
1863
                            scriptfile_getdouble(script,&specpower); break;
1864
                        case T_SPECFACTOR:
1865
                            scriptfile_getdouble(script,&specfactor); break;
3382 hendricks2 1866
#ifdef USE_OPENGL
331 terminx 1867
                        case T_NOCOMPRESS:
1868
                            flags |= 1; break;
1033 terminx 1869
                        case T_NODOWNSIZE:
1870
                            flags |= 16; break;
3382 hendricks2 1871
#endif
4062 terminx 1872
                        case T_ORIGSIZEX:
1873
                            scriptfile_getnumber(script, &xsiz);
1874
                            break;
1875
                        case T_ORIGSIZEY:
1876
                            scriptfile_getnumber(script, &ysiz);
1877
                            break;
331 terminx 1878
                        default:
1879
                            break;
1880
                        }
1881
                    }
99 terminx 1882
 
4680 terminx 1883
                    if (EDUKE32_PREDICT_FALSE((unsigned)tile >= MAXUSERTILES)) break;   // message is printed later
1884
                    if (EDUKE32_PREDICT_FALSE((unsigned)pal >= MAXPALOOKUPS - RESERVEDPALS))
584 terminx 1885
                    {
4061 helixhorne 1886
                        initprintf("Error: missing or invalid 'palette number' for texture definition near "
1887
                                   "line %s:%d\n", script->filename, scriptfile_getlinum(script,paltokptr));
331 terminx 1888
                        break;
109 terminx 1889
                    }
4680 terminx 1890
                    if (EDUKE32_PREDICT_FALSE(!fn))
584 terminx 1891
                    {
4061 helixhorne 1892
                        initprintf("Error: missing 'file name' for texture definition near line %s:%d\n",
331 terminx 1893
                                   script->filename, scriptfile_getlinum(script,paltokptr));
1894
                        break;
1895
                    }
543 terminx 1896
 
4680 terminx 1897
                    if (EDUKE32_PREDICT_FALSE(check_file_exist(fn)))
2554 helixhorne 1898
                        break;
544 terminx 1899
 
4062 terminx 1900
                    if (xsiz > 0 && ysiz > 0)
1901
                    {
1902
                        set_tilesiz(tile, xsiz, ysiz);
1903
                        Bmemset(&picanm[tile], 0, sizeof(picanm_t));
1904
                        faketilesiz[tile] = -1;
1905
                    }
3382 hendricks2 1906
#ifdef USE_OPENGL
504 Plagman 1907
                    xscale = 1.0f / xscale;
1908
                    yscale = 1.0f / yscale;
1909
 
1526 plagman 1910
                    hicsetsubsttex(tile,pal,fn,alphacut,xscale,yscale, specpower, specfactor,flags);
3382 hendricks2 1911
#endif
584 terminx 1912
                }
1913
                break;
1350 terminx 1914
                case T_DETAIL: case T_GLOW: case T_SPECULAR: case T_NORMAL:
584 terminx 1915
                {
459 Plagman 1916
                    char *detailtokptr = script->ltextptr, *detailend;
3382 hendricks2 1917
#ifdef USE_OPENGL
2554 helixhorne 1918
                    int32_t pal = 0;
3382 hendricks2 1919
                    char flags = 0;
1920
#endif
2554 helixhorne 1921
                    char *fn = NULL;
1350 terminx 1922
                    double xscale = 1.0, yscale = 1.0, specpower = 1.0, specfactor = 1.0;
459 Plagman 1923
 
1677 terminx 1924
                    static const tokenlist texturetokens_pal[] =
1925
                    {
1926
                        { "file",            T_FILE },{ "name", T_FILE },
1927
                        { "alphacut",        T_ALPHACUT },
1928
                        { "detailscale",     T_XSCALE }, { "scale",  T_XSCALE }, { "xscale",  T_XSCALE }, { "intensity",  T_XSCALE },
1929
                        { "yscale",          T_YSCALE },
2539 hendricks2 1930
                        { "specpower",       T_SPECPOWER }, { "specularpower", T_SPECPOWER }, { "parallaxscale", T_SPECPOWER },
1931
                        { "specfactor",      T_SPECFACTOR }, { "specularfactor", T_SPECFACTOR }, { "parallaxbias", T_SPECFACTOR },
1677 terminx 1932
                        { "nocompress",      T_NOCOMPRESS },
1933
                        { "nodownsize",      T_NODOWNSIZE },
1934
                    };
1935
 
4680 terminx 1936
                    if (EDUKE32_PREDICT_FALSE(scriptfile_getbraces(script,&detailend))) break;
584 terminx 1937
                    while (script->textptr < detailend)
1938
                    {
4385 terminx 1939
                        switch (getatoken(script,texturetokens_pal,ARRAY_SIZE(texturetokens_pal)))
584 terminx 1940
                        {
459 Plagman 1941
                        case T_FILE:
1942
                            scriptfile_getstring(script,&fn); break;
504 Plagman 1943
                        case T_XSCALE:
512 Plagman 1944
                            scriptfile_getdouble(script,&xscale); break;
1945
                        case T_YSCALE:
1946
                            scriptfile_getdouble(script,&yscale); break;
1350 terminx 1947
                        case T_SPECPOWER:
1948
                            scriptfile_getdouble(script,&specpower); break;
1949
                        case T_SPECFACTOR:
1950
                            scriptfile_getdouble(script,&specfactor); break;
3382 hendricks2 1951
#ifdef USE_OPENGL
459 Plagman 1952
                        case T_NOCOMPRESS:
1953
                            flags |= 1; break;
1033 terminx 1954
                        case T_NODOWNSIZE:
1955
                            flags |= 16; break;
3382 hendricks2 1956
#endif
459 Plagman 1957
                        default:
1958
                            break;
1959
                        }
1960
                    }
1961
 
4680 terminx 1962
                    if (EDUKE32_PREDICT_FALSE((unsigned)tile >= MAXUSERTILES)) break;   // message is printed later
1963
                    if (EDUKE32_PREDICT_FALSE(!fn))
584 terminx 1964
                    {
4061 helixhorne 1965
                        initprintf("Error: missing 'file name' for texture definition near line %s:%d\n",
459 Plagman 1966
                                   script->filename, scriptfile_getlinum(script,detailtokptr));
1967
                        break;
1968
                    }
543 terminx 1969
 
4680 terminx 1970
                    if (EDUKE32_PREDICT_FALSE(check_file_exist(fn)))
2554 helixhorne 1971
                        break;
544 terminx 1972
 
3382 hendricks2 1973
#ifdef USE_OPENGL
587 terminx 1974
                    switch (token)
501 Plagman 1975
                    {
587 terminx 1976
                    case T_DETAIL:
501 Plagman 1977
                        pal = DETAILPAL;
512 Plagman 1978
                        xscale = 1.0f / xscale;
513 Plagman 1979
                        yscale = 1.0f / yscale;
587 terminx 1980
                        break;
1981
                    case T_GLOW:
1982
                        pal = GLOWPAL;
1983
                        break;
1350 terminx 1984
                    case T_SPECULAR:
1985
                        pal = SPECULARPAL;
1986
                        break;
1987
                    case T_NORMAL:
1988
                        pal = NORMALPAL;
1989
                        break;
497 Plagman 1990
                    }
1350 terminx 1991
                    hicsetsubsttex(tile,pal,fn,-1.0f,xscale,yscale, specpower, specfactor,flags);
3382 hendricks2 1992
#endif
584 terminx 1993
                }
1994
                break;
331 terminx 1995
                default:
109 terminx 1996
                    break;
1997
                }
1998
            }
4680 terminx 1999
            if (EDUKE32_PREDICT_FALSE((unsigned)tile >= MAXUSERTILES))
584 terminx 2000
            {
4061 helixhorne 2001
                initprintf("Error: missing or invalid 'tile number' for texture definition near line %s:%d\n",
331 terminx 2002
                           script->filename, scriptfile_getlinum(script,texturetokptr));
2003
                break;
2004
            }
2005
        }
2006
        break;
2007
 
109 terminx 2008
        case T_UNDEFMODEL:
2009
        case T_UNDEFMODELRANGE:
331 terminx 2010
        {
1205 terminx 2011
            int32_t r0,r1;
109 terminx 2012
 
4680 terminx 2013
            if (EDUKE32_PREDICT_FALSE(scriptfile_getsymbol(script,&r0))) break;
584 terminx 2014
            if (tokn == T_UNDEFMODELRANGE)
2015
            {
331 terminx 2016
                if (scriptfile_getsymbol(script,&r1)) break;
2588 helixhorne 2017
 
2018
                if (check_tile_range("undefmodelrange", &r0, &r1, script, cmdtokptr))
331 terminx 2019
                    break;
584 terminx 2020
            }
2021
            else
2022
            {
331 terminx 2023
                r1 = r0;
2588 helixhorne 2024
 
4186 helixhorne 2025
                if (check_tile("undefmodel", r0, script, cmdtokptr))
331 terminx 2026
                    break;
2027
            }
1820 terminx 2028
#ifdef USE_OPENGL
2588 helixhorne 2029
            for (; r0 <= r1; r0++)
2030
                md_undefinetile(r0);
99 terminx 2031
#endif
331 terminx 2032
        }
2033
        break;
99 terminx 2034
 
109 terminx 2035
        case T_UNDEFMODELOF:
331 terminx 2036
        {
1205 terminx 2037
            int32_t r0;
1820 terminx 2038
#ifdef USE_OPENGL
1205 terminx 2039
            int32_t mid;
895 terminx 2040
#endif
99 terminx 2041
 
4680 terminx 2042
            if (EDUKE32_PREDICT_FALSE(scriptfile_getsymbol(script,&r0))) break;
2588 helixhorne 2043
 
4186 helixhorne 2044
            if (check_tile("undefmodelof", r0, script, cmdtokptr))
331 terminx 2045
                break;
99 terminx 2046
 
2588 helixhorne 2047
            // XXX: See comment of md_undefinemodel()
4061 helixhorne 2048
            initprintf("Warning: undefmodelof: currently non-functional.\n");
2588 helixhorne 2049
            break;
2050
 
1820 terminx 2051
#ifdef USE_OPENGL
587 terminx 2052
            mid = md_tilehasmodel(r0,0);
331 terminx 2053
            if (mid < 0) break;
99 terminx 2054
 
331 terminx 2055
            md_undefinemodel(mid);
99 terminx 2056
#endif
331 terminx 2057
        }
2058
        break;
99 terminx 2059
 
109 terminx 2060
        case T_UNDEFTEXTURE:
2061
        case T_UNDEFTEXTURERANGE:
331 terminx 2062
        {
3382 hendricks2 2063
            int32_t r0,r1;
2064
#ifdef USE_OPENGL
2065
            int32_t i;
2066
#endif
99 terminx 2067
 
4680 terminx 2068
            if (EDUKE32_PREDICT_FALSE(scriptfile_getsymbol(script,&r0))) break;
584 terminx 2069
            if (tokn == T_UNDEFTEXTURERANGE)
2070
            {
4680 terminx 2071
                if (EDUKE32_PREDICT_FALSE(scriptfile_getsymbol(script,&r1))) break;
2588 helixhorne 2072
 
4680 terminx 2073
                if (EDUKE32_PREDICT_FALSE(check_tile_range("undeftexturerange", &r0, &r1, script, cmdtokptr)))
331 terminx 2074
                    break;
584 terminx 2075
            }
2076
            else
2077
            {
331 terminx 2078
                r1 = r0;
2588 helixhorne 2079
 
4680 terminx 2080
                if (EDUKE32_PREDICT_FALSE(check_tile("undeftexture", r0, script, cmdtokptr)))
331 terminx 2081
                    break;
109 terminx 2082
            }
2083
 
3382 hendricks2 2084
#ifdef USE_OPENGL
331 terminx 2085
            for (; r0 <= r1; r0++)
2086
                for (i=MAXPALOOKUPS-1; i>=0; i--)
2087
                    hicclearsubst(r0,i);
3382 hendricks2 2088
#endif
331 terminx 2089
        }
2090
        break;
2091
 
4987 terminx 2092
        case T_CUTSCENE:
2242 helixhorne 2093
        case T_ANIMSOUNDS:
2094
        {
2095
            char *dummy;
2096
 
2097
            static const tokenlist dummytokens[] = { { "id",   T_ID  }, };
2098
 
4680 terminx 2099
            if (EDUKE32_PREDICT_FALSE(scriptfile_getstring(script, &dummy))) break;
2100
            if (EDUKE32_PREDICT_FALSE(scriptfile_getbraces(script,&dummy))) break;
2242 helixhorne 2101
            while (script->textptr < dummy)
2102
            {
2103
                // XXX?
2104
                getatoken(script,dummytokens,sizeof(dummytokens)/sizeof(dummytokens));
2105
            }
2106
        }
2107
        break;
2108
 
3078 helixhorne 2109
        case T_TEXHITSCANRANGE:
3230 helixhorne 2110
        case T_NOFULLBRIGHTRANGE:
3078 helixhorne 2111
        {
2112
            int32_t b,e, i;
2113
 
4680 terminx 2114
            if (EDUKE32_PREDICT_FALSE(scriptfile_getnumber(script,&b))) break;
2115
            if (EDUKE32_PREDICT_FALSE(scriptfile_getnumber(script,&e))) break;
3078 helixhorne 2116
 
2117
            b = max(b, 0);
4225 helixhorne 2118
            e = min(e, MAXUSERTILES-1);
3078 helixhorne 2119
 
2120
            for (i=b; i<=e; i++)
3230 helixhorne 2121
                picanm[i].sf |= (tokn==T_TEXHITSCANRANGE) ?
2122
                    PICANM_TEXHITSCAN_BIT : PICANM_NOFULLBRIGHT_BIT;
3078 helixhorne 2123
        }
2124
        break;
2125
 
1677 terminx 2126
        case T_SOUND:
587 terminx 2127
        case T_MUSIC:
2128
        {
634 terminx 2129
            char *dummy, *dummy2;
1677 terminx 2130
            static const tokenlist sound_musictokens[] =
2131
            {
2132
                { "id",   T_ID  },
2133
                { "file", T_FILE },
2134
            };
587 terminx 2135
 
4680 terminx 2136
            if (EDUKE32_PREDICT_FALSE(scriptfile_getbraces(script,&dummy))) break;
634 terminx 2137
            while (script->textptr < dummy)
587 terminx 2138
            {
4385 terminx 2139
                switch (getatoken(script,sound_musictokens,ARRAY_SIZE(sound_musictokens)))
587 terminx 2140
                {
2141
                case T_ID:
634 terminx 2142
                    scriptfile_getstring(script,&dummy2);
2143
                    break;
587 terminx 2144
                case T_FILE:
634 terminx 2145
                    scriptfile_getstring(script,&dummy2);
2146
                    break;
587 terminx 2147
                }
2148
            }
2149
        }
2150
        break;
2151
 
3309 hendricks2 2152
        case T_MAPINFO:
2153
        {
4884 hendricks2 2154
            char *mapmd4string = NULL, *title = NULL, *mhkfile = NULL, *mapinfoend, *dummy;
3309 hendricks2 2155
            static const tokenlist mapinfotokens[] =
2156
            {
2157
                { "mapfile",    T_MAPFILE },
2158
                { "maptitle",   T_MAPTITLE },
2159
                { "mapmd4",     T_MAPMD4 },
2160
                { "mhkfile",    T_MHKFILE },
2161
            };
4884 hendricks2 2162
            int32_t previous_usermaphacks = num_usermaphacks;
3309 hendricks2 2163
 
4884 hendricks2 2164
            if (EDUKE32_PREDICT_FALSE(scriptfile_getbraces(script,&mapinfoend))) break;
2165
            while (script->textptr < mapinfoend)
3309 hendricks2 2166
            {
4385 terminx 2167
                switch (getatoken(script,mapinfotokens,ARRAY_SIZE(mapinfotokens)))
3309 hendricks2 2168
                {
2169
                case T_MAPFILE:
4884 hendricks2 2170
                    scriptfile_getstring(script,&dummy);
3309 hendricks2 2171
                    break;
2172
                case T_MAPTITLE:
4884 hendricks2 2173
                    scriptfile_getstring(script,&title);