Subversion Repositories eduke32

Rev

Rev 5010 | 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
5010 terminx 369
            hicsetskybox(tile,pal,fn, 0);
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 },
5010 terminx 1189
 
1677 terminx 1190
                    };
1191
 
331 terminx 1192
                    if (scriptfile_getbraces(script,&skinend)) break;
584 terminx 1193
                    while (script->textptr < skinend)
1194
                    {
4385 terminx 1195
                        switch (getatoken(script,modelskintokens,ARRAY_SIZE(modelskintokens)))
584 terminx 1196
                        {
331 terminx 1197
                        case T_PAL:
1198
                            scriptfile_getsymbol(script,&palnum); break;
501 Plagman 1199
                        case T_PARAM:
1200
                            scriptfile_getdouble(script,&param); break;
1279 plagman 1201
                        case T_SPECPOWER:
1202
                            scriptfile_getdouble(script,&specpower); break;
1203
                        case T_SPECFACTOR:
1204
                            scriptfile_getdouble(script,&specfactor); break;
331 terminx 1205
                        case T_FILE:
1206
                            scriptfile_getstring(script,&skinfn); break; //skin filename
1207
                        case T_SURF:
1208
                            scriptfile_getnumber(script,&surfnum); break;
1209
                        }
1210
                    }
99 terminx 1211
 
4680 terminx 1212
                    if (EDUKE32_PREDICT_FALSE(!skinfn))
584 terminx 1213
                    {
4061 helixhorne 1214
                        initprintf("Error: missing 'skin filename' for skin definition near line %s:%d\n", script->filename, scriptfile_getlinum(script,skintokptr));
2237 helixhorne 1215
                        model_ok = 0;
331 terminx 1216
                        break;
1217
                    }
99 terminx 1218
 
331 terminx 1219
                    if (seenframe) { modelskin = ++lastmodelskin; }
1220
                    seenframe = 0;
99 terminx 1221
 
587 terminx 1222
                    switch (token)
501 Plagman 1223
                    {
587 terminx 1224
                    case T_DETAIL:
501 Plagman 1225
                        palnum = DETAILPAL;
1226
                        param = 1.0f / param;
587 terminx 1227
                        break;
1228
                    case T_GLOW:
1229
                        palnum = GLOWPAL;
1230
                        break;
1350 terminx 1231
                    case T_SPECULAR:
1232
                        palnum = SPECULARPAL;
1233
                        break;
1234
                    case T_NORMAL:
1235
                        palnum = NORMALPAL;
1236
                        break;
501 Plagman 1237
                    }
1238
 
2554 helixhorne 1239
                    if (check_file_exist(skinfn))
1240
                        break;
2436 hendricks2 1241
 
1820 terminx 1242
#ifdef USE_OPENGL
1279 plagman 1243
                    switch (md_defineskin(lastmodelid, skinfn, palnum, max(0,modelskin), surfnum, param, specpower, specfactor))
584 terminx 1244
                    {
331 terminx 1245
                    case 0:
1246
                        break;
1247
                    case -1:
1248
                        break; // invalid model id!?
1249
                    case -2:
4061 helixhorne 1250
                        initprintf("Invalid skin filename on line %s:%d\n",
331 terminx 1251
                                   script->filename, scriptfile_getlinum(script,skintokptr));
2237 helixhorne 1252
                        model_ok = 0;
331 terminx 1253
                        break;
1254
                    case -3:
4061 helixhorne 1255
                        initprintf("Invalid palette number on line %s:%d\n",
331 terminx 1256
                                   script->filename, scriptfile_getlinum(script,skintokptr));
2237 helixhorne 1257
                        model_ok = 0;
331 terminx 1258
                        break;
1259
                    case -4:
4061 helixhorne 1260
                        initprintf("Out of memory on line %s:%d\n",
331 terminx 1261
                                   script->filename, scriptfile_getlinum(script,skintokptr));
2237 helixhorne 1262
                        model_ok = 0;
331 terminx 1263
                        break;
1264
                    }
99 terminx 1265
#endif
584 terminx 1266
                }
1267
                break;
331 terminx 1268
                case T_HUD:
