Subversion Repositories eduke32

Rev

Rev 8471 | Rev 8490 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 8471 Rev 8488
1
/*
1
/*
2
 * Definitions file parser for Build
2
 * Definitions file parser for Build
3
 * by Jonathon Fowler (jf@jonof.id.au)
3
 * by Jonathon Fowler (jf@jonof.id.au)
4
 * Remixed substantially by Ken Silverman
4
 * Remixed substantially by Ken Silverman
5
 * See the included license file "BUILDLIC.TXT" for license info.
5
 * See the included license file "BUILDLIC.TXT" for license info.
6
 */
6
 */
7
7
8
#include "build.h"
8
#include "build.h"
9
#include "compat.h"
9
#include "compat.h"
10
#include "engine_priv.h"
10
#include "engine_priv.h"
11
#include "baselayer.h"
11
#include "baselayer.h"
12
#include "scriptfile.h"
12
#include "scriptfile.h"
13
#include "cache1d.h"
13
#include "cache1d.h"
14
#include "kplib.h"
14
#include "kplib.h"
15
#include "lz4.h"
15
#include "lz4.h"
16
#include "common.h"
16
#include "common.h"
17
#include "mdsprite.h"  // md3model_t
17
#include "mdsprite.h"  // md3model_t
18
#include "colmatch.h"
18
#include "colmatch.h"
19
19
20
#ifdef USE_OPENGL
20
#ifdef USE_OPENGL
21
# include "hightile.h"
21
# include "hightile.h"
22
#endif
22
#endif
23
23
24
#include "vfs.h"
24
#include "vfs.h"
25
25
26
enum scripttoken_t
26
enum scripttoken_t
27
{
27
{
28
    T_INCLUDE = 0,
28
    T_INCLUDE = 0,
29
    T_DEFINE,
29
    T_DEFINE,
30
    T_DEFINETEXTURE,
30
    T_DEFINETEXTURE,
31
    T_DEFINESKYBOX,
31
    T_DEFINESKYBOX,
32
    T_DEFINETINT,
32
    T_DEFINETINT,
33
    T_DEFINEMODEL,
33
    T_DEFINEMODEL,
34
    T_DEFINEMODELFRAME,
34
    T_DEFINEMODELFRAME,
35
    T_DEFINEMODELANIM,
35
    T_DEFINEMODELANIM,
36
    T_DEFINEMODELSKIN,
36
    T_DEFINEMODELSKIN,
37
    T_SELECTMODELSKIN,
37
    T_SELECTMODELSKIN,
38
    T_DEFINEVOXEL,
38
    T_DEFINEVOXEL,
39
    T_DEFINEVOXELTILES,
39
    T_DEFINEVOXELTILES,
40
    T_MODEL,
40
    T_MODEL,
41
    T_FILE,
41
    T_FILE,
42
    T_SCALE,
42
    T_SCALE,
43
    T_SHADE,
43
    T_SHADE,
44
    T_FRAME,
44
    T_FRAME,
45
    T_SMOOTHDURATION,
45
    T_SMOOTHDURATION,
46
    T_ANIM,
46
    T_ANIM,
47
    T_SKIN,
47
    T_SKIN,
48
    T_SURF,
48
    T_SURF,
49
    T_TILE,
49
    T_TILE,
50
    T_TILE0,
50
    T_TILE0,
51
    T_TILE1,
51
    T_TILE1,
52
    T_FRAME0,
52
    T_FRAME0,
53
    T_FRAME1,
53
    T_FRAME1,
54
    T_FPS,
54
    T_FPS,
55
    T_FLAGS,
55
    T_FLAGS,
56
    T_PAL,
56
    T_PAL,
57
    T_BASEPAL,
57
    T_BASEPAL,
58
    T_DETAIL,
58
    T_DETAIL,
59
    T_GLOW,
59
    T_GLOW,
60
    T_SPECULAR,
60
    T_SPECULAR,
61
    T_NORMAL,
61
    T_NORMAL,
62
    T_PARAM,
62
    T_PARAM,
63
    T_HUD,
63
    T_HUD,
64
    T_XADD,
64
    T_XADD,
65
    T_YADD,
65
    T_YADD,
66
    T_ZADD,
66
    T_ZADD,
67
    T_ANGADD,
67
    T_ANGADD,
68
    T_FOV,
68
    T_FOV,
69
    T_FLIPPED,
69
    T_FLIPPED,
70
    T_HIDE,
70
    T_HIDE,
71
    T_NOBOB,
71
    T_NOBOB,
72
    T_NODEPTH,
72
    T_NODEPTH,
73
    T_VOXEL,
73
    T_VOXEL,
74
    T_SKYBOX,
74
    T_SKYBOX,
75
    T_FRONT,T_RIGHT,T_BACK,T_LEFT,T_TOP,T_BOTTOM,
75
    T_FRONT,T_RIGHT,T_BACK,T_LEFT,T_TOP,T_BOTTOM,
76
    T_HIGHPALOOKUP,
76
    T_HIGHPALOOKUP,
77
    T_TINT,
77
    T_TINT,
78
    T_MAKEPALOOKUP, T_REMAPPAL, T_REMAPSELF,
78
    T_MAKEPALOOKUP, T_REMAPPAL, T_REMAPSELF,
79
    T_NOFLOORPAL, T_FLOORPAL,
79
    T_NOFLOORPAL, T_FLOORPAL,
80
    T_RED,T_GREEN,T_BLUE,
80
    T_RED,T_GREEN,T_BLUE,
81
    T_TEXTURE,T_ALPHACUT,T_XSCALE,T_YSCALE,T_SPECPOWER,T_SPECFACTOR,T_NOCOMPRESS,T_NODOWNSIZE,
81
    T_TEXTURE,T_ALPHACUT,T_XSCALE,T_YSCALE,T_SPECPOWER,T_SPECFACTOR,T_NOCOMPRESS,T_NODOWNSIZE,
82
    T_FORCEFILTER,
82
    T_FORCEFILTER,
83
    T_ARTQUALITY,
83
    T_ARTQUALITY,
84
    T_ORIGSIZEX,T_ORIGSIZEY,
84
    T_ORIGSIZEX,T_ORIGSIZEY,
85
    T_UNDEFMODEL,T_UNDEFMODELRANGE,T_UNDEFMODELOF,T_UNDEFTEXTURE,T_UNDEFTEXTURERANGE,
85
    T_UNDEFMODEL,T_UNDEFMODELRANGE,T_UNDEFMODELOF,T_UNDEFTEXTURE,T_UNDEFTEXTURERANGE,
86
    T_ALPHAHACK,T_ALPHAHACKRANGE,
86
    T_ALPHAHACK,T_ALPHAHACKRANGE,
87
    T_SPRITECOL,T_2DCOL,T_2DCOLIDXRANGE,
87
    T_SPRITECOL,T_2DCOL,T_2DCOLIDXRANGE,
88
    T_FOGPAL,
88
    T_FOGPAL,
89
    T_LOADGRP,
89
    T_LOADGRP,
90
    T_DUMMYTILE,T_DUMMYTILERANGE,
90
    T_DUMMYTILE,T_DUMMYTILERANGE,
91
    T_SETUPTILE,T_SETUPTILERANGE,
91
    T_SETUPTILE,T_SETUPTILERANGE,
92
    T_UNDEFINETILE,T_UNDEFINETILERANGE,
92
    T_UNDEFINETILE,T_UNDEFINETILERANGE,
93
    T_ANIMTILERANGE,
93
    T_ANIMTILERANGE,
94
    T_CACHESIZE,
94
    T_CACHESIZE,
95
    T_IMPORTTILE,
95
    T_IMPORTTILE,
96
    T_MUSIC,T_ID,T_SOUND,
96
    T_MUSIC,T_ID,T_SOUND,
97
    T_TILEFROMTEXTURE, T_XOFFSET, T_YOFFSET, T_TEXHITSCAN, T_NOFULLBRIGHT,
97
    T_TILEFROMTEXTURE, T_XOFFSET, T_YOFFSET, T_TEXHITSCAN, T_NOFULLBRIGHT,
98
    T_ARTFILE,
98
    T_ARTFILE,
99
    T_INCLUDEDEFAULT,
99
    T_INCLUDEDEFAULT,
100
    T_ANIMSOUNDS,
100
    T_ANIMSOUNDS,
101
    T_CUTSCENE,
101
    T_CUTSCENE,
102
    T_NOFLOORPALRANGE,
102
    T_NOFLOORPALRANGE,
103
    T_TEXHITSCANRANGE,
103
    T_TEXHITSCANRANGE,
104
    T_NOFULLBRIGHTRANGE,
104
    T_NOFULLBRIGHTRANGE,
105
    T_MAPINFO, T_MAPFILE, T_MAPTITLE, T_MAPMD4, T_MHKFILE,
105
    T_MAPINFO, T_MAPFILE, T_MAPTITLE, T_MAPMD4, T_MHKFILE,
106
    T_ECHO,
106
    T_ECHO,
107
    T_GLOBALFLAGS,
107
    T_GLOBALFLAGS,
108
    T_COPYTILE,
108
    T_COPYTILE,
109
    T_GLOBALGAMEFLAGS,
109
    T_GLOBALGAMEFLAGS,
110
    T_MULTIPSKY, T_HORIZFRAC, T_LOGNUMTILES,
110
    T_MULTIPSKY, T_HORIZFRAC, T_LOGNUMTILES,
111
    T_BASEPALETTE, T_PALOOKUP, T_BLENDTABLE,
111
    T_BASEPALETTE, T_PALOOKUP, T_BLENDTABLE,
112
    T_RAW, T_OFFSET, T_SHIFTLEFT, T_NOSHADES, T_COPY,
112
    T_RAW, T_OFFSET, T_SHIFTLEFT, T_NOSHADES, T_COPY,
113
    T_NUMALPHATABS,
113
    T_NUMALPHATABS,
114
    T_UNDEF,
114
    T_UNDEF,
115
    T_UNDEFBASEPALETTERANGE, T_UNDEFPALOOKUPRANGE, T_UNDEFBLENDTABLERANGE,
115
    T_UNDEFBASEPALETTERANGE, T_UNDEFPALOOKUPRANGE, T_UNDEFBLENDTABLERANGE,
116
    T_GLBLEND, T_FORWARD, T_REVERSE, T_BOTH, T_SRC, T_DST, T_ALPHA,
116
    T_GLBLEND, T_FORWARD, T_REVERSE, T_BOTH, T_SRC, T_DST, T_ALPHA,
117
    T_ZERO, T_ONE,
117
    T_ZERO, T_ONE,
118
    T_SRC_COLOR, T_ONE_MINUS_SRC_COLOR,
118
    T_SRC_COLOR, T_ONE_MINUS_SRC_COLOR,
119
    T_SRC_ALPHA, T_ONE_MINUS_SRC_ALPHA,
119
    T_SRC_ALPHA, T_ONE_MINUS_SRC_ALPHA,
120
    T_DST_ALPHA, T_ONE_MINUS_DST_ALPHA,
120
    T_DST_ALPHA, T_ONE_MINUS_DST_ALPHA,
121
    T_DST_COLOR, T_ONE_MINUS_DST_COLOR,
121
    T_DST_COLOR, T_ONE_MINUS_DST_COLOR,
122
    T_SHADERED, T_SHADEGREEN, T_SHADEBLUE,
122
    T_SHADERED, T_SHADEGREEN, T_SHADEBLUE,
123
    T_SHADEFACTOR,
123
    T_SHADEFACTOR,
124
    T_IFCRC,T_IFMATCH,T_CRC32,
124
    T_IFCRC,T_IFMATCH,T_CRC32,
125
    T_SIZE,
125
    T_SIZE,
126
    T_NEWGAMECHOICES,
126
    T_NEWGAMECHOICES,
127
};
127
};
128
128
129
static int32_t lastmodelid = -1, lastvoxid = -1, modelskin = -1, lastmodelskin = -1, seenframe = 0;
129
static int32_t lastmodelid = -1, lastvoxid = -1, modelskin = -1, lastmodelskin = -1, seenframe = 0;
130
static char *faketilebuffer = NULL;
130
static char *faketilebuffer = NULL;
131
static int32_t faketilebuffersiz = 0;
131
static int32_t faketilebuffersiz = 0;
132
132
133
static const char *skyfaces[6] =
133
static const char *skyfaces[6] =
134
{
134
{
135
    "front face", "right face", "back face",
135
    "front face", "right face", "back face",
136
    "left face", "top face", "bottom face"
136
    "left face", "top face", "bottom face"
137
};
137
};
138
138
139
static int32_t defsparser(scriptfile *script);
139
static int32_t defsparser(scriptfile *script);
140
140
141
static void defsparser_include(const char *fn, const scriptfile *script, const char *cmdtokptr)
141
static void defsparser_include(const char *fn, const scriptfile *script, const char *cmdtokptr)
142
{
142
{
143
    scriptfile *included;
143
    scriptfile *included;
144
144
145
    included = scriptfile_fromfile(fn);
145
    included = scriptfile_fromfile(fn);
146
    if (EDUKE32_PREDICT_FALSE(!included))
146
    if (EDUKE32_PREDICT_FALSE(!included))
147
    {
147
    {
148
        if (!cmdtokptr)
148
        if (!cmdtokptr)
149
            initprintf("Warning: Failed including %s as module\n", fn);
149
            initprintf("Warning: Failed including %s as module\n", fn);
150
        else
150
        else
151
            initprintf("Warning: Failed including %s on line %s:%d\n",
151
            initprintf("Warning: Failed including %s on line %s:%d\n",
152
                       fn, script->filename,scriptfile_getlinum(script,cmdtokptr));
152
                       fn, script->filename,scriptfile_getlinum(script,cmdtokptr));
153
    }
153
    }
154
    else
154
    else
155
    {
155
    {
156
        if (!cmdtokptr)
156
        if (!cmdtokptr)
157
        {
157
        {
158
            g_logFlushWindow = 1;
158
            g_logFlushWindow = 1;
159
            initprintf("Loading module \"%s\"\n",fn);
159
            initprintf("Loading module \"%s\"\n",fn);
160
            g_logFlushWindow = 0;
160
            g_logFlushWindow = 0;
161
        }
161
        }
162
162
163
        defsparser(included);
163
        defsparser(included);
164
        scriptfile_close(included);
164
        scriptfile_close(included);
165
    }
165
    }
166
}
166
}
167
167
168
168
169
static int32_t check_tile_range(const char *defcmd, int32_t *tilebeg, int32_t *tileend,
169
static int32_t check_tile_range(const char *defcmd, int32_t *tilebeg, int32_t *tileend,
170
                                const scriptfile *script, const char *cmdtokptr)
170
                                const scriptfile *script, const char *cmdtokptr)
171
{
171
{
172
    if (EDUKE32_PREDICT_FALSE(*tileend < *tilebeg))
172
    if (EDUKE32_PREDICT_FALSE(*tileend < *tilebeg))
173
    {
173
    {
174
        initprintf("Warning: %s: backwards tile range on line %s:%d\n", defcmd,
174
        initprintf("Warning: %s: backwards tile range on line %s:%d\n", defcmd,
175
                   script->filename, scriptfile_getlinum(script,cmdtokptr));
175
                   script->filename, scriptfile_getlinum(script,cmdtokptr));
176
        swaplong(tilebeg, tileend);
176
        swaplong(tilebeg, tileend);
177
    }
177
    }
178
178
179
    if (EDUKE32_PREDICT_FALSE((unsigned)*tilebeg >= MAXUSERTILES || (unsigned)*tileend >= MAXUSERTILES))
179
    if (EDUKE32_PREDICT_FALSE((unsigned)*tilebeg >= MAXUSERTILES || (unsigned)*tileend >= MAXUSERTILES))
180
    {
180
    {
181
        initprintf("Error: %s: Invalid tile range on line %s:%d\n", defcmd,
181
        initprintf("Error: %s: Invalid tile range on line %s:%d\n", defcmd,
182
                   script->filename, scriptfile_getlinum(script,cmdtokptr));
182
                   script->filename, scriptfile_getlinum(script,cmdtokptr));
183
        return 1;
183
        return 1;
184
    }
184
    }
185
185
186
    return 0;
186
    return 0;
187
}
187
}
188
188
189
static int32_t check_tile(const char *defcmd, int32_t tile, const scriptfile *script,
189
static int32_t check_tile(const char *defcmd, int32_t tile, const scriptfile *script,
190
                          const char *cmdtokptr)
190
                          const char *cmdtokptr)
