Subversion Repositories eduke32

Rev

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
 
8488 hendricks2 209
    paletteFlushClosestColor();
4680 terminx 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] =
8488 hendricks2 218
            (col->f < alphacut) ? 255 : paletteGetClosestColorUpToIndex(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)
8490 hendricks2 592
            {
593
                editorcolorsdef[col] = 1;
5427 helixhorne 594
                editorcolors[col++] = idx++;
8490 hendricks2 595
            }
5427 helixhorne 596
        }
597
        break;
109 terminx 598
        case T_FOGPAL:
331 terminx 599
        {
2569 helixhorne 600
            int32_t p,r,g,b;
5 Plagman 601
 
6896 hendricks2 602
            if (scriptfile_getsymbol(script,&p)) break;
331 terminx 603
            if (scriptfile_getnumber(script,&r)) break;
604
            if (scriptfile_getnumber(script,&g)) break;
605
            if (scriptfile_getnumber(script,&b)) break;
5 Plagman 606
 
2568 helixhorne 607
            r = clamp(r, 0, 63);
608
            g = clamp(g, 0, 63);
609
            b = clamp(b, 0, 63);
610
 
6829 terminx 611
            paletteMakeLookupTable(p, NULL, r<<2, g<<2, b<<2, 1);
331 terminx 612
        }
613
        break;
4811 helixhorne 614
        case T_NOFLOORPALRANGE:
615
        {
616
            int32_t b,e,i;
617
 
6896 hendricks2 618
            if (scriptfile_getsymbol(script,&b)) break;
619
            if (scriptfile_getsymbol(script,&e)) break;
4811 helixhorne 620
 
621
            b = max(b, 1);
622
            e = min(e, MAXPALOOKUPS-1);
623
 
624
            for (i=b; i<=e; i++)
625
                g_noFloorPal[i] = 1;
626
        }
627
        break;
109 terminx 628
        case T_LOADGRP:
331 terminx 629
        {
630
            char *bs;
631
            scriptfile_getstring(script,&bs);
632
        }
633
        break;
441 terminx 634
        case T_CACHESIZE:
635
        {
1205 terminx 636
            int32_t j;
584 terminx 637
 
441 terminx 638
            if (scriptfile_getnumber(script,&j)) break;
639
        }
640
        break;
6592 hendricks2 641
        case T_SHADEFACTOR:
642
            scriptfile_getnumber(script, &realmaxshade);
643
            frealmaxshade = (float)realmaxshade;
644
            break;
5180 hendricks2 645
        case T_ARTFILE:
646
        {
647
            char *blockend, *fn = NULL;
648
            int32_t tile = -1, havetile = 0;
649
 
650
            static const tokenlist artfiletokens[] =
651
            {
652
                { "file",            T_FILE },
653
                { "tile",            T_TILE },
654
            };
655
 
656
            if (scriptfile_getbraces(script,&blockend)) break;
657
            while (script->textptr < blockend)
658
            {
659
                int32_t token = getatoken(script,artfiletokens,ARRAY_SIZE(artfiletokens));
660
                switch (token)
661
                {
662
                case T_FILE:
663
                    scriptfile_getstring(script,&fn);
664
                    break;
665
                case T_TILE:
666
                    havetile = 1;
667
                    scriptfile_getsymbol(script,&tile);
668
                    break;
669
                default:
670
                    break;
671
                }
672
            }
673
 
674
            if (EDUKE32_PREDICT_FALSE(!fn))
675
            {
676
                initprintf("Error: missing 'file name' for artfile definition near line %s:%d\n",
677
                           script->filename, scriptfile_getlinum(script,cmdtokptr));
678
                break;
679
            }
680
 
7359 hendricks2 681
            buildvfs_kfd const fil = kopen4load(fn, 0);
682
            if (fil == buildvfs_kfd_invalid)
5180 hendricks2 683
                break;
684
 
685
            artheader_t local;
6830 terminx 686
            int32_t headerval = artReadHeader(fil, fn, &local);
5180 hendricks2 687
            if (headerval != 0)
6570 pogokeen 688
            {
6571 pogokeen 689
                kclose(fil);
5180 hendricks2 690
                break;
6570 pogokeen 691
            }
5180 hendricks2 692
 
693
            if (havetile)
694
            {
695
                if (!check_tile("artfile", tile, script, cmdtokptr))
696
                {
697
                    local.tilestart = tile;
698
                    local.tileend = tile + local.numtiles - 1;
699
                }
700
            }
701
 
6830 terminx 702
            artReadManifest(fil, &local);
703
            artPreloadFile(fil, &local);
5180 hendricks2 704
 
705
            kclose(fil);
706
        }
707
        break;
665 terminx 708
        case T_SETUPTILE:
709
        {
1205 terminx 710
            int32_t tile, tmp;
665 terminx 711
 
712
            if (scriptfile_getsymbol(script,&tile)) break;
5137 hendricks2 713
            if (check_tile("setuptile", tile, script, cmdtokptr))
714
                break;
5079 terminx 715
            if (scriptfile_getsymbol(script,&tmp)) break;  // XXX
716
            h_xsize[tile] = tmp;
665 terminx 717
            if (scriptfile_getsymbol(script,&tmp)) break;
5079 terminx 718
            h_ysize[tile] = tmp;
719
            if (scriptfile_getsymbol(script,&tmp)) break;
665 terminx 720
            h_xoffs[tile]=tmp;
721
            if (scriptfile_getsymbol(script,&tmp)) break;
722
            h_yoffs[tile]=tmp;
723
            break;
724
        }
725
        case T_SETUPTILERANGE:
726
        {
1205 terminx 727
            int32_t tile1,tile2,xsiz,ysiz,xoffs,yoffs,i;
665 terminx 728
 
6896 hendricks2 729
            if (scriptfile_getsymbol(script,&tile1)) break;
730
            if (scriptfile_getsymbol(script,&tile2)) break;
665 terminx 731
            if (scriptfile_getnumber(script,&xsiz)) break;
732
            if (scriptfile_getnumber(script,&ysiz)) break;
733
            if (scriptfile_getsymbol(script,&xoffs)) break;
734
            if (scriptfile_getsymbol(script,&yoffs)) break;
2553 helixhorne 735
 
2588 helixhorne 736
            if (check_tile_range("setuptilerange", &tile1, &tile2, script, cmdtokptr))
737
                break;
738
 
739
            for (i=tile1; i<=tile2; i++)
665 terminx 740
            {
2588 helixhorne 741
                h_xsize[i] = xsiz;
742
                h_ysize[i] = ysiz;
743
                h_xoffs[i] = xoffs;
744
                h_yoffs[i] = yoffs;
665 terminx 745
            }
2553 helixhorne 746
 
665 terminx 747
            break;
748
        }
928 hnt_ts 749
        case T_ANIMTILERANGE:
750
        {
2588 helixhorne 751
            int32_t tile1, tile2, spd, type;
928 hnt_ts 752
 
753
            if (scriptfile_getsymbol(script,&tile1)) break;
754
            if (scriptfile_getsymbol(script,&tile2)) break;
755
            if (scriptfile_getsymbol(script,&spd)) break;
756
            if (scriptfile_getsymbol(script,&type)) break;
2588 helixhorne 757
 
5357 hendricks2 758
            if (check_tile("animtilerange", tile1, script, cmdtokptr))
2588 helixhorne 759
                break;
5357 hendricks2 760
            if (check_tile("animtilerange", tile2, script, cmdtokptr))
761
                break;
2588 helixhorne 762
 
5357 hendricks2 763
            spd = clamp(spd, 0, 15);
764
            if (EDUKE32_PREDICT_FALSE(type&~3))
928 hnt_ts 765
            {
5357 hendricks2 766
                initprintf("Error: animtilerange: animation type must be 0, 1, 2 or 3 on line %s:%d\n",
2588 helixhorne 767
                           script->filename, scriptfile_getlinum(script,cmdtokptr));
768
                break;
928 hnt_ts 769
            }
2553 helixhorne 770
 
5357 hendricks2 771
            int32_t num = tile2-tile1;
772
            if (type == 3 && tile1 > tile2) // PICANM_ANIMTYPE_BACK
773
                num = -num;
774
 
775
            if (EDUKE32_PREDICT_FALSE((unsigned)num > 255))
3202 helixhorne 776
            {
5357 hendricks2 777
                initprintf("Error: animtilerange: tile difference can be at most 255 on line %s:%d\n",
3202 helixhorne 778
                           script->filename, scriptfile_getlinum(script,cmdtokptr));
5357 hendricks2 779
                break;
3202 helixhorne 780
            }
2553 helixhorne 781
 
3202 helixhorne 782
            // set anim speed
783
            picanm[tile1].sf &= ~PICANM_ANIMSPEED_MASK;
784
            picanm[tile1].sf |= spd;
785
            // set anim type
786
            picanm[tile1].sf &= ~PICANM_ANIMTYPE_MASK;
787
            picanm[tile1].sf |= type<<PICANM_ANIMTYPE_SHIFT;
788
            // set anim number
5357 hendricks2 789
            picanm[tile1].num = num;
2588 helixhorne 790
 
928 hnt_ts 791
            break;
792
        }
1151 terminx 793
        case T_TILEFROMTEXTURE:
794
        {
2588 helixhorne 795
            char *texturetokptr = script->ltextptr, *textureend, *fn = NULL;
3973 hendricks2 796
            int32_t tile = -1;
797
            int32_t alphacut = 255, flags = 0;
4402 helixhorne 798
            int32_t havexoffset = 0, haveyoffset = 0;
799
            int32_t xoffset = 0, yoffset = 0;
5247 hendricks2 800
            int32_t istexture = 0;
8464 hendricks2 801
            int32_t tile_crc32 = 0;
8465 hendricks2 802
            vec2_t  tile_size{};
8464 hendricks2 803
            uint8_t have_crc32 = 0;
8465 hendricks2 804
            uint8_t have_size = 0;
1151 terminx 805
 
1677 terminx 806
            static const tokenlist tilefromtexturetokens[] =
807
            {
808
                { "file",            T_FILE },
809
                { "name",            T_FILE },
810
                { "alphacut",        T_ALPHACUT },
811
                { "xoffset",         T_XOFFSET },
812
                { "xoff",            T_XOFFSET },
813
                { "yoffset",         T_YOFFSET },
814
                { "yoff",            T_YOFFSET },
3078 helixhorne 815
                { "texhitscan",      T_TEXHITSCAN },
3230 helixhorne 816
                { "nofullbright",    T_NOFULLBRIGHT },
5247 hendricks2 817
                { "texture",         T_TEXTURE },
7370 terminx 818
                { "ifcrc",           T_IFCRC },
8465 hendricks2 819
                { "ifmatch",         T_IFMATCH },
1677 terminx 820
            };
821
 
1151 terminx 822
            if (scriptfile_getsymbol(script,&tile)) break;
823
            if (scriptfile_getbraces(script,&textureend)) break;
824
            while (script->textptr < textureend)
825
            {
4385 terminx 826
                int32_t token = getatoken(script,tilefromtexturetokens,ARRAY_SIZE(tilefromtexturetokens));
1151 terminx 827
                switch (token)
828
                {
829
                case T_FILE:
5178 hendricks2 830
                    scriptfile_getstring(script,&fn);
831
                    break;
1151 terminx 832
                case T_ALPHACUT:
5178 hendricks2 833
                    scriptfile_getsymbol(script,&alphacut);
834
                    alphacut = clamp(alphacut, 0, 255);
835
                    break;
1188 terminx 836
                case T_XOFFSET:
4402 helixhorne 837
                    havexoffset = 1;
5178 hendricks2 838
                    scriptfile_getsymbol(script,&xoffset);
839
                    xoffset = clamp(xoffset, -128, 127);
840
                    break;
1188 terminx 841
                case T_YOFFSET:
4402 helixhorne 842
                    haveyoffset = 1;
5178 hendricks2 843
                    scriptfile_getsymbol(script,&yoffset);
844
                    yoffset = clamp(yoffset, -128, 127);
845
                    break;
7370 terminx 846
                case T_IFCRC:
8464 hendricks2 847
                    scriptfile_getsymbol(script, &tile_crc32);
848
                    have_crc32 = 1;
7370 terminx 849
                    break;
8465 hendricks2 850
                case T_IFMATCH:
851
                {
852
                    char *ifmatchend;
853
 
854
                    static const tokenlist ifmatchtokens[] =
855
                    {
856
                        { "crc32",           T_CRC32 },
857
                        { "size",            T_SIZE },
858
                    };
859
 
860
                    if (scriptfile_getbraces(script,&ifmatchend)) break;
861
                    while (script->textptr < ifmatchend)
862
                    {
863
                        int32_t token = getatoken(script,ifmatchtokens,ARRAY_SIZE(ifmatchtokens));
864
                        switch (token)
865
                        {
866
                        case T_CRC32:
867
                            scriptfile_getsymbol(script, &tile_crc32);
868
                            have_crc32 = 1;
869
                            break;
870
                        case T_SIZE:
871
                            scriptfile_getsymbol(script, &tile_size.x);
872
                            scriptfile_getsymbol(script, &tile_size.y);
873
                            have_size = 1;
874
                            break;
875
                        default:
876
                            break;
877
                        }
878
                    }
879
                    break;
880
                }
3078 helixhorne 881
                case T_TEXHITSCAN:
3973 hendricks2 882
                    flags |= PICANM_TEXHITSCAN_BIT;
3078 helixhorne 883
                    break;
3973 hendricks2 884
                case T_NOFULLBRIGHT:
885
                    flags |= PICANM_NOFULLBRIGHT_BIT;
886
                    break;
5247 hendricks2 887
                case T_TEXTURE:
888
                    istexture = 1;
889
                    break;
1151 terminx 890
                default:
891
                    break;
892
                }
893
            }
894
 
4680 terminx 895
            if (EDUKE32_PREDICT_FALSE((unsigned)tile >= MAXUSERTILES))
1151 terminx 896
            {
4061 helixhorne 897
                initprintf("Error: missing or invalid 'tile number' for texture definition near line %s:%d\n",
1151 terminx 898
                           script->filename, scriptfile_getlinum(script,texturetokptr));
899
                break;
900
            }
901
 
8464 hendricks2 902
            if (have_crc32)
7370 terminx 903
            {
8464 hendricks2 904
                int32_t const orig_crc32 = tileGetCRC32(tile);
905
                if (orig_crc32 != tile_crc32)
7370 terminx 906
                {
8464 hendricks2 907
                    // initprintf("CRC32 of tile %d doesn't match! CRC32: %d, Expected: %d\n", tile, orig_crc32, tile_crc32);
7370 terminx 908
                    break;
909
                }
910
            }
911
 
8465 hendricks2 912
            if (have_size)
913
            {
914
                vec2_16_t const orig_size = tileGetSize(tile);
915
                if (orig_size.x != tile_size.x && orig_size.y != tile_size.y)
916
                {
917
                    // 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);
918
                    break;
919
                }
920
            }
921
 
3078 helixhorne 922
            if (!fn)
1151 terminx 923
            {
3973 hendricks2 924
                // tilefromtexture <tile> { texhitscan }  sets the bit but doesn't change tile data
925
                picanm[tile].sf |= flags;
4402 helixhorne 926
                if (havexoffset)
5178 hendricks2 927
                    picanm[tile].xofs = xoffset;
4402 helixhorne 928
                if (haveyoffset)
5178 hendricks2 929
                    picanm[tile].yofs = yoffset;
3230 helixhorne 930
 
4680 terminx 931
                if (EDUKE32_PREDICT_FALSE(flags == 0 && !havexoffset && !haveyoffset))
3835 hendricks2 932
                    initprintf("\nError: missing 'file name' for tilefromtexture definition near line %s:%d",
3078 helixhorne 933
                               script->filename, scriptfile_getlinum(script,texturetokptr));
934
                break;
935
            }
936
 
5247 hendricks2 937
            int32_t const texstatus = Defs_ImportTileFromTexture(fn, tile, alphacut, istexture);
5346 hendricks2 938
            if (texstatus == -3)
939
                initprintf("Error: No palette loaded, in tilefromtexture definition near line %s:%d\n",
940
                           script->filename, scriptfile_getlinum(script,texturetokptr));
5491 terminx 941
            if (texstatus == -(3<<8))
5178 hendricks2 942
                initprintf("Error: \"%s\" has more than one tile, in tilefromtexture definition near line %s:%d\n",
943
                           fn, script->filename, scriptfile_getlinum(script,texturetokptr));
944
            if (texstatus < 0)
3078 helixhorne 945
                break;
946
 
5178 hendricks2 947
            picanm[tile].sf |= flags;
3078 helixhorne 948
 
5178 hendricks2 949
            if (havexoffset)
950
                picanm[tile].xofs = xoffset;
951
            else if (texstatus == 0)
952
                picanm[tile].xofs = 0;
1151 terminx 953
 
5178 hendricks2 954
            if (haveyoffset)
955
                picanm[tile].yofs = yoffset;
956
            else if (texstatus == 0)
957
                picanm[tile].yofs = 0;
1151 terminx 958
        }
959
        break;
5139 hendricks2 960
        case T_COPYTILE:
961
        {
962
            char *blockend;
963
            int32_t tile = -1, source;
964
            int32_t havetile = 0, havexoffset = 0, haveyoffset = 0;
965
            int32_t xoffset = 0, yoffset = 0;
966
            int32_t flags = 0;
967
            int32_t tsiz = 0;
968
 
969
            static const tokenlist copytiletokens[] =
970
            {
971
                { "tile",            T_TILE },
972
                { "pal",             T_PAL },
973
                { "xoffset",         T_XOFFSET },
974
                { "xoff",            T_XOFFSET },
975
                { "yoffset",         T_YOFFSET },
976
                { "yoff",            T_YOFFSET },
977
                { "texhitscan",      T_TEXHITSCAN },
978
                { "nofullbright",    T_NOFULLBRIGHT },
979
            };
980
 
981
            if (scriptfile_getsymbol(script,&tile)) break;
982
            source = tile; // without a "tile" token, we still palettize self by default
983
            if (scriptfile_getbraces(script,&blockend)) break;
984
            while (script->textptr < blockend)
985
            {
986
                int32_t token = getatoken(script,copytiletokens,ARRAY_SIZE(copytiletokens));
987
                switch (token)
988
                {
989
                case T_TILE:
990
                {
991
                    int32_t tempsource;
992
                    scriptfile_getsymbol(script,&tempsource);
993
 
994
                    if (check_tile("copytile", tempsource, script, cmdtokptr))
995
                        break;
996
                    if ((tsiz = Defs_LoadTileIntoBuffer(tempsource)) <= 0)
997
                        break;
998
                    source = tempsource;
999
 
1000
                    havetile = 1;
1001
                    break;
1002
                }
1003
                case T_PAL:
1004
                {
1005
                    int32_t temppal;
1006
                    scriptfile_getsymbol(script,&temppal);
1007
 
1008
                    // palettize self case
1009
                    if (!havetile)
1010
                    {
1011
                        if (check_tile("copytile", source, script, cmdtokptr))
1012
                            break;
1013
                        if ((tsiz = Defs_LoadTileIntoBuffer(source)) <= 0)
1014
                            break;
1015
                        havetile = 1;
1016
                    }
1017
 
1018
                    if (EDUKE32_PREDICT_FALSE((unsigned)temppal >= MAXPALOOKUPS-RESERVEDPALS))
1019
                    {
1020
                        initprintf("Error: copytile 'palette number' out of range (max=%d)\n",
1021
                                   MAXPALOOKUPS-RESERVEDPALS-1);
1022
                        break;
1023
                    }
1024
 
1025
                    Defs_ApplyPaletteToTileBuffer(tsiz, temppal);
1026
                    break;
1027
                }
1028
                case T_XOFFSET:
1029
                    havexoffset = 1;
1030
                    scriptfile_getsymbol(script,&xoffset); break;
1031
                case T_YOFFSET:
1032
                    haveyoffset = 1;
1033
                    scriptfile_getsymbol(script,&yoffset); break;
1034
                case T_TEXHITSCAN:
1035
                    flags |= PICANM_TEXHITSCAN_BIT;
1036
                    break;
1037
                case T_NOFULLBRIGHT:
1038
                    flags |= PICANM_NOFULLBRIGHT_BIT;
1039
                    break;
1040
                default:
1041
                    break;
1042
                }
1043
            }
1044
 
1045
            if (check_tile("copytile", tile, script, cmdtokptr))
1046
                break;
1047
 
1048
            if (havetile)
1049
            {
6830 terminx 1050
                tileSetData(tile, tsiz, faketilebuffer);
5139 hendricks2 1051
            }
1052
            else // if !havetile, we have never confirmed a valid source
1053
            {
1054
                if (check_tile("copytile", source, script, cmdtokptr))
1055
                    break;
1056
            }
1057
 
1058
            if (tsiz <= 0)
1059
            {
6830 terminx 1060
                tileDelete(tile);
5139 hendricks2 1061
                break;
1062
            }
1063
 
6830 terminx 1064
            tileSetSize(tile, tilesiz[source].x, tilesiz[source].y);
5139 hendricks2 1065
            picanm[tile].xofs = havexoffset ? clamp(xoffset, -128, 127) : picanm[source].xofs;
1066
            picanm[tile].yofs = haveyoffset ? clamp(yoffset, -128, 127) : picanm[source].yofs;
1067
            picanm[tile].sf = (picanm[tile].sf & ~PICANM_MISC_MASK) | (picanm[source].sf & PICANM_MISC_MASK) | flags;
1068
 
1069
        }
1070
        break;
1150 terminx 1071
        case T_IMPORTTILE:
1072
        {
5178 hendricks2 1073
            int32_t tile;
2588 helixhorne 1074
            char *fn;
1150 terminx 1075
 
1076
            if (scriptfile_getsymbol(script,&tile)) break;
1077
            if (scriptfile_getstring(script,&fn))  break;
1078
 
5178 hendricks2 1079
            if (check_tile("importtile", tile, script, cmdtokptr))
2588 helixhorne 1080
                break;
1150 terminx 1081
 
5247 hendricks2 1082
            int32_t const texstatus = Defs_ImportTileFromTexture(fn, tile, 255, 0);
5346 hendricks2 1083
            if (texstatus == -3)
1084
                initprintf("Error: No palette loaded, in importtile definition near line %s:%d\n",
1085
                           script->filename, scriptfile_getlinum(script,cmdtokptr));
5491 terminx 1086
            if (texstatus == -(3<<8))
5178 hendricks2 1087
                initprintf("Error: \"%s\" has more than one tile, in importtile definition near line %s:%d\n",
1088
                           fn, script->filename, scriptfile_getlinum(script,cmdtokptr));
1089
            if (texstatus < 0)
2588 helixhorne 1090
                break;
1150 terminx 1091
 
3202 helixhorne 1092
            Bmemset(&picanm[tile], 0, sizeof(picanm_t));
1150 terminx 1093
 
1094
            break;
1095
        }
116 terminx 1096
        case T_DUMMYTILE:
331 terminx 1097
        {
2588 helixhorne 1098
            int32_t tile, xsiz, ysiz;
331 terminx 1099
 
1100
            if (scriptfile_getsymbol(script,&tile)) break;
1101
            if (scriptfile_getsymbol(script,&xsiz)) break;
1102
            if (scriptfile_getsymbol(script,&ysiz)) break;
1103
 
5137 hendricks2 1104
            if (check_tile("dummytile", tile, script, cmdtokptr))
1105
                break;
5127 hendricks2 1106
 
1107
            if ((int16_t) xsiz == 0 || (int16_t) ysiz == 0)
1108
            {
6830 terminx 1109
                tileDelete(tile);
5127 hendricks2 1110
                break;
1111
            }
1112
 
331 terminx 1113
            if (xsiz > 0 && ysiz > 0)
116 terminx 1114
            {
6830 terminx 1115
                tileSetSize(tile, xsiz, ysiz);
3202 helixhorne 1116
                Bmemset(&picanm[tile], 0, sizeof(picanm_t));
6830 terminx 1117
                tileSetupDummy(tile);
331 terminx 1118
            }
116 terminx 1119
 
331 terminx 1120
            break;
1121
        }
1122
        case T_DUMMYTILERANGE:
1123
        {
2588 helixhorne 1124
            int32_t tile1,tile2,xsiz,ysiz,i;
257 terminx 1125
 
6896 hendricks2 1126
            if (scriptfile_getsymbol(script,&tile1)) break;
1127
            if (scriptfile_getsymbol(script,&tile2)) break;
331 terminx 1128
            if (scriptfile_getnumber(script,&xsiz)) break;
1129
            if (scriptfile_getnumber(script,&ysiz)) break;
2588 helixhorne 1130
 
1131
            if (check_tile_range("dummytilerange", &tile1, &tile2, script, cmdtokptr))
1132
                break;
1133
 
5127 hendricks2 1134
            if (xsiz < 0 || ysiz < 0)
2588 helixhorne 1135
                break;  // TODO: message
1136
 
5127 hendricks2 1137
            if ((int16_t) xsiz == 0 || (int16_t) ysiz == 0)
1138
            {
1139
                for (i=tile1; i<=tile2; i++)
6830 terminx 1140
                    tileDelete(i);
5127 hendricks2 1141
                break;
1142
            }
1143
 
2588 helixhorne 1144
            for (i=tile1; i<=tile2; i++)
584 terminx 1145
            {
6830 terminx 1146
                tileSetSize(i, xsiz, ysiz);
3202 helixhorne 1147
                Bmemset(&picanm[i], 0, sizeof(picanm_t));
6830 terminx 1148
                tileSetupDummy(i);
116 terminx 1149
            }
330 terminx 1150
 
331 terminx 1151
            break;
1152
        }
116 terminx 1153
 
5127 hendricks2 1154
        case T_UNDEFINETILE:
1155
        {
1156
            int32_t tile;
1157
 
1158
            if (scriptfile_getsymbol(script,&tile)) break;
1159
 
5137 hendricks2 1160
            if (check_tile("undefinetile", tile, script, cmdtokptr))
1161
                break;
5127 hendricks2 1162
 
6830 terminx 1163
            tileDelete(tile);
5127 hendricks2 1164
 
1165
            break;
1166
        }
1167
        case T_UNDEFINETILERANGE:
1168
        {
1169
            int32_t tile1, tile2;
1170
 
6896 hendricks2 1171
            if (scriptfile_getsymbol(script,&tile1)) break;
1172
            if (scriptfile_getsymbol(script,&tile2)) break;
5127 hendricks2 1173
 
1174
            if (check_tile_range("undefinetilerange", &tile1, &tile2, script, cmdtokptr))
1175
                break;
1176
 
5829 terminx 1177
            for (bssize_t i = tile1; i <= tile2; i++)
6830 terminx 1178
                tileDelete(i);
5127 hendricks2 1179
 
1180
            break;
1181
        }
1182
 
109 terminx 1183
        case T_DEFINEMODEL:
331 terminx 1184
        {
1185
            char *modelfn;
1186
            double scale;
1205 terminx 1187
            int32_t shadeoffs;
99 terminx 1188
 
331 terminx 1189
            if (scriptfile_getstring(script,&modelfn)) break;
1190
            if (scriptfile_getdouble(script,&scale)) break;
1191
            if (scriptfile_getnumber(script,&shadeoffs)) break;
99 terminx 1192
 
1820 terminx 1193
#ifdef USE_OPENGL
331 terminx 1194
            lastmodelid = md_loadmodel(modelfn);
4680 terminx 1195
            if (EDUKE32_PREDICT_FALSE(lastmodelid < 0))
584 terminx 1196
            {
4061 helixhorne 1197
                initprintf("Warning: Failed loading MD2/MD3 model \"%s\"\n", modelfn);
331 terminx 1198
                break;
1199
            }
2264 hendricks2 1200
            md_setmisc(lastmodelid,(float)scale, shadeoffs,0.0,0.0,0);
3467 helixhorne 1201
# ifdef POLYMER
3784 terminx 1202
            if (glrendmode == REND_POLYMER)
1910 helixhorne 1203
                md3postload_polymer((md3model_t *)models[lastmodelid]);
3467 helixhorne 1204
# endif
99 terminx 1205
#endif
331 terminx 1206
            modelskin = lastmodelskin = 0;
1207
            seenframe = 0;
1208
        }
1209
        break;
109 terminx 1210
        case T_DEFINEMODELFRAME:
331 terminx 1211
        {
895 terminx 1212
            char *framename;
1820 terminx 1213
#ifdef USE_OPENGL
895 terminx 1214
            char happy=1;
3382 hendricks2 1215
            int32_t tilex;
895 terminx 1216
#endif
3382 hendricks2 1217
            int32_t ftilenume, ltilenume;
99 terminx 1218
 
331 terminx 1219
            if (scriptfile_getstring(script,&framename)) break;
6896 hendricks2 1220
            if (scriptfile_getsymbol(script,&ftilenume)) break; //first tile number
1221
            if (scriptfile_getsymbol(script,&ltilenume)) break; //last tile number (inclusive)
99 terminx 1222
 
2588 helixhorne 1223
            if (check_tile_range("definemodelframe", &ftilenume, &ltilenume, script, cmdtokptr))
1224
                break;
1225
 
4680 terminx 1226
            if (EDUKE32_PREDICT_FALSE(lastmodelid < 0))
584 terminx 1227
            {
2288 helixhorne 1228
#ifdef USE_OPENGL
4061 helixhorne 1229
                initprintf("Warning: Ignoring frame definition.\n");
2288 helixhorne 1230
#endif
331 terminx 1231
                break;
1232
            }
1820 terminx 1233
#ifdef USE_OPENGL
584 terminx 1234
            for (tilex = ftilenume; tilex <= ltilenume && happy; tilex++)
1235
            {
587 terminx 1236
                switch (md_defineframe(lastmodelid, framename, tilex, max(0,modelskin), 0.0f,0))
584 terminx 1237
                {
331 terminx 1238
                case -1:
1239
                    happy = 0; break; // invalid model id!?
1240
                case -2:
4061 helixhorne 1241
                    initprintf("Invalid tile number on line %s:%d\n",
331 terminx 1242
                               script->filename, scriptfile_getlinum(script,cmdtokptr));
1243
                    happy = 0;
1244
                    break;
1245
                case -3:
4061 helixhorne 1246
                    initprintf("Invalid frame name on line %s:%d\n",
331 terminx 1247
                               script->filename, scriptfile_getlinum(script,cmdtokptr));
1248
                    happy = 0;
1249
                    break;
1910 helixhorne 1250
                default:
1251
                    break;
109 terminx 1252
                }
331 terminx 1253
            }
99 terminx 1254
#endif
331 terminx 1255
            seenframe = 1;
1256
        }
1257
        break;
109 terminx 1258
        case T_DEFINEMODELANIM:
331 terminx 1259
        {
1260
            char *startframe, *endframe;
1205 terminx 1261
            int32_t flags;
331 terminx 1262
            double dfps;
99 terminx 1263
 
331 terminx 1264
            if (scriptfile_getstring(script,&startframe)) break;
1265
            if (scriptfile_getstring(script,&endframe)) break;
1266
            if (scriptfile_getdouble(script,&dfps)) break; //animation frame rate
1267
            if (scriptfile_getnumber(script,&flags)) break;
99 terminx 1268
 
4680 terminx 1269
            if (EDUKE32_PREDICT_FALSE(lastmodelid < 0))
584 terminx 1270
            {
2288 helixhorne 1271
#ifdef USE_OPENGL
4061 helixhorne 1272
                initprintf("Warning: Ignoring animation definition.\n");
2288 helixhorne 1273
#endif
331 terminx 1274
                break;
1275
            }
1820 terminx 1276
#ifdef USE_OPENGL
1205 terminx 1277
            switch (md_defineanimation(lastmodelid, startframe, endframe, (int32_t)(dfps*(65536.0*.001)), flags))
584 terminx 1278
            {
331 terminx 1279
            case 0:
1280
                break;
1281
            case -1:
1282
                break; // invalid model id!?
1283
            case -2:
4061 helixhorne 1284
                initprintf("Invalid starting frame name on line %s:%d\n",
331 terminx 1285
                           script->filename, scriptfile_getlinum(script,cmdtokptr));
1286
                break;
1287
            case -3:
4061 helixhorne 1288
                initprintf("Invalid ending frame name on line %s:%d\n",
331 terminx 1289
                           script->filename, scriptfile_getlinum(script,cmdtokptr));
1290
                break;
1291
            case -4:
4061 helixhorne 1292
                initprintf("Out of memory on line %s:%d\n",
331 terminx 1293
                           script->filename, scriptfile_getlinum(script,cmdtokptr));
1294
                break;
1295
            }
99 terminx 1296
#endif
331 terminx 1297
        }
1298
        break;
109 terminx 1299
        case T_DEFINEMODELSKIN:
331 terminx 1300
        {
2554 helixhorne 1301
            int32_t palnum;
1302
            char *skinfn;
99 terminx 1303
 
331 terminx 1304
            if (scriptfile_getsymbol(script,&palnum)) break;
1305
            if (scriptfile_getstring(script,&skinfn)) break; //skin filename
99 terminx 1306
 
331 terminx 1307
            // if we see a sequence of definemodelskin, then a sequence of definemodelframe,
1308
            // and then a definemodelskin, we need to increment the skin counter.
1309
            //
1310
            // definemodel "mymodel.md2" 1 1
1311
            // definemodelskin 0 "normal.png"   // skin 0
1312
            // definemodelskin 21 "normal21.png"
1313
            // definemodelframe "foo" 1000 1002   // these use skin 0
1314
            // definemodelskin 0 "wounded.png"   // skin 1
1315
            // definemodelskin 21 "wounded21.png"
1316
            // definemodelframe "foo2" 1003 1004   // these use skin 1
1317
            // selectmodelskin 0         // resets to skin 0
1318
            // definemodelframe "foo3" 1005 1006   // these use skin 0
584 terminx 1319
            if (seenframe) { modelskin = ++lastmodelskin; }
331 terminx 1320
            seenframe = 0;
109 terminx 1321
 
2554 helixhorne 1322
            if (check_file_exist(skinfn))
1323
                break;
2436 hendricks2 1324
 
1820 terminx 1325
#ifdef USE_OPENGL
5107 hendricks2 1326
            switch (md_defineskin(lastmodelid, skinfn, palnum, max(0,modelskin), 0, 0.0f, 1.0f, 1.0f, 0))
584 terminx 1327
            {
331 terminx 1328
            case 0:
1329
                break;
1330
            case -1:
1331
                break; // invalid model id!?
1332
            case -2:
4061 helixhorne 1333
                initprintf("Invalid skin filename on line %s:%d\n",
331 terminx 1334
                           script->filename, scriptfile_getlinum(script,cmdtokptr));
1335
                break;
1336
            case -3:
4061 helixhorne 1337
                initprintf("Invalid palette number on line %s:%d\n",
331 terminx 1338
                           script->filename, scriptfile_getlinum(script,cmdtokptr));
1339
                break;
1340
            case -4:
4061 helixhorne 1341
                initprintf("Out of memory on line %s:%d\n",
331 terminx 1342
                           script->filename, scriptfile_getlinum(script,cmdtokptr));
1343
                break;
109 terminx 1344
            }
331 terminx 1345
#endif
1346
        }
1347
        break;
109 terminx 1348
        case T_SELECTMODELSKIN:
331 terminx 1349
        {
1350
            if (scriptfile_getsymbol(script,&modelskin)) break;
1351
        }
1352
        break;
109 terminx 1353
        case T_DEFINEVOXEL:
331 terminx 1354
        {
1355
            char *fn;
99 terminx 1356
 
4834 helixhorne 1357
            if (EDUKE32_PREDICT_FALSE(scriptfile_getstring(script,&fn)))
1358
                break; //voxel filename
99 terminx 1359
 
4680 terminx 1360
            if (EDUKE32_PREDICT_FALSE(nextvoxid == MAXVOXELS))
584 terminx 1361
            {
4835 helixhorne 1362
                initprintf("Maximum number of voxels (%d) already defined.\n", MAXVOXELS);
331 terminx 1363
                break;
1364
            }
99 terminx 1365
 
4680 terminx 1366
            if (EDUKE32_PREDICT_FALSE(qloadkvx(nextvoxid, fn)))
584 terminx 1367
            {
4061 helixhorne 1368
                initprintf("Failure loading voxel file \"%s\"\n",fn);
331 terminx 1369
                break;
1370
            }
99 terminx 1371
 
331 terminx 1372
            lastvoxid = nextvoxid++;
1373
        }
1374
        break;
109 terminx 1375
        case T_DEFINEVOXELTILES:
331 terminx 1376
        {
1205 terminx 1377
            int32_t ftilenume, ltilenume, tilex;
99 terminx 1378
 
6896 hendricks2 1379
            if (scriptfile_getsymbol(script,&ftilenume)) break; //1st tile #
1380
            if (scriptfile_getsymbol(script,&ltilenume)) break; //last tile #
99 terminx 1381
 
2588 helixhorne 1382
            if (check_tile_range("definevoxeltiles", &ftilenume, &ltilenume, script, cmdtokptr))
331 terminx 1383
                break;
99 terminx 1384
 
4680 terminx 1385
            if (EDUKE32_PREDICT_FALSE(lastvoxid < 0))
584 terminx 1386
            {
4061 helixhorne 1387
                initprintf("Warning: Ignoring voxel tiles definition.\n");
331 terminx 1388
                break;
1389
            }
1820 terminx 1390
 
584 terminx 1391
            for (tilex = ftilenume; tilex <= ltilenume; tilex++)
331 terminx 1392
                tiletovox[tilex] = lastvoxid;
1393
        }
1394
        break;
99 terminx 1395
 
331 terminx 1396
        // NEW (ENCOURAGED) DEFINITION SYNTAX
109 terminx 1397
        case T_MODEL:
331 terminx 1398
        {
1399
            char *modelend, *modelfn;
2264 hendricks2 1400
            double scale=1.0, mzadd=0.0, myoffset=0.0;
1205 terminx 1401
            int32_t shadeoffs=0, pal=0, flags=0;
7806 terminx 1402
            uint8_t usedframebitmap[(1024+7)>>3];
99 terminx 1403
 
2237 helixhorne 1404
            int32_t model_ok = 1;
1405
 
1677 terminx 1406
            static const tokenlist modeltokens[] =
1407
            {
1408
                { "scale",    T_SCALE    },
1409
                { "shade",    T_SHADE    },
1410
                { "zadd",     T_ZADD     },
2264 hendricks2 1411
                { "yoffset",  T_YOFFSET  },
1677 terminx 1412
                { "frame",    T_FRAME    },
1413
                { "anim",     T_ANIM     },
1414
                { "skin",     T_SKIN     },
1415
                { "detail",   T_DETAIL   },
1416
                { "glow",     T_GLOW     },
1417
                { "specular", T_SPECULAR },
1418
                { "normal",   T_NORMAL   },
1419
                { "hud",      T_HUD      },
1420
                { "flags",    T_FLAGS    },
1421
            };
1422
 
1925 helixhorne 1423
            Bmemset(usedframebitmap, 0, sizeof(usedframebitmap));
1424
 
331 terminx 1425
            modelskin = lastmodelskin = 0;
1426
            seenframe = 0;
99 terminx 1427
 
331 terminx 1428
            if (scriptfile_getstring(script,&modelfn)) break;
875 terminx 1429
            if (scriptfile_getbraces(script,&modelend)) break;
1820 terminx 1430
#ifdef USE_OPENGL
331 terminx 1431
            lastmodelid = md_loadmodel(modelfn);
4680 terminx 1432
            if (EDUKE32_PREDICT_FALSE(lastmodelid < 0))
584 terminx 1433
            {
4061 helixhorne 1434
                initprintf("Warning: Failed loading MD2/MD3 model \"%s\"\n", modelfn);
875 terminx 1435
                script->textptr = modelend+1;
331 terminx 1436
                break;
1437
            }
99 terminx 1438
#endif
584 terminx 1439
            while (script->textptr < modelend)
1440
            {
4385 terminx 1441
                int32_t token = getatoken(script,modeltokens,ARRAY_SIZE(modeltokens));
584 terminx 1442
                switch (token)
1443
                {
4061 helixhorne 1444
                    //case T_ERROR: initprintf("Error on line %s:%d in model tokens\n", script->filename,script->linenum); break;
331 terminx 1445
                case T_SCALE:
1446
                    scriptfile_getdouble(script,&scale); break;
1447
                case T_SHADE:
1448
                    scriptfile_getnumber(script,&shadeoffs); break;
1449
                case T_ZADD:
1450
                    scriptfile_getdouble(script,&mzadd); break;
2264 hendricks2 1451
                case T_YOFFSET:
1452
                    scriptfile_getdouble(script,&myoffset); break;
587 terminx 1453
                case T_FLAGS:
1454
                    scriptfile_getnumber(script,&flags); break;
331 terminx 1455
                case T_FRAME:
1456
                {
1457
                    char *frametokptr = script->ltextptr;
3382 hendricks2 1458
                    char *frameend, *framename = 0;
1459
#ifdef USE_OPENGL
1460
                    char happy=1;
1461
                    int32_t tilex = 0, framei;
1462
#endif
1463
                    int32_t ftilenume = -1, ltilenume = -1;
1178 terminx 1464
                    double smoothduration = 0.1f;
99 terminx 1465
 
1677 terminx 1466
                    static const tokenlist modelframetokens[] =
1467
                    {
1468
                        { "pal",              T_PAL               },
1469
                        { "frame",            T_FRAME             },
1470
                        { "name",             T_FRAME             },
1471
                        { "tile",             T_TILE              },
1472
                        { "tile0",            T_TILE0             },
1473
                        { "tile1",            T_TILE1             },
1474
                        { "smoothduration",   T_SMOOTHDURATION    },
1475
                    };
1476
 
331 terminx 1477
                    if (scriptfile_getbraces(script,&frameend)) break;
584 terminx 1478
                    while (script->textptr < frameend)
1479
                    {
4385 terminx 1480
                        switch (getatoken(script,modelframetokens,ARRAY_SIZE(modelframetokens)))
584 terminx 1481
                        {
587 terminx 1482
                        case T_PAL:
6896 hendricks2 1483
                            scriptfile_getsymbol(script,&pal); break;
331 terminx 1484
                        case T_FRAME:
1485
                            scriptfile_getstring(script,&framename); break;
1486
                        case T_TILE:
1487
                            scriptfile_getsymbol(script,&ftilenume); ltilenume = ftilenume; break;
1488
                        case T_TILE0:
1489
                            scriptfile_getsymbol(script,&ftilenume); break; //first tile number
1490
                        case T_TILE1:
1491
                            scriptfile_getsymbol(script,&ltilenume); break; //last tile number (inclusive)
531 Plagman 1492
                        case T_SMOOTHDURATION:
1493
                            scriptfile_getdouble(script,&smoothduration); break;
331 terminx 1494
                        }
1495
                    }
99 terminx 1496
 
2588 helixhorne 1497
                    if (check_tile_range("model: frame", &ftilenume, &ltilenume, script, frametokptr))
584 terminx 1498
                    {
2588 helixhorne 1499
                        model_ok = 0;
1500
                        break;
331 terminx 1501
                    }
99 terminx 1502
 
4680 terminx 1503
                    if (EDUKE32_PREDICT_FALSE(lastmodelid < 0))
584 terminx 1504
                    {
2288 helixhorne 1505
#ifdef USE_OPENGL
5243 terminx 1506
                        initprintf("Warning: ignoring frame definition on line %s:%d.\n",
1507
                                   script->filename, scriptfile_getlinum(script,frametokptr));
2288 helixhorne 1508
#endif
331 terminx 1509
                        break;
1510
                    }
5079 terminx 1511
 
1512
                    if (smoothduration > 1.0)
1513
                    {
5243 terminx 1514
                        initprintf("Warning: smoothduration out of range on line %s:%d.\n",
1515
                                   script->filename, scriptfile_getlinum(script,frametokptr));
5079 terminx 1516
                        smoothduration = 1.0;
1517
                    }
1820 terminx 1518
#ifdef USE_OPENGL
584 terminx 1519
                    for (tilex = ftilenume; tilex <= ltilenume && happy; tilex++)
1520
                    {
1910 helixhorne 1521
                        framei = md_defineframe(lastmodelid, framename, tilex, max(0,modelskin), smoothduration,pal);
1522
                        switch (framei)
584 terminx 1523
                        {
331 terminx 1524
                        case -1:
1525
                            happy = 0; break; // invalid model id!?
1526
                        case -2:
4061 helixhorne 1527
                            initprintf("Invalid tile number on line %s:%d\n",
331 terminx 1528
                                       script->filename, scriptfile_getlinum(script,frametokptr));
1529
                            happy = 0;
1530
                            break;
1531
                        case -3:
4061 helixhorne 1532
                            initprintf("Invalid frame name on line %s:%d\n",
331 terminx 1533
                                       script->filename, scriptfile_getlinum(script,frametokptr));
1534
                            happy = 0;
1535
                            break;
1910 helixhorne 1536
                        default:
1537
                            if (framei >= 0 && framei<1024)
7876 terminx 1538
                                usedframebitmap[framei>>3] |= pow2char[framei&7];
331 terminx 1539
                        }
2237 helixhorne 1540
 
1541
                        model_ok &= happy;
331 terminx 1542
                    }
99 terminx 1543
#endif
331 terminx 1544
                    seenframe = 1;
1545
                }
1546
                break;
1547
                case T_ANIM:
1548
                {
1549
                    char *animtokptr = script->ltextptr;
1550
                    char *animend, *startframe = 0, *endframe = 0, happy=1;
1205 terminx 1551
                    int32_t flags = 0;
331 terminx 1552
                    double dfps = 1.0;
1553
 
1677 terminx 1554
                    static const tokenlist modelanimtokens[] =
1555
                    {
1556
                        { "frame0", T_FRAME0 },
1557
                        { "frame1", T_FRAME1 },
1558
                        { "fps",    T_FPS    },
1559
                        { "flags",  T_FLAGS  },
1560
                    };
1561
 
331 terminx 1562
                    if (scriptfile_getbraces(script,&animend)) break;
584 terminx 1563
                    while (script->textptr < animend)
1564
                    {
4385 terminx 1565
                        switch (getatoken(script,modelanimtokens,ARRAY_SIZE(modelanimtokens)))
584 terminx 1566
                        {
331 terminx 1567
                        case T_FRAME0:
1568
                            scriptfile_getstring(script,&startframe); break;
1569
                        case T_FRAME1:
1570
                            scriptfile_getstring(script,&endframe); break;
1571
                        case T_FPS:
1572
                            scriptfile_getdouble(script,&dfps); break; //animation frame rate
1573
                        case T_FLAGS:
1574
                            scriptfile_getsymbol(script,&flags); break;
109 terminx 1575
                        }
331 terminx 1576
                    }
99 terminx 1577
 
4680 terminx 1578
                    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;
1579
                    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 1580
                    model_ok &= happy;
4680 terminx 1581
                    if (EDUKE32_PREDICT_FALSE(!happy)) break;
99 terminx 1582
 
4680 terminx 1583
                    if (EDUKE32_PREDICT_FALSE(lastmodelid < 0))
584 terminx 1584
                    {
2288 helixhorne 1585
#ifdef USE_OPENGL
4061 helixhorne 1586
                        initprintf("Warning: Ignoring animation definition.\n");
2288 helixhorne 1587
#endif
331 terminx 1588
                        break;
1589
                    }
1820 terminx 1590
#ifdef USE_OPENGL
1205 terminx 1591
                    switch (md_defineanimation(lastmodelid, startframe, endframe, (int32_t)(dfps*(65536.0*.001)), flags))
584 terminx 1592
                    {
331 terminx 1593
                    case 0:
1594
                        break;
1595
                    case -1:
1596
                        break; // invalid model id!?
1597
                    case -2:
4061 helixhorne 1598
                        initprintf("Invalid starting frame name on line %s:%d\n",
331 terminx 1599
                                   script->filename, scriptfile_getlinum(script,animtokptr));
2237 helixhorne 1600
                        model_ok = 0;
331 terminx 1601
                        break;
1602
                    case -3:
4061 helixhorne 1603
                        initprintf("Invalid ending frame name on line %s:%d\n",
331 terminx 1604
                                   script->filename, scriptfile_getlinum(script,animtokptr));
2237 helixhorne 1605
                        model_ok = 0;
331 terminx 1606
                        break;
1607
                    case -4:
4061 helixhorne 1608
                        initprintf("Out of memory on line %s:%d\n",
331 terminx 1609
                                   script->filename, scriptfile_getlinum(script,animtokptr));
2237 helixhorne 1610
                        model_ok = 0;
331 terminx 1611
                        break;
1612
                    }
99 terminx 1613
#endif
584 terminx 1614
                }
1615
                break;
1350 terminx 1616
                case T_SKIN: case T_DETAIL: case T_GLOW: case T_SPECULAR: case T_NORMAL:
331 terminx 1617
                {
1618
                    char *skintokptr = script->ltextptr;
2554 helixhorne 1619
                    char *skinend, *skinfn = 0;
1620
                    int32_t palnum = 0, surfnum = 0;
1279 plagman 1621
                    double param = 1.0, specpower = 1.0, specfactor = 1.0;
5107 hendricks2 1622
#ifdef USE_OPENGL
1623
                    int32_t flags = 0;
1624
#endif
99 terminx 1625
 
1677 terminx 1626
                    static const tokenlist modelskintokens[] =
1627
                    {
1628
                        { "pal",           T_PAL        },
1629
                        { "file",          T_FILE       },
1630
                        { "surf",          T_SURF       },
1631
                        { "surface",       T_SURF       },
1632
                        { "intensity",     T_PARAM      },
1633
                        { "scale",         T_PARAM      },
1634
                        { "detailscale",   T_PARAM      },
2539 hendricks2 1635
                        { "specpower",     T_SPECPOWER  }, { "specularpower",  T_SPECPOWER  }, { "parallaxscale", T_SPECPOWER },
1636
                        { "specfactor",    T_SPECFACTOR }, { "specularfactor", T_SPECFACTOR }, { "parallaxbias", T_SPECFACTOR },
5107 hendricks2 1637
                        { "nocompress",    T_NOCOMPRESS },
1638
                        { "nodownsize",    T_NODOWNSIZE },
5108 hendricks2 1639
                        { "forcefilter",  T_FORCEFILTER },
5705 hendricks2 1640
                        { "artquality",    T_ARTQUALITY },
1677 terminx 1641
                    };
1642
 
331 terminx 1643
                    if (scriptfile_getbraces(script,&skinend)) break;
584 terminx 1644
                    while (script->textptr < skinend)
1645
                    {
4385 terminx 1646
                        switch (getatoken(script,modelskintokens,ARRAY_SIZE(modelskintokens)))
584 terminx 1647
                        {
331 terminx 1648
                        case T_PAL:
1649
                            scriptfile_getsymbol(script,&palnum); break;
501 Plagman 1650
                        case T_PARAM:
1651
                            scriptfile_getdouble(script,&param); break;
1279 plagman 1652
                        case T_SPECPOWER:
1653
                            scriptfile_getdouble(script,&specpower); break;
1654
                        case T_SPECFACTOR:
1655
                            scriptfile_getdouble(script,&specfactor); break;
331 terminx 1656
                        case T_FILE:
1657
                            scriptfile_getstring(script,&skinfn); break; //skin filename
1658
                        case T_SURF:
1659
                            scriptfile_getnumber(script,&surfnum); break;
5107 hendricks2 1660
#ifdef USE_OPENGL
1661
                        case T_NOCOMPRESS:
5640 hendricks2 1662
                            flags |= HICR_NOTEXCOMPRESS; break;
5107 hendricks2 1663
                        case T_NODOWNSIZE:
5640 hendricks2 1664
                            flags |= HICR_NODOWNSIZE; break;
5108 hendricks2 1665
                        case T_FORCEFILTER:
1666
                            flags |= HICR_FORCEFILTER; break;
5705 hendricks2 1667
                        case T_ARTQUALITY:
1668
                            flags |= HICR_ARTIMMUNITY; break;
5107 hendricks2 1669
#endif
331 terminx 1670
                        }
1671
                    }
99 terminx 1672
 
4680 terminx 1673
                    if (EDUKE32_PREDICT_FALSE(!skinfn))
584 terminx 1674
                    {
4061 helixhorne 1675
                        initprintf("Error: missing 'skin filename' for skin definition near line %s:%d\n", script->filename, scriptfile_getlinum(script,skintokptr));
2237 helixhorne 1676
                        model_ok = 0;
331 terminx 1677
                        break;
1678
                    }
99 terminx 1679
 
331 terminx 1680
                    if (seenframe) { modelskin = ++lastmodelskin; }
1681
                    seenframe = 0;
99 terminx 1682
 
587 terminx 1683
                    switch (token)
501 Plagman 1684
                    {
587 terminx 1685
                    case T_DETAIL:
501 Plagman 1686
                        palnum = DETAILPAL;
1687
                        param = 1.0f / param;
587 terminx 1688
                        break;
1689
                    case T_GLOW:
1690
                        palnum = GLOWPAL;
1691
                        break;
1350 terminx 1692
                    case T_SPECULAR:
1693
                        palnum = SPECULARPAL;
1694
                        break;
1695
                    case T_NORMAL:
1696
                        palnum = NORMALPAL;
1697
                        break;
501 Plagman 1698
                    }
1699
 
2554 helixhorne 1700
                    if (check_file_exist(skinfn))
1701
                        break;
2436 hendricks2 1702
 
1820 terminx 1703
#ifdef USE_OPENGL
5107 hendricks2 1704
                    switch (md_defineskin(lastmodelid, skinfn, palnum, max(0,modelskin), surfnum, param, specpower, specfactor, flags))
584 terminx 1705
                    {
331 terminx 1706
                    case 0:
1707
                        break;
1708
                    case -1:
1709
                        break; // invalid model id!?
1710
                    case -2:
4061 helixhorne 1711
                        initprintf("Invalid skin filename on line %s:%d\n",
331 terminx 1712
                                   script->filename, scriptfile_getlinum(script,skintokptr));
2237 helixhorne 1713
                        model_ok = 0;
331 terminx 1714
                        break;
1715
                    case -3:
4061 helixhorne 1716
                        initprintf("Invalid palette number on line %s:%d\n",
331 terminx 1717
                                   script->filename, scriptfile_getlinum(script,skintokptr));
2237 helixhorne 1718
                        model_ok = 0;
331 terminx 1719
                        break;
1720
                    case -4:
4061 helixhorne 1721
                        initprintf("Out of memory on line %s:%d\n",
331 terminx 1722
                                   script->filename, scriptfile_getlinum(script,skintokptr));
2237 helixhorne 1723
                        model_ok = 0;
331 terminx 1724
                        break;
1725
                    }
99 terminx 1726
#endif
584 terminx 1727
                }
1728
                break;
331 terminx 1729
                case T_HUD:
1730
                {
1731
                    char *hudtokptr = script->ltextptr;
3382 hendricks2 1732
                    char *frameend;
1733
#ifdef USE_OPENGL
1734
                    char happy=1;
1735
                    int32_t tilex = 0;
1736
#endif
4607 terminx 1737
                    int32_t ftilenume = -1, ltilenume = -1, flags = 0, fov = -1, angadd = 0;
1738
                    double xadd = 0.0, yadd = 0.0, zadd = 0.0;
99 terminx 1739
 
1677 terminx 1740
                    static const tokenlist modelhudtokens[] =
1741
                    {
1742
                        { "tile",   T_TILE   },
1743
                        { "tile0",  T_TILE0  },
1744
                        { "tile1",  T_TILE1  },
1745
                        { "xadd",   T_XADD   },
1746
                        { "yadd",   T_YADD   },
1747
                        { "zadd",   T_ZADD   },
1748
                        { "angadd", T_ANGADD },
1814 plagman 1749
                        { "fov",    T_FOV    },
1677 terminx 1750
                        { "hide",   T_HIDE   },
1751
                        { "nobob",  T_NOBOB  },
1752
                        { "flipped",T_FLIPPED},
1753
                        { "nodepth",T_NODEPTH},
1754
                    };
1755
 
331 terminx 1756
                    if (scriptfile_getbraces(script,&frameend)) break;
584 terminx 1757
                    while (script->textptr < frameend)
1758
                    {
4385 terminx 1759
                        switch (getatoken(script,modelhudtokens,ARRAY_SIZE(modelhudtokens)))
584 terminx 1760
                        {
331 terminx 1761
                        case T_TILE:
1762
                            scriptfile_getsymbol(script,&ftilenume); ltilenume = ftilenume; break;
1763
                        case T_TILE0:
1764
                            scriptfile_getsymbol(script,&ftilenume); break; //first tile number
1765
                        case T_TILE1:
1766
                            scriptfile_getsymbol(script,&ltilenume); break; //last tile number (inclusive)
1767
                        case T_XADD:
1768
                            scriptfile_getdouble(script,&xadd); break;
1769
                        case T_YADD:
1770
                            scriptfile_getdouble(script,&yadd); break;
1771
                        case T_ZADD:
1772
                            scriptfile_getdouble(script,&zadd); break;
1773
                        case T_ANGADD:
4607 terminx 1774
                            scriptfile_getsymbol(script,&angadd); break;
1814 plagman 1775
                        case T_FOV:
1776
                            scriptfile_getsymbol(script,&fov); break;
331 terminx 1777
                        case T_HIDE:
4174 helixhorne 1778
                            flags |= HUDFLAG_HIDE; break;
331 terminx 1779
                        case T_NOBOB:
4174 helixhorne 1780
                            flags |= HUDFLAG_NOBOB; break;
331 terminx 1781
                        case T_FLIPPED:
4174 helixhorne 1782
                            flags |= HUDFLAG_FLIPPED; break;
331 terminx 1783
                        case T_NODEPTH:
4174 helixhorne 1784
                            flags |= HUDFLAG_NODEPTH; break;
331 terminx 1785
                        }
1786
                    }
99 terminx 1787
 
4680 terminx 1788
                    if (EDUKE32_PREDICT_FALSE(check_tile_range("hud", &ftilenume, &ltilenume, script, hudtokptr)))
584 terminx 1789
                    {
2588 helixhorne 1790
                        model_ok = 0;
1791
                        break;
331 terminx 1792
                    }
99 terminx 1793
 
4680 terminx 1794
                    if (EDUKE32_PREDICT_FALSE(lastmodelid < 0))
584 terminx 1795
                    {
2288 helixhorne 1796
#ifdef USE_OPENGL
4061 helixhorne 1797
                        initprintf("Warning: Ignoring frame definition.\n");
2288 helixhorne 1798
#endif
331 terminx 1799
                        break;
1800
                    }
1820 terminx 1801
#ifdef USE_OPENGL
584 terminx 1802
                    for (tilex = ftilenume; tilex <= ltilenume && happy; tilex++)
1803
                    {
5079 terminx 1804
                        vec3f_t const add = { (float)xadd, (float)yadd, (float)zadd };
1805
                        switch (md_definehud(lastmodelid, tilex, add, angadd, flags, fov))
584 terminx 1806
                        {
331 terminx 1807
                        case 0:
1808
                            break;
1809
                        case -1:
1810
                            happy = 0; break; // invalid model id!?
1811
                        case -2:
4061 helixhorne 1812
                            initprintf("Invalid tile number on line %s:%d\n",
331 terminx 1813
                                       script->filename, scriptfile_getlinum(script,hudtokptr));
1814
                            happy = 0;
1815
                            break;
1816
                        case -3:
4061 helixhorne 1817
                            initprintf("Invalid frame name on line %s:%d\n",
331 terminx 1818
                                       script->filename, scriptfile_getlinum(script,hudtokptr));
1819
                            happy = 0;
1820
                            break;
1821
                        }
2237 helixhorne 1822
 
1823
                        model_ok &= happy;
331 terminx 1824
                    }
99 terminx 1825
#endif
109 terminx 1826
                }
584 terminx 1827
                break;
1828
                }
331 terminx 1829
            }
99 terminx 1830
 
2287 helixhorne 1831
#ifdef USE_OPENGL
4680 terminx 1832
            if (EDUKE32_PREDICT_FALSE(!model_ok))
2237 helixhorne 1833
            {
1834
                if (lastmodelid >= 0)
1835
                {
4061 helixhorne 1836
                    initprintf("Removing model %d due to errors.\n", lastmodelid);
2237 helixhorne 1837
                    md_undefinemodel(lastmodelid);
1838
                    nextmodelid--;
1839
                }
1840
                break;
1841
            }
1842
 
2264 hendricks2 1843
            md_setmisc(lastmodelid,(float)scale,shadeoffs,(float)mzadd,(float)myoffset,flags);
1910 helixhorne 1844
 
1845
            // thin out the loaded model by throwing away unused frames
2251 helixhorne 1846
            // FIXME: CURRENTLY DISABLED: interpolation may access frames we consider 'unused'?
1847
# if 0
1910 helixhorne 1848
            if (models[lastmodelid]->mdnum==3 && ((md3model_t *)models[lastmodelid])->numframes <= 1024)
1849
            {
2251 helixhorne 1850
#  ifdef DEBUG_MODEL_MEM
1910 helixhorne 1851
                md3model_t *m = (md3model_t *)models[lastmodelid];
1852
                int32_t i, onumframes;
1853
                onumframes = m->numframes;
2079 helixhorne 1854
                i =
2251 helixhorne 1855
#  endif
2079 helixhorne 1856
                md_thinoutmodel(lastmodelid, usedframebitmap);
2251 helixhorne 1857
#  ifdef DEBUG_MODEL_MEM
1910 helixhorne 1858
                if (i>=0 && i<onumframes)
4061 helixhorne 1859
                    initprintf("used %d/%d frames: %s\n", i, onumframes, modelfn);
1910 helixhorne 1860
                else if (i<0)
4061 helixhorne 1861
                    initprintf("md_thinoutmodel returned %d: %s\n", i, modelfn);
2251 helixhorne 1862
#  endif
1910 helixhorne 1863
            }
2251 helixhorne 1864
# endif
99 terminx 1865
 
3784 terminx 1866
            if (glrendmode == REND_POLYMER)
1910 helixhorne 1867
                md3postload_polymer((md3model_t *)models[lastmodelid]);
1868
#endif
1869
 
331 terminx 1870
            modelskin = lastmodelskin = 0;
1871
            seenframe = 0;
99 terminx 1872
 
331 terminx 1873
        }