1269
                {
1270
                    char *hudtokptr = script->ltextptr;
3382 hendricks2 1271
                    char *frameend;
1272
#ifdef USE_OPENGL
1273
                    char happy=1;
1274
                    int32_t tilex = 0;
1275
#endif
4607 terminx 1276
                    int32_t ftilenume = -1, ltilenume = -1, flags = 0, fov = -1, angadd = 0;
1277
                    double xadd = 0.0, yadd = 0.0, zadd = 0.0;
99 terminx 1278
 
1677 terminx 1279
                    static const tokenlist modelhudtokens[] =
1280
                    {
1281
                        { "tile",   T_TILE   },
1282
                        { "tile0",  T_TILE0  },
1283
                        { "tile1",  T_TILE1  },
1284
                        { "xadd",   T_XADD   },
1285
                        { "yadd",   T_YADD   },
1286
                        { "zadd",   T_ZADD   },
1287
                        { "angadd", T_ANGADD },
1814 plagman 1288
                        { "fov",    T_FOV    },
1677 terminx 1289
                        { "hide",   T_HIDE   },
1290
                        { "nobob",  T_NOBOB  },
1291
                        { "flipped",T_FLIPPED},
1292
                        { "nodepth",T_NODEPTH},
1293
                    };
1294
 
331 terminx 1295
                    if (scriptfile_getbraces(script,&frameend)) break;
584 terminx 1296
                    while (script->textptr < frameend)
1297
                    {
4385 terminx 1298
                        switch (getatoken(script,modelhudtokens,ARRAY_SIZE(modelhudtokens)))
584 terminx 1299
                        {
331 terminx 1300
                        case T_TILE:
1301
                            scriptfile_getsymbol(script,&ftilenume); ltilenume = ftilenume; break;
1302
                        case T_TILE0:
1303
                            scriptfile_getsymbol(script,&ftilenume); break; //first tile number
1304
                        case T_TILE1:
1305
                            scriptfile_getsymbol(script,&ltilenume); break; //last tile number (inclusive)
1306
                        case T_XADD:
1307
                            scriptfile_getdouble(script,&xadd); break;
1308
                        case T_YADD:
1309
                            scriptfile_getdouble(script,&yadd); break;
1310
                        case T_ZADD:
1311
                            scriptfile_getdouble(script,&zadd); break;
1312
                        case T_ANGADD:
4607 terminx 1313
                            scriptfile_getsymbol(script,&angadd); break;
1814 plagman 1314
                        case T_FOV:
1315
                            scriptfile_getsymbol(script,&fov); break;
331 terminx 1316
                        case T_HIDE:
4174 helixhorne 1317
                            flags |= HUDFLAG_HIDE; break;
331 terminx 1318
                        case T_NOBOB:
4174 helixhorne 1319
                            flags |= HUDFLAG_NOBOB; break;
331 terminx 1320
                        case T_FLIPPED:
4174 helixhorne 1321
                            flags |= HUDFLAG_FLIPPED; break;
331 terminx 1322
                        case T_NODEPTH:
4174 helixhorne 1323
                            flags |= HUDFLAG_NODEPTH; break;
331 terminx 1324
                        }
1325
                    }
99 terminx 1326
 
4680 terminx 1327
                    if (EDUKE32_PREDICT_FALSE(check_tile_range("hud", &ftilenume, &ltilenume, script, hudtokptr)))
584 terminx 1328
                    {
2588 helixhorne 1329
                        model_ok = 0;
1330
                        break;
331 terminx 1331
                    }
99 terminx 1332
 
4680 terminx 1333
                    if (EDUKE32_PREDICT_FALSE(lastmodelid < 0))
584 terminx 1334
                    {
2288 helixhorne 1335
#ifdef USE_OPENGL
4061 helixhorne 1336
                        initprintf("Warning: Ignoring frame definition.\n");
2288 helixhorne 1337
#endif
331 terminx 1338
                        break;
1339
                    }
1820 terminx 1340
#ifdef USE_OPENGL
584 terminx 1341
                    for (tilex = ftilenume; tilex <= ltilenume && happy; tilex++)
1342
                    {
1814 plagman 1343
                        switch (md_definehud(lastmodelid, tilex, xadd, yadd, zadd, angadd, flags, fov))
584 terminx 1344
                        {
331 terminx 1345
                        case 0:
1346
                            break;
1347
                        case -1:
1348
                            happy = 0; break; // invalid model id!?
1349
                        case -2:
4061 helixhorne 1350
                            initprintf("Invalid tile number on line %s:%d\n",
331 terminx 1351
                                       script->filename, scriptfile_getlinum(script,hudtokptr));
1352
                            happy = 0;
1353
                            break;
1354
                        case -3:
4061 helixhorne 1355
                            initprintf("Invalid frame name on line %s:%d\n",
331 terminx 1356
                                       script->filename, scriptfile_getlinum(script,hudtokptr));
1357
                            happy = 0;
1358
                            break;
1359
                        }
2237 helixhorne 1360
 
1361
                        model_ok &= happy;
331 terminx 1362
                    }
99 terminx 1363
#endif
109 terminx 1364
                }
584 terminx 1365
                break;
1366
                }
331 terminx 1367
            }
99 terminx 1368
 
2287 helixhorne 1369
#ifdef USE_OPENGL
4680 terminx 1370
            if (EDUKE32_PREDICT_FALSE(!model_ok))
2237 helixhorne 1371
            {
1372
                if (lastmodelid >= 0)
1373
                {
4061 helixhorne 1374
                    initprintf("Removing model %d due to errors.\n", lastmodelid);
2237 helixhorne 1375
                    md_undefinemodel(lastmodelid);
1376
                    nextmodelid--;
1377
                }
1378
                break;
1379
            }
1380
 
2264 hendricks2 1381
            md_setmisc(lastmodelid,(float)scale,shadeoffs,(float)mzadd,(float)myoffset,flags);
1910 helixhorne 1382
 
1383
            // thin out the loaded model by throwing away unused frames
2251 helixhorne 1384
            // FIXME: CURRENTLY DISABLED: interpolation may access frames we consider 'unused'?
1385
# if 0
1910 helixhorne 1386
            if (models[lastmodelid]->mdnum==3 && ((md3model_t *)models[lastmodelid])->numframes <= 1024)
1387
            {
2251 helixhorne 1388
#  ifdef DEBUG_MODEL_MEM
1910 helixhorne 1389
                md3model_t *m = (md3model_t *)models[lastmodelid];
1390
                int32_t i, onumframes;
1391
                onumframes = m->numframes;
2079 helixhorne 1392
                i =
2251 helixhorne 1393
#  endif
2079 helixhorne 1394
                md_thinoutmodel(lastmodelid, usedframebitmap);
2251 helixhorne 1395
#  ifdef DEBUG_MODEL_MEM
1910 helixhorne 1396
                if (i>=0 && i<onumframes)
4061 helixhorne 1397
                    initprintf("used %d/%d frames: %s\n", i, onumframes, modelfn);
1910 helixhorne 1398
                else if (i<0)
4061 helixhorne 1399
                    initprintf("md_thinoutmodel returned %d: %s\n", i, modelfn);
2251 helixhorne 1400
#  endif
1910 helixhorne 1401
            }
2251 helixhorne 1402
# endif
99 terminx 1403
 
3784 terminx 1404
            if (glrendmode == REND_POLYMER)
1910 helixhorne 1405
                md3postload_polymer((md3model_t *)models[lastmodelid]);
1406
#endif
1407
 
331 terminx 1408
            modelskin = lastmodelskin = 0;
1409
            seenframe = 0;
99 terminx 1410
 
331 terminx 1411
        }
1412
        break;
109 terminx 1413
        case T_VOXEL:
331 terminx 1414
        {
1415
            char *voxeltokptr = script->ltextptr;
1416
            char *fn, *modelend;
1205 terminx 1417
            int32_t tile0 = MAXTILES, tile1 = -1, tilex = -1;
99 terminx 1418
 
1677 terminx 1419
            static const tokenlist voxeltokens[] =
1420
            {
1421
                { "tile",   T_TILE   },
1422
                { "tile0",  T_TILE0  },
1423
                { "tile1",  T_TILE1  },
1424
                { "scale",  T_SCALE  },
1425
            };
1426
 
4835 helixhorne 1427
            if (EDUKE32_PREDICT_FALSE(scriptfile_getstring(script,&fn)))
1428
                break; //voxel filename
1429
 
1430
            if (EDUKE32_PREDICT_FALSE(nextvoxid == MAXVOXELS))
1431
            {
1432
                initprintf("Maximum number of voxels (%d) already defined.\n", MAXVOXELS);
1433
                break;
1434
            }
1435
 
1436
            if (EDUKE32_PREDICT_FALSE(qloadkvx(nextvoxid, fn)))
1437
            {
1438
                initprintf("Failure loading voxel file \"%s\"\n",fn);
1439
                break;
1440
            }
1441
 
331 terminx 1442
            lastvoxid = nextvoxid++;
99 terminx 1443
 
331 terminx 1444
            if (scriptfile_getbraces(script,&modelend)) break;
584 terminx 1445
            while (script->textptr < modelend)
1446
            {
4834 helixhorne 1447
                switch (getatoken(script, voxeltokens, ARRAY_SIZE(voxeltokens)))
584 terminx 1448
                {
4061 helixhorne 1449
                    //case T_ERROR: initprintf("Error on line %s:%d in voxel tokens\n", script->filename,linenum); break;
331 terminx 1450
                case T_TILE:
1451
                    scriptfile_getsymbol(script,&tilex);
2588 helixhorne 1452
 
4186 helixhorne 1453
                    if (check_tile("voxel", tilex, script, voxeltokptr))
2588 helixhorne 1454
                        break;
1455
 
1456
                    tiletovox[tilex] = lastvoxid;
331 terminx 1457
                    break;
2588 helixhorne 1458
 
331 terminx 1459
                case T_TILE0:
2588 helixhorne 1460
                    scriptfile_getsymbol(script,&tile0);
1461
                    break; //1st tile #
1462
 
331 terminx 1463
                case T_TILE1:
1464
                    scriptfile_getsymbol(script,&tile1);
2588 helixhorne 1465
 
3329 helixhorne 1466
                    if (check_tile_range("voxel", &tile0, &tile1, script, voxeltokptr))
2588 helixhorne 1467
                        break;
1468
 
1469
                    for (tilex=tile0; tilex<=tile1; tilex++)
1470
                        tiletovox[tilex] = lastvoxid;
331 terminx 1471
                    break; //last tile number (inclusive)
2588 helixhorne 1472
 
584 terminx 1473
                case T_SCALE:
1474
                {
331 terminx 1475
                    double scale=1.0;
1476
                    scriptfile_getdouble(script,&scale);
1205 terminx 1477
                    voxscale[lastvoxid] = (int32_t)(65536*scale);
1908 helixhorne 1478
#ifdef USE_OPENGL
1479
                    if (voxmodels[lastvoxid])
1480
                        voxmodels[lastvoxid]->scale = scale;
1481
#endif
331 terminx 1482
                    break;
109 terminx 1483
                }
331 terminx 1484
                }
109 terminx 1485
            }
331 terminx 1486
            lastvoxid = -1;
1487
        }
1488
        break;
109 terminx 1489
        case T_SKYBOX:
331 terminx 1490
        {
1491
            char *skyboxtokptr = script->ltextptr;
2554 helixhorne 1492
            char *fn[6] = {0,0,0,0,0,0};
1493
            char *modelend;
5040 hendricks2 1494
            int32_t i, tile = -1, pal = 0, happy = 1;
1495
#ifdef USE_OPENGL
1496
            int32_t flags = 0;
1497
#endif
99 terminx 1498
 
1677 terminx 1499
            static const tokenlist skyboxtokens[] =
1500
            {
1501
                { "tile"   ,T_TILE   },
1502
                { "pal"    ,T_PAL    },
1503
                { "ft"     ,T_FRONT  },{ "front"  ,T_FRONT  },{ "forward",T_FRONT  },
1504
                { "rt"     ,T_RIGHT  },{ "right"  ,T_RIGHT  },
1505
                { "bk"     ,T_BACK   },{ "back"   ,T_BACK   },
1506
                { "lf"     ,T_LEFT   },{ "left"   ,T_LEFT   },{ "lt"     ,T_LEFT   },
1507
                { "up"     ,T_TOP    },{ "top"    ,T_TOP    },{ "ceiling",T_TOP    },{ "ceil"   ,T_TOP    },
5010 terminx 1508
                { "dn"     ,T_BOTTOM },{ "bottom" ,T_BOTTOM },{ "floor"  ,T_BOTTOM },{ "down"   ,T_BOTTOM },
1509
                { "nocompress", T_NOCOMPRESS },
1510
                { "nodownsize", T_NODOWNSIZE },
1677 terminx 1511
            };
1512
 
331 terminx 1513
            if (scriptfile_getbraces(script,&modelend)) break;
584 terminx 1514
            while (script->textptr < modelend)
1515
            {
4385 terminx 1516
                switch (getatoken(script,skyboxtokens,ARRAY_SIZE(skyboxtokens)))
584 terminx 1517
                {
4061 helixhorne 1518
                    //case T_ERROR: initprintf("Error on line %s:%d in skybox tokens\n",script->filename,linenum); break;
331 terminx 1519
                case T_TILE:
584 terminx 1520
                    scriptfile_getsymbol(script,&tile); break;
331 terminx 1521
                case T_PAL:
584 terminx 1522
                    scriptfile_getsymbol(script,&pal); break;
331 terminx 1523
                case T_FRONT:
1524
                    scriptfile_getstring(script,&fn[0]); break;
1525
                case T_RIGHT:
1526
                    scriptfile_getstring(script,&fn[1]); break;
1527
                case T_BACK:
1528
                    scriptfile_getstring(script,&fn[2]); break;
1529
                case T_LEFT:
1530
                    scriptfile_getstring(script,&fn[3]); break;
1531
                case T_TOP:
1532
                    scriptfile_getstring(script,&fn[4]); break;
1533
                case T_BOTTOM:
1534
                    scriptfile_getstring(script,&fn[5]); break;
5010 terminx 1535
#ifdef USE_OPENGL
1536
                case T_NOCOMPRESS:
1537
                    flags |= 1; break;
1538
                case T_NODOWNSIZE:
1539
                    flags |= 16; break;
1540
#endif
109 terminx 1541
                }
331 terminx 1542
            }
99 terminx 1543
 
4680 terminx 1544
            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 1545
            for (i=0; i<6; i++)
584 terminx 1546
            {
4680 terminx 1547
                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 1548
                // FIXME?
2554 helixhorne 1549
                if (check_file_exist(fn[i]))
1550
                    happy = 0;
331 terminx 1551
            }
1552
            if (!happy) break;
99 terminx 1553
 
3382 hendricks2 1554
#ifdef USE_OPENGL
5010 terminx 1555
            hicsetskybox(tile,pal,fn, flags);
3382 hendricks2 1556
#endif
331 terminx 1557
        }
1558
        break;
1748 plagman 1559
        case T_HIGHPALOOKUP:
1560
        {
1561
            char *highpaltokptr = script->ltextptr;
2554 helixhorne 1562
            int32_t basepal=-1, pal=-1;
1563
            char *fn = NULL;
1748 plagman 1564
            char *highpalend;
1778 helixhorne 1565
#ifdef POLYMER
1566
            int32_t fd;
1748 plagman 1567
            char *highpaldata;
1778 helixhorne 1568
#endif
1748 plagman 1569
            static const tokenlist highpaltokens[] =
1570
            {
1782 plagman 1571
                { "basepal",   T_BASEPAL },
1748 plagman 1572
                { "pal",   T_PAL },
1573
                { "file",  T_FILE }
1574
            };
1575
 
1576
            if (scriptfile_getbraces(script,&highpalend)) break;
1577
            while (script->textptr < highpalend)
1578
            {
4385 terminx 1579
                switch (getatoken(script,highpaltokens,ARRAY_SIZE(highpaltokens)))
1748 plagman 1580
                {
1782 plagman 1581
                case T_BASEPAL:
1582
                    scriptfile_getsymbol(script,&basepal);   break;
1748 plagman 1583
                case T_PAL:
1584
                    scriptfile_getsymbol(script,&pal);   break;
1585
                case T_FILE:
1586
                    scriptfile_getstring(script,&fn); break;
1587
                }
1588
            }
4680 terminx 1589
            if (EDUKE32_PREDICT_FALSE((unsigned)basepal >= ((unsigned)basepalcount)))
1782 plagman 1590
            {
4061 helixhorne 1591
                initprintf("Error: missing or invalid 'base palette number' for highpalookup definition "
1592
                           "near line %s:%d\n", script->filename, scriptfile_getlinum(script,highpaltokptr));
1782 plagman 1593
                break;
1594
            }
1748 plagman 1595
 
4680 terminx 1596
            if (EDUKE32_PREDICT_FALSE((unsigned)pal >= MAXPALOOKUPS - RESERVEDPALS))
1748 plagman 1597
            {
4061 helixhorne 1598
                initprintf("Error: missing or invalid 'palette number' for highpalookup definition near "
1599
                           "line %s:%d\n", script->filename, scriptfile_getlinum(script,highpaltokptr));
1748 plagman 1600
                break;
1601
            }
1782 plagman 1602
 
4680 terminx 1603
            if (EDUKE32_PREDICT_FALSE(!fn))
1748 plagman 1604
            {
4061 helixhorne 1605
                initprintf("Error: missing 'file name' for highpalookup definition near line %s:%d\n",
1748 plagman 1606
                           script->filename, scriptfile_getlinum(script,highpaltokptr));
1607
                break;
1608
            }
1762 terminx 1609
 
2554 helixhorne 1610
            if (check_file_exist(fn))
1611
                break;
1748 plagman 1612
 
1778 helixhorne 1613
#ifdef POLYMER
1748 plagman 1614
            fd = kopen4load(fn, 0);
1615
 
1751 helixhorne 1616
            // load the highpalookup and send it to polymer
4491 helixhorne 1617
            highpaldata = (char *)Xmalloc(PR_HIGHPALOOKUP_DATA_SIZE);
1749 helixhorne 1618
 
1619
            {
1751 helixhorne 1620
                char *filebuf;
1749 helixhorne 1621
                int32_t xsiz, ysiz, filesize, i;
1622
 
1623
                filesize = kfilelength(fd);
1624
 
4491 helixhorne 1625
                filebuf = (char *)Xmalloc(filesize);
1749 helixhorne 1626
 
1627
                klseek(fd, 0, SEEK_SET);
1628
                if (kread(fd, filebuf, filesize)!=filesize)
4061 helixhorne 1629
                    { kclose(fd); Bfree(highpaldata); initprintf("Error: didn't read all of \"%s\".\n", fn); break; }
1749 helixhorne 1630
 
1631
                kclose(fd);
1632
                kpgetdim(filebuf, filesize, &xsiz, &ysiz);
1633
 
4680 terminx 1634
                if (EDUKE32_PREDICT_FALSE(xsiz != PR_HIGHPALOOKUP_DIM*PR_HIGHPALOOKUP_DIM || ysiz != PR_HIGHPALOOKUP_DIM))
1749 helixhorne 1635
                {
4061 helixhorne 1636
                    initprintf("Error: image dimensions of \"%s\" must be %dx%d.\n",
1751 helixhorne 1637
                               fn, PR_HIGHPALOOKUP_DIM*PR_HIGHPALOOKUP_DIM, PR_HIGHPALOOKUP_DIM);
1749 helixhorne 1638
                    Bfree(filebuf); Bfree(highpaldata);
1748 plagman 1639
                    break;
1749 helixhorne 1640
                }
1641
 
4637 terminx 1642
                i = kprender(filebuf, filesize, (intptr_t)highpaldata, xsiz*sizeof(coltype), xsiz, ysiz);
1749 helixhorne 1643
                Bfree(filebuf);
4680 terminx 1644
                if (EDUKE32_PREDICT_FALSE(i))
4061 helixhorne 1645
                    { Bfree(highpaldata); initprintf("Error: failed rendering \"%s\".\n", fn); break; }
1748 plagman 1646
            }
1749 helixhorne 1647
 
1782 plagman 1648
            polymer_definehighpalookup(basepal, pal, highpaldata);
1748 plagman 1649
 
1650
            Bfree(highpaldata);
1778 helixhorne 1651
#endif
1748 plagman 1652
        }
1653
        break;
109 terminx 1654
        case T_TINT:
331 terminx 1655
        {
1656
            char *tinttokptr = script->ltextptr;
1205 terminx 1657
            int32_t red=255, green=255, blue=255, pal=-1, flags=0;
331 terminx 1658
            char *tintend;
99 terminx 1659
 
1677 terminx 1660
            static const tokenlist tinttokens[] =
1661
            {
1662
                { "pal",   T_PAL },
1663
                { "red",   T_RED   },{ "r", T_RED },
1664
                { "green", T_GREEN },{ "g", T_GREEN },
1665
                { "blue",  T_BLUE  },{ "b", T_BLUE },
1666
                { "flags", T_FLAGS }
1667
            };
1668
 
331 terminx 1669
            if (scriptfile_getbraces(script,&tintend)) break;
584 terminx 1670
            while (script->textptr < tintend)
1671
            {
4385 terminx 1672
                switch (getatoken(script,tinttokens,ARRAY_SIZE(tinttokens)))
584 terminx 1673
                {
331 terminx 1674
                case T_PAL:
1675
                    scriptfile_getsymbol(script,&pal);   break;
1676
                case T_RED:
1677
                    scriptfile_getnumber(script,&red);   red   = min(255,max(0,red));   break;
1678
                case T_GREEN:
1679
                    scriptfile_getnumber(script,&green); green = min(255,max(0,green)); break;
1680
                case T_BLUE:
1681
                    scriptfile_getnumber(script,&blue);  blue  = min(255,max(0,blue));  break;
1682
                case T_FLAGS:
1683
                    scriptfile_getsymbol(script,&flags); break;
109 terminx 1684
                }
331 terminx 1685
            }
99 terminx 1686
 
4680 terminx 1687
            if (EDUKE32_PREDICT_FALSE(pal < 0))
584 terminx 1688
            {
4061 helixhorne 1689
                initprintf("Error: tint: missing 'palette number' near line %s:%d\n",
2568 helixhorne 1690
                           script->filename, scriptfile_getlinum(script,tinttokptr));
331 terminx 1691
                break;
1692
            }
99 terminx 1693
 
3382 hendricks2 1694
#ifdef USE_OPENGL
331 terminx 1695
            hicsetpalettetint(pal,red,green,blue,flags);
3382 hendricks2 1696
#endif
331 terminx 1697
        }
