Subversion Repositories eduke32

Rev

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