1874
        break;
109 terminx 1875
        case T_VOXEL:
331 terminx 1876
        {
1877
            char *voxeltokptr = script->ltextptr;
1878
            char *fn, *modelend;
1205 terminx 1879
            int32_t tile0 = MAXTILES, tile1 = -1, tilex = -1;
99 terminx 1880
 
1677 terminx 1881
            static const tokenlist voxeltokens[] =
1882
            {
1883
                { "tile",   T_TILE   },
1884
                { "tile0",  T_TILE0  },
1885
                { "tile1",  T_TILE1  },
1886
                { "scale",  T_SCALE  },
1887
            };
1888
 
4835 helixhorne 1889
            if (EDUKE32_PREDICT_FALSE(scriptfile_getstring(script,&fn)))
1890
                break; //voxel filename
1891
 
1892
            if (EDUKE32_PREDICT_FALSE(nextvoxid == MAXVOXELS))
1893
            {
1894
                initprintf("Maximum number of voxels (%d) already defined.\n", MAXVOXELS);
1895
                break;
1896
            }
1897
 
1898
            if (EDUKE32_PREDICT_FALSE(qloadkvx(nextvoxid, fn)))
1899
            {
1900
                initprintf("Failure loading voxel file \"%s\"\n",fn);
1901
                break;
1902
            }
1903
 
331 terminx 1904
            lastvoxid = nextvoxid++;
99 terminx 1905
 
331 terminx 1906
            if (scriptfile_getbraces(script,&modelend)) break;
584 terminx 1907
            while (script->textptr < modelend)
1908
            {
4834 helixhorne 1909
                switch (getatoken(script, voxeltokens, ARRAY_SIZE(voxeltokens)))
584 terminx 1910
                {
4061 helixhorne 1911
                    //case T_ERROR: initprintf("Error on line %s:%d in voxel tokens\n", script->filename,linenum); break;
331 terminx 1912
                case T_TILE:
1913
                    scriptfile_getsymbol(script,&tilex);
2588 helixhorne 1914
 
4186 helixhorne 1915
                    if (check_tile("voxel", tilex, script, voxeltokptr))
2588 helixhorne 1916
                        break;
1917
 
1918
                    tiletovox[tilex] = lastvoxid;
331 terminx 1919
                    break;
2588 helixhorne 1920
 
331 terminx 1921
                case T_TILE0:
2588 helixhorne 1922
                    scriptfile_getsymbol(script,&tile0);
1923
                    break; //1st tile #
1924
 
331 terminx 1925
                case T_TILE1:
1926
                    scriptfile_getsymbol(script,&tile1);
2588 helixhorne 1927
 
3329 helixhorne 1928
                    if (check_tile_range("voxel", &tile0, &tile1, script, voxeltokptr))
2588 helixhorne 1929
                        break;
1930
 
1931
                    for (tilex=tile0; tilex<=tile1; tilex++)
1932
                        tiletovox[tilex] = lastvoxid;
331 terminx 1933
                    break; //last tile number (inclusive)
2588 helixhorne 1934
 
584 terminx 1935
                case T_SCALE:
1936
                {
331 terminx 1937
                    double scale=1.0;
1938
                    scriptfile_getdouble(script,&scale);
1205 terminx 1939
                    voxscale[lastvoxid] = (int32_t)(65536*scale);
1908 helixhorne 1940
#ifdef USE_OPENGL
1941
                    if (voxmodels[lastvoxid])
1942
                        voxmodels[lastvoxid]->scale = scale;
1943
#endif
331 terminx 1944
                    break;
109 terminx 1945
                }
331 terminx 1946
                }
109 terminx 1947
            }
331 terminx 1948
            lastvoxid = -1;
1949
        }