1698
        break;
2568 helixhorne 1699
        case T_MAKEPALOOKUP:
1700
        {
1701
            char *const starttokptr = script->ltextptr;
1702
            int32_t red=0, green=0, blue=0, pal=-1;
1703
            int32_t havepal=0, remappal=0;
1704
            char *endtextptr;
1705
 
1706
            static const tokenlist palookuptokens[] =
1707
            {
1708
                { "pal",   T_PAL },
1709
                { "red",   T_RED   }, { "r", T_RED },
1710
                { "green", T_GREEN }, { "g", T_GREEN },
1711
                { "blue",  T_BLUE  }, { "b", T_BLUE },
1712
                { "remappal", T_REMAPPAL },
1713
                { "remapself", T_REMAPSELF },
1714
            };
1715
 
4813 helixhorne 1716
            enum {
1717
                HAVE_PAL = 1,
1718
                HAVE_REMAPPAL = 2,
1719
                HAVE_REMAPSELF = 4,
1720
 
1721
                HAVEPAL_SPECIAL = HAVE_REMAPPAL | HAVE_REMAPSELF,
1722
                HAVEPAL_ERROR = 8,
1723
            };
1724
 
2568 helixhorne 1725
            if (scriptfile_getbraces(script,&endtextptr)) break;
1726
            while (script->textptr < endtextptr)
1727
            {
4385 terminx 1728
                switch (getatoken(script, palookuptokens, ARRAY_SIZE(palookuptokens)))
2568 helixhorne 1729
                {
1730
                case T_PAL:
1731
                    scriptfile_getsymbol(script, &pal);
4813 helixhorne 1732
                    havepal |= HAVE_PAL;
2568 helixhorne 1733
                    break;
1734
                case T_RED:
1735
                    scriptfile_getnumber(script,&red);
1736
                    red = clamp(red, 0, 63);
1737
                    break;
1738
                case T_GREEN:
1739
                    scriptfile_getnumber(script,&green);
1740
                    green = clamp(green, 0, 63);
1741
                    break;
1742
                case T_BLUE:
1743
                    scriptfile_getnumber(script,&blue);
1744
                    blue = clamp(blue, 0, 63);
1745
                    break;
1746
                case T_REMAPPAL:
1747
                    scriptfile_getsymbol(script,&remappal);
4813 helixhorne 1748
                    if (havepal & HAVEPAL_SPECIAL)
1749
                        havepal |= HAVEPAL_ERROR;
1750
                    havepal |= HAVE_REMAPPAL;
2568 helixhorne 1751
                    break;
1752
                case T_REMAPSELF:
4813 helixhorne 1753
                    if (havepal & HAVEPAL_SPECIAL)
1754
                        havepal |= HAVEPAL_ERROR;
1755
                    havepal |= HAVE_REMAPSELF;
2568 helixhorne 1756
                    break;
1757
                }
1758
            }
1759
 
1760
            {
1761
                char msgend[BMAX_PATH+64];
1762
 
1763
                Bsprintf(msgend, "for palookup definition near line %s:%d",
1764
                         script->filename, scriptfile_getlinum(script,starttokptr));
1765
 
4813 helixhorne 1766
                if (EDUKE32_PREDICT_FALSE((havepal & HAVE_PAL)==0))
2568 helixhorne 1767
                {
4061 helixhorne 1768
                    initprintf("Error: missing 'palette number' %s\n", msgend);
2568 helixhorne 1769
                    break;
1770
                }
4680 terminx 1771
                else if (EDUKE32_PREDICT_FALSE(pal==0 || (unsigned)pal >= MAXPALOOKUPS-RESERVEDPALS))
2568 helixhorne 1772
                {
4061 helixhorne 1773
                    initprintf("Error: 'palette number' out of range (1 .. %d) %s\n",
2568 helixhorne 1774
                               MAXPALOOKUPS-RESERVEDPALS-1, msgend);
1775
                    break;
1776
                }
4813 helixhorne 1777
 
1778
                if (EDUKE32_PREDICT_FALSE(havepal & HAVEPAL_ERROR))
2568 helixhorne 1779
                {
1780
                    // will also disallow multiple remappals or remapselfs
4061 helixhorne 1781
                    initprintf("Error: must have exactly one of either 'remappal' or 'remapself' %s\n", msgend);
2568 helixhorne 1782
                    break;
1783
                }
4813 helixhorne 1784
                else if (EDUKE32_PREDICT_FALSE((havepal & HAVE_REMAPPAL)
1785
                                               && (unsigned)remappal >= MAXPALOOKUPS-RESERVEDPALS))
2568 helixhorne 1786
                {
4061 helixhorne 1787
                    initprintf("Error: 'remap palette number' out of range (max=%d) %s\n",
2568 helixhorne 1788
                               MAXPALOOKUPS-RESERVEDPALS-1, msgend);
1789
                    break;
1790
                }
1791
 
4813 helixhorne 1792
                if (havepal & HAVE_REMAPSELF)
2568 helixhorne 1793
                    remappal = pal;
1794
            }
1795
 
1796
            // NOTE: all palookups are initialized, i.e. non-NULL!
1797
            // NOTE2: aliasing (pal==remappal) is OK
4812 helixhorne 1798
            makepalookup(pal, palookup[remappal], red, green, blue,
1799
                         remappal==0 ? 1 : g_noFloorPal[remappal]);
2568 helixhorne 1800
        }
1801
        break;
109 terminx 1802
        case T_TEXTURE:
331 terminx 1803
        {
1804
            char *texturetokptr = script->ltextptr, *textureend;
1205 terminx 1805
            int32_t tile=-1, token;
99 terminx 1806
 
1677 terminx 1807
            static const tokenlist texturetokens[] =
1808
            {
1809
                { "pal",     T_PAL  },
1810
                { "detail",  T_DETAIL },
1811
                { "glow",    T_GLOW },
1812
                { "specular",T_SPECULAR },
1813
                { "normal",  T_NORMAL },
1814
            };
1815
 
331 terminx 1816
            if (scriptfile_getsymbol(script,&tile)) break;
1817
            if (scriptfile_getbraces(script,&textureend)) break;
584 terminx 1818
            while (script->textptr < textureend)
1819
            {
4385 terminx 1820
                token = getatoken(script,texturetokens,ARRAY_SIZE(texturetokens));
584 terminx 1821
                switch (token)
1822
                {
1823
                case T_PAL:
1824
                {
331 terminx 1825
                    char *paltokptr = script->ltextptr, *palend;
4062 terminx 1826
                    int32_t pal=-1, xsiz = 0, ysiz = 0;
2554 helixhorne 1827
                    char *fn = NULL;
1526 plagman 1828
                    double alphacut = -1.0, xscale = 1.0, yscale = 1.0, specpower = 1.0, specfactor = 1.0;
3382 hendricks2 1829
#ifdef USE_OPENGL
331 terminx 1830
                    char flags = 0;
3382 hendricks2 1831
#endif
99 terminx 1832
 
1677 terminx 1833
                    static const tokenlist texturetokens_pal[] =
1834
                    {
1835
                        { "file",            T_FILE },{ "name", T_FILE },
1836
                        { "alphacut",        T_ALPHACUT },
1837
                        { "detailscale",     T_XSCALE }, { "scale",  T_XSCALE }, { "xscale",  T_XSCALE }, { "intensity",  T_XSCALE },
1838
                        { "yscale",          T_YSCALE },
2539 hendricks2 1839
                        { "specpower",       T_SPECPOWER }, { "specularpower", T_SPECPOWER }, { "parallaxscale", T_SPECPOWER },
1840
                        { "specfactor",      T_SPECFACTOR }, { "specularfactor", T_SPECFACTOR }, { "parallaxbias", T_SPECFACTOR },
1677 terminx 1841
                        { "nocompress",      T_NOCOMPRESS },
1842
                        { "nodownsize",      T_NODOWNSIZE },
4062 terminx 1843
                        { "orig_sizex",      T_ORIGSIZEX }, { "orig_sizey", T_ORIGSIZEY }
1677 terminx 1844
                    };
1845
 
331 terminx 1846
                    if (scriptfile_getsymbol(script,&pal)) break;
1847
                    if (scriptfile_getbraces(script,&palend)) break;
584 terminx 1848
                    while (script->textptr < palend)
1849
                    {
4385 terminx 1850
                        switch (getatoken(script,texturetokens_pal,ARRAY_SIZE(texturetokens_pal)))
584 terminx 1851
                        {
331 terminx 1852
                        case T_FILE:
1853
                            scriptfile_getstring(script,&fn); break;
1854
                        case T_ALPHACUT:
1855
                            scriptfile_getdouble(script,&alphacut); break;
504 Plagman 1856
                        case T_XSCALE:
1857
                            scriptfile_getdouble(script,&xscale); break;
1858
                        case T_YSCALE:
1859
                            scriptfile_getdouble(script,&yscale); break;
1526 plagman 1860
                        case T_SPECPOWER:
1861
                            scriptfile_getdouble(script,&specpower); break;
1862
                        case T_SPECFACTOR:
1863
                            scriptfile_getdouble(script,&specfactor); break;
3382 hendricks2 1864
#ifdef USE_OPENGL
331 terminx 1865
                        case T_NOCOMPRESS:
1866
                            flags |= 1; break;
1033 terminx 1867
                        case T_NODOWNSIZE:
1868
                            flags |= 16; break;
3382 hendricks2 1869
#endif
4062 terminx 1870
                        case T_ORIGSIZEX:
1871
                            scriptfile_getnumber(script, &xsiz);
1872
                            break;
1873
                        case T_ORIGSIZEY:
1874
                            scriptfile_getnumber(script, &ysiz);
1875
                            break;
331 terminx 1876
                        default:
1877
                            break;
1878
                        }
1879
                    }
99 terminx 1880
 
4680 terminx 1881
                    if (EDUKE32_PREDICT_FALSE((unsigned)tile >= MAXUSERTILES)) break;   // message is printed later
1882
                    if (EDUKE32_PREDICT_FALSE((unsigned)pal >= MAXPALOOKUPS - RESERVEDPALS))
584 terminx 1883
                    {
4061 helixhorne 1884
                        initprintf("Error: missing or invalid 'palette number' for texture definition near "
1885
                                   "line %s:%d\n", script->filename, scriptfile_getlinum(script,paltokptr));
331 terminx 1886
                        break;
109 terminx 1887
                    }
4680 terminx 1888
                    if (EDUKE32_PREDICT_FALSE(!fn))
584 terminx 1889
                    {
4061 helixhorne 1890
                        initprintf("Error: missing 'file name' for texture definition near line %s:%d\n",
331 terminx 1891
                                   script->filename, scriptfile_getlinum(script,paltokptr));
1892
                        break;
1893
                    }
543 terminx 1894
 
4680 terminx 1895
                    if (EDUKE32_PREDICT_FALSE(check_file_exist(fn)))
2554 helixhorne 1896
                        break;
544 terminx 1897
 
4062 terminx 1898
                    if (xsiz > 0 && ysiz > 0)
1899
                    {
1900
                        set_tilesiz(tile, xsiz, ysiz);
1901
                        Bmemset(&picanm[tile], 0, sizeof(picanm_t));
1902
                        faketilesiz[tile] = -1;
1903
                    }
3382 hendricks2 1904
#ifdef USE_OPENGL
504 Plagman 1905
                    xscale = 1.0f / xscale;
1906
                    yscale = 1.0f / yscale;
1907
 
1526 plagman 1908
                    hicsetsubsttex(tile,pal,fn,alphacut,xscale,yscale, specpower, specfactor,flags);
3382 hendricks2 1909
#endif
584 terminx 1910
                }
1911
                break;
1350 terminx 1912
                case T_DETAIL: case T_GLOW: case T_SPECULAR: case T_NORMAL:
584 terminx 1913
                {
459 Plagman 1914
                    char *detailtokptr = script->ltextptr, *detailend;
3382 hendricks2 1915
#ifdef USE_OPENGL
2554 helixhorne 1916
                    int32_t pal = 0;
3382 hendricks2 1917
                    char flags = 0;
1918
#endif
2554 helixhorne 1919
                    char *fn = NULL;
1350 terminx 1920
                    double xscale = 1.0, yscale = 1.0, specpower = 1.0, specfactor = 1.0;
459 Plagman 1921
 
1677 terminx 1922
                    static const tokenlist texturetokens_pal[] =
1923
                    {
1924
                        { "file",            T_FILE },{ "name", T_FILE },
1925
                        { "alphacut",        T_ALPHACUT },
1926
                        { "detailscale",     T_XSCALE }, { "scale",  T_XSCALE }, { "xscale",  T_XSCALE }, { "intensity",  T_XSCALE },
1927
                        { "yscale",          T_YSCALE },
2539 hendricks2 1928
                        { "specpower",       T_SPECPOWER }, { "specularpower", T_SPECPOWER }, { "parallaxscale", T_SPECPOWER },
1929
                        { "specfactor",      T_SPECFACTOR }, { "specularfactor", T_SPECFACTOR }, { "parallaxbias", T_SPECFACTOR },
1677 terminx 1930
                        { "nocompress",      T_NOCOMPRESS },
1931
                        { "nodownsize",      T_NODOWNSIZE },
1932
                    };
1933
 
4680 terminx 1934
                    if (EDUKE32_PREDICT_FALSE(scriptfile_getbraces(script,&detailend))) break;
584 terminx 1935
                    while (script->textptr < detailend)
1936
                    {
4385 terminx 1937
                        switch (getatoken(script,texturetokens_pal,ARRAY_SIZE(texturetokens_pal)))
584 terminx 1938
                        {
459 Plagman 1939
                        case T_FILE:
1940
                            scriptfile_getstring(script,&fn); break;
504 Plagman 1941
                        case T_XSCALE:
512 Plagman 1942
                            scriptfile_getdouble(script,&xscale); break;
1943
                        case T_YSCALE:
1944
                            scriptfile_getdouble(script,&yscale); break;
1350 terminx 1945
                        case T_SPECPOWER:
1946
                            scriptfile_getdouble(script,&specpower); break;
1947
                        case T_SPECFACTOR:
1948
                            scriptfile_getdouble(script,&specfactor); break;
3382 hendricks2 1949
#ifdef USE_OPENGL
459 Plagman 1950
                        case T_NOCOMPRESS:
1951
                            flags |= 1; break;
1033 terminx 1952
                        case T_NODOWNSIZE:
1953
                            flags |= 16; break;
3382 hendricks2 1954
#endif
459 Plagman 1955
                        default:
1956
                            break;
1957
                        }
1958
                    }
1959
 
4680 terminx 1960
                    if (EDUKE32_PREDICT_FALSE((unsigned)tile >= MAXUSERTILES)) break;   // message is printed later
1961
                    if (EDUKE32_PREDICT_FALSE(!fn))
584 terminx 1962
                    {
4061 helixhorne 1963
                        initprintf("Error: missing 'file name' for texture definition near line %s:%d\n",
459 Plagman 1964
                                   script->filename, scriptfile_getlinum(script,detailtokptr));
1965
                        break;
1966
                    }
543 terminx 1967
 
4680 terminx 1968
                    if (EDUKE32_PREDICT_FALSE(check_file_exist(fn)))
2554 helixhorne 1969
                        break;
544 terminx 1970
 
3382 hendricks2 1971
#ifdef USE_OPENGL
587 terminx 1972
                    switch (token)
501 Plagman 1973
                    {
587 terminx 1974
                    case T_DETAIL:
501 Plagman 1975
                        pal = DETAILPAL;
512 Plagman 1976
                        xscale = 1.0f / xscale;
513 Plagman 1977
                        yscale = 1.0f / yscale;
587 terminx 1978
                        break;
1979
                    case T_GLOW:
1980
                        pal = GLOWPAL;
1981
                        break;
1350 terminx 1982
                    case T_SPECULAR:
1983
                        pal = SPECULARPAL;
1984
                        break;
1985
                    case T_NORMAL:
1986
                        pal = NORMALPAL;
1987
                        break;
497 Plagman 1988
                    }
1350 terminx 1989
                    hicsetsubsttex(tile,pal,fn,-1.0f,xscale,yscale, specpower, specfactor,flags);
3382 hendricks2 1990
#endif
584 terminx 1991
                }
1992
                break;
331 terminx 1993
                default:
109 terminx 1994
                    break;
1995
                }
1996
            }
4680 terminx 1997
            if (EDUKE32_PREDICT_FALSE((unsigned)tile >= MAXUSERTILES))
584 terminx 1998
            {
4061 helixhorne 1999
                initprintf("Error: missing or invalid 'tile number' for texture definition near line %s:%d\n",
331 terminx 2000
                           script->filename, scriptfile_getlinum(script,texturetokptr));
2001
                break;
2002
            }
2003
        }
