Subversion Repositories eduke32

Rev

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

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