191
{
191
{
192
    if (EDUKE32_PREDICT_FALSE((unsigned)tile >= MAXUSERTILES))
192
    if (EDUKE32_PREDICT_FALSE((unsigned)tile >= MAXUSERTILES))
193
    {
193
    {
194
        initprintf("Error: %s: Invalid tile number on line %s:%d\n", defcmd,
194
        initprintf("Error: %s: Invalid tile number on line %s:%d\n", defcmd,
195
                   script->filename, scriptfile_getlinum(script,cmdtokptr));
195
                   script->filename, scriptfile_getlinum(script,cmdtokptr));
196
        return 1;
196
        return 1;
197
    }
197
    }
198
198
199
    return 0;
199
    return 0;
200
}
200
}
201
201
202
static void tile_from_truecolpic(int32_t tile, const palette_t *picptr, int32_t alphacut)
202
static void tile_from_truecolpic(int32_t tile, const palette_t *picptr, int32_t alphacut)
203
{
203
{
204
    vec2_16_t const siz = tilesiz[tile];
204
    vec2_16_t const siz = tilesiz[tile];
205
    int32_t i, j, tsiz = siz.x * siz.y;
205
    int32_t i, j, tsiz = siz.x * siz.y;
206
206
207
    maybe_grow_buffer(&faketilebuffer, &faketilebuffersiz, tsiz);
207
    maybe_grow_buffer(&faketilebuffer, &faketilebuffersiz, tsiz);
208
208
209
    getclosestcol_flush();
209
    paletteFlushClosestColor();
210
210
211
    for (j = 0; j < siz.y; ++j)
211
    for (j = 0; j < siz.y; ++j)
212
    {
212
    {
213
        int const ofs = j * siz.x;
213
        int const ofs = j * siz.x;
214
        for (i = 0; i < siz.x; ++i)
214
        for (i = 0; i < siz.x; ++i)
215
        {
215
        {
216
            palette_t const *const col = &picptr[ofs + i];
216
            palette_t const *const col = &picptr[ofs + i];
217
            faketilebuffer[(i * siz.y) + j] =
217
            faketilebuffer[(i * siz.y) + j] =
218
            (col->f < alphacut) ? 255 : getclosestcol_lim(col->b, col->g, col->r, 254);
218
            (col->f < alphacut) ? 255 : paletteGetClosestColorUpToIndex(col->b, col->g, col->r, 254);
219
        }
219
        }
220
    }
220
    }
221
221
222
    tileSetData(tile, tsiz, faketilebuffer);
222
    tileSetData(tile, tsiz, faketilebuffer);
223
}
223
}
224
224
225
static int32_t Defs_LoadTileIntoBuffer(int32_t const tile)
225
static int32_t Defs_LoadTileIntoBuffer(int32_t const tile)
226
{
226
{
227
    vec2_16_t const siz = tilesiz[tile];
227
    vec2_16_t const siz = tilesiz[tile];
228
    int32_t const tsiz = siz.x * siz.y;
228
    int32_t const tsiz = siz.x * siz.y;
229
229
230
    if (EDUKE32_PREDICT_FALSE(tilesiz[tile].x <= 0 || tilesiz[tile].y <= 0))
230
    if (EDUKE32_PREDICT_FALSE(tilesiz[tile].x <= 0 || tilesiz[tile].y <= 0))
231
        return 0;
231
        return 0;
232
232
233
    maybe_grow_buffer(&faketilebuffer, &faketilebuffersiz, tsiz);
233
    maybe_grow_buffer(&faketilebuffer, &faketilebuffersiz, tsiz);
234
234
235
    tileLoadData(tile, tsiz, faketilebuffer);
235
    tileLoadData(tile, tsiz, faketilebuffer);
236
236
237
    return tsiz;
237
    return tsiz;
238
}
238
}
239
239
240
static void Defs_ApplyPaletteToTileBuffer(int32_t const tsiz, int32_t const pal)
240
static void Defs_ApplyPaletteToTileBuffer(int32_t const tsiz, int32_t const pal)
241
{
241
{
242
    for (bssize_t i = 0; i < tsiz; i++)
242
    for (bssize_t i = 0; i < tsiz; i++)
243
        faketilebuffer[i] = palookup[pal][faketilebuffer[i]];
243
        faketilebuffer[i] = palookup[pal][faketilebuffer[i]];
244
}
244
}
245
245
246
static int32_t Defs_ImportTileFromTexture(char const * const fn, int32_t const tile, int32_t const alphacut, int32_t istexture)
246
static int32_t Defs_ImportTileFromTexture(char const * const fn, int32_t const tile, int32_t const alphacut, int32_t istexture)
247
{
247
{
248
    if (check_file_exist(fn))
248
    if (check_file_exist(fn))
249
        return -1;
249
        return -1;
250
250
251
    int32_t xsiz = 0, ysiz = 0;
251
    int32_t xsiz = 0, ysiz = 0;
252
    palette_t *picptr = NULL;
252
    palette_t *picptr = NULL;
253
253
254
    int32_t const length = kpzbufload(fn);
254
    int32_t const length = kpzbufload(fn);
255
#ifdef WITHKPLIB
255
#ifdef WITHKPLIB
256
    kpzdecode(length, (intptr_t *)&picptr, &xsiz, &ysiz);
256
    kpzdecode(length, (intptr_t *)&picptr, &xsiz, &ysiz);
257
#endif
257
#endif
258
258
259
    if (!picptr)
259
    if (!picptr)
260
    {
260
    {
261
        int32_t const artstatus = artCheckUnitFileHeader((uint8_t *)kpzbuf, length);
261
        int32_t const artstatus = artCheckUnitFileHeader((uint8_t *)kpzbuf, length);
262
        if (artstatus < 0)
262
        if (artstatus < 0)
263
            return artstatus<<8;
263
            return artstatus<<8;
264
264
265
        Bmemcpy(&picanm[tile], &kpzbuf[20], sizeof(picanm_t));
265
        Bmemcpy(&picanm[tile], &kpzbuf[20], sizeof(picanm_t));
266
        tileConvertAnimFormat(tile);
266
        tileConvertAnimFormat(tile);
267
267
268
        int32_t const xsiz = B_LITTLE16(B_UNBUF16(&kpzbuf[16]));
268
        int32_t const xsiz = B_LITTLE16(B_UNBUF16(&kpzbuf[16]));
269
        int32_t const ysiz = B_LITTLE16(B_UNBUF16(&kpzbuf[18]));
269
        int32_t const ysiz = B_LITTLE16(B_UNBUF16(&kpzbuf[18]));
270
270
271
        if (EDUKE32_PREDICT_FALSE(xsiz <= 0 || ysiz <= 0))
271
        if (EDUKE32_PREDICT_FALSE(xsiz <= 0 || ysiz <= 0))
272
        {
272
        {
273
            tileDelete(tile);
273
            tileDelete(tile);
274
            return 2;
274
            return 2;
275
        }
275
        }
276
276
277
        tileSetSize(tile, xsiz, ysiz);
277
        tileSetSize(tile, xsiz, ysiz);
278
        int32_t const dasiz = xsiz * ysiz;
278
        int32_t const dasiz = xsiz * ysiz;
279
279
280
        if (EDUKE32_PREDICT_FALSE(ARTv1_UNITOFFSET + dasiz > length))
280
        if (EDUKE32_PREDICT_FALSE(ARTv1_UNITOFFSET + dasiz > length))
281
        {
281
        {
282
            tileSetupDummy(tile);
282
            tileSetupDummy(tile);
283
            return 3;
283
            return 3;
284
        }
284
        }
285
285
286
        tileSetData(tile, dasiz, &kpzbuf[ARTv1_UNITOFFSET]);
286
        tileSetData(tile, dasiz, &kpzbuf[ARTv1_UNITOFFSET]);
287
287
288
#ifdef USE_OPENGL
288
#ifdef USE_OPENGL
289
        if (istexture)
289
        if (istexture)
290
            hicsetsubsttex(tile, 0, fn, (float)(255-alphacut) * (1.f/255.f), 1.0f, 1.0f, 1.0f, 1.0f, HICR_ARTIMMUNITY);
290
            hicsetsubsttex(tile, 0, fn, (float)(255-alphacut) * (1.f/255.f), 1.0f, 1.0f, 1.0f, 1.0f, HICR_ARTIMMUNITY);
291
#endif
291
#endif
292
292
293
        return 1;
293
        return 1;
294
    }
294
    }
295
295
296
    if (EDUKE32_PREDICT_FALSE(xsiz <= 0 || ysiz <= 0))
296
    if (EDUKE32_PREDICT_FALSE(xsiz <= 0 || ysiz <= 0))
297
        return -2;
297
        return -2;
298
298
299
    if (!(paletteloaded & PALETTE_MAIN))
299
    if (!(paletteloaded & PALETTE_MAIN))
300
        return -3;
300
        return -3;
301
301
302
    tileSetSize(tile, xsiz, ysiz);
302
    tileSetSize(tile, xsiz, ysiz);
303
303
304
    tile_from_truecolpic(tile, picptr, alphacut);
304
    tile_from_truecolpic(tile, picptr, alphacut);
305
305
306
    Xfree(picptr);
306
    Xfree(picptr);
307
307
308
#ifdef USE_OPENGL
308
#ifdef USE_OPENGL
309
    if (istexture)
309
    if (istexture)
310
        hicsetsubsttex(tile, 0, fn, (float)(255-alphacut) * (1.f/255.f), 1.0f, 1.0f, 1.0, 1.0, HICR_ARTIMMUNITY);
310
        hicsetsubsttex(tile, 0, fn, (float)(255-alphacut) * (1.f/255.f), 1.0f, 1.0f, 1.0, 1.0, HICR_ARTIMMUNITY);
311
#else
311
#else
312
    UNREFERENCED_PARAMETER(istexture);
312
    UNREFERENCED_PARAMETER(istexture);
313
#endif
313
#endif
314
314
315
    return 0;
315
    return 0;
316
}
316
}
317
317
318
#undef USE_DEF_PROGRESS
318
#undef USE_DEF_PROGRESS
319
#if defined _WIN32 || defined HAVE_GTK2
319
#if defined _WIN32 || defined HAVE_GTK2
320
# define USE_DEF_PROGRESS
320
# define USE_DEF_PROGRESS
321
#endif
321
#endif
322
322
323
static int32_t defsparser(scriptfile *script)
323
static int32_t defsparser(scriptfile *script)
324
{
324
{
325
    int32_t tokn;
325
    int32_t tokn;
326
    char *cmdtokptr;
326
    char *cmdtokptr;
327
#ifdef USE_DEF_PROGRESS
327
#ifdef USE_DEF_PROGRESS
328
    static uint32_t iter = 0;
328
    static uint32_t iter = 0;
329
#endif
329
#endif
330
330
331
    static const tokenlist basetokens[] =
331
    static const tokenlist basetokens[] =
332
    {
332
    {
333
        { "include",         T_INCLUDE          },
333
        { "include",         T_INCLUDE          },
334
        { "#include",        T_INCLUDE          },
334
        { "#include",        T_INCLUDE          },
335
        { "includedefault",  T_INCLUDEDEFAULT   },
335
        { "includedefault",  T_INCLUDEDEFAULT   },
336
        { "#includedefault", T_INCLUDEDEFAULT   },
336
        { "#includedefault", T_INCLUDEDEFAULT   },
337
        { "define",          T_DEFINE           },
337
        { "define",          T_DEFINE           },
338
        { "#define",         T_DEFINE           },
338
        { "#define",         T_DEFINE           },
339
339
340
        // deprecated style
340
        // deprecated style
341
        { "definetexture",   T_DEFINETEXTURE    },
341
        { "definetexture",   T_DEFINETEXTURE    },
342
        { "defineskybox",    T_DEFINESKYBOX     },
342
        { "defineskybox",    T_DEFINESKYBOX     },
343
        { "definetint",      T_DEFINETINT       },
343
        { "definetint",      T_DEFINETINT       },
344
        { "definemodel",     T_DEFINEMODEL      },
344
        { "definemodel",     T_DEFINEMODEL      },
345
        { "definemodelframe",T_DEFINEMODELFRAME },
345
        { "definemodelframe",T_DEFINEMODELFRAME },
346
        { "definemodelanim", T_DEFINEMODELANIM  },
346
        { "definemodelanim", T_DEFINEMODELANIM  },
347
        { "definemodelskin", T_DEFINEMODELSKIN  },
347
        { "definemodelskin", T_DEFINEMODELSKIN  },
348
        { "selectmodelskin", T_SELECTMODELSKIN  },
348
        { "selectmodelskin", T_SELECTMODELSKIN  },
349
        { "definevoxel",     T_DEFINEVOXEL      },
349
        { "definevoxel",     T_DEFINEVOXEL      },
350
        { "definevoxeltiles",T_DEFINEVOXELTILES },
350
        { "definevoxeltiles",T_DEFINEVOXELTILES },
351
351
352
        // new style
352
        // new style
353
        { "model",           T_MODEL            },
353
        { "model",           T_MODEL            },
354
        { "voxel",           T_VOXEL            },
354
        { "voxel",           T_VOXEL            },
355
        { "skybox",          T_SKYBOX           },
355
        { "skybox",          T_SKYBOX           },
356
        { "highpalookup",    T_HIGHPALOOKUP     },
356
        { "highpalookup",    T_HIGHPALOOKUP     },
357
        { "tint",            T_TINT             },
357
        { "tint",            T_TINT             },
358
        { "makepalookup",    T_MAKEPALOOKUP     },
358
        { "makepalookup",    T_MAKEPALOOKUP     },
359
        { "texture",         T_TEXTURE          },
359
        { "texture",         T_TEXTURE          },
360
        { "tile",            T_TEXTURE          },
360
        { "tile",            T_TEXTURE          },
361
        { "music",           T_MUSIC            },
361
        { "music",           T_MUSIC            },
362
        { "sound",           T_SOUND            },
362
        { "sound",           T_SOUND            },
363
        { "animsounds",      T_ANIMSOUNDS       },  // dummy
363
        { "animsounds",      T_ANIMSOUNDS       },  // dummy
364
        { "cutscene",        T_CUTSCENE         },
364
        { "cutscene",        T_CUTSCENE         },
365
        { "nofloorpalrange", T_NOFLOORPALRANGE  },
365
        { "nofloorpalrange", T_NOFLOORPALRANGE  },
366
        { "texhitscanrange", T_TEXHITSCANRANGE  },
366
        { "texhitscanrange", T_TEXHITSCANRANGE  },
367
        { "nofullbrightrange", T_NOFULLBRIGHTRANGE },
367
        { "nofullbrightrange", T_NOFULLBRIGHTRANGE },
368
        // other stuff
368
        // other stuff
369
        { "undefmodel",      T_UNDEFMODEL       },
369
        { "undefmodel",      T_UNDEFMODEL       },
370
        { "undefmodelrange", T_UNDEFMODELRANGE  },
370
        { "undefmodelrange", T_UNDEFMODELRANGE  },
371
        { "undefmodelof",    T_UNDEFMODELOF     },
371
        { "undefmodelof",    T_UNDEFMODELOF     },
372
        { "undeftexture",    T_UNDEFTEXTURE     },
372
        { "undeftexture",    T_UNDEFTEXTURE     },
373
        { "undeftexturerange", T_UNDEFTEXTURERANGE },
373
        { "undeftexturerange", T_UNDEFTEXTURERANGE },
374
        { "alphahack",       T_ALPHAHACK                },
374
        { "alphahack",       T_ALPHAHACK                },
375
        { "alphahackrange",  T_ALPHAHACKRANGE   },
375
        { "alphahackrange",  T_ALPHAHACKRANGE   },
376
        { "spritecol",       T_SPRITECOL                },
376
        { "spritecol",       T_SPRITECOL                },
377
        { "2dcol",               T_2DCOL                        },
377
        { "2dcol",               T_2DCOL                        },
378
        { "2dcolidxrange",   T_2DCOLIDXRANGE    },
378
        { "2dcolidxrange",   T_2DCOLIDXRANGE    },
379
        { "fogpal",              T_FOGPAL                       },
379
        { "fogpal",              T_FOGPAL                       },
380
        { "loadgrp",             T_LOADGRP                      },
380
        { "loadgrp",             T_LOADGRP                      },
381
        { "dummytile",           T_DUMMYTILE            },
381
        { "dummytile",           T_DUMMYTILE            },
382
        { "dummytilerange",  T_DUMMYTILERANGE   },
382
        { "dummytilerange",  T_DUMMYTILERANGE   },
383
        { "setuptile",       T_SETUPTILE        },
383
        { "setuptile",       T_SETUPTILE        },
384
        { "setuptilerange",  T_SETUPTILERANGE   },
384
        { "setuptilerange",  T_SETUPTILERANGE   },
385
        { "undefinetile",    T_UNDEFINETILE             },
385
        { "undefinetile",    T_UNDEFINETILE             },
386
        { "undefinetilerange", T_UNDEFINETILERANGE },
386
        { "undefinetilerange", T_UNDEFINETILERANGE },
387
        { "animtilerange",   T_ANIMTILERANGE    },
387
        { "animtilerange",   T_ANIMTILERANGE    },
388
        { "cachesize",       T_CACHESIZE        },
388
        { "cachesize",       T_CACHESIZE        },
389
        { "dummytilefrompic",T_IMPORTTILE       },
389
        { "dummytilefrompic",T_IMPORTTILE       },
390
        { "tilefromtexture", T_TILEFROMTEXTURE  },
390
        { "tilefromtexture", T_TILEFROMTEXTURE  },
391
        { "artfile",         T_ARTFILE          },
391
        { "artfile",         T_ARTFILE          },
392
        { "mapinfo",         T_MAPINFO          },
392
        { "mapinfo",         T_MAPINFO          },
393
        { "echo",            T_ECHO             },
393
        { "echo",            T_ECHO             },
394
        { "globalflags",     T_GLOBALFLAGS      },
394
        { "globalflags",     T_GLOBALFLAGS      },
395
        { "copytile",        T_COPYTILE         },
395
        { "copytile",        T_COPYTILE         },
396
        { "globalgameflags", T_GLOBALGAMEFLAGS  },  // dummy
396
        { "globalgameflags", T_GLOBALGAMEFLAGS  },  // dummy
397
        { "multipsky",       T_MULTIPSKY        },
397
        { "multipsky",       T_MULTIPSKY        },
398
        { "basepalette",     T_BASEPALETTE      },
398
        { "basepalette",     T_BASEPALETTE      },
399
        { "palookup",        T_PALOOKUP         },
399
        { "palookup",        T_PALOOKUP         },
400
        { "blendtable",      T_BLENDTABLE       },
400
        { "blendtable",      T_BLENDTABLE       },
401
        { "numalphatables",  T_NUMALPHATABS     },
401
        { "numalphatables",  T_NUMALPHATABS     },
402
        { "undefbasepaletterange", T_UNDEFBASEPALETTERANGE },
402
        { "undefbasepaletterange", T_UNDEFBASEPALETTERANGE },
403
        { "undefpalookuprange", T_UNDEFPALOOKUPRANGE },
403
        { "undefpalookuprange", T_UNDEFPALOOKUPRANGE },
404
        { "undefblendtablerange", T_UNDEFBLENDTABLERANGE },
404
        { "undefblendtablerange", T_UNDEFBLENDTABLERANGE },
405
        { "shadefactor",     T_SHADEFACTOR      },
405
        { "shadefactor",     T_SHADEFACTOR      },
406
        { "newgamechoices",  T_NEWGAMECHOICES   },
406
        { "newgamechoices",  T_NEWGAMECHOICES   },
407
    };
407
    };
408
408
409
    while (1)
409
    while (1)
410
    {
410
    {
411
#ifdef USE_DEF_PROGRESS
411
#ifdef USE_DEF_PROGRESS
412
        if (++iter >= 50)
412
        if (++iter >= 50)
413
        {
413
        {
414
            g_logFlushWindow = 1;
414
            g_logFlushWindow = 1;
415
            initprintf(".");
415
            initprintf(".");
416
            g_logFlushWindow = 0;
416
            g_logFlushWindow = 0;
417
            iter = 0;
417
            iter = 0;
418
        }
418
        }
419
#endif
419
#endif
420
        handleevents();
420
        handleevents();
421
        if (quitevent) return 0;
421
        if (quitevent) return 0;
422
        tokn = getatoken(script,basetokens,ARRAY_SIZE(basetokens));
422
        tokn = getatoken(script,basetokens,ARRAY_SIZE(basetokens));
423
        cmdtokptr = script->ltextptr;
423
        cmdtokptr = script->ltextptr;
424
        switch (tokn)
424
        switch (tokn)
425
        {
425
        {
426
        case T_ERROR:
426
        case T_ERROR:
427
            initprintf("Error on line %s:%d.\n", script->filename,scriptfile_getlinum(script,cmdtokptr));
427
            initprintf("Error on line %s:%d.\n", script->filename,scriptfile_getlinum(script,cmdtokptr));
428
            break;
428
            break;
429
        case T_EOF:
429
        case T_EOF:
430
            return 0;
430
            return 0;
431
        case T_INCLUDE:
431
        case T_INCLUDE:
432
        {
432
        {
433
            char *fn;
433
            char *fn;
434
            if (!scriptfile_getstring(script,&fn))
434
            if (!scriptfile_getstring(script,&fn))
435
                defsparser_include(fn, script, cmdtokptr);
435
                defsparser_include(fn, script, cmdtokptr);
436
            break;
436
            break;
437
        }
437
        }
438
        case T_INCLUDEDEFAULT:
438
        case T_INCLUDEDEFAULT:
439
        {
439
        {
440
            defsparser_include(G_DefaultDefFile(), script, cmdtokptr);
440
            defsparser_include(G_DefaultDefFile(), script, cmdtokptr);
441
            break;
441
            break;
442
        }
442
        }
443
        case T_DEFINE:
443
        case T_DEFINE:
444
        {
444
        {
445
            char *name;
445
            char *name;
446
            int32_t number;
446
            int32_t number;
447
447
448
            if (scriptfile_getstring(script,&name)) break;
448
            if (scriptfile_getstring(script,&name)) break;
449
            if (scriptfile_getsymbol(script,&number)) break;
449
            if (scriptfile_getsymbol(script,&number)) break;
450
450
451
            if (EDUKE32_PREDICT_FALSE(scriptfile_addsymbolvalue(name,number) < 0))
451
            if (EDUKE32_PREDICT_FALSE(scriptfile_addsymbolvalue(name,number) < 0))
452
                initprintf("Warning: Symbol %s was NOT redefined to %d on line %s:%d\n",
452
                initprintf("Warning: Symbol %s was NOT redefined to %d on line %s:%d\n",
453
                           name,number,script->filename,scriptfile_getlinum(script,cmdtokptr));
453
                           name,number,script->filename,scriptfile_getlinum(script,cmdtokptr));
454
            break;
454
            break;
455
        }
455
        }
456
456
457
        // OLD (DEPRECATED) DEFINITION SYNTAX
457
        // OLD (DEPRECATED) DEFINITION SYNTAX
458
        case T_DEFINETEXTURE:
458
        case T_DEFINETEXTURE:
459
        {
459
        {
460
            int32_t tile,pal,fnoo;
460
            int32_t tile,pal,fnoo;
461
            char *fn;
461
            char *fn;
462
462
463
            if (scriptfile_getsymbol(script,&tile)) break;
463
            if (scriptfile_getsymbol(script,&tile)) break;
464
            if (scriptfile_getsymbol(script,&pal))  break;
464
            if (scriptfile_getsymbol(script,&pal))  break;
465
            if (scriptfile_getnumber(script,&fnoo)) break; //x-center
465
            if (scriptfile_getnumber(script,&fnoo)) break; //x-center
466
            if (scriptfile_getnumber(script,&fnoo)) break; //y-center
466
            if (scriptfile_getnumber(script,&fnoo)) break; //y-center
467
            if (scriptfile_getnumber(script,&fnoo)) break; //x-size
467
            if (scriptfile_getnumber(script,&fnoo)) break; //x-size
468
            if (scriptfile_getnumber(script,&fnoo)) break; //y-size
468
            if (scriptfile_getnumber(script,&fnoo)) break; //y-size
469
            if (scriptfile_getstring(script,&fn))  break;
469
            if (scriptfile_getstring(script,&fn))  break;
470
470
471
            if (check_file_exist(fn))
471
            if (check_file_exist(fn))
472
                break;
472
                break;
473
473
474
#ifdef USE_OPENGL
474
#ifdef USE_OPENGL
475
            hicsetsubsttex(tile,pal,fn,-1.0,1.0,1.0,1.0,1.0,0);
475
            hicsetsubsttex(tile,pal,fn,-1.0,1.0,1.0,1.0,1.0,0);
476
#endif
476
#endif
477
        }
477
        }
478
        break;
478
        break;
479
        case T_DEFINESKYBOX:
479
        case T_DEFINESKYBOX:
480
        {
480
        {
481
            int32_t tile,pal,i;
481
            int32_t tile,pal,i;
482
            char *fn[6],happy=1;
482
            char *fn[6],happy=1;
483
483
484
            if (scriptfile_getsymbol(script,&tile)) break;
484
            if (scriptfile_getsymbol(script,&tile)) break;
485
            if (scriptfile_getsymbol(script,&pal)) break;
485
            if (scriptfile_getsymbol(script,&pal)) break;
486
            if (scriptfile_getsymbol(script,&i)) break; //future expansion
486
            if (scriptfile_getsymbol(script,&i)) break; //future expansion
487
            for (i=0; i<6; i++)
487
            for (i=0; i<6; i++)
488
            {
488
            {
489
                if (scriptfile_getstring(script,&fn[i])) break; //grab the 6 faces
489
                if (scriptfile_getstring(script,&fn[i])) break; //grab the 6 faces
490
490
491
                if (check_file_exist(fn[i]))
491
                if (check_file_exist(fn[i]))
492
                    happy = 0;
492
                    happy = 0;
493
            }
493
            }
494
            if (i < 6 || !happy) break;
494
            if (i < 6 || !happy) break;
495
#ifdef USE_OPENGL
495
#ifdef USE_OPENGL
496
            hicsetskybox(tile,pal,fn, 0);
496
            hicsetskybox(tile,pal,fn, 0);
497
#endif
497
#endif
498
        }
498
        }
499
        break;
499
        break;
500
        case T_DEFINETINT:
500
        case T_DEFINETINT:
501
        {
501
        {
502
            int32_t pal, r,g,b,f;
502
            int32_t pal, r,g,b,f;
503
503
504
            if (scriptfile_getsymbol(script,&pal)) break;
504
            if (scriptfile_getsymbol(script,&pal)) break;
505
            if (scriptfile_getnumber(script,&r)) break;
505
            if (scriptfile_getnumber(script,&r)) break;
506
            if (scriptfile_getnumber(script,&g)) break;
506
            if (scriptfile_getnumber(script,&g)) break;
507
            if (scriptfile_getnumber(script,&b)) break;
507
            if (scriptfile_getnumber(script,&b)) break;
508
            if (scriptfile_getnumber(script,&f)) break; //effects
508
            if (scriptfile_getnumber(script,&f)) break; //effects
509
#ifdef USE_OPENGL
509
#ifdef USE_OPENGL
510
            hicsetpalettetint(pal,r,g,b,0,0,0,f);
510
            hicsetpalettetint(pal,r,g,b,0,0,0,f);
511
#endif
511
#endif
512
        }
512
        }
513
        break;
513
        break;
514
        case T_ALPHAHACK:
514
        case T_ALPHAHACK:
515
        {
515
        {
516
            int32_t tile;
516
            int32_t tile;
517
            double alpha;
517
            double alpha;
518
518
519
            if (scriptfile_getsymbol(script,&tile)) break;
519
            if (scriptfile_getsymbol(script,&tile)) break;
520
            if (scriptfile_getdouble(script,&alpha)) break;
520
            if (scriptfile_getdouble(script,&alpha)) break;
521
#ifdef USE_OPENGL
521
#ifdef USE_OPENGL
522
            if ((uint32_t)tile < MAXTILES)
522
            if ((uint32_t)tile < MAXTILES)
523
                alphahackarray[tile] = Blrintf(alpha * (float)UINT8_MAX);
523
                alphahackarray[tile] = Blrintf(alpha * (float)UINT8_MAX);
524
#endif
524
#endif
525
        }
525
        }
526
        break;
526
        break;
527
        case T_ALPHAHACKRANGE:
527
        case T_ALPHAHACKRANGE:
528
        {
528
        {
529
            int32_t tilenume1,tilenume2;
529
            int32_t tilenume1,tilenume2;
530
            double alpha;
530
            double alpha;
531
#ifdef USE_OPENGL
531
#ifdef USE_OPENGL
532
            int32_t i;
532
            int32_t i;
533
#endif
533
#endif
534
534
535
            if (scriptfile_getsymbol(script,&tilenume1)) break;
535
            if (scriptfile_getsymbol(script,&tilenume1)) break;
536
            if (scriptfile_getsymbol(script,&tilenume2)) break;
536
            if (scriptfile_getsymbol(script,&tilenume2)) break;
537
            if (scriptfile_getdouble(script,&alpha)) break;
537
            if (scriptfile_getdouble(script,&alpha)) break;
538
538
539
            if (check_tile_range("alphahackrange", &tilenume1, &tilenume2, script, cmdtokptr))
539
            if (check_tile_range("alphahackrange", &tilenume1, &tilenume2, script, cmdtokptr))
540
                break;
540
                break;
541
541
542
#ifdef USE_OPENGL
542
#ifdef USE_OPENGL
543
            for (i=tilenume1; i<=tilenume2; i++)
543
            for (i=tilenume1; i<=tilenume2; i++)
544
                alphahackarray[i] = Blrintf(alpha * (float)UINT8_MAX);
544
                alphahackarray[i] = Blrintf(alpha * (float)UINT8_MAX);
545
#endif
545
#endif
546
        }
546
        }
547
        break;
547
        break;
548
        case T_SPRITECOL:
548
        case T_SPRITECOL:
549
        {
549
        {
550
            int32_t tile,col,col2;
550
            int32_t tile,col,col2;
551
551
552
            if (scriptfile_getsymbol(script,&tile)) break;
552
            if (scriptfile_getsymbol(script,&tile)) break;
553
            if (scriptfile_getnumber(script,&col)) break;
553
            if (scriptfile_getnumber(script,&col)) break;
554
            if (scriptfile_getnumber(script,&col2)) break;
554
            if (scriptfile_getnumber(script,&col2)) break;
555
            if ((uint32_t)tile < MAXTILES)
555
            if ((uint32_t)tile < MAXTILES)
556
            {
556
            {
557
                spritecol2d[tile][0] = col;
557
                spritecol2d[tile][0] = col;
558
                spritecol2d[tile][1] = col2;
558
                spritecol2d[tile][1] = col2;
559
            }
559
            }
560
        }
560
        }
561
        break;
561
        break;
562
        case T_2DCOL:
562
        case T_2DCOL:
563
        {
563
        {
564
            int32_t col,b,g,r;
564
            int32_t col,b,g,r;
565
565
566
            if (scriptfile_getnumber(script,&col)) break;
566
            if (scriptfile_getnumber(script,&col)) break;
567
            if (scriptfile_getnumber(script,&r)) break;
567
            if (scriptfile_getnumber(script,&r)) break;
568
            if (scriptfile_getnumber(script,&g)) break;
568
            if (scriptfile_getnumber(script,&g)) break;
569
            if (scriptfile_getnumber(script,&b)) break;
569
            if (scriptfile_getnumber(script,&b)) break;
570
570
571
            if ((unsigned)col < 256)
571
            if ((unsigned)col < 256)
572
            {
572
            {
573
                r = clamp(r, 0, 63);
573
                r = clamp(r, 0, 63);
574
                g = clamp(g, 0, 63);
574
                g = clamp(g, 0, 63);
575
                b = clamp(b, 0, 63);
575
                b = clamp(b, 0, 63);
576
576
577
                vgapal16[col*4+0] = b<<2; // blue
577
                vgapal16[col*4+0] = b<<2; // blue
578
                vgapal16[col*4+1] = g<<2; // green
578
                vgapal16[col*4+1] = g<<2; // green
579
                vgapal16[col*4+2] = r<<2; // red
579
                vgapal16[col*4+2] = r<<2; // red
580
            }
580
            }
581
        }
581
        }
582
        break;
582
        break;
583
        case T_2DCOLIDXRANGE:  // NOTE: takes precedence over 2dcol, see InitCustomColors()
583
        case T_2DCOLIDXRANGE:  // NOTE: takes precedence over 2dcol, see InitCustomColors()
584
        {
584
        {
585
            int32_t col, idx, idxend;
585
            int32_t col, idx, idxend;
586
586
587
            if (scriptfile_getnumber(script,&col)) break;
587
            if (scriptfile_getnumber(script,&col)) break;
588
            if (scriptfile_getnumber(script,&idx)) break;
588
            if (scriptfile_getnumber(script,&idx)) break;
589
            if (scriptfile_getnumber(script,&idxend)) break;
589
            if (scriptfile_getnumber(script,&idxend)) break;
590
590
591
            while ((unsigned)col < 256 && idx <= idxend)
591
            while ((unsigned)col < 256 && idx <= idxend)
592
                editorcolors[col++] = idx++;
592
                editorcolors[col++] = idx++;
593
        }
593
        }
594
        break;
594
        break;
595
        case T_FOGPAL:
595
        case T_FOGPAL:
596
        {
596
        {
597
            int32_t p,r,g,b;
597
            int32_t p,r,g,b;
598
598
599
            if (scriptfile_getsymbol(script,&p)) break;
599
            if (scriptfile_getsymbol(script,&p)) break;
600
            if (scriptfile_getnumber(script,&r)) break;
600
            if (scriptfile_getnumber(script,&r)) break;
601
            if (scriptfile_getnumber(script,&g)) break;
601
            if (scriptfile_getnumber(script,&g)) break;
602
            if (scriptfile_getnumber(script,&b)) break;
602
            if (scriptfile_getnumber(script,&b)) break;
603
603
604
            r = clamp(r, 0, 63);
604
            r = clamp(r, 0, 63);
605
            g = clamp(g, 0, 63);
605
            g = clamp(g, 0, 63);
606
            b = clamp(b, 0, 63);
606
            b = clamp(b, 0, 63);
607
607
608
            paletteMakeLookupTable(p, NULL, r<<2, g<<2, b<<2, 1);
608
            paletteMakeLookupTable(p, NULL, r<<2, g<<2, b<<2, 1);
609
        }
609
        }
610
        break;
610
        break;
611
        case T_NOFLOORPALRANGE:
611
        case T_NOFLOORPALRANGE:
612
        {
612
        {
613
            int32_t b,e,i;
613
            int32_t b,e,i;
614
614
615
            if (scriptfile_getsymbol(script,&b)) break;
615
            if (scriptfile_getsymbol(script,&b)) break;
616
            if (scriptfile_getsymbol(script,&e)) break;
616
            if (scriptfile_getsymbol(script,&e)) break;
617
617
618
            b = max(b, 1);
618
            b = max(b, 1);
619
            e = min(e, MAXPALOOKUPS-1);
619
            e = min(e, MAXPALOOKUPS-1);
620
620
621
            for (i=b; i<=e; i++)
621
            for (i=b; i<=e; i++)
622
                g_noFloorPal[i] = 1;
622
                g_noFloorPal[i] = 1;
623
        }
623
        }
624
        break;
624
        break;
625
        case T_LOADGRP:
625
        case T_LOADGRP:
626
        {
626
        {
627
            char *bs;
627
            char *bs;
628
            scriptfile_getstring(script,&bs);
628
            scriptfile_getstring(script,&bs);
629
        }
629
        }
630
        break;
630
        break;
631
        case T_CACHESIZE:
631
        case T_CACHESIZE:
632
        {
632
        {
633
            int32_t j;
633
            int32_t j;
634
634
635
            if (scriptfile_getnumber(script,&j)) break;
635
            if (scriptfile_getnumber(script,&j)) break;
636
        }
636
        }
637
        break;
637
        break;
638
        case T_SHADEFACTOR:
638
        case T_SHADEFACTOR:
639
            scriptfile_getnumber(script, &realmaxshade);
639
            scriptfile_getnumber(script, &realmaxshade);
640
            frealmaxshade = (float)realmaxshade;
640
            frealmaxshade = (float)realmaxshade;
641
            break;
641
            break;
642
        case T_ARTFILE:
642
        case T_ARTFILE:
643
        {
643
        {
644
            char *blockend, *fn = NULL;
644
            char *blockend, *fn = NULL;
645
            int32_t tile = -1, havetile = 0;
645
            int32_t tile = -1, havetile = 0;
646
646
647
            static const tokenlist artfiletokens[] =
647
            static const tokenlist artfiletokens[] =
648
            {
648
            {
649
                { "file",            T_FILE },
649
                { "file",            T_FILE },
650
                { "tile",            T_TILE },
650
                { "tile",            T_TILE },
651
            };
651
            };
652
652
653
            if (scriptfile_getbraces(script,&blockend)) break;
653
            if (scriptfile_getbraces(script,&blockend)) break;
654
            while (script->textptr < blockend)
654
            while (script->textptr < blockend)
655
            {
655
            {
656
                int32_t token = getatoken(script,artfiletokens,ARRAY_SIZE(artfiletokens));
656
                int32_t token = getatoken(script,artfiletokens,ARRAY_SIZE(artfiletokens));
657
                switch (token)
657
                switch (token)
658
                {
658
                {
659
                case T_FILE:
659
                case T_FILE:
660
                    scriptfile_getstring(script,&fn);
660
                    scriptfile_getstring(script,&fn);
661
                    break;
661
                    break;
662
                case T_TILE:
662
                case T_TILE:
663
                    havetile = 1;
663
                    havetile = 1;
664
                    scriptfile_getsymbol(script,&tile);
664
                    scriptfile_getsymbol(script,&tile);
665
                    break;
665
                    break;
666
                default:
666
                default:
667
                    break;
667
                    break;
668
                }
668
                }
669
            }
669
            }
670
670
671
            if (EDUKE32_PREDICT_FALSE(!fn))
671
            if (EDUKE32_PREDICT_FALSE(!fn))
672
            {
672
            {
673
                initprintf("Error: missing 'file name' for artfile definition near line %s:%d\n",
673
                initprintf("Error: missing 'file name' for artfile definition near line %s:%d\n",
674
                           script->filename, scriptfile_getlinum(script,cmdtokptr));
674
                           script->filename, scriptfile_getlinum(script,cmdtokptr));
675
                break;
675
                break;
676
            }
676
            }
677
677
678
            buildvfs_kfd const fil = kopen4load(fn, 0);
678
            buildvfs_kfd const fil = kopen4load(fn, 0);
679
            if (fil == buildvfs_kfd_invalid)
679
            if (fil == buildvfs_kfd_invalid)
680
                break;
680
                break;
681
681
682
            artheader_t local;
682
            artheader_t local;
683
            int32_t headerval = artReadHeader(fil, fn, &local);
683
            int32_t headerval = artReadHeader(fil, fn, &local);
684
            if (headerval != 0)
684
            if (headerval != 0)
685
            {
685
            {
686
                kclose(fil);
686
                kclose(fil);
687
                break;
687
                break;
688
            }
688
            }
689
689
690
            if (havetile)
690
            if (havetile)
691
            {
691
            {
692
                if (!check_tile("artfile", tile, script, cmdtokptr))
692
                if (!check_tile("artfile", tile, script, cmdtokptr))
693
                {
693
                {
694
                    local.tilestart = tile;
694
                    local.tilestart = tile;
695
                    local.tileend = tile + local.numtiles - 1;
695
                    local.tileend = tile + local.numtiles - 1;
696
                }
696
                }
697
            }
697
            }
698
698
699
            artReadManifest(fil, &local);
699
            artReadManifest(fil, &local);
700
            artPreloadFile(fil, &local);
700
            artPreloadFile(fil, &local);
701
701
702
            kclose(fil);
702
            kclose(fil);
703
        }
703
        }
704
        break;
704
        break;
705
        case T_SETUPTILE:
705
        case T_SETUPTILE:
706
        {
706
        {
707
            int32_t tile, tmp;
707
            int32_t tile, tmp;
708
708
709
            if (scriptfile_getsymbol(script,&tile)) break;
709
            if (scriptfile_getsymbol(script,&tile)) break;
710
            if (check_tile("setuptile", tile, script, cmdtokptr))
710
            if (check_tile("setuptile", tile, script, cmdtokptr))
711
                break;
711
                break;
712
            if (scriptfile_getsymbol(script,&tmp)) break;  // XXX
712
            if (scriptfile_getsymbol(script,&tmp)) break;  // XXX
713
            h_xsize[tile] = tmp;
713
            h_xsize[tile] = tmp;
714
            if (scriptfile_getsymbol(script,&tmp)) break;
714
            if (scriptfile_getsymbol(script,&tmp)) break;
715
            h_ysize[tile] = tmp;
715
            h_ysize[tile] = tmp;
716
            if (scriptfile_getsymbol(script,&tmp)) break;
716
            if (scriptfile_getsymbol(script,&tmp)) break;
717
            h_xoffs[tile]=tmp;
717
            h_xoffs[tile]=tmp;
718
            if (scriptfile_getsymbol(script,&tmp)) break;
718
            if (scriptfile_getsymbol(script,&tmp)) break;
719
            h_yoffs[tile]=tmp;
719
            h_yoffs[tile]=tmp;
720
            break;
720
            break;
721
        }
721
        }
722
        case T_SETUPTILERANGE:
722
        case T_SETUPTILERANGE:
723
        {
723
        {
724
            int32_t tile1,tile2,xsiz,ysiz,xoffs,yoffs,i;
724
            int32_t tile1,tile2,xsiz,ysiz,xoffs,yoffs,i;
725
725
726
            if (scriptfile_getsymbol(script,&tile1)) break;
726
            if (scriptfile_getsymbol(script,&tile1)) break;
727
            if (scriptfile_getsymbol(script,&tile2)) break;
727
            if (scriptfile_getsymbol(script,&tile2)) break;
728
            if (scriptfile_getnumber(script,&xsiz)) break;
728
            if (scriptfile_getnumber(script,&xsiz)) break;
729
            if (scriptfile_getnumber(script,&ysiz)) break;
729
            if (scriptfile_getnumber(script,&ysiz)) break;
730
            if (scriptfile_getsymbol(script,&xoffs)) break;
730
            if (scriptfile_getsymbol(script,&xoffs)) break;
731
            if (scriptfile_getsymbol(script,&yoffs)) break;
731
            if (scriptfile_getsymbol(script,&yoffs)) break;
732
732
733
            if (check_tile_range("setuptilerange", &tile1, &tile2, script, cmdtokptr))
733
            if (check_tile_range("setuptilerange", &tile1, &tile2, script, cmdtokptr))
734
                break;
734
                break;
735
735
736
            for (i=tile1; i<=tile2; i++)
736
            for (i=tile1; i<=tile2; i++)
737
            {
737
            {
738
                h_xsize[i] = xsiz;
738
                h_xsize[i] = xsiz;
739
                h_ysize[i] = ysiz;
739
                h_ysize[i] = ysiz;
740
                h_xoffs[i] = xoffs;
740
                h_xoffs[i] = xoffs;
741
                h_yoffs[i] = yoffs;
741
                h_yoffs[i] = yoffs;
742
            }
742
            }
743
743
744
            break;
744
            break;
745
        }
745
        }
746
        case T_ANIMTILERANGE:
746
        case T_ANIMTILERANGE:
747
        {
747
        {
748
            int32_t tile1, tile2, spd, type;
748
            int32_t tile1, tile2, spd, type;
749
749
750
            if (scriptfile_getsymbol(script,&tile1)) break;
750
            if (scriptfile_getsymbol(script,&tile1)) break;
751
            if (scriptfile_getsymbol(script,&tile2)) break;
751
            if (scriptfile_getsymbol(script,&tile2)) break;
752
            if (scriptfile_getsymbol(script,&spd)) break;
752
            if (scriptfile_getsymbol(script,&spd)) break;
753
            if (scriptfile_getsymbol(script,&type)) break;
753
            if (scriptfile_getsymbol(script,&type)) break;
754
754
755
            if (check_tile("animtilerange", tile1, script, cmdtokptr))
755
            if (check_tile("animtilerange", tile1, script, cmdtokptr))
756
                break;
756
                break;
757
            if (check_tile("animtilerange", tile2, script, cmdtokptr))
757
            if (check_tile("animtilerange", tile2, script, cmdtokptr))
758
                break;
758
                break;
759
759
760
            spd = clamp(spd, 0, 15);
760
            spd = clamp(spd, 0, 15);
761
            if (EDUKE32_PREDICT_FALSE(type&~3))
761
            if (EDUKE32_PREDICT_FALSE(type&~3))
762
            {
762
            {
763
                initprintf("Error: animtilerange: animation type must be 0, 1, 2 or 3 on line %s:%d\n",
763
                initprintf("Error: animtilerange: animation type must be 0, 1, 2 or 3 on line %s:%d\n",
764
                           script->filename, scriptfile_getlinum(script,cmdtokptr));
764
                           script->filename, scriptfile_getlinum(script,cmdtokptr));
765
                break;
765
                break;
766
            }
766
            }
767
767
768
            int32_t num = tile2-tile1;
768
            int32_t num = tile2-tile1;
769
            if (type == 3 && tile1 > tile2) // PICANM_ANIMTYPE_BACK
769
            if (type == 3 && tile1 > tile2) // PICANM_ANIMTYPE_BACK
770
                num = -num;
770
                num = -num;
771
771
772
            if (EDUKE32_PREDICT_FALSE((unsigned)num > 255))
772
            if (EDUKE32_PREDICT_FALSE((unsigned)num > 255))
773
            {
773
            {
774
                initprintf("Error: animtilerange: tile difference can be at most 255 on line %s:%d\n",
774
                initprintf("Error: animtilerange: tile difference can be at most 255 on line %s:%d\n",
775
                           script->filename, scriptfile_getlinum(script,cmdtokptr));
775
                           script->filename, scriptfile_getlinum(script,cmdtokptr));
776
                break;
776
                break;
777
            }
777
            }
778
778
779
            // set anim speed
779
            // set anim speed
780
            picanm[tile1].sf &= ~PICANM_ANIMSPEED_MASK;
780
            picanm[tile1].sf &= ~PICANM_ANIMSPEED_MASK;
781
            picanm[tile1].sf |= spd;
781
            picanm[tile1].sf |= spd;
782
            // set anim type
782
            // set anim type
783
            picanm[tile1].sf &= ~PICANM_ANIMTYPE_MASK;
783
            picanm[tile1].sf &= ~PICANM_ANIMTYPE_MASK;
784
            picanm[tile1].sf |= type<<PICANM_ANIMTYPE_SHIFT;
784
            picanm[tile1].sf |= type<<PICANM_ANIMTYPE_SHIFT;
785
            // set anim number
785
            // set anim number
786
            picanm[tile1].num = num;
786
            picanm[tile1].num = num;
787
787
788
            break;
788
            break;
789
        }
789
        }
790
        case T_TILEFROMTEXTURE:
790
        case T_TILEFROMTEXTURE:
791
        {
791
        {
792
            char *texturetokptr = script->ltextptr, *textureend, *fn = NULL;
792
            char *texturetokptr = script->ltextptr, *textureend, *fn = NULL;
793
            int32_t tile = -1;
793
            int32_t tile = -1;
794
            int32_t alphacut = 255, flags = 0;
794
            int32_t alphacut = 255, flags = 0;
795
            int32_t havexoffset = 0, haveyoffset = 0;
795
            int32_t havexoffset = 0, haveyoffset = 0;
796
            int32_t xoffset = 0, yoffset = 0;
796
            int32_t xoffset = 0, yoffset = 0;
797
            int32_t istexture = 0;
797
            int32_t istexture = 0;
798
            int32_t tile_crc32 = 0;
798
            int32_t tile_crc32 = 0;
799
            vec2_t  tile_size{};
799
            vec2_t  tile_size{};
800
            uint8_t have_crc32 = 0;
800
            uint8_t have_crc32 = 0;
801
            uint8_t have_size = 0;
801
            uint8_t have_size = 0;
802
802
803
            static const tokenlist tilefromtexturetokens[] =
803
            static const tokenlist tilefromtexturetokens[] =
804
            {
804
            {
805
                { "file",            T_FILE },
805
                { "file",            T_FILE },
806
                { "name",            T_FILE },
806
                { "name",            T_FILE },
807
                { "alphacut",        T_ALPHACUT },
807
                { "alphacut",        T_ALPHACUT },
808
                { "xoffset",         T_XOFFSET },
808
                { "xoffset",         T_XOFFSET },
809
                { "xoff",            T_XOFFSET },
809
                { "xoff",            T_XOFFSET },
810
                { "yoffset",         T_YOFFSET },
810
                { "yoffset",         T_YOFFSET },
811
                { "yoff",            T_YOFFSET },
811
                { "yoff",            T_YOFFSET },
812
                { "texhitscan",      T_TEXHITSCAN },
812
                { "texhitscan",      T_TEXHITSCAN },
813
                { "nofullbright",    T_NOFULLBRIGHT },
813
                { "nofullbright",    T_NOFULLBRIGHT },
814
                { "texture",         T_TEXTURE },
814
                { "texture",         T_TEXTURE },
815
                { "ifcrc",           T_IFCRC },
815
                { "ifcrc",           T_IFCRC },
816
                { "ifmatch",         T_IFMATCH },
816
                { "ifmatch",         T_IFMATCH },
817
            };
817
            };
818
818
819
            if (scriptfile_getsymbol(script,&tile)) break;
819
            if (scriptfile_getsymbol(script,&tile)) break;
820
            if (scriptfile_getbraces(script,&textureend)) break;
820
            if (scriptfile_getbraces(script,&textureend)) break;
821
            while (script->textptr < textureend)
821
            while (script->textptr < textureend)
822
            {
822
            {
823
                int32_t token = getatoken(script,tilefromtexturetokens,ARRAY_SIZE(tilefromtexturetokens));
823
                int32_t token = getatoken(script,tilefromtexturetokens,ARRAY_SIZE(tilefromtexturetokens));
824
                switch (token)
824
                switch (token)
825
                {
825
                {
826
                case T_FILE:
826
                case T_FILE:
827
                    scriptfile_getstring(script,&fn);
827
                    scriptfile_getstring(script,&fn);
828
                    break;
828
                    break;
829
                case T_ALPHACUT:
829
                case T_ALPHACUT:
830
                    scriptfile_getsymbol(script,&alphacut);
830
                    scriptfile_getsymbol(script,&alphacut);
831
                    alphacut = clamp(alphacut, 0, 255);
831
                    alphacut = clamp(alphacut, 0, 255);
832
                    break;
832
                    break;
833
                case T_XOFFSET:
833
                case T_XOFFSET:
834
                    havexoffset = 1;
834
                    havexoffset = 1;
835
                    scriptfile_getsymbol(script,&xoffset);
835
                    scriptfile_getsymbol(script,&xoffset);
836
                    xoffset = clamp(xoffset, -128, 127);
836
                    xoffset = clamp(xoffset, -128, 127);
837
                    break;
837
                    break;
838
                case T_YOFFSET:
838
                case T_YOFFSET:
839
                    haveyoffset = 1;
839
                    haveyoffset = 1;
840
                    scriptfile_getsymbol(script,&yoffset);
840
                    scriptfile_getsymbol(script,&yoffset);
841
                    yoffset = clamp(yoffset, -128, 127);
841
                    yoffset = clamp(yoffset, -128, 127);
842
                    break;
842
                    break;
843
                case T_IFCRC:
843
                case T_IFCRC:
844
                    scriptfile_getsymbol(script, &tile_crc32);
844
                    scriptfile_getsymbol(script, &tile_crc32);
845
                    have_crc32 = 1;
845
                    have_crc32 = 1;
846
                    break;
846
                    break;
847
                case T_IFMATCH:
847
                case T_IFMATCH:
848
                {
848
                {
849
                    char *ifmatchend;
849
                    char *ifmatchend;
850
850
851
                    static const tokenlist ifmatchtokens[] =
851
                    static const tokenlist ifmatchtokens[] =
852
                    {
852
                    {
853
                        { "crc32",           T_CRC32 },
853
                        { "crc32",           T_CRC32 },
854
                        { "size",            T_SIZE },
854
                        { "size",            T_SIZE },
855
                    };
855
                    };
856
856
857
                    if (scriptfile_getbraces(script,&ifmatchend)) break;
857
                    if (scriptfile_getbraces(script,&ifmatchend)) break;
858
                    while (script->textptr < ifmatchend)
858
                    while (script->textptr < ifmatchend)
859
                    {
859
                    {
860
                        int32_t token = getatoken(script,ifmatchtokens,ARRAY_SIZE(ifmatchtokens));
860
                        int32_t token = getatoken(script,ifmatchtokens,ARRAY_SIZE(ifmatchtokens));
861
                        switch (token)
861
                        switch (token)
862
                        {
862
                        {
863
                        case T_CRC32:
863
                        case T_CRC32:
864
                            scriptfile_getsymbol(script, &tile_crc32);
864
                            scriptfile_getsymbol(script, &tile_crc32);
865
                            have_crc32 = 1;
865
                            have_crc32 = 1;
866
                            break;
866
                            break;
867
                        case T_SIZE:
867
                        case T_SIZE:
868
                            scriptfile_getsymbol(script, &tile_size.x);
868
                            scriptfile_getsymbol(script, &tile_size.x);
869
                            scriptfile_getsymbol(script, &tile_size.y);
869
                            scriptfile_getsymbol(script, &tile_size.y);
870
                            have_size = 1;
870
                            have_size = 1;
871
                            break;
871
                            break;
872
                        default:
872
                        default:
873
                            break;
873
                            break;
874
                        }
874
                        }
875
                    }
875
                    }
876
                    break;
876
                    break;
877
                }
877
                }
878
                case T_TEXHITSCAN:
878
                case T_TEXHITSCAN:
879
                    flags |= PICANM_TEXHITSCAN_BIT;
879
                    flags |= PICANM_TEXHITSCAN_BIT;
880
                    break;
880
                    break;
881
                case T_NOFULLBRIGHT:
881
                case T_NOFULLBRIGHT:
882
                    flags |= PICANM_NOFULLBRIGHT_BIT;
882
                    flags |= PICANM_NOFULLBRIGHT_BIT;
883
                    break;
883
                    break;
884
                case T_TEXTURE:
884
                case T_TEXTURE:
885
                    istexture = 1;
885
                    istexture = 1;
886
                    break;
886
                    break;
887
                default:
887
                default:
888
                    break;
888
                    break;
889
                }
889
                }
890
            }
890
            }
891
891
892
            if (EDUKE32_PREDICT_FALSE((unsigned)tile >= MAXUSERTILES))
892
            if (EDUKE32_PREDICT_FALSE((unsigned)tile >= MAXUSERTILES))
893
            {
893
            {
894
                initprintf("Error: missing or invalid 'tile number' for texture definition near line %s:%d\n",
894
                initprintf("Error: missing or invalid 'tile number' for texture definition near line %s:%d\n",
895
                           script->filename, scriptfile_getlinum(script,texturetokptr));
895
                           script->filename, scriptfile_getlinum(script,texturetokptr));
896
                break;
896
                break;
897
            }
897
            }
898
898
899
            if (have_crc32)
899
            if (have_crc32)
900
            {
900
            {
901
                int32_t const orig_crc32 = tileGetCRC32(tile);
901
                int32_t const orig_crc32 = tileGetCRC32(tile);
902
                if (orig_crc32 != tile_crc32)
902
                if (orig_crc32 != tile_crc32)
903
                {
903
                {
904
                    // initprintf("CRC32 of tile %d doesn't match! CRC32: %d, Expected: %d\n", tile, orig_crc32, tile_crc32);
904
                    // initprintf("CRC32 of tile %d doesn't match! CRC32: %d, Expected: %d\n", tile, orig_crc32, tile_crc32);
905
                    break;
905
                    break;
906
                }
906
                }
907
            }
907
            }
908
908
909
            if (have_size)
909
            if (have_size)
910
            {
910
            {
911
                vec2_16_t const orig_size = tileGetSize(tile);
911
                vec2_16_t const orig_size = tileGetSize(tile);
912
                if (orig_size.x != tile_size.x && orig_size.y != tile_size.y)
912
                if (orig_size.x != tile_size.x && orig_size.y != tile_size.y)
913
                {
913
                {
914
                    // initprintf("Size of tile %d doesn't match! Size: (%d, %d), Expected: (%d, %d)\n", tile, orig_size.x, orig_size.y, tile_size.x, tile_size.y);
914
                    // initprintf("Size of tile %d doesn't match! Size: (%d, %d), Expected: (%d, %d)\n", tile, orig_size.x, orig_size.y, tile_size.x, tile_size.y);
915
                    break;
915
                    break;
916
                }
916
                }
917
            }
917
            }
918
918
919
            if (!fn)
919
            if (!fn)
920
            {
920
            {
921
                // tilefromtexture <tile> { texhitscan }  sets the bit but doesn't change tile data
921
                // tilefromtexture <tile> { texhitscan }  sets the bit but doesn't change tile data
922
                picanm[tile].sf |= flags;
922
                picanm[tile].sf |= flags;
923
                if (havexoffset)
923
                if (havexoffset)
924
                    picanm[tile].xofs = xoffset;
924
                    picanm[tile].xofs = xoffset;
925
                if (haveyoffset)
925
                if (haveyoffset)
926
                    picanm[tile].yofs = yoffset;
926
                    picanm[tile].yofs = yoffset;
927
927
928
                if (EDUKE32_PREDICT_FALSE(flags == 0 && !havexoffset && !haveyoffset))
928
                if (EDUKE32_PREDICT_FALSE(flags == 0 && !havexoffset && !haveyoffset))
929
                    initprintf("\nError: missing 'file name' for tilefromtexture definition near line %s:%d",
929
                    initprintf("\nError: missing 'file name' for tilefromtexture definition near line %s:%d",
930
                               script->filename, scriptfile_getlinum(script,texturetokptr));
930
                               script->filename, scriptfile_getlinum(script,texturetokptr));
931
                break;
931
                break;
932
            }
932
            }
933
933
934
            int32_t const texstatus = Defs_ImportTileFromTexture(fn, tile, alphacut, istexture);
934
            int32_t const texstatus = Defs_ImportTileFromTexture(fn, tile, alphacut, istexture);
935
            if (texstatus == -3)
935
            if (texstatus == -3)
936
                initprintf("Error: No palette loaded, in tilefromtexture definition near line %s:%d\n",
936
                initprintf("Error: No palette loaded, in tilefromtexture definition near line %s:%d\n",
937
                           script->filename, scriptfile_getlinum(script,texturetokptr));
937
                           script->filename, scriptfile_getlinum(script,texturetokptr));
938
            if (texstatus == -(3<<8))
938
            if (texstatus == -(3<<8))
939
                initprintf("Error: \"%s\" has more than one tile, in tilefromtexture definition near line %s:%d\n",
939
                initprintf("Error: \"%s\" has more than one tile, in tilefromtexture definition near line %s:%d\n",
940
                           fn, script->filename, scriptfile_getlinum(script,texturetokptr));
940
                           fn, script->filename, scriptfile_getlinum(script,texturetokptr));
941
            if (texstatus < 0)
941
            if (texstatus < 0)
942
                break;
942
                break;
943
943
944
            picanm[tile].sf |= flags;
944
            picanm[tile].sf |= flags;
945
945
946
            if (havexoffset)
946
            if (havexoffset)
947
                picanm[tile].xofs = xoffset;
947
                picanm[tile].xofs = xoffset;
948
            else if (texstatus == 0)
948
            else if (texstatus == 0)
949
                picanm[tile].xofs = 0;
949
                picanm[tile].xofs = 0;
950
950
951
            if (haveyoffset)
951
            if (haveyoffset)
952
                picanm[tile].yofs = yoffset;
952
                picanm[tile].yofs = yoffset;
953
            else if (texstatus == 0)
953
            else if (texstatus == 0)
954
                picanm[tile].yofs = 0;
954
                picanm[tile].yofs = 0;
955
        }
955
        }
956
        break;
956
        break;
957
        case T_COPYTILE:
957
        case T_COPYTILE:
958
        {
958
        {
959
            char *blockend;
959
            char *blockend;
960
            int32_t tile = -1, source;
960
            int32_t tile = -1, source;
961
            int32_t havetile = 0, havexoffset = 0, haveyoffset = 0;
961
            int32_t havetile = 0, havexoffset = 0, haveyoffset = 0;
962
            int32_t xoffset = 0, yoffset = 0;
962
            int32_t xoffset = 0, yoffset = 0;
963
            int32_t flags = 0;
963
            int32_t flags = 0;
964
            int32_t tsiz = 0;
964
            int32_t tsiz = 0;
965
965
966
            static const tokenlist copytiletokens[] =
966
            static const tokenlist copytiletokens[] =
967
            {
967
            {
968
                { "tile",            T_TILE },
968
                { "tile",            T_TILE },
969
                { "pal",             T_PAL },
969
                { "pal",             T_PAL },
970
                { "xoffset",         T_XOFFSET },
970
                { "xoffset",         T_XOFFSET },
971
                { "xoff",            T_XOFFSET },
971
                { "xoff",            T_XOFFSET },
972
                { "yoffset",         T_YOFFSET },
972
                { "yoffset",         T_YOFFSET },
973
                { "yoff",            T_YOFFSET },
973
                { "yoff",            T_YOFFSET },
974
                { "texhitscan",      T_TEXHITSCAN },
974
                { "texhitscan",      T_TEXHITSCAN },
975
                { "nofullbright",    T_NOFULLBRIGHT },
975
                { "nofullbright",    T_NOFULLBRIGHT },
976
            };
976
            };
977
977
978
            if (scriptfile_getsymbol(script,&tile)) break;
978
            if (scriptfile_getsymbol(script,&tile)) break;
979
            source = tile; // without a "tile" token, we still palettize self by default
979
            source = tile; // without a "tile" token, we still palettize self by default
980
            if (scriptfile_getbraces(script,&blockend)) break;
980
            if (scriptfile_getbraces(script,&blockend)) break;
981
            while (script->textptr < blockend)
981
            while (script->textptr < blockend)
982
            {
982
            {
983
                int32_t token = getatoken(script,copytiletokens,ARRAY_SIZE(copytiletokens));
983
                int32_t token = getatoken(script,copytiletokens,ARRAY_SIZE(copytiletokens));
984
                switch (token)
984
                switch (token)
985
                {
985
                {
986
                case T_TILE:
986
                case T_TILE:
987
                {
987
                {
988
                    int32_t tempsource;
988
                    int32_t tempsource;
989
                    scriptfile_getsymbol(script,&tempsource);
989
                    scriptfile_getsymbol(script,&tempsource);
990
990
991
                    if (check_tile("copytile", tempsource, script, cmdtokptr))
991
                    if (check_tile("copytile", tempsource, script, cmdtokptr))
992
                        break;
992
                        break;
993
                    if ((tsiz = Defs_LoadTileIntoBuffer(tempsource)) <= 0)
993
                    if ((tsiz = Defs_LoadTileIntoBuffer(tempsource)) <= 0)
994
                        break;
994
                        break;
995
                    source = tempsource;
995
                    source = tempsource;
996
996
997
                    havetile = 1;
997
                    havetile = 1;
998
                    break;
998
                    break;
999
                }
999
                }
1000
                case T_PAL:
1000
                case T_PAL:
1001
                {
1001
                {
1002
                    int32_t temppal;
1002
                    int32_t temppal;
1003
                    scriptfile_getsymbol(script,&temppal);
1003
                    scriptfile_getsymbol(script,&temppal);
1004
1004
1005
                    // palettize self case
1005
                    // palettize self case
1006
                    if (!havetile)
1006
                    if (!havetile)
1007
                    {
1007
                    {
1008
                        if (check_tile("copytile", source, script, cmdtokptr))
1008
                        if (check_tile("copytile", source, script, cmdtokptr))
1009
                            break;
1009
                            break;
1010
                        if ((tsiz = Defs_LoadTileIntoBuffer(source)) <= 0)
1010
                        if ((tsiz = Defs_LoadTileIntoBuffer(source)) <= 0)
1011
                            break;
1011
                            break;
1012
                        havetile = 1;
1012
                        havetile = 1;
1013
                    }
1013
                    }
1014
1014
1015
                    if (EDUKE32_PREDICT_FALSE((unsigned)temppal >= MAXPALOOKUPS-RESERVEDPALS))
1015
                    if (EDUKE32_PREDICT_FALSE((unsigned)temppal >= MAXPALOOKUPS-RESERVEDPALS))
1016
                    {
1016
                    {
1017
                        initprintf("Error: copytile 'palette number' out of range (max=%d)\n",
1017
                        initprintf("Error: copytile 'palette number' out of range (max=%d)\n",
1018
                                   MAXPALOOKUPS-RESERVEDPALS-1);
1018
                                   MAXPALOOKUPS-RESERVEDPALS-1);
1019
                        break;
1019
                        break;
1020
                    }
1020
                    }
1021
1021
1022
                    Defs_ApplyPaletteToTileBuffer(tsiz, temppal);
1022
                    Defs_ApplyPaletteToTileBuffer(tsiz, temppal);
1023
                    break;
1023
                    break;
1024
                }
1024
                }
1025
                case T_XOFFSET:
1025
                case T_XOFFSET:
1026
                    havexoffset = 1;
1026
                    havexoffset = 1;
1027
                    scriptfile_getsymbol(script,&xoffset); break;
1027
                    scriptfile_getsymbol(script,&xoffset); break;
1028
                case T_YOFFSET:
1028
                case T_YOFFSET:
1029
                    haveyoffset = 1;
1029
                    haveyoffset = 1;
1030
                    scriptfile_getsymbol(script,&yoffset); break;
1030
                    scriptfile_getsymbol(script,&yoffset); break;
1031
                case T_TEXHITSCAN:
1031
                case T_TEXHITSCAN:
1032
                    flags |= PICANM_TEXHITSCAN_BIT;
1032
                    flags |= PICANM_TEXHITSCAN_BIT;
1033
                    break;
1033
                    break;
1034
                case T_NOFULLBRIGHT:
1034
                case T_NOFULLBRIGHT:
1035
                    flags |= PICANM_NOFULLBRIGHT_BIT;
1035
                    flags |= PICANM_NOFULLBRIGHT_BIT;
1036
                    break;
1036
                    break;
1037
                default:
1037
                default:
1038
                    break;
1038
                    break;
1039
                }
1039
                }
1040
            }
1040
            }
1041
1041
1042
            if (check_tile("copytile", tile, script, cmdtokptr))
1042
            if (check_tile("copytile", tile, script, cmdtokptr))
1043
                break;
1043
                break;
1044
1044
1045
            if (havetile)
1045
            if (havetile)
1046
            {
1046
            {
1047
                tileSetData(tile, tsiz, faketilebuffer);
1047
                tileSetData(tile, tsiz, faketilebuffer);
1048
            }
1048
            }
1049
            else // if !havetile, we have never confirmed a valid source
1049
            else // if !havetile, we have never confirmed a valid source
1050
            {
1050
            {
1051
                if (check_tile("copytile", source, script, cmdtokptr))
1051
                if (check_tile("copytile", source, script, cmdtokptr))
1052
                    break;
1052
                    break;
1053
            }
1053
            }
1054
1054
1055
            if (tsiz <= 0)
1055
            if (tsiz <= 0)
1056
            {
1056
            {
1057
                tileDelete(tile);
1057
                tileDelete(tile);
1058
                break;
1058
                break;
1059
            }
1059
            }
1060
1060
1061
            tileSetSize(tile, tilesiz[source].x, tilesiz[source].y);
1061
            tileSetSize(tile, tilesiz[source].x, tilesiz[source].y);
1062
            picanm[tile].xofs = havexoffset ? clamp(xoffset, -128, 127) : picanm[source].xofs;
1062
            picanm[tile].xofs = havexoffset ? clamp(xoffset, -128, 127) : picanm[source].xofs;
1063
            picanm[tile].yofs = haveyoffset ? clamp(yoffset, -128, 127) : picanm[source].yofs;
1063
            picanm[tile].yofs = haveyoffset ? clamp(yoffset, -128, 127) : picanm[source].yofs;
1064
            picanm[tile].sf = (picanm[tile].sf & ~PICANM_MISC_MASK) | (picanm[source].sf & PICANM_MISC_MASK) | flags;
1064
            picanm[tile].sf = (picanm[tile].sf & ~PICANM_MISC_MASK) | (picanm[source].sf & PICANM_MISC_MASK) | flags;
1065
1065
1066
        }
1066
        }
1067
        break;
1067
        break;
1068
        case T_IMPORTTILE:
1068
        case T_IMPORTTILE:
1069
        {
1069
        {
1070
            int32_t tile;
1070
            int32_t tile;
1071
            char *fn;
1071
            char *fn;
1072
1072
1073
            if (scriptfile_getsymbol(script,&tile)) break;
1073
            if (scriptfile_getsymbol(script,&tile)) break;
1074
            if (scriptfile_getstring(script,&fn))  break;
1074
            if (scriptfile_getstring(script,&fn))  break;
1075
1075
1076
            if (check_tile("importtile", tile, script, cmdtokptr))
1076
            if (check_tile("importtile", tile, script, cmdtokptr))
1077
                break;
1077
                break;
1078
1078
1079
            int32_t const texstatus = Defs_ImportTileFromTexture(fn, tile, 255, 0);
1079
            int32_t const texstatus = Defs_ImportTileFromTexture(fn, tile, 255, 0);
1080
            if (texstatus == -3)
1080
            if (texstatus == -3)
1081
                initprintf("Error: No palette loaded, in importtile definition near line %s:%d\n",
1081
                initprintf("Error: No palette loaded, in importtile definition near line %s:%d\n",
1082
                           script->filename, scriptfile_getlinum(script,cmdtokptr));
1082
                           script->filename, scriptfile_getlinum(script,cmdtokptr));
1083
            if (texstatus == -(3<<8))
1083
            if (texstatus == -(3<<8))
1084
                initprintf("Error: \"%s\" has more than one tile, in importtile definition near line %s:%d\n",
1084
                initprintf("Error: \"%s\" has more than one tile, in importtile definition near line %s:%d\n",
1085
                           fn, script->filename, scriptfile_getlinum(script,cmdtokptr));
1085
                           fn, script->filename, scriptfile_getlinum(script,cmdtokptr));
1086
            if (texstatus < 0)
1086
            if (texstatus < 0)
1087
                break;
1087
                break;
1088
1088
1089
            Bmemset(&picanm[tile], 0, sizeof(picanm_t));
1089
            Bmemset(&picanm[tile], 0, sizeof(picanm_t));
1090
1090
1091
            break;
1091
            break;
1092
        }
1092
        }
1093
        case T_DUMMYTILE:
1093
        case T_DUMMYTILE:
1094
        {
1094
        {
1095
            int32_t tile, xsiz, ysiz;
1095
            int32_t tile, xsiz, ysiz;
1096
1096
1097
            if (scriptfile_getsymbol(script,&tile)) break;
1097
            if (scriptfile_getsymbol(script,&tile)) break;
1098
            if (scriptfile_getsymbol(script,&xsiz)) break;
1098
            if (scriptfile_getsymbol(script,&xsiz)) break;
1099
            if (scriptfile_getsymbol(script,&ysiz)) break;
1099
            if (scriptfile_getsymbol(script,&ysiz)) break;
1100
1100
1101
            if (check_tile("dummytile", tile, script, cmdtokptr))
1101
            if (check_tile("dummytile", tile, script, cmdtokptr))
1102
                break;
1102
                break;
1103
1103
1104
            if ((int16_t) xsiz == 0 || (int16_t) ysiz == 0)
1104
            if ((int16_t) xsiz == 0 || (int16_t) ysiz == 0)
1105
            {
1105
            {
1106
                tileDelete(tile);
1106
                tileDelete(tile);
1107
                break;
1107
                break;
1108
            }
1108
            }
1109
1109
1110
            if (xsiz > 0 && ysiz > 0)
1110
            if (xsiz > 0 && ysiz > 0)
1111
            {
1111
            {
1112
                tileSetSize(tile, xsiz, ysiz);
1112
                tileSetSize(tile, xsiz, ysiz);
1113
                Bmemset(&picanm[tile], 0, sizeof(picanm_t));
1113
                Bmemset(&picanm[tile], 0, sizeof(picanm_t));
1114
                tileSetupDummy(tile);
1114
                tileSetupDummy(tile);
1115
            }
1115
            }
1116
1116
1117
            break;
1117
            break;
1118
        }
1118
        }
1119
        case T_DUMMYTILERANGE:
1119
        case T_DUMMYTILERANGE:
1120
        {
1120
        {
1121
            int32_t tile1,tile2,xsiz,ysiz,i;
1121
            int32_t tile1,tile2,xsiz,ysiz,i;
1122
1122
1123
            if (scriptfile_getsymbol(script,&tile1)) break;
1123
            if (scriptfile_getsymbol(script,&tile1)) break;
1124
            if (scriptfile_getsymbol(script,&tile2)) break;
1124
            if (scriptfile_getsymbol(script,&tile2)) break;
1125
            if (scriptfile_getnumber(script,&xsiz)) break;
1125
            if (scriptfile_getnumber(script,&xsiz)) break;
1126
            if (scriptfile_getnumber(script,&ysiz)) break;
1126
            if (scriptfile_getnumber(script,&ysiz)) break;
1127
1127
1128
            if (check_tile_range("dummytilerange", &tile1, &tile2, script, cmdtokptr))
1128
            if (check_tile_range("dummytilerange", &tile1, &tile2, script, cmdtokptr))
1129
                break;
1129
                break;
1130
1130
1131
            if (xsiz < 0 || ysiz < 0)
1131
            if (xsiz < 0 || ysiz < 0)
1132
                break;  // TODO: message
1132
                break;  // TODO: message
1133
1133
1134
            if ((int16_t) xsiz == 0 || (int16_t) ysiz == 0)
1134
            if ((int16_t) xsiz == 0 || (int16_t) ysiz == 0)
1135
            {
1135
            {
1136
                for (i=tile1; i<=tile2; i++)
1136
                for (i=tile1; i<=tile2; i++)
1137
                    tileDelete(i);
1137
                    tileDelete(i);
1138
                break;
1138
                break;
1139
            }
1139
            }
1140
1140
1141
            for (i=tile1; i<=tile2; i++)
1141
            for (i=tile1; i<=tile2; i++)
1142
            {
1142
            {
1143
                tileSetSize(i, xsiz, ysiz);
1143
                tileSetSize(i, xsiz, ysiz);
1144
                Bmemset(&picanm[i], 0, sizeof(picanm_t));
1144
                Bmemset(&picanm[i], 0, sizeof(picanm_t));
1145
                tileSetupDummy(i);
1145
                tileSetupDummy(i);
1146
            }
1146
            }
1147
1147
1148
            break;
1148
            break;
1149
        }
1149
        }
1150
1150
1151
        case T_UNDEFINETILE:
1151
        case T_UNDEFINETILE:
1152
        {
1152
        {
1153
            int32_t tile;
1153
            int32_t tile;
1154
1154
1155
            if (scriptfile_getsymbol(script,&tile)) break;
1155
            if (scriptfile_getsymbol(script,&tile)) break;
1156
1156
1157
            if (check_tile("undefinetile", tile, script, cmdtokptr))
1157
            if (check_tile("undefinetile", tile, script, cmdtokptr))
1158
                break;
1158
                break;
1159
1159
1160
            tileDelete(tile);
1160
            tileDelete(tile);
1161
1161
1162
            break;
1162
            break;
1163
        }
1163
        }
1164
        case T_UNDEFINETILERANGE:
1164
        case T_UNDEFINETILERANGE:
1165
        {
1165
        {
1166
            int32_t tile1, tile2;
1166
            int32_t tile1, tile2;
1167
1167
1168
            if (scriptfile_getsymbol(script,&tile1)) break;
1168
            if (scriptfile_getsymbol(script,&tile1)) break;
1169
            if (scriptfile_getsymbol(script,&tile2)) break;
1169
            if (scriptfile_getsymbol(script,&tile2)) break;
1170
1170
1171
            if (check_tile_range("undefinetilerange", &tile1, &tile2, script, cmdtokptr))
1171
            if (check_tile_range("undefinetilerange", &tile1, &tile2, script, cmdtokptr))
1172
                break;
1172
                break;
1173
1173
1174
            for (bssize_t i = tile1; i <= tile2; i++)
1174
            for (bssize_t i = tile1; i <= tile2; i++)
1175
                tileDelete(i);
1175
                tileDelete(i);
1176
1176
1177
            break;
1177
            break;
1178
        }
1178
        }
1179
1179
1180
        case T_DEFINEMODEL:
1180
        case T_DEFINEMODEL:
1181
        {
1181
        {
1182
            char *modelfn;
1182
            char *modelfn;
1183
            double scale;
1183
            double scale;
1184
            int32_t shadeoffs;
1184
            int32_t shadeoffs;
1185
1185
1186
            if (scriptfile_getstring(script,&modelfn)) break;
1186
            if (scriptfile_getstring(script,&modelfn)) break;
1187
            if (scriptfile_getdouble(script,&scale)) break;
1187
            if (scriptfile_getdouble(script,&scale)) break;
1188
            if (scriptfile_getnumber(script,&shadeoffs)) break;
1188
            if (scriptfile_getnumber(script,&shadeoffs)) break;
1189
1189
1190
#ifdef USE_OPENGL
1190
#ifdef USE_OPENGL
1191
            lastmodelid = md_loadmodel(modelfn);
1191
            lastmodelid = md_loadmodel(modelfn);
1192
            if (EDUKE32_PREDICT_FALSE(lastmodelid < 0))
1192
            if (EDUKE32_PREDICT_FALSE(lastmodelid < 0))
1193
            {
1193
            {
1194
                initprintf("Warning: Failed loading MD2/MD3 model \"%s\"\n", modelfn);
1194
                initprintf("Warning: Failed loading MD2/MD3 model \"%s\"\n", modelfn);
1195
                break;
1195
                break;
1196
            }
1196
            }
1197
            md_setmisc(lastmodelid,(float)scale, shadeoffs,0.0,0.0,0);
1197
            md_setmisc(lastmodelid,(float)scale, shadeoffs,0.0,0.0,0);
1198
# ifdef POLYMER
1198
# ifdef POLYMER
1199
            if (glrendmode == REND_POLYMER)
1199
            if (glrendmode == REND_POLYMER)
1200
                md3postload_polymer((md3model_t *)models[lastmodelid]);
1200
                md3postload_polymer((md3model_t *)models[lastmodelid]);
1201
# endif
1201
# endif
1202
#endif
1202
#endif
1203
            modelskin = lastmodelskin = 0;
1203
            modelskin = lastmodelskin = 0;
1204
            seenframe = 0;
1204
            seenframe = 0;
1205
        }
1205
        }
1206
        break;
1206
        break;
1207
        case T_DEFINEMODELFRAME:
1207
        case T_DEFINEMODELFRAME:
1208
        {
1208
        {
1209
            char *framename;
1209
            char *framename;
1210
#ifdef USE_OPENGL
1210
#ifdef USE_OPENGL
1211
            char happy=1;
1211
            char happy=1;
1212
            int32_t tilex;
1212
            int32_t tilex;
1213
#endif
1213
#endif
1214
            int32_t ftilenume, ltilenume;
1214
            int32_t ftilenume, ltilenume;
1215
1215
1216
            if (scriptfile_getstring(script,&framename)) break;
1216
            if (scriptfile_getstring(script,&framename)) break;
1217
            if (scriptfile_getsymbol(script,&ftilenume)) break; //first tile number
1217
            if (scriptfile_getsymbol(script,&ftilenume)) break; //first tile number
1218
            if (scriptfile_getsymbol(script,&ltilenume)) break; //last tile number (inclusive)
1218
            if (scriptfile_getsymbol(script,&ltilenume)) break; //last tile number (inclusive)
1219
1219
1220
            if (check_tile_range("definemodelframe", &ftilenume, &ltilenume, script, cmdtokptr))
1220
            if (check_tile_range("definemodelframe", &ftilenume, &ltilenume, script, cmdtokptr))
1221
                break;
1221
                break;
1222
1222
1223
            if (EDUKE32_PREDICT_FALSE(lastmodelid < 0))
1223
            if (EDUKE32_PREDICT_FALSE(lastmodelid < 0))
1224
            {
1224
            {
1225
#ifdef USE_OPENGL
1225
#ifdef USE_OPENGL
1226
                initprintf("Warning: Ignoring frame definition.\n");
1226
                initprintf("Warning: Ignoring frame definition.\n");
1227
#endif
1227
#endif
1228
                break;
1228
                break;
1229
            }
1229
            }
1230
#ifdef USE_OPENGL
1230
#ifdef USE_OPENGL
1231
            for (tilex = ftilenume; tilex <= ltilenume && happy; tilex++)
1231
            for (tilex = ftilenume; tilex <= ltilenume && happy; tilex++)
1232
            {
1232
            {
1233
                switch (md_defineframe(lastmodelid, framename, tilex, max(0,modelskin), 0.0f,0))
1233
                switch (md_defineframe(lastmodelid, framename, tilex, max(0,modelskin), 0.0f,0))
1234
                {
1234
                {
1235
                case -1:
1235
                case -1:
1236
                    happy = 0; break; // invalid model id!?
1236
                    happy = 0; break; // invalid model id!?
1237
                case -2:
1237
                case -2:
1238
                    initprintf("Invalid tile number on line %s:%d\n",
1238
                    initprintf("Invalid tile number on line %s:%d\n",
1239
                               script->filename, scriptfile_getlinum(script,cmdtokptr));
1239
                               script->filename, scriptfile_getlinum(script,cmdtokptr));
1240
                    happy = 0;
1240
                    happy = 0;
1241
                    break;
1241
                    break;
1242
                case -3:
1242
                case -3:
1243
                    initprintf("Invalid frame name on line %s:%d\n",
1243
                    initprintf("Invalid frame name on line %s:%d\n",
1244
                               script->filename, scriptfile_getlinum(script,cmdtokptr));
1244
                               script->filename, scriptfile_getlinum(script,cmdtokptr));
1245
                    happy = 0;
1245
                    happy = 0;
1246
                    break;
1246
                    break;
1247
                default:
1247
                default:
1248
                    break;
1248
                    break;
1249
                }
1249
                }
1250
            }
1250
            }
1251
#endif
1251
#endif
1252
            seenframe = 1;
1252
            seenframe = 1;
1253
        }
1253
        }
1254
        break;
1254
        break;
1255
        case T_DEFINEMODELANIM:
1255
        case T_DEFINEMODELANIM:
1256
        {
1256
        {
1257
            char *startframe, *endframe;
1257
            char *startframe, *endframe;
1258
            int32_t flags;
1258
            int32_t flags;
1259
            double dfps;
1259
            double dfps;
1260
1260
1261
            if (scriptfile_getstring(script,&startframe)) break;
1261
            if (scriptfile_getstring(script,&startframe)) break;
1262
            if (scriptfile_getstring(script,&endframe)) break;
1262
            if (scriptfile_getstring(script,&endframe)) break;
1263
            if (scriptfile_getdouble(script,&dfps)) break; //animation frame rate
1263
            if (scriptfile_getdouble(script,&dfps)) break; //animation frame rate
1264
            if (scriptfile_getnumber(script,&flags)) break;
1264
            if (scriptfile_getnumber(script,&flags)) break;
1265
1265
1266
            if (EDUKE32_PREDICT_FALSE(lastmodelid < 0))
1266
            if (EDUKE32_PREDICT_FALSE(lastmodelid < 0))
1267
            {
1267
            {
1268
#ifdef USE_OPENGL
1268
#ifdef USE_OPENGL
1269
                initprintf("Warning: Ignoring animation definition.\n");
1269
                initprintf("Warning: Ignoring animation definition.\n");
1270
#endif
1270
#endif
1271
                break;
1271
                break;
1272
            }
1272
            }
1273
#ifdef USE_OPENGL
1273
#ifdef USE_OPENGL
1274
            switch (md_defineanimation(lastmodelid, startframe, endframe, (int32_t)(dfps*(65536.0*.001)), flags))
1274
            switch (md_defineanimation(lastmodelid, startframe, endframe, (int32_t)(dfps*(65536.0*.001)), flags))
1275
            {
1275
            {
1276
            case 0:
1276
            case 0:
1277
                break;
1277
                break;
1278
            case -1:
1278
            case -1:
1279
                break; // invalid model id!?
1279
                break; // invalid model id!?
1280
            case -2:
1280
            case -2:
1281
                initprintf("Invalid starting frame name on line %s:%d\n",
1281
                initprintf("Invalid starting frame name on line %s:%d\n",
1282
                           script->filename, scriptfile_getlinum(script,cmdtokptr));
1282
                           script->filename, scriptfile_getlinum(script,cmdtokptr));
1283
                break;
1283
                break;
1284
            case -3:
1284
            case -3:
1285
                initprintf("Invalid ending frame name on line %s:%d\n",
1285
                initprintf("Invalid ending frame name on line %s:%d\n",
1286
                           script->filename, scriptfile_getlinum(script,cmdtokptr));
1286
                           script->filename, scriptfile_getlinum(script,cmdtokptr));
1287
                break;
1287
                break;
1288
            case -4:
1288
            case -4:
1289
                initprintf("Out of memory on line %s:%d\n",
1289
                initprintf("Out of memory on line %s:%d\n",
1290
                           script->filename, scriptfile_getlinum(script,cmdtokptr));
1290
                           script->filename, scriptfile_getlinum(script,cmdtokptr));
1291
                break;
1291
                break;
1292
            }
1292
            }
1293
#endif
1293
#endif
1294
        }
1294
        }
1295
        break;
1295
        break;
1296
        case T_DEFINEMODELSKIN:
1296
        case T_DEFINEMODELSKIN:
1297
        {
1297
        {
1298
            int32_t palnum;
1298
            int32_t palnum;
1299
            char *skinfn;
1299
            char *skinfn;
1300
1300
1301
            if (scriptfile_getsymbol(script,&palnum)) break;
1301
            if (scriptfile_getsymbol(script,&palnum)) break;
1302
            if (scriptfile_getstring(script,&skinfn)) break; //skin filename
1302
            if (scriptfile_getstring(script,&skinfn)) break; //skin filename
1303
1303
1304
            // if we see a sequence of definemodelskin, then a sequence of definemodelframe,
1304
            // if we see a sequence of definemodelskin, then a sequence of definemodelframe,
1305
            // and then a definemodelskin, we need to increment the skin counter.
1305
            // and then a definemodelskin, we need to increment the skin counter.
1306
            //
1306
            //
1307
            // definemodel "mymodel.md2" 1 1
1307
            // definemodel "mymodel.md2" 1 1
1308
            // definemodelskin 0 "normal.png"   // skin 0
1308
            // definemodelskin 0 "normal.png"   // skin 0
1309
            // definemodelskin 21 "normal21.png"
1309
            // definemodelskin 21 "normal21.png"
1310
            // definemodelframe "foo" 1000 1002   // these use skin 0
1310
            // definemodelframe "foo" 1000 1002   // these use skin 0
1311
            // definemodelskin 0 "wounded.png"   // skin 1
1311
            // definemodelskin 0 "wounded.png"   // skin 1
1312
            // definemodelskin 21 "wounded21.png"
1312
            // definemodelskin 21 "wounded21.png"
1313
            // definemodelframe "foo2" 1003 1004   // these use skin 1
1313
            // definemodelframe "foo2" 1003 1004   // these use skin 1
1314
            // selectmodelskin 0         // resets to skin 0
1314
            // selectmodelskin 0         // resets to skin 0
1315
            // definemodelframe "foo3" 1005 1006   // these use skin 0
1315
            // definemodelframe "foo3" 1005 1006   // these use skin 0
1316
            if (seenframe) { modelskin = ++lastmodelskin; }
1316
            if (seenframe) { modelskin = ++lastmodelskin; }
1317
            seenframe = 0;
1317
            seenframe = 0;
1318
1318
1319
            if (check_file_exist(skinfn))
1319
            if (check_file_exist(skinfn))
1320
                break;
1320
                break;
1321
1321
1322
#ifdef USE_OPENGL
1322
#ifdef USE_OPENGL
1323
            switch (md_defineskin(lastmodelid, skinfn, palnum, max(0,modelskin), 0, 0.0f, 1.0f, 1.0f, 0))
1323
            switch (md_defineskin(lastmodelid, skinfn, palnum, max(0,modelskin), 0, 0.0f, 1.0f, 1.0f, 0))
1324
            {
1324
            {
1325
            case 0:
1325
            case 0:
1326
                break;
1326
                break;
1327
            case -1:
1327
            case -1:
1328
                break; // invalid model id!?
1328
                break; // invalid model id!?
1329
            case -2:
1329
            case -2:
1330
                initprintf("Invalid skin filename on line %s:%d\n",
1330
                initprintf("Invalid skin filename on line %s:%d\n",
1331
                           script->filename, scriptfile_getlinum(script,cmdtokptr));
1331
                           script->filename, scriptfile_getlinum(script,cmdtokptr));
1332
                break;
1332
                break;
1333
            case -3:
1333
            case -3:
1334
                initprintf("Invalid palette number on line %s:%d\n",
1334
                initprintf("Invalid palette number on line %s:%d\n",
1335
                           script->filename, scriptfile_getlinum(script,cmdtokptr));
1335
                           script->filename, scriptfile_getlinum(script,cmdtokptr));
1336
                break;
1336
                break;
1337
            case -4:
1337
            case -4:
1338
                initprintf("Out of memory on line %s:%d\n",
1338
                initprintf("Out of memory on line %s:%d\n",
1339
                           script->filename, scriptfile_getlinum(script,cmdtokptr));
1339
                           script->filename, scriptfile_getlinum(script,cmdtokptr));
1340
                break;
1340
                break;
1341
            }
1341
            }
1342
#endif
1342
#endif
1343
        }
1343
        }
1344
        break;
1344
        break;
1345
        case T_SELECTMODELSKIN:
1345
        case T_SELECTMODELSKIN:
1346
        {
1346
        {
1347
            if (scriptfile_getsymbol(script,&modelskin)) break;
1347
            if (scriptfile_getsymbol(script,&modelskin)) break;
1348
        }
1348
        }
1349
        break;
1349
        break;
1350
        case T_DEFINEVOXEL:
1350
        case T_DEFINEVOXEL:
1351
        {
1351
        {
1352
            char *fn;
1352
            char *fn;
1353
1353
1354
            if (EDUKE32_PREDICT_FALSE(scriptfile_getstring(script,&fn)))
1354
            if (EDUKE32_PREDICT_FALSE(scriptfile_getstring(script,&fn)))
1355
                break; //voxel filename
1355
                break; //voxel filename
1356
1356
1357
            if (EDUKE32_PREDICT_FALSE(nextvoxid == MAXVOXELS))
1357
            if (EDUKE32_PREDICT_FALSE(nextvoxid == MAXVOXELS))
1358
            {
1358
            {
1359
                initprintf("Maximum number of voxels (%d) already defined.\n", MAXVOXELS);
1359
                initprintf("Maximum number of voxels (%d) already defined.\n", MAXVOXELS);
1360
                break;
1360
                break;
1361
            }
1361
            }
1362
1362
1363
            if (EDUKE32_PREDICT_FALSE(qloadkvx(nextvoxid, fn)))
1363
            if (EDUKE32_PREDICT_FALSE(qloadkvx(nextvoxid, fn)))
1364
            {
1364
            {
1365
                initprintf("Failure loading voxel file \"%s\"\n",fn);
1365
                initprintf("Failure loading voxel file \"%s\"\n",fn);
1366
                break;
1366
                break;
1367
            }
1367
            }
1368
1368
1369
            lastvoxid = nextvoxid++;
1369
            lastvoxid = nextvoxid++;
1370
        }
1370
        }
1371
        break;
1371
        break;
1372
        case T_DEFINEVOXELTILES:
1372
        case T_DEFINEVOXELTILES:
1373
        {
1373
        {
1374
            int32_t ftilenume, ltilenume, tilex;
1374
            int32_t ftilenume, ltilenume, tilex;
1375
1375
1376
            if (scriptfile_getsymbol(script,&ftilenume)) break; //1st tile #
1376
            if (scriptfile_getsymbol(script,&ftilenume)) break; //1st tile #
1377
            if (scriptfile_getsymbol(script,&ltilenume)) break; //last tile #
1377
            if (scriptfile_getsymbol(script,&ltilenume)) break; //last tile #
1378
1378
1379
            if (check_tile_range("definevoxeltiles", &ftilenume, &ltilenume, script, cmdtokptr))
1379
            if (check_tile_range("definevoxeltiles", &ftilenume, &ltilenume, script, cmdtokptr))
1380
                break;
1380
                break;
1381
1381
1382
            if (EDUKE32_PREDICT_FALSE(lastvoxid < 0))
1382
            if (EDUKE32_PREDICT_FALSE(lastvoxid < 0))
1383
            {
1383
            {
1384
                initprintf("Warning: Ignoring voxel tiles definition.\n");
1384
                initprintf("Warning: Ignoring voxel tiles definition.\n");
1385
                break;
1385
                break;
1386
            }
1386
            }
1387
1387
1388
            for (tilex = ftilenume; tilex <= ltilenume; tilex++)
1388
            for (tilex = ftilenume; tilex <= ltilenume; tilex++)
1389
                tiletovox[tilex] = lastvoxid;
1389
                tiletovox[tilex] = lastvoxid;
1390
        }
1390
        }
1391
        break;
1391
        break;
1392
1392
1393
        // NEW (ENCOURAGED) DEFINITION SYNTAX
1393
        // NEW (ENCOURAGED) DEFINITION SYNTAX
1394
        case T_MODEL:
1394
        case T_MODEL:
1395
        {
1395
        {
1396
            char *modelend, *modelfn;
1396
            char *modelend, *modelfn;
1397
            double scale=1.0, mzadd=0.0, myoffset=0.0;
1397
            double scale=1.0, mzadd=0.0, myoffset=0.0;
1398
            int32_t shadeoffs=0, pal=0, flags=0;
1398
            int32_t shadeoffs=0, pal=0, flags=0;
1399
            uint8_t usedframebitmap[(1024+7)>>3];
1399
            uint8_t usedframebitmap[(1024+7)>>3];
1400
1400
1401
            int32_t model_ok = 1;
1401
            int32_t model_ok = 1;
1402
1402
1403
            static const tokenlist modeltokens[] =
1403
            static const tokenlist modeltokens[] =
1404
            {
1404
            {
1405
                { "scale",    T_SCALE    },
1405
                { "scale",    T_SCALE    },
1406
                { "shade",    T_SHADE    },
1406
                { "shade",    T_SHADE    },
1407
                { "zadd",     T_ZADD     },
1407
                { "zadd",     T_ZADD     },
1408
                { "yoffset",  T_YOFFSET  },
1408
                { "yoffset",  T_YOFFSET  },
1409
                { "frame",    T_FRAME    },
1409
                { "frame",    T_FRAME    },
1410
                { "anim",     T_ANIM     },
1410
                { "anim",     T_ANIM     },
1411
                { "skin",     T_SKIN     },
1411
                { "skin",     T_SKIN     },
1412
                { "detail",   T_DETAIL   },
1412
                { "detail",   T_DETAIL   },
1413
                { "glow",     T_GLOW     },
1413
                { "glow",     T_GLOW     },
1414
                { "specular", T_SPECULAR },
1414
                { "specular", T_SPECULAR },
1415
                { "normal",   T_NORMAL   },
1415
                { "normal",   T_NORMAL   },
1416
                { "hud",      T_HUD      },
1416
                { "hud",      T_HUD      },
1417
                { "flags",    T_FLAGS    },
1417
                { "flags",    T_FLAGS    },
1418
            };
1418
            };
1419
1419
1420
            Bmemset(usedframebitmap, 0, sizeof(usedframebitmap));
1420
            Bmemset(usedframebitmap, 0, sizeof(usedframebitmap));
1421
1421
1422
            modelskin = lastmodelskin = 0;
1422
            modelskin = lastmodelskin = 0;
1423
            seenframe = 0;
1423
            seenframe = 0;
1424
1424
1425
            if (scriptfile_getstring(script,&modelfn)) break;
1425
            if (scriptfile_getstring(script,&modelfn)) break;
1426
            if (scriptfile_getbraces(script,&modelend)) break;
1426
            if (scriptfile_getbraces(script,&modelend)) break;
1427
#ifdef USE_OPENGL
1427
#ifdef USE_OPENGL
1428
            lastmodelid = md_loadmodel(modelfn);
1428
            lastmodelid = md_loadmodel(modelfn);
1429
            if (EDUKE32_PREDICT_FALSE(lastmodelid < 0))
1429
            if (EDUKE32_PREDICT_FALSE(lastmodelid < 0))
1430
            {
1430
            {
1431
                initprintf("Warning: Failed loading MD2/MD3 model \"%s\"\n", modelfn);
1431
                initprintf("Warning: Failed loading MD2/MD3 model \"%s\"\n", modelfn);
1432
                script->textptr = modelend+1;
1432
                script->textptr = modelend+1;
1433
                break;
1433
                break;
1434
            }
1434
            }
1435
#endif
1435
#endif
1436
            while (script->textptr < modelend)
1436
            while (script->textptr < modelend)
1437
            {
1437
            {
1438
                int32_t token = getatoken(script,modeltokens,ARRAY_SIZE(modeltokens));
1438
                int32_t token = getatoken(script,modeltokens,ARRAY_SIZE(modeltokens));
1439
                switch (token)
1439
                switch (token)
1440
                {
1440
                {
1441
                    //case T_ERROR: initprintf("Error on line %s:%d in model tokens\n", script->filename,script->linenum); break;
1441
                    //case T_ERROR: initprintf("Error on line %s:%d in model tokens\n", script->filename,script->linenum); break;
1442
                case T_SCALE:
1442
                case T_SCALE:
1443
                    scriptfile_getdouble(script,&scale); break;
1443
                    scriptfile_getdouble(script,&scale); break;
1444
                case T_SHADE:
1444
                case T_SHADE:
1445
                    scriptfile_getnumber(script,&shadeoffs); break;
1445
                    scriptfile_getnumber(script,&shadeoffs); break;
1446
                case T_ZADD:
1446
                case T_ZADD:
1447
                    scriptfile_getdouble(script,&mzadd); break;
1447
                    scriptfile_getdouble(script,&mzadd); break;
1448
                case T_YOFFSET:
1448
                case T_YOFFSET:
1449
                    scriptfile_getdouble(script,&myoffset); break;
1449
                    scriptfile_getdouble(script,&myoffset); break;
1450
                case T_FLAGS:
1450
                case T_FLAGS:
1451
                    scriptfile_getnumber(script,&flags); break;
1451
                    scriptfile_getnumber(script,&flags); break;
1452
                case T_FRAME:
1452
                case T_FRAME:
1453
                {
1453
                {
1454
                    char *frametokptr = script->ltextptr;
1454
                    char *frametokptr = script->ltextptr;
1455
                    char *frameend, *framename = 0;
1455
                    char *frameend, *framename = 0;
1456
#ifdef USE_OPENGL
1456
#ifdef USE_OPENGL
1457
                    char happy=1;
1457
                    char happy=1;
1458
                    int32_t tilex = 0, framei;
1458
                    int32_t tilex = 0, framei;
1459
#endif
1459
#endif
1460
                    int32_t ftilenume = -1, ltilenume = -1;
1460
                    int32_t ftilenume = -1, ltilenume = -1;
1461
                    double smoothduration = 0.1f;
1461
                    double smoothduration = 0.1f;
1462
1462
1463
                    static const tokenlist modelframetokens[] =
1463
                    static const tokenlist modelframetokens[] =
1464
                    {
1464
                    {
1465
                        { "pal",              T_PAL               },
1465
                        { "pal",              T_PAL               },
1466
                        { "frame",            T_FRAME             },
1466
                        { "frame",            T_FRAME             },
1467
                        { "name",             T_FRAME             },
1467
                        { "name",             T_FRAME             },
1468
                        { "tile",             T_TILE              },
1468
                        { "tile",             T_TILE              },
1469
                        { "tile0",            T_TILE0             },
1469
                        { "tile0",            T_TILE0             },
1470
                        { "tile1",            T_TILE1             },
1470
                        { "tile1",            T_TILE1             },
1471
                        { "smoothduration",   T_SMOOTHDURATION    },
1471
                        { "smoothduration",   T_SMOOTHDURATION    },
1472
                    };
1472
                    };
1473
1473
1474
                    if (scriptfile_getbraces(script,&frameend)) break;
1474
                    if (scriptfile_getbraces(script,&frameend)) break;
1475
                    while (script->textptr < frameend)
1475
                    while (script->textptr < frameend)
1476
                    {
1476
                    {
1477
                        switch (getatoken(script,modelframetokens,ARRAY_SIZE(modelframetokens)))
1477
                        switch (getatoken(script,modelframetokens,ARRAY_SIZE(modelframetokens)))
1478
                        {
1478
                        {
1479
                        case T_PAL:
1479
                        case T_PAL:
1480
                            scriptfile_getsymbol(script,&pal); break;
1480
                            scriptfile_getsymbol(script,&pal); break;
1481
                        case T_FRAME:
1481
                        case T_FRAME:
1482
                            scriptfile_getstring(script,&framename); break;
1482
                            scriptfile_getstring(script,&framename); break;
1483
                        case T_TILE:
1483
                        case T_TILE:
1484
                            scriptfile_getsymbol(script,&ftilenume); ltilenume = ftilenume; break;
1484
                            scriptfile_getsymbol(script,&ftilenume); ltilenume = ftilenume; break;
1485
                        case T_TILE0:
1485
                        case T_TILE0:
1486
                            scriptfile_getsymbol(script,&ftilenume); break; //first tile number
1486
                            scriptfile_getsymbol(script,&ftilenume); break; //first tile number
1487
                        case T_TILE1:
1487
                        case T_TILE1:
1488
                            scriptfile_getsymbol(script,&ltilenume); break; //last tile number (inclusive)
1488
                            scriptfile_getsymbol(script,&ltilenume); break; //last tile number (inclusive)
1489
                        case T_SMOOTHDURATION:
1489
                        case T_SMOOTHDURATION:
1490
                            scriptfile_getdouble(script,&smoothduration); break;
1490
                            scriptfile_getdouble(script,&smoothduration); break;
1491
                        }
1491
                        }
1492
                    }
1492
                    }
1493
1493
1494
                    if (check_tile_range("model: frame", &ftilenume, &ltilenume, script, frametokptr))
1494
                    if (check_tile_range("model: frame", &ftilenume, &ltilenume, script, frametokptr))
1495
                    {
1495
                    {
1496
                        model_ok = 0;
1496
                        model_ok = 0;
1497
                        break;
1497
                        break;
1498
                    }
1498
                    }
1499
1499
1500
                    if (EDUKE32_PREDICT_FALSE(lastmodelid < 0))
1500
                    if (EDUKE32_PREDICT_FALSE(lastmodelid < 0))
1501
                    {
1501
                    {
1502
#ifdef USE_OPENGL
1502
#ifdef USE_OPENGL
1503
                        initprintf("Warning: ignoring frame definition on line %s:%d.\n",
1503
                        initprintf("Warning: ignoring frame definition on line %s:%d.\n",
1504
                                   script->filename, scriptfile_getlinum(script,frametokptr));
1504
                                   script->filename, scriptfile_getlinum(script,frametokptr));
1505
#endif
1505
#endif
1506
                        break;
1506
                        break;
1507
                    }
1507
                    }
1508
1508
1509
                    if (smoothduration > 1.0)
1509
                    if (smoothduration > 1.0)
1510
                    {
1510
                    {
1511
                        initprintf("Warning: smoothduration out of range on line %s:%d.\n",
1511
                        initprintf("Warning: smoothduration out of range on line %s:%d.\n",
1512
                                   script->filename, scriptfile_getlinum(script,frametokptr));
1512
                                   script->filename, scriptfile_getlinum(script,frametokptr));
1513
                        smoothduration = 1.0;
1513
                        smoothduration = 1.0;
1514
                    }
1514
                    }
1515
#ifdef USE_OPENGL
1515
#ifdef USE_OPENGL
1516
                    for (tilex = ftilenume; tilex <= ltilenume && happy; tilex++)
1516
                    for (tilex = ftilenume; tilex <= ltilenume && happy; tilex++)
1517
                    {
1517
                    {
1518
                        framei = md_defineframe(lastmodelid, framename, tilex, max(0,modelskin), smoothduration,pal);
1518
                        framei = md_defineframe(lastmodelid, framename, tilex, max(0,modelskin), smoothduration,pal);
1519
                        switch (framei)
1519
                        switch (framei)
1520
                        {
1520
                        {
1521
                        case -1:
1521
                        case -1:
1522
                            happy = 0; break; // invalid model id!?
1522
                            happy = 0; break; // invalid model id!?
1523
                        case -2:
1523
                        case -2:
1524
                            initprintf("Invalid tile number on line %s:%d\n",
1524
                            initprintf("Invalid tile number on line %s:%d\n",
1525
                                       script->filename, scriptfile_getlinum(script,frametokptr));
1525
                                       script->filename, scriptfile_getlinum(script,frametokptr));
1526
                            happy = 0;
1526
                            happy = 0;
1527
                            break;
1527
                            break;
1528
                        case -3:
1528
                        case -3:
1529
                            initprintf("Invalid frame name on line %s:%d\n",
1529
                            initprintf("Invalid frame name on line %s:%d\n",
1530
                                       script->filename, scriptfile_getlinum(script,frametokptr));
1530
                                       script->filename, scriptfile_getlinum(script,frametokptr));
1531
                            happy = 0;
1531
                            happy = 0;
1532
                            break;
1532
                            break;
1533
                        default:
1533
                        default:
1534
                            if (framei >= 0 && framei<1024)
1534
                            if (framei >= 0 && framei<1024)
1535
                                usedframebitmap[framei>>3] |= pow2char[framei&7];
1535
                                usedframebitmap[framei>>3] |= pow2char[framei&7];
1536
                        }
1536
                        }
1537
1537
1538
                        model_ok &= happy;
1538
                        model_ok &= happy;
1539
                    }
1539
                    }
1540
#endif
1540
#endif
1541
                    seenframe = 1;
1541
                    seenframe = 1;
1542
                }
1542
                }
1543
                break;
1543
                break;
1544
                case T_ANIM:
1544
                case T_ANIM:
1545
                {
1545
                {
1546
                    char *animtokptr = script->ltextptr;
1546
                    char *animtokptr = script->ltextptr;
1547
                    char *animend, *startframe = 0, *endframe = 0, happy=1;
1547
                    char *animend, *startframe = 0, *endframe = 0, happy=1;
1548
                    int32_t flags = 0;
1548
                    int32_t flags = 0;
1549
                    double dfps = 1.0;
1549
                    double dfps = 1.0;
1550
1550
1551
                    static const tokenlist modelanimtokens[] =
1551
                    static const tokenlist modelanimtokens[] =
1552
                    {
1552
                    {
1553
                        { "frame0", T_FRAME0 },
1553
                        { "frame0", T_FRAME0 },
1554
                        { "frame1", T_FRAME1 },
1554
                        { "frame1", T_FRAME1 },
1555
                        { "fps",    T_FPS    },
1555
                        { "fps",    T_FPS    },
1556
                        { "flags",  T_FLAGS  },
1556
                        { "flags",  T_FLAGS  },
1557
                    };
1557
                    };
1558
1558
1559
                    if (scriptfile_getbraces(script,&animend)) break;
1559
                    if (scriptfile_getbraces(script,&animend)) break;
1560
                    while (script->textptr < animend)
1560
                    while (script->textptr < animend)
1561
                    {
1561
                    {
1562
                        switch (getatoken(script,modelanimtokens,ARRAY_SIZE(modelanimtokens)))
1562
                        switch (getatoken(script,modelanimtokens,ARRAY_SIZE(modelanimtokens)))
1563
                        {
1563
                        {
1564
                        case T_FRAME0:
1564
                        case T_FRAME0:
1565
                            scriptfile_getstring(script,&startframe); break;
1565
                            scriptfile_getstring(script,&startframe); break;
1566
                        case T_FRAME1:
1566
                        case T_FRAME1:
1567
                            scriptfile_getstring(script,&endframe); break;
1567
                            scriptfile_getstring(script,&endframe); break;
1568
                        case T_FPS:
1568
                        case T_FPS:
1569
                            scriptfile_getdouble(script,&dfps); break; //animation frame rate
1569
                            scriptfile_getdouble(script,&dfps); break; //animation frame rate
1570
                        case T_FLAGS:
1570
                        case T_FLAGS:
1571
                            scriptfile_getsymbol(script,&flags); break;
1571
                            scriptfile_getsymbol(script,&flags); break;
1572
                        }
1572
                        }
1573
                    }
1573
                    }
1574
1574
1575
                    if (EDUKE32_PREDICT_FALSE(!startframe)) initprintf("Error: missing 'start frame' for anim definition near line %s:%d\n", script->filename, scriptfile_getlinum(script,animtokptr)), happy = 0;
1575
                    if (EDUKE32_PREDICT_FALSE(!startframe)) initprintf("Error: missing 'start frame' for anim definition near line %s:%d\n", script->filename, scriptfile_getlinum(script,animtokptr)), happy = 0;
1576
                    if (EDUKE32_PREDICT_FALSE(!endframe)) initprintf("Error: missing 'end frame' for anim definition near line %s:%d\n", script->filename, scriptfile_getlinum(script,animtokptr)), happy = 0;
1576
                    if (EDUKE32_PREDICT_FALSE(!endframe)) initprintf("Error: missing 'end frame' for anim definition near line %s:%d\n", script->filename, scriptfile_getlinum(script,animtokptr)), happy = 0;
1577
                    model_ok &= happy;
1577
                    model_ok &= happy;
1578
                    if (EDUKE32_PREDICT_FALSE(!happy)) break;
1578
                    if (EDUKE32_PREDICT_FALSE(!happy)) break;
1579
1579
1580
                    if (EDUKE32_PREDICT_FALSE(lastmodelid < 0))
1580
                    if (EDUKE32_PREDICT_FALSE(lastmodelid < 0))
1581
                    {
1581
                    {
1582
#ifdef USE_OPENGL
1582
#ifdef USE_OPENGL
1583
                        initprintf("Warning: Ignoring animation definition.\n");
1583
                        initprintf("Warning: Ignoring animation definition.\n");
1584
#endif
1584
#endif
1585
                        break;
1585
                        break;
1586
                    }
1586
                    }
1587
#ifdef USE_OPENGL
1587
#ifdef USE_OPENGL
1588
                    switch (md_defineanimation(lastmodelid, startframe, endframe, (int32_t)(dfps*(65536.0*.001)), flags))
1588
                    switch (md_defineanimation(lastmodelid, startframe, endframe, (int32_t)(dfps*(65536.0*.001)), flags))
1589
                    {
1589
                    {
1590
                    case 0:
1590
                    case 0:
1591
                        break;
1591
                        break;
1592
                    case -1:
1592
                    case -1:
1593
                        break; // invalid model id!?
1593
                        break; // invalid model id!?
1594
                    case -2:
1594
                    case -2:
1595
                        initprintf("Invalid starting frame name on line %s:%d\n",
1595
                        initprintf("Invalid starting frame name on line %s:%d\n",
1596
                                   script->filename, scriptfile_getlinum(script,animtokptr));
1596
                                   script->filename, scriptfile_getlinum(script,animtokptr));
1597
                        model_ok = 0;
1597
                        model_ok = 0;
1598
                        break;
1598
                        break;
1599
                    case -3:
1599
                    case -3:
1600
                        initprintf("Invalid ending frame name on line %s:%d\n",
1600
                        initprintf("Invalid ending frame name on line %s:%d\n",
1601
                                   script->filename, scriptfile_getlinum(script,animtokptr));
1601
                                   script->filename, scriptfile_getlinum(script,animtokptr));
1602
                        model_ok = 0;
1602
                        model_ok = 0;
1603
                        break;
1603
                        break;
1604
                    case -4:
1604
                    case -4:
1605
                        initprintf("Out of memory on line %s:%d\n",
1605
                        initprintf("Out of memory on line %s:%d\n",
1606
                                   script->filename, scriptfile_getlinum(script,animtokptr));
1606
                                   script->filename, scriptfile_getlinum(script,animtokptr));
1607
                        model_ok = 0;
1607
                        model_ok = 0;
1608
                        break;
1608
                        break;
1609
                    }
1609
                    }
1610
#endif
1610
#endif
1611
                }
1611
                }
1612
                break;
1612
                break;
1613
                case T_SKIN: case T_DETAIL: case T_GLOW: case T_SPECULAR: case T_NORMAL:
1613
                case T_SKIN: case T_DETAIL: case T_GLOW: case T_SPECULAR: case T_NORMAL:
1614
                {
1614
                {
1615
                    char *skintokptr = script->ltextptr;
1615
                    char *skintokptr = script->ltextptr;
1616
                    char *skinend, *skinfn = 0;
1616
                    char *skinend, *skinfn = 0;
1617
                    int32_t palnum = 0, surfnum = 0;
1617
                    int32_t palnum = 0, surfnum = 0;
1618
                    double param = 1.0, specpower = 1.0, specfactor = 1.0;
1618
                    double param = 1.0, specpower = 1.0, specfactor = 1.0;
1619
#ifdef USE_OPENGL
1619
#ifdef USE_OPENGL
1620
                    int32_t flags = 0;
1620
                    int32_t flags = 0;
1621
#endif
1621
#endif
1622
1622
1623
                    static const tokenlist modelskintokens[] =
1623
                    static const tokenlist modelskintokens[] =
1624
                    {
1624
                    {
1625
                        { "pal",           T_PAL        },
1625
                        { "pal",           T_PAL        },
1626
                        { "file",          T_FILE       },
1626
                        { "file",          T_FILE       },
1627
                        { "surf",          T_SURF       },
1627
                        { "surf",          T_SURF       },
1628
                        { "surface",       T_SURF       },
1628
                        { "surface",       T_SURF       },
1629
                        { "intensity",     T_PARAM      },
1629
                        { "intensity",     T_PARAM      },
1630
                        { "scale",         T_PARAM      },
1630
                        { "scale",         T_PARAM      },
1631
                        { "detailscale",   T_PARAM      },
1631
                        { "detailscale",   T_PARAM      },
1632
                        { "specpower",     T_SPECPOWER  }, { "specularpower",  T_SPECPOWER  }, { "parallaxscale", T_SPECPOWER },
1632
                        { "specpower",     T_SPECPOWER  }, { "specularpower",  T_SPECPOWER  }, { "parallaxscale", T_SPECPOWER },
1633
                        { "specfactor",    T_SPECFACTOR }, { "specularfactor", T_SPECFACTOR }, { "parallaxbias", T_SPECFACTOR },
1633
                        { "specfactor",    T_SPECFACTOR }, { "specularfactor", T_SPECFACTOR }, { "parallaxbias", T_SPECFACTOR },
1634
                        { "nocompress",    T_NOCOMPRESS },
1634
                        { "nocompress",    T_NOCOMPRESS },
1635
                        { "nodownsize",    T_NODOWNSIZE },
1635
                        { "nodownsize",    T_NODOWNSIZE },
1636
                        { "forcefilter",  T_FORCEFILTER },
1636
                        { "forcefilter",  T_FORCEFILTER },
1637
                        { "artquality",    T_ARTQUALITY },
1637
                        { "artquality",    T_ARTQUALITY },
1638
                    };
1638
                    };
1639
1639
1640
                    if (scriptfile_getbraces(script,&skinend)) break;
1640
                    if (scriptfile_getbraces(script,&skinend)) break;
1641
                    while (script->textptr < skinend)
1641
                    while (script->textptr < skinend)
1642
                    {
1642
                    {
1643
                        switch (getatoken(script,modelskintokens,ARRAY_SIZE(modelskintokens)))
1643
                        switch (getatoken(script,modelskintokens,ARRAY_SIZE(modelskintokens)))
1644
                        {
1644
                        {
1645
                        case T_PAL:
1645
                        case T_PAL:
1646
                            scriptfile_getsymbol(script,&palnum); break;
1646
                            scriptfile_getsymbol(script,&palnum); break;
1647
                        case T_PARAM:
1647
                        case T_PARAM:
1648
                            scriptfile_getdouble(script,&param); break;
1648
                            scriptfile_getdouble(script,&param); break;
1649
                        case T_SPECPOWER:
1649
                        case T_SPECPOWER:
1650
                            scriptfile_getdouble(script,&specpower); break;
1650
                            scriptfile_getdouble(script,&specpower); break;
1651
                        case T_SPECFACTOR:
1651
                        case T_SPECFACTOR:
1652
                            scriptfile_getdouble(script,&specfactor); break;
1652
                            scriptfile_getdouble(script,&specfactor); break;
1653
                        case T_FILE:
1653
                        case T_FILE:
1654
                            scriptfile_getstring(script,&skinfn); break; //skin filename
1654
                            scriptfile_getstring(script,&skinfn); break; //skin filename
1655
                        case T_SURF:
1655
                        case T_SURF:
1656
                            scriptfile_getnumber(script,&surfnum); break;
1656
                            scriptfile_getnumber(script,&surfnum); break;
1657
#ifdef USE_OPENGL
1657
#ifdef USE_OPENGL
1658
                        case T_NOCOMPRESS:
1658
                        case T_NOCOMPRESS:
1659
                            flags |= HICR_NOTEXCOMPRESS; break;
1659
                            flags |= HICR_NOTEXCOMPRESS; break;
1660
                        case T_NODOWNSIZE:
1660
                        case T_NODOWNSIZE:
1661
                            flags |= HICR_NODOWNSIZE; break;
1661
                            flags |= HICR_NODOWNSIZE; break;
1662
                        case T_FORCEFILTER:
1662
                        case T_FORCEFILTER:
1663
                            flags |= HICR_FORCEFILTER; break;
1663
                            flags |= HICR_FORCEFILTER; break;
1664
                        case T_ARTQUALITY:
1664
                        case T_ARTQUALITY:
1665
                            flags |= HICR_ARTIMMUNITY; break;
1665
                            flags |= HICR_ARTIMMUNITY; break;
1666
#endif
1666
#endif
1667
                        }
1667
                        }
1668
                    }
1668
                    }
1669
1669
1670
                    if (EDUKE32_PREDICT_FALSE(!skinfn))
1670
                    if (EDUKE32_PREDICT_FALSE(!skinfn))
1671
                    {
1671
                    {
1672
                        initprintf("Error: missing 'skin filename' for skin definition near line %s:%d\n", script->filename, scriptfile_getlinum(script,skintokptr));
1672
                        initprintf("Error: missing 'skin filename' for skin definition near line %s:%d\n", script->filename, scriptfile_getlinum(script,skintokptr));
1673
                        model_ok = 0;
1673
                        model_ok = 0;
1674
                        break;
1674
                        break;
1675
                    }
1675
                    }
1676
1676
1677
                    if (seenframe) { modelskin = ++lastmodelskin; }
1677
                    if (seenframe) { modelskin = ++lastmodelskin; }
1678
                    seenframe = 0;
1678
                    seenframe = 0;
1679
1679
1680
                    switch (token)
1680
                    switch (token)
1681
                    {
1681
                    {
1682
                    case T_DETAIL:
1682
                    case T_DETAIL:
1683
                        palnum = DETAILPAL;
1683
                        palnum = DETAILPAL;
1684
                        param = 1.0f / param;
1684
                        param = 1.0f / param;
1685
                        break;
1685
                        break;
1686
                    case T_GLOW:
1686
                    case T_GLOW:
1687
                        palnum = GLOWPAL;
1687
                        palnum = GLOWPAL;
1688
                        break;
1688
                        break;
1689
                    case T_SPECULAR:
1689
                    case T_SPECULAR:
1690
                        palnum = SPECULARPAL;
1690
                        palnum = SPECULARPAL;
1691
                        break;
1691
                        break;
1692
                    case T_NORMAL:
1692
                    case T_NORMAL:
1693
                        palnum = NORMALPAL;
1693
                        palnum = NORMALPAL;
1694
                        break;
1694
                        break;
1695
                    }
1695
                    }
1696
1696
1697
                    if (check_file_exist(skinfn))
1697
                    if (check_file_exist(skinfn))
1698
                        break;
1698
                        break;
1699
1699
1700
#ifdef USE_OPENGL
1700
#ifdef USE_OPENGL
1701
                    switch (md_defineskin(lastmodelid, skinfn, palnum, max(0,modelskin), surfnum, param, specpower, specfactor, flags))
1701
                    switch (md_defineskin(lastmodelid, skinfn, palnum, max(0,modelskin), surfnum, param, specpower, specfactor, flags))
1702
                    {
1702
                    {
1703
                    case 0:
1703
                    case 0:
1704
                        break;
1704
                        break;
1705
                    case -1:
1705
                    case -1:
1706
                        break; // invalid model id!?
1706
                        break; // invalid model id!?
1707
                    case -2:
1707
                    case -2:
1708
                        initprintf("Invalid skin filename on line %s:%d\n",
1708
                        initprintf("Invalid skin filename on line %s:%d\n",
1709
                                   script->filename, scriptfile_getlinum(script,skintokptr));
1709
                                   script->filename, scriptfile_getlinum(script,skintokptr));
1710
                        model_ok = 0;
1710
                        model_ok = 0;
1711
                        break;
1711
                        break;
1712
                    case -3:
1712
                    case -3:
1713
                        initprintf("Invalid palette number on line %s:%d\n",
1713
                        initprintf("Invalid palette number on line %s:%d\n",
1714
                                   script->filename, scriptfile_getlinum(script,skintokptr));
1714
                                   script->filename, scriptfile_getlinum(script,skintokptr));
1715
                        model_ok = 0;
1715
                        model_ok = 0;
1716
                        break;
1716
                        break;
1717
                    case -4:
1717
                    case -4:
1718
                        initprintf("Out of memory on line %s:%d\n",
1718
                        initprintf("Out of memory on line %s:%d\n",
1719
                                   script->filename, scriptfile_getlinum(script,skintokptr));
1719
                                   script->filename, scriptfile_getlinum(script,skintokptr));
1720
                        model_ok = 0;
1720
                        model_ok = 0;
1721
                        break;
1721
                        break;
1722
                    }
1722
                    }
1723
#endif
1723
#endif
1724
                }
1724
                }
1725
                break;
1725
                break;
1726
                case T_HUD:
1726
                case T_HUD:
1727
                {
1727
                {
1728
                    char *hudtokptr = script->ltextptr;
1728
                    char *hudtokptr = script->ltextptr;
1729
                    char *frameend;
1729
                    char *frameend;
1730
#ifdef USE_OPENGL
1730
#ifdef USE_OPENGL
1731
                    char happy=1;
1731
                    char happy=1;
1732
                    int32_t tilex = 0;
1732
                    int32_t tilex = 0;
1733
#endif
1733
#endif
1734
                    int32_t ftilenume = -1, ltilenume = -1, flags = 0, fov = -1, angadd = 0;
1734
                    int32_t ftilenume = -1, ltilenume = -1, flags = 0, fov = -1, angadd = 0;
1735
                    double xadd = 0.0, yadd = 0.0, zadd = 0.0;
1735
                    double xadd = 0.0, yadd = 0.0, zadd = 0.0;
1736
1736
1737
                    static const tokenlist modelhudtokens[] =
1737
                    static const tokenlist modelhudtokens[] =
1738
                    {
1738
                    {
1739
                        { "tile",   T_TILE   },
1739
                        { "tile",   T_TILE   },
1740
                        { "tile0",  T_TILE0  },
1740
                        { "tile0",  T_TILE0  },
1741
                        { "tile1",  T_TILE1  },
1741
                        { "tile1",  T_TILE1  },
1742
                        { "xadd",   T_XADD   },
1742
                        { "xadd",   T_XADD   },
1743
                        { "yadd",   T_YADD   },
1743
                        { "yadd",   T_YADD   },
1744
                        { "zadd",   T_ZADD   },
1744
                        { "zadd",   T_ZADD   },
1745
                        { "angadd", T_ANGADD },
1745
                        { "angadd", T_ANGADD },
1746
                        { "fov",    T_FOV    },
1746
                        { "fov",    T_FOV    },
1747
                        { "hide",   T_HIDE   },
1747
                        { "hide",   T_HIDE   },
1748
                        { "nobob",  T_NOBOB  },
1748
                        { "nobob",  T_NOBOB  },
1749
                        { "flipped",T_FLIPPED},
1749
                        { "flipped",T_FLIPPED},
1750
                        { "nodepth",T_NODEPTH},
1750
                        { "nodepth",T_NODEPTH},
1751
                    };
1751
                    };
1752
1752
1753
                    if (scriptfile_getbraces(script,&frameend)) break;
1753
                    if (scriptfile_getbraces(script,&frameend)) break;
1754
                    while (script->textptr < frameend)
1754
                    while (script->textptr < frameend)
1755
                    {
1755
                    {
1756
                        switch (getatoken(script,modelhudtokens,ARRAY_SIZE(modelhudtokens)))
1756
                        switch (getatoken(script,modelhudtokens,ARRAY_SIZE(modelhudtokens)))
1757
                        {
1757
                        {
1758
                        case T_TILE:
1758
                        case T_TILE:
1759
                            scriptfile_getsymbol(script,&ftilenume); ltilenume = ftilenume; break;
1759
                            scriptfile_getsymbol(script,&ftilenume); ltilenume = ftilenume; break;
1760
                        case T_TILE0:
1760
                        case T_TILE0:
1761
                            scriptfile_getsymbol(script,&ftilenume); break; //first tile number
1761
                            scriptfile_getsymbol(script,&ftilenume); break; //first tile number
1762
                        case T_TILE1:
1762
                        case T_TILE1:
1763
                            scriptfile_getsymbol(script,&ltilenume); break; //last tile number (inclusive)
1763
                            scriptfile_getsymbol(script,&ltilenume); break; //last tile number (inclusive)
1764
                        case T_XADD:
1764
                        case T_XADD:
1765
                            scriptfile_getdouble(script,&xadd); break;
1765
                            scriptfile_getdouble(script,&xadd); break;
1766
                        case T_YADD:
1766
                        case T_YADD:
1767
                            scriptfile_getdouble(script,&yadd); break;
1767
                            scriptfile_getdouble(script,&yadd); break;
1768
                        case T_ZADD:
1768
                        case T_ZADD:
1769
                            scriptfile_getdouble(script,&zadd); break;
1769
                            scriptfile_getdouble(script,&zadd); break;
1770
                        case T_ANGADD:
1770
                        case T_ANGADD:
1771
                            scriptfile_getsymbol(script,&angadd); break;
1771
                            scriptfile_getsymbol(script,&angadd); break;
1772
                        case T_FOV:
1772
                        case T_FOV:
1773
                            scriptfile_getsymbol(script,&fov); break;
1773
                            scriptfile_getsymbol(script,&fov); break;
1774
                        case T_HIDE:
1774
                        case T_HIDE:
1775
                            flags |= HUDFLAG_HIDE; break;
1775
                            flags |= HUDFLAG_HIDE; break;
1776
                        case T_NOBOB:
1776
                        case T_NOBOB:
1777
                            flags |= HUDFLAG_NOBOB; break;
1777
                            flags |= HUDFLAG_NOBOB; break;
1778
                        case T_FLIPPED:
1778
                        case T_FLIPPED:
1779
                            flags |= HUDFLAG_FLIPPED; break;
1779
                            flags |= HUDFLAG_FLIPPED; break;
1780
                        case T_NODEPTH:
1780
                        case T_NODEPTH:
1781
                            flags |= HUDFLAG_NODEPTH; break;
1781
                            flags |= HUDFLAG_NODEPTH; break;
1782
                        }
1782
                        }
1783
                    }
1783
                    }
1784
1784
1785
                    if (EDUKE32_PREDICT_FALSE(check_tile_range("hud", &ftilenume, &ltilenume, script, hudtokptr