2004
        break;
2005
 
109 terminx 2006
        case T_UNDEFMODEL:
2007
        case T_UNDEFMODELRANGE:
331 terminx 2008
        {
1205 terminx 2009
            int32_t r0,r1;
109 terminx 2010
 
4680 terminx 2011
            if (EDUKE32_PREDICT_FALSE(scriptfile_getsymbol(script,&r0))) break;
584 terminx 2012
            if (tokn == T_UNDEFMODELRANGE)
2013
            {
331 terminx 2014
                if (scriptfile_getsymbol(script,&r1)) break;
2588 helixhorne 2015
 
2016
                if (check_tile_range("undefmodelrange", &r0, &r1, script, cmdtokptr))
331 terminx 2017
                    break;
584 terminx 2018
            }
2019
            else
2020
            {
331 terminx 2021
                r1 = r0;
2588 helixhorne 2022
 
4186 helixhorne 2023
                if (check_tile("undefmodel", r0, script, cmdtokptr))
331 terminx 2024
                    break;
2025
            }
1820 terminx 2026
#ifdef USE_OPENGL
2588 helixhorne 2027
            for (; r0 <= r1; r0++)
2028
                md_undefinetile(r0);
99 terminx 2029
#endif
331 terminx 2030
        }
2031
        break;
99 terminx 2032
 
109 terminx 2033
        case T_UNDEFMODELOF:
331 terminx 2034
        {
1205 terminx 2035
            int32_t r0;
1820 terminx 2036
#ifdef USE_OPENGL
1205 terminx 2037
            int32_t mid;
895 terminx 2038
#endif
99 terminx 2039
 
4680 terminx 2040
            if (EDUKE32_PREDICT_FALSE(scriptfile_getsymbol(script,&r0))) break;
2588 helixhorne 2041
 
4186 helixhorne 2042
            if (check_tile("undefmodelof", r0, script, cmdtokptr))
331 terminx 2043
                break;
99 terminx 2044
 
2588 helixhorne 2045
            // XXX: See comment of md_undefinemodel()
4061 helixhorne 2046
            initprintf("Warning: undefmodelof: currently non-functional.\n");
2588 helixhorne 2047
            break;
2048
 
1820 terminx 2049
#ifdef USE_OPENGL
587 terminx 2050
            mid = md_tilehasmodel(r0,0);
331 terminx 2051
            if (mid < 0) break;
99 terminx 2052
 
331 terminx 2053
            md_undefinemodel(mid);
99 terminx 2054
#endif
331 terminx 2055
        }
