Subversion Repositories eduke32

Rev

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