1950
        break;
109 terminx 1951
        case T_SKYBOX:
331 terminx 1952
        {
1953
            char *skyboxtokptr = script->ltextptr;
2554 helixhorne 1954
            char *fn[6] = {0,0,0,0,0,0};
1955
            char *modelend;
5040 hendricks2 1956
            int32_t i, tile = -1, pal = 0, happy = 1;
1957
#ifdef USE_OPENGL
1958
            int32_t flags = 0;
1959
#endif
99 terminx 1960
 
1677 terminx 1961
            static const tokenlist skyboxtokens[] =
1962
            {
1963
                { "tile"   ,T_TILE   },
1964
                { "pal"    ,T_PAL    },
1965
                { "ft"     ,T_FRONT  },{ "front"  ,T_FRONT  },{ "forward",T_FRONT  },
1966
                { "rt"     ,T_RIGHT  },{ "right"  ,T_RIGHT  },
1967
                { "bk"     ,T_BACK   },{ "back"   ,T_BACK   },
1968
                { "lf"     ,T_LEFT   },{ "left"   ,T_LEFT   },{ "lt"     ,T_LEFT   },
1969
                { "up"     ,T_TOP    },{ "top"    ,T_TOP    },{ "ceiling",T_TOP    },{ "ceil"   ,T_TOP    },
5010 terminx 1970
                { "dn"     ,T_BOTTOM },{ "bottom" ,T_BOTTOM },{ "floor"  ,T_BOTTOM },{ "down"   ,T_BOTTOM },
1971
                { "nocompress", T_NOCOMPRESS },
1972
                { "nodownsize", T_NODOWNSIZE },
5108 hendricks2 1973
                { "forcefilter", T_FORCEFILTER },
5705 hendricks2 1974
                { "artquality", T_ARTQUALITY },
1677 terminx 1975
            };
1976
 
331 terminx 1977
            if (scriptfile_getbraces(script,&modelend)) break;
584 terminx 1978
            while (script->textptr < modelend)
1979
            {
4385 terminx 1980
                switch (getatoken(script,skyboxtokens,ARRAY_SIZE(skyboxtokens)))
584 terminx 1981
                {
4061 helixhorne 1982
                    //case T_ERROR: initprintf("Error on line %s:%d in skybox tokens\n",script->filename,linenum); break;
331 terminx 1983
                case T_TILE:
584 terminx 1984
                    scriptfile_getsymbol(script,&tile); break;
331 terminx 1985
                case T_PAL:
584 terminx 1986
                    scriptfile_getsymbol(script,&pal); break;
331 terminx 1987
                case T_FRONT:
1988
                    scriptfile_getstring(script,&fn[0]); break;
1989
                case T_RIGHT:
1990
                    scriptfile_getstring(script,&fn[1]); break;
1991
                case T_BACK:
1992
                    scriptfile_getstring(script,&fn[2]); break;
1993
                case T_LEFT:
1994
                    scriptfile_getstring(script,&fn[3]); break;
1995
                case T_TOP:
1996
                    scriptfile_getstring(script,&fn[4]); break;
1997
                case T_BOTTOM:
1998
                    scriptfile_getstring(script,&fn[5]); break;
5010 terminx 1999
#ifdef USE_OPENGL
2000
                case T_NOCOMPRESS:
5640 hendricks2 2001
                    flags |= HICR_NOTEXCOMPRESS; break;
5010 terminx 2002
                case T_NODOWNSIZE:
5640 hendricks2 2003
                    flags |= HICR_NODOWNSIZE; break;
5108 hendricks2 2004
                case T_FORCEFILTER:
2005
                    flags |= HICR_FORCEFILTER; break;
5705 hendricks2 2006
                case T_ARTQUALITY:
2007
                    flags |= HICR_ARTIMMUNITY; break;
5010 terminx 2008
#endif
109 terminx 2009
                }
331 terminx 2010
            }
99 terminx 2011
 
4680 terminx 2012
            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 2013
            for (i=0; i<6; i++)
584 terminx 2014
            {
4680 terminx 2015
                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 2016
                // FIXME?
2554 helixhorne 2017
                if (check_file_exist(fn[i]))
2018
                    happy = 0;
331 terminx 2019
            }
2020
            if (!happy) break;
99 terminx 2021
 
3382 hendricks2 2022
#ifdef USE_OPENGL
5010 terminx 2023
            hicsetskybox(tile,pal,fn, flags);
3382 hendricks2 2024
#endif
331 terminx 2025
        }
2026
        break;
1748 plagman 2027
        case T_HIGHPALOOKUP:
2028
        {
2029
            char *highpaltokptr = script->ltextptr;
2554 helixhorne 2030
            int32_t basepal=-1, pal=-1;
2031
            char *fn = NULL;
1748 plagman 2032
            char *highpalend;
1778 helixhorne 2033
#ifdef POLYMER
7359 hendricks2 2034
            buildvfs_kfd fd;
1748 plagman 2035
            char *highpaldata;
1778 helixhorne 2036
#endif
1748 plagman 2037
            static const tokenlist highpaltokens[] =
2038
            {
1782 plagman 2039
                { "basepal",   T_BASEPAL },
1748 plagman 2040
                { "pal",   T_PAL },
2041
                { "file",  T_FILE }
2042
            };
2043
 
2044
            if (scriptfile_getbraces(script,&highpalend)) break;
2045
            while (script->textptr < highpalend)
2046
            {
4385 terminx 2047
                switch (getatoken(script,highpaltokens,ARRAY_SIZE(highpaltokens)))
1748 plagman 2048
                {
1782 plagman 2049
                case T_BASEPAL:
2050
                    scriptfile_getsymbol(script,&basepal);   break;
1748 plagman 2051
                case T_PAL:
2052
                    scriptfile_getsymbol(script,&pal);   break;
2053
                case T_FILE:
2054
                    scriptfile_getstring(script,&fn); break;
2055
                }
2056
            }
5348 hendricks2 2057
            if (EDUKE32_PREDICT_FALSE((unsigned)basepal >= MAXBASEPALS))
1782 plagman 2058
            {
4061 helixhorne 2059
                initprintf("Error: missing or invalid 'base palette number' for highpalookup definition "
2060
                           "near line %s:%d\n", script->filename, scriptfile_getlinum(script,highpaltokptr));
1782 plagman 2061
                break;
2062
            }
1748 plagman 2063
 
4680 terminx 2064
            if (EDUKE32_PREDICT_FALSE((unsigned)pal >= MAXPALOOKUPS - RESERVEDPALS))
1748 plagman 2065
            {
4061 helixhorne 2066
                initprintf("Error: missing or invalid 'palette number' for highpalookup definition near "
2067
                           "line %s:%d\n", script->filename, scriptfile_getlinum(script,highpaltokptr));
1748 plagman 2068
                break;
2069
            }
1782 plagman 2070
 
4680 terminx 2071
            if (EDUKE32_PREDICT_FALSE(!fn))
1748 plagman 2072
            {
4061 helixhorne 2073
                initprintf("Error: missing 'file name' for highpalookup definition near line %s:%d\n",
1748 plagman 2074
                           script->filename, scriptfile_getlinum(script,highpaltokptr));
2075
                break;
2076
            }
1762 terminx 2077
 
2554 helixhorne 2078
            if (check_file_exist(fn))
2079
                break;
1748 plagman 2080
 
1778 helixhorne 2081
#ifdef POLYMER
1748 plagman 2082
            fd = kopen4load(fn, 0);
2083
 
1751 helixhorne 2084
            // load the highpalookup and send it to polymer
4491 helixhorne 2085
            highpaldata = (char *)Xmalloc(PR_HIGHPALOOKUP_DATA_SIZE);
1749 helixhorne 2086
 
2087
            {
1751 helixhorne 2088
                char *filebuf;
1749 helixhorne 2089
                int32_t xsiz, ysiz, filesize, i;
2090
 
2091
                filesize = kfilelength(fd);
2092
 
4491 helixhorne 2093
                filebuf = (char *)Xmalloc(filesize);
1749 helixhorne 2094
 
2095
                klseek(fd, 0, SEEK_SET);
2096
                if (kread(fd, filebuf, filesize)!=filesize)
7705 terminx 2097
                    { kclose(fd); Xfree(highpaldata); initprintf("Error: didn't read all of \"%s\".\n", fn); break; }
1749 helixhorne 2098
 
2099
                kclose(fd);
2100
                kpgetdim(filebuf, filesize, &xsiz, &ysiz);
2101
 
4680 terminx 2102
                if (EDUKE32_PREDICT_FALSE(xsiz != PR_HIGHPALOOKUP_DIM*PR_HIGHPALOOKUP_DIM || ysiz != PR_HIGHPALOOKUP_DIM))
1749 helixhorne 2103
                {
4061 helixhorne 2104
                    initprintf("Error: image dimensions of \"%s\" must be %dx%d.\n",
1751 helixhorne 2105
                               fn, PR_HIGHPALOOKUP_DIM*PR_HIGHPALOOKUP_DIM, PR_HIGHPALOOKUP_DIM);
7705 terminx 2106
                    Xfree(filebuf); Xfree(highpaldata);
1748 plagman 2107
                    break;
1749 helixhorne 2108
                }
2109
 
4637 terminx 2110
                i = kprender(filebuf, filesize, (intptr_t)highpaldata, xsiz*sizeof(coltype), xsiz, ysiz);
7705 terminx 2111
                Xfree(filebuf);
4680 terminx 2112
                if (EDUKE32_PREDICT_FALSE(i))
7705 terminx 2113
                    { Xfree(highpaldata); initprintf("Error: failed rendering \"%s\".\n", fn); break; }
1748 plagman 2114
            }
1749 helixhorne 2115
 
1782 plagman 2116
            polymer_definehighpalookup(basepal, pal, highpaldata);
1748 plagman 2117
 
7705 terminx 2118
            Xfree(highpaldata);
1778 helixhorne 2119
#endif
1748 plagman 2120
        }
2121
        break;
109 terminx 2122
        case T_TINT:
331 terminx 2123
        {
2124
            char *tinttokptr = script->ltextptr;
6557 hendricks2 2125
            int32_t red=255, green=255, blue=255, shadered=0, shadegreen=0, shadeblue=0, pal=-1, flags=0;
331 terminx 2126
            char *tintend;
99 terminx 2127
 
1677 terminx 2128
            static const tokenlist tinttokens[] =
2129
            {
6557 hendricks2 2130
                { "pal",        T_PAL        },
2131
                { "red",        T_RED        },{ "r",  T_RED },
2132
                { "green",      T_GREEN      },{ "g",  T_GREEN },
2133
                { "blue",       T_BLUE       },{ "b",  T_BLUE },
2134
                { "shadered",   T_SHADERED   },{ "sr", T_SHADERED },
2135
                { "shadegreen", T_SHADEGREEN },{ "sg", T_SHADEGREEN },
2136
                { "shadeblue",  T_SHADEBLUE  },{ "sb", T_SHADEBLUE },
2137
                { "flags",      T_FLAGS      }
1677 terminx 2138
            };
2139
 
331 terminx 2140
            if (scriptfile_getbraces(script,&tintend)) break;
584 terminx 2141
            while (script->textptr < tintend)
2142
            {
4385 terminx 2143
                switch (getatoken(script,tinttokens,ARRAY_SIZE(tinttokens)))
584 terminx 2144
                {
331 terminx 2145
                case T_PAL:
6557 hendricks2 2146
                    scriptfile_getsymbol(script,&pal);        break;
331 terminx 2147
                case T_RED:
6557 hendricks2 2148
                    scriptfile_getnumber(script,&red);        red        = min(255,max(0,red));   break;
331 terminx 2149
                case T_GREEN:
6557 hendricks2 2150
                    scriptfile_getnumber(script,&green);      green      = min(255,max(0,green)); break;
331 terminx 2151
                case T_BLUE:
6557 hendricks2 2152
                    scriptfile_getnumber(script,&blue);       blue       = min(255,max(0,blue));  break;
2153
                case T_SHADERED:
2154
                    scriptfile_getnumber(script,&shadered);   shadered   = min(255,max(0,shadered));   break;
2155
                case T_SHADEGREEN:
2156
                    scriptfile_getnumber(script,&shadegreen); shadegreen = min(255,max(0,shadegreen)); break;
2157
                case T_SHADEBLUE:
2158
                    scriptfile_getnumber(script,&shadeblue);  shadeblue  = min(255,max(0,shadeblue));  break;
331 terminx 2159
                case T_FLAGS:
6557 hendricks2 2160
                    scriptfile_getsymbol(script,&flags);      break;
109 terminx 2161
                }
331 terminx 2162
            }
99 terminx 2163
 
4680 terminx 2164
            if (EDUKE32_PREDICT_FALSE(pal < 0))
584 terminx 2165
            {
4061 helixhorne 2166
                initprintf("Error: tint: missing 'palette number' near line %s:%d\n",
2568 helixhorne 2167
                           script->filename, scriptfile_getlinum(script,tinttokptr));
331 terminx 2168
                break;
2169
            }
99 terminx 2170
 
3382 hendricks2 2171
#ifdef USE_OPENGL
6557 hendricks2 2172
            hicsetpalettetint(pal,red,green,blue,shadered,shadegreen,shadeblue,flags);
3382 hendricks2 2173
#endif
331 terminx 2174
        }
2175
        break;
2568 helixhorne 2176
        case T_MAKEPALOOKUP:
2177
        {
2178
            char *const starttokptr = script->ltextptr;
2179
            int32_t red=0, green=0, blue=0, pal=-1;
2180
            int32_t havepal=0, remappal=0;
5101 hendricks2 2181
            int32_t nofloorpal=-1;
2568 helixhorne 2182
            char *endtextptr;
2183
 
2184
            static const tokenlist palookuptokens[] =
2185
            {
2186
                { "pal",   T_PAL },
2187
                { "red",   T_RED   }, { "r", T_RED },
2188
                { "green", T_GREEN }, { "g", T_GREEN },
2189
                { "blue",  T_BLUE  }, { "b", T_BLUE },
2190
                { "remappal", T_REMAPPAL },
2191
                { "remapself", T_REMAPSELF },
5101 hendricks2 2192
                { "nofloorpal", T_NOFLOORPAL },
2568 helixhorne 2193
            };
2194
 
4813 helixhorne 2195
            enum {
2196
                HAVE_PAL = 1,
2197
                HAVE_REMAPPAL = 2,
2198
                HAVE_REMAPSELF = 4,
2199
 
2200
                HAVEPAL_SPECIAL = HAVE_REMAPPAL | HAVE_REMAPSELF,
2201
                HAVEPAL_ERROR = 8,
2202
            };
2203
 
2568 helixhorne 2204
            if (scriptfile_getbraces(script,&endtextptr)) break;
2205
            while (script->textptr < endtextptr)
2206
            {
4385 terminx 2207
                switch (getatoken(script, palookuptokens, ARRAY_SIZE(palookuptokens)))
2568 helixhorne 2208
                {
2209
                case T_PAL:
2210
                    scriptfile_getsymbol(script, &pal);
4813 helixhorne 2211
                    havepal |= HAVE_PAL;
2568 helixhorne 2212
                    break;
2213
                case T_RED:
2214
                    scriptfile_getnumber(script,&red);
2215
                    red = clamp(red, 0, 63);
2216
                    break;
2217
                case T_GREEN:
2218
                    scriptfile_getnumber(script,&green);
2219
                    green = clamp(green, 0, 63);
2220
                    break;
2221
                case T_BLUE:
2222
                    scriptfile_getnumber(script,&blue);
2223
                    blue = clamp(blue, 0, 63);
2224
                    break;
2225
                case T_REMAPPAL:
2226
                    scriptfile_getsymbol(script,&remappal);
4813 helixhorne 2227
                    if (havepal & HAVEPAL_SPECIAL)
2228
                        havepal |= HAVEPAL_ERROR;
2229
                    havepal |= HAVE_REMAPPAL;
2568 helixhorne 2230
                    break;
2231
                case T_REMAPSELF:
4813 helixhorne 2232
                    if (havepal & HAVEPAL_SPECIAL)
2233
                        havepal |= HAVEPAL_ERROR;
2234
                    havepal |= HAVE_REMAPSELF;
2568 helixhorne 2235
                    break;
5101 hendricks2 2236
                case T_NOFLOORPAL:
2237
                    scriptfile_getsymbol(script, &nofloorpal);
2238
                    nofloorpal = clamp(nofloorpal, 0, 1);
2239
                    break;
2568 helixhorne 2240
                }
2241
            }
2242
 
2243
            {
2244
                char msgend[BMAX_PATH+64];
2245
 
2246
                Bsprintf(msgend, "for palookup definition near line %s:%d",
2247
                         script->filename, scriptfile_getlinum(script,starttokptr));
2248
 
4813 helixhorne 2249
                if (EDUKE32_PREDICT_FALSE((havepal & HAVE_PAL)==0))
2568 helixhorne 2250
                {
4061 helixhorne 2251
                    initprintf("Error: missing 'palette number' %s\n", msgend);
2568 helixhorne 2252
                    break;
2253
                }
4680 terminx 2254
                else if (EDUKE32_PREDICT_FALSE(pal==0 || (unsigned)pal >= MAXPALOOKUPS-RESERVEDPALS))
2568 helixhorne 2255
                {
4061 helixhorne 2256
                    initprintf("Error: 'palette number' out of range (1 .. %d) %s\n",
2568 helixhorne 2257
                               MAXPALOOKUPS-RESERVEDPALS-1, msgend);
2258
                    break;
2259
                }
4813 helixhorne 2260
 
2261
                if (EDUKE32_PREDICT_FALSE(havepal & HAVEPAL_ERROR))
2568 helixhorne 2262
                {
2263
                    // will also disallow multiple remappals or remapselfs
4061 helixhorne 2264
                    initprintf("Error: must have exactly one of either 'remappal' or 'remapself' %s\n", msgend);
2568 helixhorne 2265
                    break;
2266
                }
4813 helixhorne 2267
                else if (EDUKE32_PREDICT_FALSE((havepal & HAVE_REMAPPAL)
2268
                                               && (unsigned)remappal >= MAXPALOOKUPS-RESERVEDPALS))
2568 helixhorne 2269
                {
4061 helixhorne 2270
                    initprintf("Error: 'remap palette number' out of range (max=%d) %s\n",
2568 helixhorne 2271
                               MAXPALOOKUPS-RESERVEDPALS-1, msgend);
2272
                    break;
2273
                }
2274
 
4813 helixhorne 2275
                if (havepal & HAVE_REMAPSELF)
2568 helixhorne 2276
                    remappal = pal;
2277
            }
2278
 
2279
            // NOTE: all palookups are initialized, i.e. non-NULL!
2280
            // NOTE2: aliasing (pal==remappal) is OK
6829 terminx 2281
            paletteMakeLookupTable(pal, palookup[remappal], red<<2, green<<2, blue<<2,
5101 hendricks2 2282
                         remappal==0 ? 1 : (nofloorpal == -1 ? g_noFloorPal[remappal] : nofloorpal));
2568 helixhorne 2283
        }
2284
        break;
109 terminx 2285
        case T_TEXTURE:
331 terminx 2286
        {
2287
            char *texturetokptr = script->ltextptr, *textureend;
1205 terminx 2288
            int32_t tile=-1, token;
99 terminx 2289
 
1677 terminx 2290
            static const tokenlist texturetokens[] =
2291
            {
2292
                { "pal",     T_PAL  },
2293
                { "detail",  T_DETAIL },
2294
                { "glow",    T_GLOW },
2295
                { "specular",T_SPECULAR },
2296
                { "normal",  T_NORMAL },
2297
            };
2298
 
331 terminx 2299
            if (scriptfile_getsymbol(script,&tile)) break;
2300
            if (scriptfile_getbraces(script,&textureend)) break;
584 terminx 2301
            while (script->textptr < textureend)
2302
            {
4385 terminx 2303
                token = getatoken(script,texturetokens,ARRAY_SIZE(texturetokens));
584 terminx 2304
                switch (token)
2305
                {
2306
                case T_PAL:
2307
                {
331 terminx 2308
                    char *paltokptr = script->ltextptr, *palend;
4062 terminx 2309
                    int32_t pal=-1, xsiz = 0, ysiz = 0;
2554 helixhorne 2310
                    char *fn = NULL;
1526 plagman 2311
                    double alphacut = -1.0, xscale = 1.0, yscale = 1.0, specpower = 1.0, specfactor = 1.0;
3382 hendricks2 2312
#ifdef USE_OPENGL
331 terminx 2313
                    char flags = 0;
3382 hendricks2 2314
#endif
99 terminx 2315
 
1677 terminx 2316
                    static const tokenlist texturetokens_pal[] =
2317
                    {
2318
                        { "file",            T_FILE },{ "name", T_FILE },
2319
                        { "alphacut",        T_ALPHACUT },
2320
                        { "detailscale",     T_XSCALE }, { "scale",  T_XSCALE }, { "xscale",  T_XSCALE }, { "intensity",  T_XSCALE },
2321
                        { "yscale",          T_YSCALE },
2539 hendricks2 2322
                        { "specpower",       T_SPECPOWER }, { "specularpower", T_SPECPOWER }, { "parallaxscale", T_SPECPOWER },
2323