2056
        break;
99 terminx 2057
 
109 terminx 2058
        case T_UNDEFTEXTURE:
2059
        case T_UNDEFTEXTURERANGE:
331 terminx 2060
        {
3382 hendricks2 2061
            int32_t r0,r1;
2062
#ifdef USE_OPENGL
2063
            int32_t i;
2064
#endif
99 terminx 2065
 
4680 terminx 2066
            if (EDUKE32_PREDICT_FALSE(scriptfile_getsymbol(script,&r0))) break;
584 terminx 2067
            if (tokn == T_UNDEFTEXTURERANGE)
2068
            {
4680 terminx 2069
                if (EDUKE32_PREDICT_FALSE(scriptfile_getsymbol(script,&r1))) break;
2588 helixhorne 2070
 
4680 terminx 2071
                if (EDUKE32_PREDICT_FALSE(check_tile_range("undeftexturerange", &r0, &r1, script, cmdtokptr)))
331 terminx 2072
                    break;
584 terminx 2073
            }
2074
            else
2075
            {
331 terminx 2076
                r1 = r0;
2588 helixhorne 2077
 
4680 terminx 2078
                if (EDUKE32_PREDICT_FALSE(check_tile("undeftexture", r0, script, cmdtokptr)))
331 terminx 2079
                    break;
109 terminx 2080
            }
2081
 
3382 hendricks2 2082
#ifdef USE_OPENGL
331 terminx 2083
            for (; r0 <= r1; r0++)
2084
                for (i=MAXPALOOKUPS-1; i>=0; i--)
2085
                    hicclearsubst(r0,i);
3382 hendricks2 2086
#endif
331 terminx 2087
        }
2088
        break;
2089
 
4987 terminx 2090
        case T_CUTSCENE:
2242 helixhorne 2091
        case T_ANIMSOUNDS:
2092
        {
2093
            char *dummy;
2094
 
2095
            static const tokenlist dummytokens[] = { { "id",   T_ID  }, };
2096
 
4680 terminx 2097
            if (EDUKE32_PREDICT_FALSE(scriptfile_getstring(script, &dummy))) break;
2098
            if (EDUKE32_PREDICT_FALSE(scriptfile_getbraces(script,&dummy))) break;
2242 helixhorne 2099
            while (script->textptr < dummy)
2100
            {
2101
                // XXX?
2102
                getatoken(script,dummytokens,sizeof(dummytokens)/sizeof(dummytokens));
2103
            }
2104
        }
2105
        break;
2106
 
3078 helixhorne 2107
        case T_TEXHITSCANRANGE:
3230 helixhorne 2108
        case T_NOFULLBRIGHTRANGE:
3078 helixhorne 2109
        {
2110
            int32_t b,e, i;
2111
 
4680 terminx 2112
            if (EDUKE32_PREDICT_FALSE(scriptfile_getnumber(script,&b))) break;
2113
            if (EDUKE32_PREDICT_FALSE(scriptfile_getnumber(script,&e))) break;
3078 helixhorne 2114
 
2115
            b = max(b, 0);
4225 helixhorne 2116
            e = min(e, MAXUSERTILES-1);
3078 helixhorne 2117
 
2118
            for (i=b; i<=e; i++)
3230 helixhorne 2119
                picanm[i].sf |= (tokn==T_TEXHITSCANRANGE) ?
2120
                    PICANM_TEXHITSCAN_BIT : PICANM_NOFULLBRIGHT_BIT;
3078 helixhorne 2121
        }
2122
        break;
2123
 
1677 terminx 2124
        case T_SOUND:
587 terminx 2125
        case T_MUSIC:
2126
        {
634 terminx 2127
            char *dummy, *dummy2;
1677 terminx 2128
            static const tokenlist sound_musictokens[] =
2129
            {
2130
                { "id",   T_ID  },
2131
                { "file", T_FILE },
2132
            };
587 terminx 2133
 
4680 terminx 2134
            if (EDUKE32_PREDICT_FALSE(scriptfile_getbraces(script,&dummy))) break;
634 terminx 2135
            while (script->textptr < dummy)
587 terminx 2136
            {
4385 terminx 2137
                switch (getatoken(script,sound_musictokens,ARRAY_SIZE(sound_musictokens)))
587 terminx 2138
                {
2139
                case T_ID:
634 terminx 2140
                    scriptfile_getstring(script,&dummy2);
2141
                    break;
587 terminx 2142
                case T_FILE:
634 terminx 2143
                    scriptfile_getstring(script,&dummy2);
2144
                    break;
587 terminx 2145
                }
2146
            }
2147
        }
2148
        break;
2149
 
3309 hendricks2 2150
        case T_MAPINFO:
2151
        {
4884 hendricks2 2152
            char *mapmd4string = NULL, *title = NULL, *mhkfile = NULL, *mapinfoend, *dummy;
3309 hendricks2 2153
            static const tokenlist mapinfotokens[] =
2154
            {
2155
                { "mapfile",    T_MAPFILE },
2156
                { "maptitle",   T_MAPTITLE },
2157
                { "mapmd4",     T_MAPMD4 },
2158
                { "mhkfile",    T_MHKFILE },
2159
            };
4884 hendricks2 2160
            int32_t previous_usermaphacks = num_usermaphacks;
3309 hendricks2 2161
 
4884 hendricks2 2162
            if (EDUKE32_PREDICT_FALSE(scriptfile_getbraces(script,&mapinfoend))) break;
2163
            while (script->textptr < mapinfoend)
3309 hendricks2 2164
            {
4385 terminx 2165
                switch (getatoken(script,mapinfotokens,ARRAY_SIZE(mapinfotokens)))
3309 hendricks2 2166
                {
2167
                case T_MAPFILE:
4884 hendricks2 2168
                    scriptfile_getstring(script,&dummy);
3309 hendricks2 2169
                    break;
2170
                case T_MAPTITLE:
4884 hendricks2 2171
                    scriptfile_getstring(script,&title);
3309 hendricks2 2172
                    break;
2173
                case T_MAPMD4:
4884 hendricks2