Subversion Repositories eduke32

Rev

Rev 5053 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 5053 Rev 5075
1
//------------------------------------- MD2/MD3 LIBRARY BEGINS -------------------------------------
1
//------------------------------------- MD2/MD3 LIBRARY BEGINS -------------------------------------
2
2
3
#ifdef USE_OPENGL
3
#ifdef USE_OPENGL
4
4
5
#include "compat.h"
5
#include "compat.h"
6
#include "build.h"
6
#include "build.h"
7
#include "glbuild.h"
7
#include "glbuild.h"
8
#include "pragmas.h"
8
#include "pragmas.h"
9
#include "baselayer.h"
9
#include "baselayer.h"
10
#include "engine_priv.h"
10
#include "engine_priv.h"
11
#include "hightile.h"
11
#include "hightile.h"
12
#include "polymost.h"
12
#include "polymost.h"
13
#include "texcache.h"
13
#include "texcache.h"
14
#include "mdsprite.h"
14
#include "mdsprite.h"
15
#include "cache1d.h"
15
#include "cache1d.h"
16
#include "kplib.h"
16
#include "kplib.h"
17
#include "common.h"
17
#include "common.h"
18
18
19
#include <math.h>
19
#include <math.h>
20
#include <float.h>
20
#include <float.h>
21
21
22
static int32_t curextra=MAXTILES;
22
static int32_t curextra=MAXTILES;
23
23
24
#define MIN_CACHETIME_PRINT 10
24
#define MIN_CACHETIME_PRINT 10
25
25
26
static void QuitOnFatalError(const char *msg)
26
static void QuitOnFatalError(const char *msg)
27
{
27
{
28
    if (msg)
28
    if (msg)
29
        initprintf("%s\n", msg);
29
        initprintf("%s\n", msg);
30
    uninitengine();
30
    uninitengine();
31
    Bexit(1);
31
    Bexit(1);
32
}
32
}
33
33
34
34
35
static int32_t addtileP(int32_t model,int32_t tile,int32_t pallet)
35
static int32_t addtileP(int32_t model,int32_t tile,int32_t pallet)
36
{
36
{
37
    // tile >= 0 && tile < MAXTILES
37
    // tile >= 0 && tile < MAXTILES
38
38
39
    UNREFERENCED_PARAMETER(model);
39
    UNREFERENCED_PARAMETER(model);
40
    if (curextra==MAXTILES+EXTRATILES-1)
40
    if (curextra==MAXTILES+EXTRATILES-1)
41
    {
41
    {
42
        initprintf("warning: max EXTRATILES reached\n");
42
        initprintf("warning: max EXTRATILES reached\n");
43
        return curextra;
43
        return curextra;
44
    }
44
    }
45
45
46
    if (tile2model[tile].modelid==-1)
46
    if (tile2model[tile].modelid==-1)
47
    {
47
    {
48
        tile2model[tile].pal=pallet;
48
        tile2model[tile].pal=pallet;
49
        return tile;
49
        return tile;
50
    }
50
    }
51
51
52
    if (tile2model[tile].pal==pallet)
52
    if (tile2model[tile].pal==pallet)
53
        return tile;
53
        return tile;
54
54
55
    while (tile2model[tile].next!=-1)
55
    while (tile2model[tile].next!=-1)
56
    {
56
    {
57
        tile=tile2model[tile].next;
57
        tile=tile2model[tile].next;
58
        if (tile2model[tile].pal==pallet)
58
        if (tile2model[tile].pal==pallet)
59
            return tile;
59
            return tile;
60
    }
60
    }
61
61
62
    tile2model[tile].next=curextra;
62
    tile2model[tile].next=curextra;
63
    tile2model[curextra].pal=pallet;
63
    tile2model[curextra].pal=pallet;
64
64
65
    return curextra++;
65
    return curextra++;
66
}
66
}
67
int32_t Ptile2tile(int32_t tile,int32_t pallet)
67
int32_t Ptile2tile(int32_t tile,int32_t pallet)
68
{
68
{
69
    int32_t t=tile;
69
    int32_t t=tile;
70
//  if(tile>=1550&&tile<=1589){initprintf("(%d, %d)\n",tile,pallet);pallet=0;}
70
//  if(tile>=1550&&tile<=1589){initprintf("(%d, %d)\n",tile,pallet);pallet=0;}
71
    while ((tile=tile2model[tile].next)!=-1)
71
    while ((tile=tile2model[tile].next)!=-1)
72
        if (tile2model[tile].pal==pallet)
72
        if (tile2model[tile].pal==pallet)
73
            return tile;
73
            return tile;
74
    return t;
74
    return t;
75
}
75
}
76
76
77
#define MODELALLOCGROUP 256
77
#define MODELALLOCGROUP 256
78
static int32_t nummodelsalloced = 0;
78
static int32_t nummodelsalloced = 0;
79
79
80
static int32_t maxmodelverts = 0, allocmodelverts = 0;
80
static int32_t maxmodelverts = 0, allocmodelverts = 0;
81
static int32_t maxmodeltris = 0, allocmodeltris = 0;
81
static int32_t maxmodeltris = 0, allocmodeltris = 0;
82
static vec3f_t *vertlist = NULL; //temp array to store interpolated vertices for drawing
82
static vec3f_t *vertlist = NULL; //temp array to store interpolated vertices for drawing
83
83
84
static int32_t allocvbos = 0, curvbo = 0;
84
static int32_t allocvbos = 0, curvbo = 0;
85
static GLuint *vertvbos = NULL;
85
static GLuint *vertvbos = NULL;
86
static GLuint *indexvbos = NULL;
86
static GLuint *indexvbos = NULL;
87
87
88
#ifdef POLYMER
88
#ifdef POLYMER
89
static int32_t *tribuf = NULL;
89
static int32_t *tribuf = NULL;
90
static int32_t tribufverts = 0;
90
static int32_t tribufverts = 0;
91
#endif
91
#endif
92
92
93
static mdmodel_t *mdload(const char *);
93
static mdmodel_t *mdload(const char *);
94
static void mdfree(mdmodel_t *);
94
static void mdfree(mdmodel_t *);
95
int32_t globalnoeffect=0;
95
int32_t globalnoeffect=0;
96
96
97
extern int32_t timerticspersec;
97
extern int32_t timerticspersec;
98
98
99
void md_freevbos()
99
void md_freevbos()
100
{
100
{
101
    int32_t i;
101
    int32_t i;
102
102
103
    for (i=0; i<nextmodelid; i++)
103
    for (i=0; i<nextmodelid; i++)
104
        if (models[i]->mdnum == 3)
104
        if (models[i]->mdnum == 3)
105
        {
105
        {
106
            md3model_t *m = (md3model_t *)models[i];
106
            md3model_t *m = (md3model_t *)models[i];
107
            if (m->vbos)
107
            if (m->vbos)
108
            {
108
            {
109
                //            OSD_Printf("freeing model %d vbo\n",i);
109
                //            OSD_Printf("freeing model %d vbo\n",i);
110
                bglDeleteBuffersARB(m->head.numsurfs, m->vbos);
110
                bglDeleteBuffersARB(m->head.numsurfs, m->vbos);
111
                Bfree(m->vbos);
111
                Bfree(m->vbos);
112
                m->vbos = NULL;
112
                m->vbos = NULL;
113
            }
113
            }
114
        }
114
        }
115
115
116
    if (allocvbos)
116
    if (allocvbos)
117
    {
117
    {
118
        bglDeleteBuffersARB(allocvbos, indexvbos);
118
        bglDeleteBuffersARB(allocvbos, indexvbos);
119
        bglDeleteBuffersARB(allocvbos, vertvbos);
119
        bglDeleteBuffersARB(allocvbos, vertvbos);
120
        allocvbos = 0;
120
        allocvbos = 0;
121
    }
121
    }
122
}
122
}
123
123
124
void freeallmodels()
124
void freeallmodels()
125
{
125
{
126
    int32_t i;
126
    int32_t i;
127
127
128
    if (models)
128
    if (models)
129
    {
129
    {
130
        for (i=0; i<nextmodelid; i++) mdfree(models[i]);
130
        for (i=0; i<nextmodelid; i++) mdfree(models[i]);
131
        Bfree(models); models = NULL;
131
        Bfree(models); models = NULL;
132
        nummodelsalloced = 0;
132
        nummodelsalloced = 0;
133
        nextmodelid = 0;
133
        nextmodelid = 0;
134
    }
134
    }
135
135
136
    memset(tile2model,-1,sizeof(tile2model));
136
    memset(tile2model,-1,sizeof(tile2model));
137
    curextra=MAXTILES;
137
    curextra=MAXTILES;
138
138
139
    if (vertlist)
139
    if (vertlist)
140
    {
140
    {
141
        Bfree(vertlist);
141
        Bfree(vertlist);
142
        vertlist = NULL;
142
        vertlist = NULL;
143
        allocmodelverts = maxmodelverts = 0;
143
        allocmodelverts = maxmodelverts = 0;
144
        allocmodeltris = maxmodeltris = 0;
144
        allocmodeltris = maxmodeltris = 0;
145
    }
145
    }
146
146
147
    md_freevbos();
147
    md_freevbos();
148
#ifdef POLYMER
148
#ifdef POLYMER
149
    DO_FREE_AND_NULL(tribuf);
149
    DO_FREE_AND_NULL(tribuf);
150
#endif
150
#endif
151
}
151
}
152
152
153
153
154
// Skin texture names can be aliased! This is ugly, but at least correct.
154
// Skin texture names can be aliased! This is ugly, but at least correct.
155
static void nullskintexids(GLuint texid)
155
static void nullskintexids(GLuint texid)
156
{
156
{
157
    int32_t i, j;
157
    int32_t i, j;
158
158
159
    for (i=0; i<nextmodelid; i++)
159
    for (i=0; i<nextmodelid; i++)
160
    {
160
    {
161
        mdmodel_t *m = models[i];
161
        mdmodel_t *m = models[i];
162
162
163
        if (m->mdnum == 2 || m->mdnum == 3)
163
        if (m->mdnum == 2 || m->mdnum == 3)
164
        {
164
        {
165
            mdskinmap_t *sk;
165
            mdskinmap_t *sk;
166
            md2model_t *m2 = (md2model_t *)m;
166
            md2model_t *m2 = (md2model_t *)m;
167
167
168
            for (j=0; j<m2->numskins*(HICEFFECTMASK+1); j++)
168
            for (j=0; j<m2->numskins*(HICEFFECTMASK+1); j++)
169
                if (m2->texid[j] == texid)
169
                if (m2->texid[j] == texid)
170
                    m2->texid[j] = 0;
170
                    m2->texid[j] = 0;
171
171
172
            for (sk=m2->skinmap; sk; sk=sk->next)
172
            for (sk=m2->skinmap; sk; sk=sk->next)
173
                for (j=0; j<(HICEFFECTMASK+1); j++)
173
                for (j=0; j<(HICEFFECTMASK+1); j++)
174
                    if (sk->texid[j] == texid)
174
                    if (sk->texid[j] == texid)
175
                        sk->texid[j] = 0;
175
                        sk->texid[j] = 0;
176
        }
176
        }
177
    }
177
    }
178
}
178
}
179
179
180
void clearskins()
180
void clearskins()
181
{
181
{
182
    int32_t i, j;
182
    int32_t i, j;
183
183
184
    for (i=0; i<nextmodelid; i++)
184
    for (i=0; i<nextmodelid; i++)
185
    {
185
    {
186
        mdmodel_t *m = models[i];
186
        mdmodel_t *m = models[i];
187
187
188
        if (m->mdnum == 1)
188
        if (m->mdnum == 1)
189
        {
189
        {
190
            voxmodel_t *v = (voxmodel_t *)m;
190
            voxmodel_t *v = (voxmodel_t *)m;
191
191
192
            for (j=0; j<MAXPALOOKUPS; j++)
192
            for (j=0; j<MAXPALOOKUPS; j++)
193
                if (v->texid[j])
193
                if (v->texid[j])
194
                {
194
                {
195
                    bglDeleteTextures(1, &v->texid[j]);
195
                    bglDeleteTextures(1, &v->texid[j]);
196
                    v->texid[j] = 0;
196
                    v->texid[j] = 0;
197
                }
197
                }
198
        }
198
        }
199
        else if (m->mdnum == 2 || m->mdnum == 3)
199
        else if (m->mdnum == 2 || m->mdnum == 3)
200
        {
200
        {
201
            mdskinmap_t *sk;
201
            mdskinmap_t *sk;
202
            md2model_t *m2 = (md2model_t *)m;
202
            md2model_t *m2 = (md2model_t *)m;
203
203
204
            for (j=0; j<m2->numskins*(HICEFFECTMASK+1); j++)
204
            for (j=0; j<m2->numskins*(HICEFFECTMASK+1); j++)
205
                if (m2->texid[j])
205
                if (m2->texid[j])
206
                {
206
                {
207
                    GLuint otexid = m2->texid[j];
207
                    GLuint otexid = m2->texid[j];
208
208
209
                    bglDeleteTextures(1, &m2->texid[j]);
209
                    bglDeleteTextures(1, &m2->texid[j]);
210
                    m2->texid[j] = 0;
210
                    m2->texid[j] = 0;
211
211
212
                    nullskintexids(otexid);
212
                    nullskintexids(otexid);
213
                }
213
                }
214
214
215
            for (sk=m2->skinmap; sk; sk=sk->next)
215
            for (sk=m2->skinmap; sk; sk=sk->next)
216
                for (j=0; j<(HICEFFECTMASK+1); j++)
216
                for (j=0; j<(HICEFFECTMASK+1); j++)
217
                    if (sk->texid[j])
217
                    if (sk->texid[j])
218
                    {
218
                    {
219
                        GLuint otexid = sk->texid[j];
219
                        GLuint otexid = sk->texid[j];
220
220
221
                        bglDeleteTextures(1, &sk->texid[j]);
221
                        bglDeleteTextures(1, &sk->texid[j]);
222
                        sk->texid[j] = 0;
222
                        sk->texid[j] = 0;
223
223
224
                        nullskintexids(otexid);
224
                        nullskintexids(otexid);
225
                    }
225
                    }
226
        }
226
        }
227
    }
227
    }
228
228
229
    for (i=0; i<MAXVOXELS; i++)
229
    for (i=0; i<MAXVOXELS; i++)
230
    {
230
    {
231
        voxmodel_t *v = voxmodels[i];
231
        voxmodel_t *v = voxmodels[i];
232
        if (!v) continue;
232
        if (!v) continue;
233
233
234
        for (j=0; j<MAXPALOOKUPS; j++)
234
        for (j=0; j<MAXPALOOKUPS; j++)
235
            if (v->texid[j])
235
            if (v->texid[j])
236
            {
236
            {
237
                bglDeleteTextures(1, &v->texid[j]);
237
                bglDeleteTextures(1, &v->texid[j]);
238
                v->texid[j] = 0;
238
                v->texid[j] = 0;
239
            }
239
            }
240
    }
240
    }
241
}
241
}
242
242
243
void mdinit()
243
void mdinit()
244
{
244
{
245
    memset(hudmem,0,sizeof(hudmem));
245
    memset(hudmem,0,sizeof(hudmem));
246
    freeallmodels();
246
    freeallmodels();
247
    mdinited = 1;
247
    mdinited = 1;
248
}
248
}
249
249
250
int32_t md_loadmodel(const char *fn)
250
int32_t md_loadmodel(const char *fn)
251
{
251
{
252
    mdmodel_t *vm, **ml;
252
    mdmodel_t *vm, **ml;
253
253
254
    if (!mdinited) mdinit();
254
    if (!mdinited) mdinit();
255
255
256
    if (nextmodelid >= nummodelsalloced)
256
    if (nextmodelid >= nummodelsalloced)
257
    {
257
    {
258
        ml = (mdmodel_t **)Xrealloc(models,(nummodelsalloced+MODELALLOCGROUP)*sizeof(void *));
258
        ml = (mdmodel_t **)Xrealloc(models,(nummodelsalloced+MODELALLOCGROUP)*sizeof(void *));
259
        models = ml; nummodelsalloced += MODELALLOCGROUP;
259
        models = ml; nummodelsalloced += MODELALLOCGROUP;
260
    }
260
    }
261
261
262
    vm = mdload(fn); if (!vm) return(-1);
262
    vm = mdload(fn); if (!vm) return(-1);
263
    models[nextmodelid++] = vm;
263
    models[nextmodelid++] = vm;
264
    return(nextmodelid-1);
264
    return(nextmodelid-1);
265
}
265
}
266
266
267
int32_t md_setmisc(int32_t modelid, float scale, int32_t shadeoff, float zadd, float yoffset, int32_t flags)
267
int32_t md_setmisc(int32_t modelid, float scale, int32_t shadeoff, float zadd, float yoffset, int32_t flags)
268
{
268
{
269
    mdmodel_t *m;
269
    mdmodel_t *m;
270
270
271
    if (!mdinited) mdinit();
271
    if (!mdinited) mdinit();
272
272
273
    if ((uint32_t)modelid >= (uint32_t)nextmodelid) return -1;
273
    if ((uint32_t)modelid >= (uint32_t)nextmodelid) return -1;
274
    m = models[modelid];
274
    m = models[modelid];
275
    m->bscale = scale;
275
    m->bscale = scale;
276
    m->shadeoff = shadeoff;
276
    m->shadeoff = shadeoff;
277
    m->zadd = zadd;
277
    m->zadd = zadd;
278
    m->yoffset = yoffset;
278
    m->yoffset = yoffset;
279
    m->flags = flags;
279
    m->flags = flags;
280
280
281
    return 0;
281
    return 0;
282
}
282
}
283
283
284
static int32_t framename2index(mdmodel_t *vm, const char *nam)
284
static int32_t framename2index(mdmodel_t *vm, const char *nam)
285
{
285
{
286
    int32_t i = 0;
286
    int32_t i = 0;
287
287
288
    switch (vm->mdnum)
288
    switch (vm->mdnum)
289
    {
289
    {
290
    case 2:
290
    case 2:
291
    {
291
    {
292
        md2model_t *m = (md2model_t *)vm;
292
        md2model_t *m = (md2model_t *)vm;
293
        md2frame_t *fr;
293
        md2frame_t *fr;
294
        for (i=0; i<m->numframes; i++)
294
        for (i=0; i<m->numframes; i++)
295
        {
295
        {
296
            fr = (md2frame_t *)&m->frames[i*m->framebytes];
296
            fr = (md2frame_t *)&m->frames[i*m->framebytes];
297
            if (!Bstrcmp(fr->name, nam)) break;
297
            if (!Bstrcmp(fr->name, nam)) break;
298
        }
298
        }
299
    }
299
    }
300
    break;
300
    break;
301
    case 3:
301
    case 3:
302
    {
302
    {
303
        md3model_t *m = (md3model_t *)vm;
303
        md3model_t *m = (md3model_t *)vm;
304
        for (i=0; i<m->numframes; i++)
304
        for (i=0; i<m->numframes; i++)
305
            if (!Bstrcmp(m->head.frames[i].nam,nam)) break;
305
            if (!Bstrcmp(m->head.frames[i].nam,nam)) break;
306
    }
306
    }
307
    break;
307
    break;
308
    }
308
    }
309
    return(i);
309
    return(i);
310
}
310
}
311
311
312
int32_t md_defineframe(int32_t modelid, const char *framename, int32_t tilenume, int32_t skinnum, float smoothduration, int32_t pal)
312
int32_t md_defineframe(int32_t modelid, const char *framename, int32_t tilenume, int32_t skinnum, float smoothduration, int32_t pal)
313
{
313
{
314
    md2model_t *m;
314
    md2model_t *m;
315
    int32_t i;
315
    int32_t i;
316
316
317
    if (!mdinited) mdinit();
317
    if (!mdinited) mdinit();
318
318
319
    if ((uint32_t)modelid >= (uint32_t)nextmodelid) return(-1);
319
    if ((uint32_t)modelid >= (uint32_t)nextmodelid) return(-1);
320
    if ((uint32_t)tilenume >= (uint32_t)MAXTILES) return(-2);
320
    if ((uint32_t)tilenume >= (uint32_t)MAXTILES) return(-2);
321
    if (!framename) return(-3);
321
    if (!framename) return(-3);
322
322
323
    tilenume=addtileP(modelid,tilenume,pal);
323
    tilenume=addtileP(modelid,tilenume,pal);
324
    m = (md2model_t *)models[modelid];
324
    m = (md2model_t *)models[modelid];
325
    if (m->mdnum == 1)
325
    if (m->mdnum == 1)
326
    {
326
    {
327
        tile2model[tilenume].modelid = modelid;
327
        tile2model[tilenume].modelid = modelid;
328
        tile2model[tilenume].framenum = tile2model[tilenume].skinnum = 0;
328
        tile2model[tilenume].framenum = tile2model[tilenume].skinnum = 0;
329
        return 0;
329
        return 0;
330
    }
330
    }
331
331
332
    i = framename2index((mdmodel_t *)m,framename);
332
    i = framename2index((mdmodel_t *)m,framename);
333
    if (i == m->numframes) return(-3);   // frame name invalid
333
    if (i == m->numframes) return(-3);   // frame name invalid
334
334
335
    tile2model[tilenume].modelid = modelid;
335
    tile2model[tilenume].modelid = modelid;
336
    tile2model[tilenume].framenum = i;
336
    tile2model[tilenume].framenum = i;
337
    tile2model[tilenume].skinnum = skinnum;
337
    tile2model[tilenume].skinnum = skinnum;
338
    tile2model[tilenume].smoothduration = smoothduration;
338
    tile2model[tilenume].smoothduration = smoothduration;
339
339
340
    return i;
340
    return i;
341
}
341
}
342
342
343
int32_t md_defineanimation(int32_t modelid, const char *framestart, const char *frameend, int32_t fpssc, int32_t flags)
343
int32_t md_defineanimation(int32_t modelid, const char *framestart, const char *frameend, int32_t fpssc, int32_t flags)
344
{
344
{
345
    md2model_t *m;
345
    md2model_t *m;
346
    mdanim_t ma, *map;
346
    mdanim_t ma, *map;
347
    int32_t i;
347
    int32_t i;
348
348
349
    if (!mdinited) mdinit();
349
    if (!mdinited) mdinit();
350
350
351
    if ((uint32_t)modelid >= (uint32_t)nextmodelid) return(-1);
351
    if ((uint32_t)modelid >= (uint32_t)nextmodelid) return(-1);
352
352
353
    Bmemset(&ma, 0, sizeof(ma));
353
    Bmemset(&ma, 0, sizeof(ma));
354
    m = (md2model_t *)models[modelid];
354
    m = (md2model_t *)models[modelid];
355
    if (m->mdnum < 2) return 0;
355
    if (m->mdnum < 2) return 0;
356
356
357
    //find index of start frame
357
    //find index of start frame
358
    i = framename2index((mdmodel_t *)m,framestart);
358
    i = framename2index((mdmodel_t *)m,framestart);
359
    if (i == m->numframes) return -2;
359
    if (i == m->numframes) return -2;
360
    ma.startframe = i;
360
    ma.startframe = i;
361
361
362
    //find index of finish frame which must trail start frame
362
    //find index of finish frame which must trail start frame
363
    i = framename2index((mdmodel_t *)m,frameend);
363
    i = framename2index((mdmodel_t *)m,frameend);
364
    if (i == m->numframes) return -3;
364
    if (i == m->numframes) return -3;
365
    ma.endframe = i;
365
    ma.endframe = i;
366
366
367
    ma.fpssc = fpssc;
367
    ma.fpssc = fpssc;
368
    ma.flags = flags;
368
    ma.flags = flags;
369
369
370
    map = (mdanim_t *)Xmalloc(sizeof(mdanim_t));
370
    map = (mdanim_t *)Xmalloc(sizeof(mdanim_t));
371
371
372
    Bmemcpy(map, &ma, sizeof(ma));
372
    Bmemcpy(map, &ma, sizeof(ma));
373
373
374
    map->next = m->animations;
374
    map->next = m->animations;
375
    m->animations = map;
375
    m->animations = map;
376
376
377
    return(0);
377
    return(0);
378
}
378
}
379
379
380
#if 0
380
#if 0
381
// FIXME: CURRENTLY DISABLED: interpolation may access frames we consider 'unused'?
381
// FIXME: CURRENTLY DISABLED: interpolation may access frames we consider 'unused'?
382
int32_t md_thinoutmodel(int32_t modelid, uint8_t *usedframebitmap)
382
int32_t md_thinoutmodel(int32_t modelid, uint8_t *usedframebitmap)
383
{
383
{
384
    md3model_t *m;
384
    md3model_t *m;
385
    md3surf_t *s;
385
    md3surf_t *s;
386
    mdanim_t *anm;
386
    mdanim_t *anm;
387
    int32_t i, surfi, sub, usedframes;
387
    int32_t i, surfi, sub, usedframes;
388
    static int16_t otonframe[1024];
388
    static int16_t otonframe[1024];
389
389
390
    if ((uint32_t)modelid >= (uint32_t)nextmodelid) return -1;
390
    if ((uint32_t)modelid >= (uint32_t)nextmodelid) return -1;
391
    m = (md3model_t *)models[modelid];
391
    m = (md3model_t *)models[modelid];
392
    if (m->mdnum != 3) return -2;
392
    if (m->mdnum != 3) return -2;
393
393
394
    for (anm=m->animations; anm; anm=anm->next)
394
    for (anm=m->animations; anm; anm=anm->next)
395
    {
395
    {
396
        if (anm->endframe <= anm->startframe)
396
        if (anm->endframe <= anm->startframe)
397
        {
397
        {
398
//            initprintf("backward anim %d-%d\n", anm->startframe, anm->endframe);
398
//            initprintf("backward anim %d-%d\n", anm->startframe, anm->endframe);
399
            return -3;
399
            return -3;
400
        }
400
        }
401
401
402
        for (i=anm->startframe; i<anm->endframe; i++)
402
        for (i=anm->startframe; i<anm->endframe; i++)
403
            usedframebitmap[i>>3] |= (1<<(i&7));
403
            usedframebitmap[i>>3] |= (1<<(i&7));
404
    }
404
    }
405
405
406
    sub = 0;
406
    sub = 0;
407
    for (i=0; i<m->numframes; i++)
407
    for (i=0; i<m->numframes; i++)
408
    {
408
    {
409
        if (!(usedframebitmap[i>>3]&(1<<(i&7))))
409
        if (!(usedframebitmap[i>>3]&(1<<(i&7))))
410
        {
410
        {
411
            sub++;
411
            sub++;
412
            otonframe[i] = -1;
412
            otonframe[i] = -1;
413
            continue;
413
            continue;
414
        }
414
        }
415
415
416
        otonframe[i] = i-sub;
416
        otonframe[i] = i-sub;
417
    }
417
    }
418
418
419
    usedframes = m->numframes - sub;
419
    usedframes = m->numframes - sub;
420
    if (usedframes==0 || usedframes==m->numframes)
420
    if (usedframes==0 || usedframes==m->numframes)
421
        return usedframes;
421
        return usedframes;
422
422
423
    //// THIN OUT! ////
423
    //// THIN OUT! ////
424
424
425
    for (i=0; i<m->numframes; i++)
425
    for (i=0; i<m->numframes; i++)
426
    {
426
    {
427
        if (otonframe[i]>=0 && otonframe[i] != i)
427
        if (otonframe[i]>=0 && otonframe[i] != i)
428
        {
428
        {
429
            if (m->muladdframes)
429
            if (m->muladdframes)
430
                Bmemcpy(&m->muladdframes[2*otonframe[i]], &m->muladdframes[2*i], 2*sizeof(vec3f_t));
430
                Bmemcpy(&m->muladdframes[2*otonframe[i]], &m->muladdframes[2*i], 2*sizeof(vec3f_t));
431
            Bmemcpy(&m->head.frames[otonframe[i]], &m->head.frames[i], sizeof(md3frame_t));
431
            Bmemcpy(&m->head.frames[otonframe[i]], &m->head.frames[i], sizeof(md3frame_t));
432
        }
432
        }
433
    }
433
    }
434
434
435
    for (surfi=0; surfi < m->head.numsurfs; surfi++)
435
    for (surfi=0; surfi < m->head.numsurfs; surfi++)
436
    {
436
    {
437
        s = &m->head.surfs[surfi];
437
        s = &m->head.surfs[surfi];
438
438
439
        for (i=0; i<m->numframes; i++)
439
        for (i=0; i<m->numframes; i++)
440
            if (otonframe[i]>=0 && otonframe[i] != i)
440
            if (otonframe[i]>=0 && otonframe[i] != i)
441
                Bmemcpy(&s->xyzn[otonframe[i]*s->numverts], &s->xyzn[i*s->numverts], s->numverts*sizeof(md3xyzn_t));
441
                Bmemcpy(&s->xyzn[otonframe[i]*s->numverts], &s->xyzn[i*s->numverts], s->numverts*sizeof(md3xyzn_t));
442
    }
442
    }
443
443
444
    ////// tweak frame indices in various places
444
    ////// tweak frame indices in various places
445
445
446
    for (anm=m->animations; anm; anm=anm->next)
446
    for (anm=m->animations; anm; anm=anm->next)
447
    {
447
    {
448
        if (otonframe[anm->startframe]==-1 || otonframe[anm->endframe-1]==-1)
448
        if (otonframe[anm->startframe]==-1 || otonframe[anm->endframe-1]==-1)
449
            initprintf("md %d WTF: anm %d %d\n", modelid, anm->startframe, anm->endframe);
449
            initprintf("md %d WTF: anm %d %d\n", modelid, anm->startframe, anm->endframe);
450
450
451
        anm->startframe = otonframe[anm->startframe];
451
        anm->startframe = otonframe[anm->startframe];
452
        anm->endframe = otonframe[anm->endframe-1];
452
        anm->endframe = otonframe[anm->endframe-1];
453
    }
453
    }
454
454
455
    for (i=0; i<MAXTILES+EXTRATILES; i++)
455
    for (i=0; i<MAXTILES+EXTRATILES; i++)
456
        if (tile2model[i].modelid == modelid)
456
        if (tile2model[i].modelid == modelid)
457
        {
457
        {
458
            if (otonframe[tile2model[i].framenum]==-1)
458
            if (otonframe[tile2model[i].framenum]==-1)
459
                initprintf("md %d WTF: tile %d, fr %d\n", modelid, i, tile2model[i].framenum);
459
                initprintf("md %d WTF: tile %d, fr %d\n", modelid, i, tile2model[i].framenum);
460
            tile2model[i].framenum = otonframe[tile2model[i].framenum];
460
            tile2model[i].framenum = otonframe[tile2model[i].framenum];
461
        }
461
        }
462
462
463
    ////// realloc & change "numframes" everywhere
463
    ////// realloc & change "numframes" everywhere
464
464
465
    if (m->muladdframes)
465
    if (m->muladdframes)
466
        m->muladdframes = Xrealloc(m->muladdframes, 2*sizeof(vec3f_t)*usedframes);
466
        m->muladdframes = Xrealloc(m->muladdframes, 2*sizeof(vec3f_t)*usedframes);
467
    m->head.frames = Xrealloc(m->head.frames, sizeof(md3frame_t)*usedframes);
467
    m->head.frames = Xrealloc(m->head.frames, sizeof(md3frame_t)*usedframes);
468
468
469
    for (surfi=0; surfi < m->head.numsurfs; surfi++)
469
    for (surfi=0; surfi < m->head.numsurfs; surfi++)
470
    {
470
    {
471
        m->head.surfs[surfi].numframes = usedframes;
471
        m->head.surfs[surfi].numframes = usedframes;
472
        // CAN'T do that because xyzn is offset from a larger block when loaded from md3:
472
        // CAN'T do that because xyzn is offset from a larger block when loaded from md3:
473
//        m->head.surfs[surfi].xyzn = Xrealloc(m->head.surfs[surfi].xyzn, s->numverts*usedframes*sizeof(md3xyzn_t));
473
//        m->head.surfs[surfi].xyzn = Xrealloc(m->head.surfs[surfi].xyzn, s->numverts*usedframes*sizeof(md3xyzn_t));
474
    }
474
    }
475
475
476
    m->head.numframes = usedframes;
476
    m->head.numframes = usedframes;
477
    m->numframes = usedframes;
477
    m->numframes = usedframes;
478
478
479
    ////////////
479
    ////////////
480
    return usedframes;
480
    return usedframes;
481
}
481
}
482
#endif
482
#endif
483
483
484
int32_t md_defineskin(int32_t modelid, const char *skinfn, int32_t palnum, int32_t skinnum, int32_t surfnum, float param, float specpower, float specfactor)
484
int32_t md_defineskin(int32_t modelid, const char *skinfn, int32_t palnum, int32_t skinnum, int32_t surfnum, float param, float specpower, float specfactor)
485
{
485
{
486
    mdskinmap_t *sk, *skl;
486
    mdskinmap_t *sk, *skl;
487
    md2model_t *m;
487
    md2model_t *m;
488
488
489
    if (!mdinited) mdinit();
489
    if (!mdinited) mdinit();
490
490
491
    if ((uint32_t)modelid >= (uint32_t)nextmodelid) return -1;
491
    if ((uint32_t)modelid >= (uint32_t)nextmodelid) return -1;
492
    if (!skinfn) return -2;
492
    if (!skinfn) return -2;
493
    if ((unsigned)palnum >= (unsigned)MAXPALOOKUPS) return -3;
493
    if ((unsigned)palnum >= (unsigned)MAXPALOOKUPS) return -3;
494
494
495
    m = (md2model_t *)models[modelid];
495
    m = (md2model_t *)models[modelid];
496
    if (m->mdnum < 2) return 0;
496
    if (m->mdnum < 2) return 0;
497
    if (m->mdnum == 2) surfnum = 0;
497
    if (m->mdnum == 2) surfnum = 0;
498
498
499
    skl = NULL;
499
    skl = NULL;
500
    for (sk = m->skinmap; sk; skl = sk, sk = sk->next)
500
    for (sk = m->skinmap; sk; skl = sk, sk = sk->next)
501
        if (sk->palette == (uint8_t)palnum && skinnum == sk->skinnum && surfnum == sk->surfnum)
501
        if (sk->palette == (uint8_t)palnum && skinnum == sk->skinnum && surfnum == sk->surfnum)
502
            break;
502
            break;
503
    if (!sk)
503
    if (!sk)
504
    {
504
    {
505
        sk = (mdskinmap_t *)Xcalloc(1,sizeof(mdskinmap_t));
505
        sk = (mdskinmap_t *)Xcalloc(1,sizeof(mdskinmap_t));
506
506
507
        if (!skl) m->skinmap = sk;
507
        if (!skl) m->skinmap = sk;
508
        else skl->next = sk;
508
        else skl->next = sk;
509
    }
509
    }
510
    else if (sk->fn) Bfree(sk->fn);
510
    else if (sk->fn) Bfree(sk->fn);
511
511
512
    sk->palette = (uint8_t)palnum;
512
    sk->palette = (uint8_t)palnum;
513
    sk->skinnum = skinnum;
513
    sk->skinnum = skinnum;
514
    sk->surfnum = surfnum;
514
    sk->surfnum = surfnum;
515
    sk->param = param;
515
    sk->param = param;
516
    sk->specpower = specpower;
516
    sk->specpower = specpower;
517
    sk->specfactor = specfactor;
517
    sk->specfactor = specfactor;
518
    sk->fn = Xstrdup(skinfn);
518
    sk->fn = Xstrdup(skinfn);
519
519
520
    return 0;
520
    return 0;
521
}
521
}
522
522
523
int32_t md_definehud(int32_t modelid, int32_t tilex, float xadd, float yadd, float zadd, int32_t angadd, int32_t flags, int32_t fov)
523
int32_t md_definehud(int32_t modelid, int32_t tilex, float xadd, float yadd, float zadd, int32_t angadd, int32_t flags, int32_t fov)
524
{
524
{
525
    if (!mdinited) mdinit();
525
    if (!mdinited) mdinit();
526
526
527
    if ((uint32_t)modelid >= (uint32_t)nextmodelid) return -1;
527
    if ((uint32_t)modelid >= (uint32_t)nextmodelid) return -1;
528
    if ((uint32_t)tilex >= (uint32_t)MAXTILES) return -2;
528
    if ((uint32_t)tilex >= (uint32_t)MAXTILES) return -2;
529
529
530
    hudmem[(flags>>2)&1][tilex].add.x = xadd;
530
    hudmem[(flags>>2)&1][tilex].add.x = xadd;
531
    hudmem[(flags>>2)&1][tilex].add.y = yadd;
531
    hudmem[(flags>>2)&1][tilex].add.y = yadd;
532
    hudmem[(flags>>2)&1][tilex].add.z = zadd;
532
    hudmem[(flags>>2)&1][tilex].add.z = zadd;
533
    hudmem[(flags>>2)&1][tilex].angadd = ((int16_t)angadd)|2048;
533
    hudmem[(flags>>2)&1][tilex].angadd = ((int16_t)angadd)|2048;
534
    hudmem[(flags>>2)&1][tilex].flags = (int16_t)flags;
534
    hudmem[(flags>>2)&1][tilex].flags = (int16_t)flags;
535
    hudmem[(flags>>2)&1][tilex].fov = (int16_t)fov;
535
    hudmem[(flags>>2)&1][tilex].fov = (int16_t)fov;
536
536
537
    return 0;
537
    return 0;
538
}
538
}
539
539
540
int32_t md_undefinetile(int32_t tile)
540
int32_t md_undefinetile(int32_t tile)
541
{
541
{
542
    if (!mdinited) return 0;
542
    if (!mdinited) return 0;
543
    if ((unsigned)tile >= (unsigned)MAXTILES) return -1;
543
    if ((unsigned)tile >= (unsigned)MAXTILES) return -1;
544
544
545
    tile2model[tile].modelid = -1;
545
    tile2model[tile].modelid = -1;
546
    tile2model[tile].next=-1;
546
    tile2model[tile].next=-1;
547
    hudmem[0][tile].angadd = 0;
547
    hudmem[0][tile].angadd = 0;
548
    hudmem[1][tile].angadd = 0;
548
    hudmem[1][tile].angadd = 0;
549
549
550
    return 0;
550
    return 0;
551
}
551
}
552
552
553
/* this function is problematic, it leaves NULL holes in model[]
553
/* this function is problematic, it leaves NULL holes in model[]
554
 * (which runs from 0 to nextmodelid-1) */
554
 * (which runs from 0 to nextmodelid-1) */
555
int32_t md_undefinemodel(int32_t modelid)
555
int32_t md_undefinemodel(int32_t modelid)
556
{
556
{
557
    int32_t i;
557
    int32_t i;
558
    if (!mdinited) return 0;
558
    if (!mdinited) return 0;
559
    if ((uint32_t)modelid >= (uint32_t)nextmodelid) return -1;
559
    if ((uint32_t)modelid >= (uint32_t)nextmodelid) return -1;
560
560
561
    for (i=MAXTILES+EXTRATILES-1; i>=0; i--)
561
    for (i=MAXTILES+EXTRATILES-1; i>=0; i--)
562
        if (tile2model[i].modelid == modelid)
562
        if (tile2model[i].modelid == modelid)
563
            tile2model[i].modelid = -1;
563
            tile2model[i].modelid = -1;
564
564
565
    if (models)
565
    if (models)
566
    {
566
    {
567
        mdfree(models[modelid]);
567
        mdfree(models[modelid]);
568
        models[modelid] = NULL;
568
        models[modelid] = NULL;
569
    }
569
    }
570
570
571
    return 0;
571
    return 0;
572
}
572
}
573
573
574
static int32_t daskinloader(int32_t filh, intptr_t *fptr, int32_t *bpl, int32_t *sizx, int32_t *sizy,
574
static int32_t daskinloader(int32_t filh, intptr_t *fptr, int32_t *bpl, int32_t *sizx, int32_t *sizy,
575
                            int32_t *osizx, int32_t *osizy, char *hasalpha, int32_t pal, char effect)
575
                            int32_t *osizx, int32_t *osizy, char *hasalpha, int32_t pal, char effect)
576
{
576
{
577
    int32_t picfillen, j,y,x;
577
    int32_t picfillen, j,y,x;
578
    char *picfil,*cptr,al=255;
578
    char *picfil,*cptr,al=255;
579
    coltype *pic;
579
    coltype *pic;
580
    int32_t xsiz, ysiz, tsizx, tsizy;
580
    int32_t xsiz, ysiz, tsizx, tsizy;
581
    int32_t r, g, b;
581
    int32_t r, g, b;
582
582
583
    picfillen = kfilelength(filh);
583
    picfillen = kfilelength(filh);
584
    picfil = (char *)Xmalloc(picfillen+1);
584
    picfil = (char *)Xmalloc(picfillen+1);
585
    kread(filh, picfil, picfillen);
585
    kread(filh, picfil, picfillen);
586
586
587
    // tsizx/y = replacement texture's natural size
587
    // tsizx/y = replacement texture's natural size
588
    // xsiz/y = 2^x size of replacement
588
    // xsiz/y = 2^x size of replacement
589
589
590
    kpgetdim(picfil,picfillen,&tsizx,&tsizy);
590
    kpgetdim(picfil,picfillen,&tsizx,&tsizy);
591
    if (tsizx == 0 || tsizy == 0) { Bfree(picfil); return -2; }
591
    if (tsizx == 0 || tsizy == 0) { Bfree(picfil); return -2; }
592
592
593
    if (!glinfo.texnpot)
593
    if (!glinfo.texnpot)
594
    {
594
    {
595
        for (xsiz=1; xsiz<tsizx; xsiz+=xsiz);
595
        for (xsiz=1; xsiz<tsizx; xsiz+=xsiz);
596
        for (ysiz=1; ysiz<tsizy; ysiz+=ysiz);
596
        for (ysiz=1; ysiz<tsizy; ysiz+=ysiz);
597
    }
597
    }
598
    else
598
    else
599
    {
599
    {
600
        xsiz = tsizx;
600
        xsiz = tsizx;
601
        ysiz = tsizy;
601
        ysiz = tsizy;
602
    }
602
    }
603
    *osizx = tsizx; *osizy = tsizy;
603
    *osizx = tsizx; *osizy = tsizy;
604
    pic = (coltype *)Xmalloc(xsiz*ysiz*sizeof(coltype));
604
    pic = (coltype *)Xmalloc(xsiz*ysiz*sizeof(coltype));
605
605
606
    memset(pic,0,xsiz*ysiz*sizeof(coltype));
606
    memset(pic,0,xsiz*ysiz*sizeof(coltype));
607
607
608
    if (kprender(picfil,picfillen,(intptr_t)pic,xsiz*sizeof(coltype),xsiz,ysiz))
608
    if (kprender(picfil,picfillen,(intptr_t)pic,xsiz*sizeof(coltype),xsiz,ysiz))
609
        { Bfree(picfil); Bfree(pic); return -2; }
609
        { Bfree(picfil); Bfree(pic); return -2; }
610
    Bfree(picfil);
610
    Bfree(picfil);
611
611
612
    cptr = &britable[gammabrightness ? 0 : curbrightness][0];
612
    cptr = &britable[gammabrightness ? 0 : curbrightness][0];
613
    r=(glinfo.bgra)?hictinting[pal].b:hictinting[pal].r;
613
    r=(glinfo.bgra)?hictinting[pal].b:hictinting[pal].r;
614
    g=hictinting[pal].g;
614
    g=hictinting[pal].g;
615
    b=(glinfo.bgra)?hictinting[pal].r:hictinting[pal].b;
615
    b=(glinfo.bgra)?hictinting[pal].r:hictinting[pal].b;
616
    for (y=0,j=0; y<tsizy; y++,j+=xsiz)
616
    for (y=0,j=0; y<tsizy; y++,j+=xsiz)
617
    {
617
    {
618
        coltype *rpptr = &pic[j], tcol;
618
        coltype *rpptr = &pic[j], tcol;
619
619
620
        for (x=0; x<tsizx; x++)
620
        for (x=0; x<tsizx; x++)
621
        {
621
        {
622
            tcol.b = cptr[rpptr[x].b];
622
            tcol.b = cptr[rpptr[x].b];
623
            tcol.g = cptr[rpptr[x].g];
623
            tcol.g = cptr[rpptr[x].g];
624
            tcol.r = cptr[rpptr[x].r];
624
            tcol.r = cptr[rpptr[x].r];
625
625
626
            if (effect & HICTINT_GRAYSCALE)
626
            if (effect & HICTINT_GRAYSCALE)
627
            {
627
            {
628
                tcol.g = tcol.r = tcol.b = (uint8_t)((tcol.r * GRAYSCALE_COEFF_RED) + (tcol.g * GRAYSCALE_COEFF_GREEN) +
628
                tcol.g = tcol.r = tcol.b = (uint8_t)((tcol.r * GRAYSCALE_COEFF_RED) + (tcol.g * GRAYSCALE_COEFF_GREEN) +
629
                                                     (tcol.b * GRAYSCALE_COEFF_BLUE));
629
                                                     (tcol.b * GRAYSCALE_COEFF_BLUE));
630
            }
630
            }
631
631
632
            if (effect & HICTINT_INVERT)
632
            if (effect & HICTINT_INVERT)
633
            {
633
            {
634
                tcol.b = 255-tcol.b;
634
                tcol.b = 255-tcol.b;
635
                tcol.g = 255-tcol.g;
635
                tcol.g = 255-tcol.g;
636
                tcol.r = 255-tcol.r;
636
                tcol.r = 255-tcol.r;
637
            }
637
            }
638
638
639
            if (effect & HICTINT_COLORIZE)
639
            if (effect & HICTINT_COLORIZE)
640
            {
640
            {
641
                tcol.b = min((int32_t)(tcol.b)*b/64,255);
641
                tcol.b = min((int32_t)(tcol.b)*b/64,255);
642
                tcol.g = min((int32_t)(tcol.g)*g/64,255);
642
                tcol.g = min((int32_t)(tcol.g)*g/64,255);
643
                tcol.r = min((int32_t)(tcol.r)*r/64,255);
643
                tcol.r = min((int32_t)(tcol.r)*r/64,255);
644
            }
644
            }
645
645
646
            rpptr[x].b = tcol.b;
646
            rpptr[x].b = tcol.b;
647
            rpptr[x].g = tcol.g;
647
            rpptr[x].g = tcol.g;
648
            rpptr[x].r = tcol.r;
648
            rpptr[x].r = tcol.r;
649
            al &= rpptr[x].a;
649
            al &= rpptr[x].a;
650
        }
650
        }
651
    }
651
    }
652
    if (!glinfo.bgra)
652
    if (!glinfo.bgra)
653
    {
653
    {
654
        for (j=xsiz*ysiz-1; j>=0; j--)
654
        for (j=xsiz*ysiz-1; j>=0; j--)
655
        {
655
        {
656
            swapchar(&pic[j].r, &pic[j].b);
656
            swapchar(&pic[j].r, &pic[j].b);
657
        }
657
        }
658
    }
658
    }
659
659
660
    *sizx = xsiz;
660
    *sizx = xsiz;
661
    *sizy = ysiz;
661
    *sizy = ysiz;
662
    *bpl = xsiz;
662
    *bpl = xsiz;
663
    *fptr = (intptr_t)pic;
663
    *fptr = (intptr_t)pic;
664
    *hasalpha = (al != 255);
664
    *hasalpha = (al != 255);
665
665
666
    return 0;
666
    return 0;
667
}
667
}
668
668
669
static inline int32_t hicfxmask(int32_t pal)
669
static inline int32_t hicfxmask(int32_t pal)
670
{
670
{
671
    return globalnoeffect ? 0 : (hictinting[pal].f & HICEFFECTMASK);
671
    return globalnoeffect ? 0 : (hictinting[pal].f & HICEFFECTMASK);
672
}
672
}
673
673
674
//Note: even though it says md2model, it works for both md2model&md3model
674
//Note: even though it says md2model, it works for both md2model&md3model
675
int32_t mdloadskin(md2model_t *m, int32_t number, int32_t pal, int32_t surf)
675
int32_t mdloadskin(md2model_t *m, int32_t number, int32_t pal, int32_t surf)
676
{
676
{
677
    int32_t i, bpl, xsiz=0, ysiz=0, osizx, osizy, texfmt = GL_RGBA, intexfmt = GL_RGBA;
677
    int32_t i, bpl, osizx, osizy, texfmt = GL_RGBA, intexfmt = GL_RGBA;
678
    char *skinfile, hasalpha, fn[BMAX_PATH];
678
    char *skinfile, hasalpha, fn[BMAX_PATH];
679
    GLuint *texidx = NULL;
679
    GLuint *texidx = NULL;
680
    mdskinmap_t *sk, *skzero = NULL;
680
    mdskinmap_t *sk, *skzero = NULL;
681
    int32_t doalloc = 1, filh;
681
    int32_t doalloc = 1, filh;
682
    int32_t gotcache, picfillen;
682
    int32_t gotcache, picfillen;
683
    texcacheheader cachead;
683
    texcacheheader cachead;
684
684
685
    int32_t startticks, willprint=0;
685
    int32_t startticks, willprint=0;
-
 
686
    vec2_t siz = { 0, 0 };
686
687
687
    if (m->mdnum == 2)
688
    if (m->mdnum == 2)
688
        surf = 0;
689
        surf = 0;
689
690
690
    if ((unsigned)pal >= (unsigned)MAXPALOOKUPS)
691
    if ((unsigned)pal >= (unsigned)MAXPALOOKUPS)
691
        return 0;
692
        return 0;
692
693
693
    i = -1;
694
    i = -1;
694
    for (sk = m->skinmap; sk; sk = sk->next)
695
    for (sk = m->skinmap; sk; sk = sk->next)
695
    {
696
    {
696
        if (sk->palette == pal && sk->skinnum == number && sk->surfnum == surf)
697
        if (sk->palette == pal && sk->skinnum == number && sk->surfnum == surf)
697
        {
698
        {
698
            skinfile = sk->fn;
699
            skinfile = sk->fn;
699
            texidx = &sk->texid[hicfxmask(pal)];
700
            texidx = &sk->texid[hicfxmask(pal)];
700
            Bstrncpyz(fn, skinfile, BMAX_PATH);
701
            Bstrncpyz(fn, skinfile, BMAX_PATH);
701
            //OSD_Printf("Using exact match skin (pal=%d,skinnum=%d,surfnum=%d) %s\n",pal,number,surf,skinfile);
702
            //OSD_Printf("Using exact match skin (pal=%d,skinnum=%d,surfnum=%d) %s\n",pal,number,surf,skinfile);
702
            break;
703
            break;
703
        }
704
        }
704
        //If no match, give highest priority to number, then pal.. (Parkar's request, 02/27/2005)
705
        //If no match, give highest priority to number, then pal.. (Parkar's request, 02/27/2005)
705
        else if ((sk->palette ==   0) && (sk->skinnum == number) && (sk->surfnum == surf) && (i < 5)) { i = 5; skzero = sk; }
706
        else if ((sk->palette ==   0) && (sk->skinnum == number) && (sk->surfnum == surf) && (i < 5)) { i = 5; skzero = sk; }
706
        else if ((sk->palette == pal) && (sk->skinnum ==      0) && (sk->surfnum == surf) && (i < 4)) { i = 4; skzero = sk; }
707
        else if ((sk->palette == pal) && (sk->skinnum ==      0) && (sk->surfnum == surf) && (i < 4)) { i = 4; skzero = sk; }
707
        else if ((sk->palette ==   0) && (sk->skinnum ==      0) && (sk->surfnum == surf) && (i < 3)) { i = 3; skzero = sk; }
708
        else if ((sk->palette ==   0) && (sk->skinnum ==      0) && (sk->surfnum == surf) && (i < 3)) { i = 3; skzero = sk; }
708
        else if ((sk->palette ==   0) && (sk->skinnum == number) && (i < 2)) { i = 2; skzero = sk; }
709
        else if ((sk->palette ==   0) && (sk->skinnum == number) && (i < 2)) { i = 2; skzero = sk; }
709
        else if ((sk->palette == pal) && (sk->skinnum ==      0) && (i < 1)) { i = 1; skzero = sk; }
710
        else if ((sk->palette == pal) && (sk->skinnum ==      0) && (i < 1)) { i = 1; skzero = sk; }
710
        else if ((sk->palette ==   0) && (sk->skinnum ==      0) && (i < 0)) { i = 0; skzero = sk; }
711
        else if ((sk->palette ==   0) && (sk->skinnum ==      0) && (i < 0)) { i = 0; skzero = sk; }
711
    }
712
    }
712
713
713
    if (!sk)
714
    if (!sk)
714
    {
715
    {
715
        if (pal >= (MAXPALOOKUPS - RESERVEDPALS))
716
        if (pal >= (MAXPALOOKUPS - RESERVEDPALS))
716
            return (0);
717
            return (0);
717
718
718
        if (skzero)
719
        if (skzero)
719
        {
720
        {
720
            skinfile = skzero->fn;
721
            skinfile = skzero->fn;
721
            texidx = &skzero->texid[hicfxmask(pal)];
722
            texidx = &skzero->texid[hicfxmask(pal)];
722
            Bstrncpyz(fn, skinfile, BMAX_PATH);
723
            Bstrncpyz(fn, skinfile, BMAX_PATH);
723
            //OSD_Printf("Using def skin 0,0 as fallback, pal=%d\n", pal);
724
            //OSD_Printf("Using def skin 0,0 as fallback, pal=%d\n", pal);
724
        }
725
        }
725
        else
726
        else
726
            return 0;
727
            return 0;
727
#if 0
728
#if 0
728
        {
729
        {
729
            // fall back to the model-defined texture
730
            // fall back to the model-defined texture
730
            if ((unsigned)number >= (unsigned)m->numskins)
731
            if ((unsigned)number >= (unsigned)m->numskins)
731
                number = 0;
732
                number = 0;
732
733
733
            // m->skinfn is undefined when md3model_t is cast to md2model_t --> crash
734
            // m->skinfn is undefined when md3model_t is cast to md2model_t --> crash
734
            skinfile = m->skinfn + number*64;
735
            skinfile = m->skinfn + number*64;
735
            texidx = &m->texid[number*(HICEFFECTMASK+1) + hicfxmask(pal)];
736
            texidx = &m->texid[number*(HICEFFECTMASK+1) + hicfxmask(pal)];
736
            Bstrncpyz(fn, m->basepath, BMAX_PATH);
737
            Bstrncpyz(fn, m->basepath, BMAX_PATH);
737
            if ((Bstrlen(fn) + Bstrlen(skinfile)) < BMAX_PATH)
738
            if ((Bstrlen(fn) + Bstrlen(skinfile)) < BMAX_PATH)
738
                Bstrcat(fn,skinfile);
739
                Bstrcat(fn,skinfile);
739
            //OSD_Printf("Using MD2/MD3 skin (%d) %s, pal=%d\n",number,skinfile,pal);
740
            //OSD_Printf("Using MD2/MD3 skin (%d) %s, pal=%d\n",number,skinfile,pal);
740
        }
741
        }
741
#endif
742
#endif
742
    }
743
    }
743
744
744
    if (!skinfile[0])
745
    if (!skinfile[0])
745
        return 0;
746
        return 0;
746
747
747
    if (*texidx)
748
    if (*texidx)
748
        return *texidx;
749
        return *texidx;
749
750
750
    // possibly fetch an already loaded multitexture :_)
751
    // possibly fetch an already loaded multitexture :_)
751
    if (pal >= (MAXPALOOKUPS - RESERVEDPALS))
752
    if (pal >= (MAXPALOOKUPS - RESERVEDPALS))
752
        for (i=0; i<nextmodelid; i++)
753
        for (i=0; i<nextmodelid; i++)
753
            for (skzero = ((md2model_t *)models[i])->skinmap; skzero; skzero = skzero->next)
754
            for (skzero = ((md2model_t *)models[i])->skinmap; skzero; skzero = skzero->next)
754
                if (!Bstrcasecmp(skzero->fn, sk->fn) && skzero->texid[hicfxmask(pal)])
755
                if (!Bstrcasecmp(skzero->fn, sk->fn) && skzero->texid[hicfxmask(pal)])
755
                {
756
                {
756
                    int32_t f = hicfxmask(pal);
757
                    int32_t f = hicfxmask(pal);
757
758
758
                    sk->texid[f] = skzero->texid[f];
759
                    sk->texid[f] = skzero->texid[f];
759
                    return sk->texid[f];
760
                    return sk->texid[f];
760
                }
761
                }
761
762
762
    *texidx = 0;
763
    *texidx = 0;
763
764
764
    if ((filh = kopen4load(fn, 0)) < 0)
765
    if ((filh = kopen4load(fn, 0)) < 0)
765
    {
766
    {
766
        OSD_Printf("Skin \"%s\" not found.\n",fn);
767
        OSD_Printf("Skin \"%s\" not found.\n",fn);
767
        skinfile[0] = 0;
768
        skinfile[0] = 0;
768
        return 0;
769
        return 0;
769
    }
770
    }
770
771
771
772
772
    picfillen = kfilelength(filh);
773
    picfillen = kfilelength(filh);
773
    kclose(filh);       // FIXME: shouldn't have to do this. bug in cache1d.c
774
    kclose(filh);       // FIXME: shouldn't have to do this. bug in cache1d.c
774
775
775
    startticks = getticks();
776
    startticks = getticks();
776
777
777
    gotcache = texcache_readtexheader(fn, picfillen, pal<<8, hicfxmask(pal), &cachead, 1);
778
    gotcache = texcache_readtexheader(fn, picfillen, pal<<8, hicfxmask(pal), &cachead, 1);
778
779
779
    if (gotcache && !texcache_loadskin(&cachead, &doalloc, texidx, &xsiz, &ysiz))
780
    if (gotcache && !texcache_loadskin(&cachead, &doalloc, texidx, &siz.x, &siz.y))
780
    {
781
    {
781
        osizx = cachead.xdim;
782
        osizx = cachead.xdim;
782
        osizy = cachead.ydim;
783
        osizy = cachead.ydim;
783
        hasalpha = (cachead.flags & CACHEAD_HASALPHA) ? 1 : 0;
784
        hasalpha = (cachead.flags & CACHEAD_HASALPHA) ? 1 : 0;
784
        if (pal < (MAXPALOOKUPS - RESERVEDPALS))
785
        if (pal < (MAXPALOOKUPS - RESERVEDPALS))
785
            m->usesalpha = hasalpha;
786
            m->usesalpha = hasalpha;
786
        //kclose(filh); // FIXME: uncomment when cache1d.c is fixed
787
        //kclose(filh); // FIXME: uncomment when cache1d.c is fixed
787
    }
788
    }
788
    else
789
    else
789
    {
790
    {
790
        int32_t ret;
791
        int32_t ret;
791
        intptr_t fptr=0;
792
        intptr_t fptr=0;
792
793
793
        gotcache = 0;   // the compressed version will be saved to disk
794
        gotcache = 0;   // the compressed version will be saved to disk
794
795
795
        if ((filh = kopen4load(fn, 0)) < 0)
796
        if ((filh = kopen4load(fn, 0)) < 0)
796
            return -1;
797
            return -1;
797
798
798
        ret = daskinloader(filh,&fptr,&bpl,&xsiz,&ysiz,&osizx,&osizy,&hasalpha,pal,hicfxmask(pal));
799
        ret = daskinloader(filh,&fptr,&bpl,&siz.x,&siz.y,&osizx,&osizy,&hasalpha,pal,hicfxmask(pal));
799
800
800
        if (ret)
801
        if (ret)
801
        {
802
        {
802
            kclose(filh);
803
            kclose(filh);
803
            OSD_Printf("Failed loading skin file \"%s\": error %d\n", fn, ret);
804
            OSD_Printf("Failed loading skin file \"%s\": error %d\n", fn, ret);
804
            if (ret==-1)
805
            if (ret==-1)
805
                QuitOnFatalError("OUT OF MEMORY in daskinloader!");
806
                QuitOnFatalError("OUT OF MEMORY in daskinloader!");
806
807
807
            skinfile[0] = 0;
808
            skinfile[0] = 0;
808
            return(0);
809
            return(0);
809
        }
810
        }
810
        else kclose(filh);
811
        else kclose(filh);
811
812
812
        willprint = 1;
813
        willprint = 1;
813
814
814
        if (pal < (MAXPALOOKUPS - RESERVEDPALS))
815
        if (pal < (MAXPALOOKUPS - RESERVEDPALS))
815
            m->usesalpha = hasalpha;
816
            m->usesalpha = hasalpha;
816
        if ((doalloc&3)==1)
817
        if ((doalloc&3)==1)
817
            bglGenTextures(1, texidx);
818
            bglGenTextures(1, texidx);
818
819
819
        bglBindTexture(GL_TEXTURE_2D, *texidx);
820
        bglBindTexture(GL_TEXTURE_2D, *texidx);
820
821
821
        //gluBuild2DMipmaps(GL_TEXTURE_2D,GL_RGBA,xsiz,ysiz,GL_BGRA_EXT,GL_UNSIGNED_BYTE,(char *)fptr);
822
        //gluBuild2DMipmaps(GL_TEXTURE_2D,GL_RGBA,xsiz,ysiz,GL_BGRA_EXT,GL_UNSIGNED_BYTE,(char *)fptr);
822
        if (glinfo.texcompr && glusetexcompr)
823
        if (glinfo.texcompr && glusetexcompr)
823
            intexfmt = hasalpha ? GL_COMPRESSED_RGBA_ARB : GL_COMPRESSED_RGB_ARB;
824
            intexfmt = hasalpha ? GL_COMPRESSED_RGBA_ARB : GL_COMPRESSED_RGB_ARB;
824
        else if (!hasalpha)
825
        else if (!hasalpha)
825
            intexfmt = GL_RGB;
826
            intexfmt = GL_RGB;
826
827
827
        if (glinfo.bgra)
828
        if (glinfo.bgra)
828
            texfmt = GL_BGRA;
829
            texfmt = GL_BGRA;
829
830
830
        uploadtexture((doalloc&1), xsiz, ysiz, intexfmt, texfmt, (coltype *)fptr, xsiz, ysiz, DAMETH_HI);
831
        uploadtexture((doalloc&1), siz, intexfmt, texfmt, (coltype *)fptr, siz, DAMETH_HI);
831
        Bfree((void *)fptr);
832
        Bfree((void *)fptr);
832
    }
833
    }
833
834
834
    if (!m->skinloaded)
835
    if (!m->skinloaded)
835
    {
836
    {
836
        if (xsiz != osizx || ysiz != osizy)
837
        if (siz.x != osizx || siz.y != osizy)
837
        {
838
        {
838
            float fx, fy;
839
            float fx, fy;
839
            fx = ((float)osizx)/((float)xsiz);
840
            fx = ((float)osizx)/((float)siz.x);
840
            fy = ((float)osizy)/((float)ysiz);
841
            fy = ((float)osizy)/((float)siz.y);
841
            if (m->mdnum == 2)
842
            if (m->mdnum == 2)
842
            {
843
            {
843
                int32_t *lptr;
844
                int32_t *lptr;
844
                for (lptr=m->glcmds; (i=*lptr++);)
845
                for (lptr=m->glcmds; (i=*lptr++);)
845
                    for (i=labs(i); i>0; i--,lptr+=3)
846
                    for (i=labs(i); i>0; i--,lptr+=3)
846
                    {
847
                    {
847
                        ((float *)lptr)[0] *= fx;
848
                        ((float *)lptr)[0] *= fx;
848
                        ((float *)lptr)[1] *= fy;
849
                        ((float *)lptr)[1] *= fy;
849
                    }
850
                    }
850
            }
851
            }
851
            else if (m->mdnum == 3)
852
            else if (m->mdnum == 3)
852
            {
853
            {
853
                md3model_t *m3 = (md3model_t *)m;
854
                md3model_t *m3 = (md3model_t *)m;
854
                md3surf_t *s;
855
                md3surf_t *s;
855
                int32_t surfi;
856
                int32_t surfi;
856
                for (surfi=0; surfi<m3->head.numsurfs; surfi++)
857
                for (surfi=0; surfi<m3->head.numsurfs; surfi++)
857
                {
858
                {
858
                    s = &m3->head.surfs[surfi];
859
                    s = &m3->head.surfs[surfi];
859
                    for (i=s->numverts-1; i>=0; i--)
860
                    for (i=s->numverts-1; i>=0; i--)
860
                    {
861
                    {
861
                        s->uv[i].u *= fx;
862
                        s->uv[i].u *= fx;
862
                        s->uv[i].v *= fy;
863
                        s->uv[i].v *= fy;
863
                    }
864
                    }
864
                }
865
                }
865
            }
866
            }
866
        }
867
        }
867
        m->skinloaded = 1+number;
868
        m->skinloaded = 1+number;
868
    }
869
    }
869
870
870
    bglTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,glfiltermodes[gltexfiltermode].mag);
871
    bglTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,glfiltermodes[gltexfiltermode].mag);
871
    bglTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,glfiltermodes[gltexfiltermode].min);
872
    bglTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,glfiltermodes[gltexfiltermode].min);
872
#ifndef EDUKE32_GLES
873
#ifndef EDUKE32_GLES
873
    if (glinfo.maxanisotropy > 1.0)
874
    if (glinfo.maxanisotropy > 1.0)
874
        bglTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAX_ANISOTROPY_EXT,glanisotropy);
875
        bglTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAX_ANISOTROPY_EXT,glanisotropy);
875
#endif
876
#endif
876
    bglTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
877
    bglTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
877
    bglTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
878
    bglTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
878
879
879
    if (glinfo.texcompr && glusetexcompr && glusetexcache)
880
    if (glinfo.texcompr && glusetexcompr && glusetexcache)
880
        if (!gotcache)
881
        if (!gotcache)
881
        {
882
        {
882
            const int32_t nonpow2 = check_nonpow2(xsiz) || check_nonpow2(ysiz);
883
            const int32_t nonpow2 = check_nonpow2(siz.x) || check_nonpow2(siz.y);
883
884
884
            // save off the compressed version
885
            // save off the compressed version
885
            cachead.quality = r_downsize;
886
            cachead.quality = r_downsize;
886
            cachead.xdim = osizx>>cachead.quality;
887
            cachead.xdim = osizx>>cachead.quality;
887
            cachead.ydim = osizy>>cachead.quality;
888
            cachead.ydim = osizy>>cachead.quality;
888
889
889
            cachead.flags = nonpow2*CACHEAD_NONPOW2 | (hasalpha ? CACHEAD_HASALPHA : 0);
890
            cachead.flags = nonpow2*CACHEAD_NONPOW2 | (hasalpha ? CACHEAD_HASALPHA : 0);
890
891
891
///            OSD_Printf("Caching \"%s\"\n",fn);
892
///            OSD_Printf("Caching \"%s\"\n",fn);
892
            texcache_writetex(fn, picfillen, pal<<8, hicfxmask(pal), &cachead);
893
            texcache_writetex(fn, picfillen, pal<<8, hicfxmask(pal), &cachead);
893
894
894
            if (willprint)
895
            if (willprint)
895
            {
896
            {
896
                int32_t etime = getticks()-startticks;
897
                int32_t etime = getticks()-startticks;
897
                if (etime>=MIN_CACHETIME_PRINT)
898
                if (etime>=MIN_CACHETIME_PRINT)
898
                    OSD_Printf("Load skin: p%d-e%d \"%s\"... cached... %d ms\n", pal, hicfxmask(pal), fn, etime);
899
                    OSD_Printf("Load skin: p%d-e%d \"%s\"... cached... %d ms\n", pal, hicfxmask(pal), fn, etime);
899
                willprint = 0;
900
                willprint = 0;
900
            }
901
            }
901
            else
902
            else
902
                OSD_Printf("Cached skin \"%s\"\n", fn);
903
                OSD_Printf("Cached skin \"%s\"\n", fn);
903
        }
904
        }
904
905
905
    if (willprint)
906
    if (willprint)
906
    {
907
    {
907
        int32_t etime = getticks()-startticks;
908
        int32_t etime = getticks()-startticks;
908
        if (etime>=MIN_CACHETIME_PRINT)
909
        if (etime>=MIN_CACHETIME_PRINT)
909
            OSD_Printf("Load skin: p%d-e%d \"%s\"... %d ms\n", pal, hicfxmask(pal), fn, etime);
910
            OSD_Printf("Load skin: p%d-e%d \"%s\"... %d ms\n", pal, hicfxmask(pal), fn, etime);
910
    }
911
    }
911
912
912
    return(*texidx);
913
    return(*texidx);
913
}
914
}
914
915
915
//Note: even though it says md2model, it works for both md2model&md3model
916
//Note: even though it says md2model, it works for both md2model&md3model
916
void updateanimation(md2model_t *m, const tspritetype *tspr, uint8_t lpal)
917
void updateanimation(md2model_t *m, const tspritetype *tspr, uint8_t lpal)
917
{
918
{
918
    const mdanim_t *anim;
919
    const mdanim_t *anim;
919
    int32_t i, j, k;
920
    int32_t i, j, k;
920
    int32_t fps;
921
    int32_t fps;
921
922
922
    int32_t tile, smoothdurationp;
923
    int32_t tile, smoothdurationp;
923
    spritesmooth_t *smooth;
924
    spritesmooth_t *smooth;
924
    spriteext_t *sprext;
925
    spriteext_t *sprext;
925
926
926
    if (m->numframes < 2)
927
    if (m->numframes < 2)
927
    {
928
    {
928
        m->interpol = 0;
929
        m->interpol = 0;
929
        return;
930
        return;
930
    }
931
    }
931
932
932
    tile = Ptile2tile(tspr->picnum,lpal);
933
    tile = Ptile2tile(tspr->picnum,lpal);
933
    m->cframe = m->nframe = tile2model[tile].framenum;
934
    m->cframe = m->nframe = tile2model[tile].framenum;
934
#ifdef DEBUGGINGAIDS
935
#ifdef DEBUGGINGAIDS
935
    if (m->cframe >= m->numframes)
936
    if (m->cframe >= m->numframes)
936
        OSD_Printf("1: c > n\n");
937
        OSD_Printf("1: c > n\n");
937
#endif
938
#endif
938
939
939
    smoothdurationp = (r_animsmoothing && (tile2model[tile].smoothduration != 0));
940
    smoothdurationp = (r_animsmoothing && (tile2model[tile].smoothduration != 0));
940
941
941
    smooth = ((unsigned)tspr->owner < MAXSPRITES+MAXUNIQHUDID) ? &spritesmooth[tspr->owner] : NULL;
942
    smooth = ((unsigned)tspr->owner < MAXSPRITES+MAXUNIQHUDID) ? &spritesmooth[tspr->owner] : NULL;
942
    sprext = ((unsigned)tspr->owner < MAXSPRITES+MAXUNIQHUDID) ? &spriteext[tspr->owner] : NULL;
943
    sprext = ((unsigned)tspr->owner < MAXSPRITES+MAXUNIQHUDID) ? &spriteext[tspr->owner] : NULL;
943
944
944
    for (anim = m->animations; anim && anim->startframe != m->cframe; anim = anim->next)
945
    for (anim = m->animations; anim && anim->startframe != m->cframe; anim = anim->next)
945
    {
946
    {
946
        /* do nothing */;
947
        /* do nothing */;
947
    }
948
    }
948
949
949
    if (!anim)
950
    if (!anim)
950
    {
951
    {
951
        if (!smoothdurationp || ((smooth->mdoldframe == m->cframe) && (smooth->mdcurframe == m->cframe)))
952
        if (!smoothdurationp || ((smooth->mdoldframe == m->cframe) && (smooth->mdcurframe == m->cframe)))
952
        {
953
        {
953
            m->interpol = 0;
954
            m->interpol = 0;
954
            return;
955
            return;
955
        }
956
        }
956
957
957
        // assert(smoothdurationp && ((smooth->mdoldframe != m->cframe) || (smooth->mdcurframe != m->cframe)))
958
        // assert(smoothdurationp && ((smooth->mdoldframe != m->cframe) || (smooth->mdcurframe != m->cframe)))
958
959
959
        if (smooth->mdoldframe != m->cframe)
960
        if (smooth->mdoldframe != m->cframe)
960
        {
961
        {
961
            if (smooth->mdsmooth == 0)
962
            if (smooth->mdsmooth == 0)
962
            {
963
            {
963
                sprext->mdanimtims = mdtims;
964
                sprext->mdanimtims = mdtims;
964
                m->interpol = 0;
965
                m->interpol = 0;
965
                smooth->mdsmooth = 1;
966
                smooth->mdsmooth = 1;
966
                smooth->mdcurframe = m->cframe;
967
                smooth->mdcurframe = m->cframe;
967
            }
968
            }
968
969
969
            if (smooth->mdcurframe != m->cframe)
970
            if (smooth->mdcurframe != m->cframe)
970
            {
971
            {
971
                sprext->mdanimtims = mdtims;
972
                sprext->mdanimtims = mdtims;
972
                m->interpol = 0;
973
                m->interpol = 0;
973
                smooth->mdsmooth = 1;
974
                smooth->mdsmooth = 1;
974
                smooth->mdoldframe = smooth->mdcurframe;
975
                smooth->mdoldframe = smooth->mdcurframe;
975
                smooth->mdcurframe = m->cframe;
976
                smooth->mdcurframe = m->cframe;
976
            }
977
            }
977
        }
978
        }
978
        else  // if (smooth->mdcurframe != m->cframe)
979
        else  // if (smooth->mdcurframe != m->cframe)
979
        {
980
        {
980
            sprext->mdanimtims = mdtims;
981
            sprext->mdanimtims = mdtims;
981
            m->interpol = 0;
982
            m->interpol = 0;
982
            smooth->mdsmooth = 1;
983
            smooth->mdsmooth = 1;
983
            smooth->mdoldframe = smooth->mdcurframe;
984
            smooth->mdoldframe = smooth->mdcurframe;
984
            smooth->mdcurframe = m->cframe;
985
            smooth->mdcurframe = m->cframe;
985
        }
986
        }
986
    }
987
    }
987
    else if (/* anim && */ sprext->mdanimcur != anim->startframe)
988
    else if (/* anim && */ sprext->mdanimcur != anim->startframe)
988
    {
989
    {
989
        //if (sprext->flags & SPREXT_NOMDANIM) OSD_Printf("SPREXT_NOMDANIM\n");
990
        //if (sprext->flags & SPREXT_NOMDANIM) OSD_Printf("SPREXT_NOMDANIM\n");
990
        //OSD_Printf("smooth launched ! oldanim %i new anim %i\n", sprext->mdanimcur, anim->startframe);
991
        //OSD_Printf("smooth launched ! oldanim %i new anim %i\n", sprext->mdanimcur, anim->startframe);
991
        sprext->mdanimcur = (int16_t)anim->startframe;
992
        sprext->mdanimcur = (int16_t)anim->startframe;
992
        sprext->mdanimtims = mdtims;
993
        sprext->mdanimtims = mdtims;
993
        m->interpol = 0;
994
        m->interpol = 0;
994
995
995
        if (!smoothdurationp)
996
        if (!smoothdurationp)
996
        {
997
        {
997
            m->cframe = m->nframe = anim->startframe;
998
            m->cframe = m->nframe = anim->startframe;
998
#ifdef DEBUGGINGAIDS
999
#ifdef DEBUGGINGAIDS
999
            if (m->cframe >= m->numframes)
1000
            if (m->cframe >= m->numframes)
1000
                OSD_Printf("2: c > n\n");
1001
                OSD_Printf("2: c > n\n");
1001
#endif
1002
#endif
1002
            return;
1003
            return;
1003
        }
1004
        }
1004
1005
1005
        m->nframe = anim->startframe;
1006
        m->nframe = anim->startframe;
1006
        m->cframe = smooth->mdoldframe;
1007
        m->cframe = smooth->mdoldframe;
1007
#ifdef DEBUGGINGAIDS
1008
#ifdef DEBUGGINGAIDS
1008
        if (m->cframe >= m->numframes)
1009
        if (m->cframe >= m->numframes)
1009
            OSD_Printf("3: c > n\n");
1010
            OSD_Printf("3: c > n\n");
1010
#endif
1011
#endif
1011
        smooth->mdsmooth = 1;
1012
        smooth->mdsmooth = 1;
1012
        return;
1013
        return;
1013
    }
1014
    }
1014
1015
1015
    fps = smooth->mdsmooth ? Blrintf((1.0f / (float) (tile2model[tile].smoothduration)) * 66.f) : anim->fpssc;
1016
    fps = smooth->mdsmooth ? Blrintf((1.0f / (float) (tile2model[tile].smoothduration)) * 66.f) : anim->fpssc;
1016
1017
1017
    i = (mdtims - sprext->mdanimtims)*((fps*timerticspersec)/120);
1018
    i = (mdtims - sprext->mdanimtims)*((fps*timerticspersec)/120);
1018
1019
1019
    if (smooth->mdsmooth)
1020
    if (smooth->mdsmooth)
1020
        j = 65536;
1021
        j = 65536;
1021
    else
1022
    else
1022
        j = ((anim->endframe+1-anim->startframe)<<16);
1023
        j = ((anim->endframe+1-anim->startframe)<<16);
1023
    // XXX: Just in case you play the game for a VERY long time...
1024
    // XXX: Just in case you play the game for a VERY long time...
1024
    if (i < 0) { i = 0; sprext->mdanimtims = mdtims; }
1025
    if (i < 0) { i = 0; sprext->mdanimtims = mdtims; }
1025
    //compare with j*2 instead of j to ensure i stays > j-65536 for MDANIM_ONESHOT
1026
    //compare with j*2 instead of j to ensure i stays > j-65536 for MDANIM_ONESHOT
1026
    if (anim && (i >= j+j) && (fps) && !mdpause) //Keep mdanimtims close to mdtims to avoid the use of MOD
1027
    if (anim && (i >= j+j) && (fps) && !mdpause) //Keep mdanimtims close to mdtims to avoid the use of MOD
1027
        sprext->mdanimtims += j/((fps*timerticspersec)/120);
1028
        sprext->mdanimtims += j/((fps*timerticspersec)/120);
1028
1029
1029
    k = i;
1030
    k = i;
1030
1031
1031
    if (anim && (anim->flags&MDANIM_ONESHOT))
1032
    if (anim && (anim->flags&MDANIM_ONESHOT))
1032
        { if (i > j-65536) i = j-65536; }
1033
        { if (i > j-65536) i = j-65536; }
1033
    else { if (i >= j) { i -= j; if (i >= j) i %= j; } }
1034
    else { if (i >= j) { i -= j; if (i >= j) i %= j; } }
1034
1035
1035
    if (r_animsmoothing && smooth->mdsmooth)
1036
    if (r_animsmoothing && smooth->mdsmooth)
1036
    {
1037
    {
1037
        m->nframe = anim ? anim->startframe : smooth->mdcurframe;
1038
        m->nframe = anim ? anim->startframe : smooth->mdcurframe;
1038
        m->cframe = smooth->mdoldframe;
1039
        m->cframe = smooth->mdoldframe;
1039
#ifdef DEBUGGINGAIDS
1040
#ifdef DEBUGGINGAIDS
1040
        if (m->cframe >= m->numframes)
1041
        if (m->cframe >= m->numframes)
1041
            OSD_Printf("4: c > n\n");
1042
            OSD_Printf("4: c > n\n");
1042
#endif
1043
#endif
1043
        //OSD_Printf("smoothing... cframe %i nframe %i\n", m->cframe, m->nframe);
1044
        //OSD_Printf("smoothing... cframe %i nframe %i\n", m->cframe, m->nframe);
1044
        if (k > 65535)
1045
        if (k > 65535)
1045
        {
1046
        {
1046
            sprext->mdanimtims = mdtims;
1047
            sprext->mdanimtims = mdtims;
1047
            m->interpol = 0;
1048
            m->interpol = 0;
1048
            smooth->mdsmooth = 0;
1049
            smooth->mdsmooth = 0;
1049
            m->cframe = m->nframe; // = anim ? anim->startframe : smooth->mdcurframe;
1050
            m->cframe = m->nframe; // = anim ? anim->startframe : smooth->mdcurframe;
1050
#ifdef DEBUGGINGAIDS
1051
#ifdef DEBUGGINGAIDS
1051
            if (m->cframe >= m->numframes)
1052
            if (m->cframe >= m->numframes)
1052
                OSD_Printf("5: c > n\n");
1053
                OSD_Printf("5: c > n\n");
1053
#endif
1054
#endif
1054
            smooth->mdoldframe = m->cframe;
1055
            smooth->mdoldframe = m->cframe;
1055
            //OSD_Printf("smooth stopped !\n");
1056
            //OSD_Printf("smooth stopped !\n");
1056
            return;
1057
            return;
1057
        }
1058
        }
1058
    }
1059
    }
1059
    else
1060
    else
1060
    {
1061
    {
1061
        m->cframe = (i>>16)+anim->startframe;
1062
        m->cframe = (i>>16)+anim->startframe;
1062
#ifdef DEBUGGINGAIDS
1063
#ifdef DEBUGGINGAIDS
1063
        if (m->cframe >= m->numframes)
1064
        if (m->cframe >= m->numframes)
1064
            OSD_Printf("6: c > n\n");
1065
            OSD_Printf("6: c > n\n");
1065
#endif
1066
#endif
1066
        m->nframe = m->cframe+1;
1067
        m->nframe = m->cframe+1;
1067
        if (m->nframe > anim->endframe)  // VERIFY: (!(r_animsmoothing && smooth->mdsmooth)) implies (anim!=NULL) ?
1068
        if (m->nframe > anim->endframe)  // VERIFY: (!(r_animsmoothing && smooth->mdsmooth)) implies (anim!=NULL) ?
1068
            m->nframe = anim->startframe;
1069
            m->nframe = anim->startframe;
1069
1070
1070
        smooth->mdoldframe = m->cframe;
1071
        smooth->mdoldframe = m->cframe;
1071
        //OSD_Printf("not smoothing... cframe %i nframe %i\n", m->cframe, m->nframe);
1072
        //OSD_Printf("not smoothing... cframe %i nframe %i\n", m->cframe, m->nframe);
1072
    }
1073
    }
1073
1074
1074
    m->interpol = ((float)(i&65535))/65536.f;
1075
    m->interpol = ((float)(i&65535))/65536.f;
1075
    //OSD_Printf("interpol %f\n", m->interpol);
1076
    //OSD_Printf("interpol %f\n", m->interpol);
1076
}
1077
}
1077
1078
1078
// VBO generation and allocation
1079
// VBO generation and allocation
1079
static void mdloadvbos(md3model_t *m)
1080
static void mdloadvbos(md3model_t *m)
1080
{
1081
{
1081
    int32_t     i;
1082
    int32_t     i;
1082
1083
1083
    m->vbos = (GLuint *)Xmalloc(m->head.numsurfs * sizeof(GLuint));
1084
    m->vbos = (GLuint *)Xmalloc(m->head.numsurfs * sizeof(GLuint));
1084
    bglGenBuffersARB(m->head.numsurfs, m->vbos);
1085
    bglGenBuffersARB(m->head.numsurfs, m->vbos);
1085
1086
1086
    i = 0;
1087
    i = 0;
1087
    while (i < m->head.numsurfs)
1088
    while (i < m->head.numsurfs)
1088
    {
1089
    {
1089
        bglBindBufferARB(GL_ARRAY_BUFFER_ARB, m->vbos[i]);
1090
        bglBindBufferARB(GL_ARRAY_BUFFER_ARB, m->vbos[i]);
1090
        bglBufferDataARB(GL_ARRAY_BUFFER_ARB, m->head.surfs[i].numverts * sizeof(md3uv_t), m->head.surfs[i].uv, GL_STATIC_DRAW_ARB);
1091
        bglBufferDataARB(GL_ARRAY_BUFFER_ARB, m->head.surfs[i].numverts * sizeof(md3uv_t), m->head.surfs[i].uv, GL_STATIC_DRAW_ARB);
1091
        i++;
1092
        i++;
1092
    }
1093
    }
1093
    bglBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
1094
    bglBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
1094
}
1095
}
1095
1096
1096
//--------------------------------------- MD2 LIBRARY BEGINS ---------------------------------------
1097
//--------------------------------------- MD2 LIBRARY BEGINS ---------------------------------------
1097
static md2model_t *md2load(int32_t fil, const char *filnam)
1098
static md2model_t *md2load(int32_t fil, const char *filnam)
1098
{
1099
{
1099
    md2model_t *m;
1100
    md2model_t *m;
1100
    md3model_t *m3;
1101
    md3model_t *m3;
1101
    md3surf_t *s;
1102
    md3surf_t *s;
1102
    md2frame_t *f;
1103
    md2frame_t *f;
1103
    md2head_t head;
1104
    md2head_t head;
1104
    char st[BMAX_PATH];
1105
    char st[BMAX_PATH];
1105
    int32_t i, j, k;
1106
    int32_t i, j, k;
1106
1107
1107
    int32_t ournumskins, ournumglcmds;
1108
    int32_t ournumskins, ournumglcmds;
1108
1109
1109
    m = (md2model_t *)Xcalloc(1,sizeof(md2model_t));
1110
    m = (md2model_t *)Xcalloc(1,sizeof(md2model_t));
1110
    m->mdnum = 2; m->scale = .01f;
1111
    m->mdnum = 2; m->scale = .01f;
1111
1112
1112
    kread(fil,(char *)&head,sizeof(md2head_t));
1113
    kread(fil,(char *)&head,sizeof(md2head_t));
1113
#if B_BIG_ENDIAN != 0
1114
#if B_BIG_ENDIAN != 0
1114
    head.id = B_LITTLE32(head.id);                 head.vers = B_LITTLE32(head.vers);
1115
    head.id = B_LITTLE32(head.id);                 head.vers = B_LITTLE32(head.vers);
1115
    head.skinxsiz = B_LITTLE32(head.skinxsiz);     head.skinysiz = B_LITTLE32(head.skinysiz);
1116
    head.skinxsiz = B_LITTLE32(head.skinxsiz);     head.skinysiz = B_LITTLE32(head.skinysiz);
1116
    head.framebytes = B_LITTLE32(head.framebytes); head.numskins = B_LITTLE32(head.numskins);
1117
    head.framebytes = B_LITTLE32(head.framebytes); head.numskins = B_LITTLE32(head.numskins);
1117
    head.numverts = B_LITTLE32(head.numverts);     head.numuv = B_LITTLE32(head.numuv);
1118
    head.numverts = B_LITTLE32(head.numverts);     head.numuv = B_LITTLE32(head.numuv);
1118
    head.numtris = B_LITTLE32(head.numtris);       head.numglcmds = B_LITTLE32(head.numglcmds);
1119
    head.numtris = B_LITTLE32(head.numtris);       head.numglcmds = B_LITTLE32(head.numglcmds);
1119
    head.numframes = B_LITTLE32(head.numframes);   head.ofsskins = B_LITTLE32(head.ofsskins);
1120
    head.numframes = B_LITTLE32(head.numframes);   head.ofsskins = B_LITTLE32(head.ofsskins);
1120
    head.ofsuv = B_LITTLE32(head.ofsuv);           head.ofstris = B_LITTLE32(head.ofstris);
1121
    head.ofsuv = B_LITTLE32(head.ofsuv);           head.ofstris = B_LITTLE32(head.ofstris);
1121
    head.ofsframes = B_LITTLE32(head.ofsframes);   head.ofsglcmds = B_LITTLE32(head.ofsglcmds);
1122
    head.ofsframes = B_LITTLE32(head.ofsframes);   head.ofsglcmds = B_LITTLE32(head.ofsglcmds);
1122
    head.ofseof = B_LITTLE32(head.ofseof);
1123
    head.ofseof = B_LITTLE32(head.ofseof);
1123
#endif
1124
#endif
1124
1125
1125
    if ((head.id != IDP2_MAGIC) || (head.vers != 8)) { Bfree(m); return(0); } //"IDP2"
1126
    if ((head.id != IDP2_MAGIC) || (head.vers != 8)) { Bfree(m); return(0); } //"IDP2"
1126
1127
1127
    ournumskins = head.numskins ? head.numskins : 1;
1128
    ournumskins = head.numskins ? head.numskins : 1;
1128
    ournumglcmds = head.numglcmds ? head.numglcmds : 1;
1129
    ournumglcmds = head.numglcmds ? head.numglcmds : 1;
1129
1130
1130
    m->numskins = head.numskins;
1131
    m->numskins = head.numskins;
1131
    m->numframes = head.numframes;
1132
    m->numframes = head.numframes;
1132
    m->numverts = head.numverts;
1133
    m->numverts = head.numverts;
1133
    m->numglcmds = head.numglcmds;
1134
    m->numglcmds = head.numglcmds;
1134
    m->framebytes = head.framebytes;
1135
    m->framebytes = head.framebytes;
1135
1136
1136
    m->frames = (char *)Xmalloc(m->numframes*m->framebytes);
1137
    m->frames = (char *)Xmalloc(m->numframes*m->framebytes);
1137
    m->glcmds = (int32_t *)Xmalloc(ournumglcmds*sizeof(int32_t));
1138
    m->glcmds = (int32_t *)Xmalloc(ournumglcmds*sizeof(int32_t));
1138
    m->tris = (md2tri_t *)Xmalloc(head.numtris*sizeof(md2tri_t));
1139
    m->tris = (md2tri_t *)Xmalloc(head.numtris*sizeof(md2tri_t));
1139
    m->uv = (md2uv_t *)Xmalloc(head.numuv*sizeof(md2uv_t));
1140
    m->uv = (md2uv_t *)Xmalloc(head.numuv*sizeof(md2uv_t));
1140
1141
1141
    klseek(fil,head.ofsframes,SEEK_SET);
1142
    klseek(fil,head.ofsframes,SEEK_SET);
1142
    if (kread(fil,(char *)m->frames,m->numframes*m->framebytes) != m->numframes*m->framebytes)
1143
    if (kread(fil,(char *)m->frames,m->numframes*m->framebytes) != m->numframes*m->framebytes)
1143
        { Bfree(m->uv); Bfree(m->tris); Bfree(m->glcmds); Bfree(m->frames); Bfree(m); return(0); }
1144
        { Bfree(m->uv); Bfree(m->tris); Bfree(m->glcmds); Bfree(m->frames); Bfree(m); return(0); }
1144
1145
1145
    if (m->numglcmds > 0)
1146
    if (m->numglcmds > 0)
1146
    {
1147
    {
1147
        klseek(fil,head.ofsglcmds,SEEK_SET);
1148
        klseek(fil,head.ofsglcmds,SEEK_SET);
1148
        if (kread(fil,(char *)m->glcmds,m->numglcmds*sizeof(int32_t)) != (int32_t)(m->numglcmds*sizeof(int32_t)))
1149
        if (kread(fil,(char *)m->glcmds,m->numglcmds*sizeof(int32_t)) != (int32_t)(m->numglcmds*sizeof(int32_t)))
1149
            { Bfree(m->uv); Bfree(m->tris); Bfree(m->glcmds); Bfree(m->frames); Bfree(m); return(0); }
1150
            { Bfree(m->uv); Bfree(m->tris); Bfree(m->glcmds); Bfree(m->frames); Bfree(m); return(0); }
1150
    }
1151
    }
1151
1152
1152
    klseek(fil,head.ofstris,SEEK_SET);
1153
    klseek(fil,head.ofstris,SEEK_SET);
1153
    if (kread(fil,(char *)m->tris,head.numtris*sizeof(md2tri_t)) != (int32_t)(head.numtris*sizeof(md2tri_t)))
1154
    if (kread(fil,(char *)m->tris,head.numtris*sizeof(md2tri_t)) != (int32_t)(head.numtris*sizeof(md2tri_t)))
1154
        { Bfree(m->uv); Bfree(m->tris); Bfree(m->glcmds); Bfree(m->frames); Bfree(m); return(0); }
1155
        { Bfree(m->uv); Bfree(m->tris); Bfree(m->glcmds); Bfree(m->frames); Bfree(m); return(0); }
1155
1156
1156
    klseek(fil,head.ofsuv,SEEK_SET);
1157
    klseek(fil,head.ofsuv,SEEK_SET);
1157
    if (kread(fil,(char *)m->uv,head.numuv*sizeof(md2uv_t)) != (int32_t)(head.numuv*sizeof(md2uv_t)))
1158
    if (kread(fil,(char *)m->uv,head.numuv*sizeof(md2uv_t)) != (int32_t)(head.numuv*sizeof(md2uv_t)))
1158
        { Bfree(m->uv); Bfree(m->tris); Bfree(m->glcmds); Bfree(m->frames); Bfree(m); return(0); }
1159
        { Bfree(m->uv); Bfree(m->tris); Bfree(m->glcmds); Bfree(m->frames); Bfree(m); return(0); }
1159
1160
1160
#if B_BIG_ENDIAN != 0
1161
#if B_BIG_ENDIAN != 0
1161
    {
1162
    {
1162
        char *f = (char *)m->frames;
1163
        char *f = (char *)m->frames;
1163
        int32_t *l,j;
1164
        int32_t *l,j;
1164
        md2frame_t *fr;
1165
        md2frame_t *fr;
1165
1166
1166
        for (i = m->numframes-1; i>=0; i--)
1167
        for (i = m->numframes-1; i>=0; i--)
1167
        {
1168
        {
1168
            fr = (md2frame_t *)f;
1169
            fr = (md2frame_t *)f;
1169
            l = (int32_t *)&fr->mul;
1170
            l = (int32_t *)&fr->mul;
1170
            for (j=5; j>=0; j--) l[j] = B_LITTLE32(l[j]);
1171
            for (j=5; j>=0; j--) l[j] = B_LITTLE32(l[j]);
1171
            f += m->framebytes;
1172
            f += m->framebytes;
1172
        }
1173
        }
1173
1174
1174
        for (i = m->numglcmds-1; i>=0; i--)
1175
        for (i = m->numglcmds-1; i>=0; i--)
1175
        {
1176
        {
1176
            m->glcmds[i] = B_LITTLE32(m->glcmds[i]);
1177
            m->glcmds[i] = B_LITTLE32(m->glcmds[i]);
1177
        }
1178
        }
1178
        for (i = head.numtris-1; i>=0; i--)
1179
        for (i = head.numtris-1; i>=0; i--)
1179
        {
1180
        {
1180
            m->tris[i].v[0] = B_LITTLE16(m->tris[i].v[0]);
1181
            m->tris[i].v[0] = B_LITTLE16(m->tris[i].v[0]);
1181
            m->tris[i].v[1] = B_LITTLE16(m->tris[i].v[1]);
1182
            m->tris[i].v[1] = B_LITTLE16(m->tris[i].v[1]);
1182
            m->tris[i].v[2] = B_LITTLE16(m->tris[i].v[2]);
1183
            m->tris[i].v[2] = B_LITTLE16(m->tris[i].v[2]);
1183
            m->tris[i].u[0] = B_LITTLE16(m->tris[i].u[0]);
1184
            m->tris[i].u[0] = B_LITTLE16(m->tris[i].u[0]);
1184
            m->tris[i].u[1] = B_LITTLE16(m->tris[i].u[1]);
1185
            m->tris[i].u[1] = B_LITTLE16(m->tris[i].u[1]);
1185
            m->tris[i].u[2] = B_LITTLE16(m->tris[i].u[2]);
1186
            m->tris[i].u[2] = B_LITTLE16(m->tris[i].u[2]);
1186
        }
1187
        }
1187
        for (i = head.numuv-1; i>=0; i--)
1188
        for (i = head.numuv-1; i>=0; i--)
1188
        {
1189
        {
1189
            m->uv[i].u = B_LITTLE16(m->uv[i].u);
1190
            m->uv[i].u = B_LITTLE16(m->uv[i].u);
1190
            m->uv[i].v = B_LITTLE16(m->uv[i].v);
1191
            m->uv[i].v = B_LITTLE16(m->uv[i].v);
1191
        }
1192
        }
1192
    }
1193
    }
1193
#endif
1194
#endif
1194
1195
1195
    Bstrcpy(st,filnam);
1196
    Bstrcpy(st,filnam);
1196
    for (i=strlen(st)-1; i>0; i--)
1197
    for (i=strlen(st)-1; i>0; i--)
1197
        if ((st[i] == '/') || (st[i] == '\\')) { i++; break; }
1198
        if ((st[i] == '/') || (st[i] == '\\')) { i++; break; }
1198
    if (i<0) i=0;
1199
    if (i<0) i=0;
1199
    st[i] = 0;
1200
    st[i] = 0;
1200
    m->basepath = (char *)Xmalloc(i+1);
1201
    m->basepath = (char *)Xmalloc(i+1);
1201
    Bstrcpy(m->basepath, st);
1202
    Bstrcpy(m->basepath, st);
1202
1203
1203
    m->skinfn = (char *)Xmalloc(ournumskins*64);
1204
    m->skinfn = (char *)Xmalloc(ournumskins*64);
1204
    if (m->numskins > 0)
1205
    if (m->numskins > 0)
1205
    {
1206
    {
1206
        klseek(fil,head.ofsskins,SEEK_SET);
1207
        klseek(fil,head.ofsskins,SEEK_SET);
1207
        if (kread(fil,m->skinfn,64*m->numskins) != 64*m->numskins)
1208
        if (kread(fil,m->skinfn,64*m->numskins) != 64*m->numskins)
1208
            { Bfree(m->glcmds); Bfree(m->frames); Bfree(m); return(0); }
1209
            { Bfree(m->glcmds); Bfree(m->frames); Bfree(m); return(0); }
1209
    }
1210
    }
1210
1211
1211
    m->texid = (GLuint *)Xcalloc(ournumskins, sizeof(GLuint) * (HICEFFECTMASK+1));
1212
    m->texid = (GLuint *)Xcalloc(ournumskins, sizeof(GLuint) * (HICEFFECTMASK+1));
1212
1213
1213
    maxmodelverts = max(maxmodelverts, m->numverts);
1214
    maxmodelverts = max(maxmodelverts, m->numverts);
1214
    maxmodeltris = max(maxmodeltris, head.numtris);
1215
    maxmodeltris = max(maxmodeltris, head.numtris);
1215
1216
1216
    //return(m);
1217
    //return(m);
1217
1218
1218
    // the MD2 is now loaded internally - let's begin the MD3 conversion process
1219
    // the MD2 is now loaded internally - let's begin the MD3 conversion process
1219
    //OSD_Printf("Beginning md3 conversion.\n");
1220
    //OSD_Printf("Beginning md3 conversion.\n");
1220
    m3 = (md3model_t *)Xcalloc(1, sizeof(md3model_t));
1221
    m3 = (md3model_t *)Xcalloc(1, sizeof(md3model_t));
1221
    m3->mdnum = 3; m3->texid = 0; m3->scale = m->scale;
1222
    m3->mdnum = 3; m3->texid = 0; m3->scale = m->scale;
1222
    m3->head.id = IDP3_MAGIC; m3->head.vers = 15;
1223
    m3->head.id = IDP3_MAGIC; m3->head.vers = 15;
1223
1224
1224
    m3->head.flags = 0;
1225
    m3->head.flags = 0;
1225
1226
1226
    m3->head.numframes = m->numframes;
1227
    m3->head.numframes = m->numframes;
1227
    m3->head.numtags = 0; m3->head.numsurfs = 1;
1228
    m3->head.numtags = 0; m3->head.numsurfs = 1;
1228
    m3->head.numskins = 0;
1229
    m3->head.numskins = 0;
1229
1230
1230
    m3->numskins = m3->head.numskins;
1231
    m3->numskins = m3->head.numskins;
1231
    m3->numframes = m3->head.numframes;
1232
    m3->numframes = m3->head.numframes;
1232
1233
1233
    m3->head.frames = (md3frame_t *)Xcalloc(m3->head.numframes, sizeof(md3frame_t));
1234
    m3->head.frames = (md3frame_t *)Xcalloc(m3->head.numframes, sizeof(md3frame_t));
1234
    m3->muladdframes = (vec3f_t *)Xcalloc(m->numframes * 2, sizeof(vec3f_t));
1235
    m3->muladdframes = (vec3f_t *)Xcalloc(m->numframes * 2, sizeof(vec3f_t));
1235
1236
1236
    f = (md2frame_t *)(m->frames);
1237
    f = (md2frame_t *)(m->frames);
1237
1238
1238
    // frames converting
1239
    // frames converting
1239
    i = 0;
1240
    i = 0;
1240
    while (i < m->numframes)
1241
    while (i < m->numframes)
1241
    {
1242
    {
1242
        f = (md2frame_t *)&m->frames[i*m->framebytes];
1243
        f = (md2frame_t *)&m->frames[i*m->framebytes];
1243
        Bstrcpy(m3->head.frames[i].nam, f->name);
1244
        Bstrcpy(m3->head.frames[i].nam, f->name);
1244
        //OSD_Printf("Copied frame %s.\n", m3->head.frames[i].nam);
1245
        //OSD_Printf("Copied frame %s.\n", m3->head.frames[i].nam);
1245
        m3->muladdframes[i*2] = f->mul;
1246
        m3->muladdframes[i*2] = f->mul;
1246
        m3->muladdframes[i*2+1] = f->add;
1247
        m3->muladdframes[i*2+1] = f->add;
1247
        i++;
1248
        i++;
1248
    }
1249
    }
1249
1250
1250
    m3->head.tags = NULL;
1251
    m3->head.tags = NULL;
1251
1252
1252
    m3->head.surfs = (md3surf_t *)Xcalloc(1, sizeof(md3surf_t));
1253
    m3->head.surfs = (md3surf_t *)Xcalloc(1, sizeof(md3surf_t));
1253
    s = m3->head.surfs;
1254
    s = m3->head.surfs;
1254
1255
1255
    // model converting
1256
    // model converting
1256
    s->id = IDP3_MAGIC; s->flags = 0;
1257
    s->id = IDP3_MAGIC; s->flags = 0;
1257
    s->numframes = m->numframes; s->numshaders = 0;
1258
    s->numframes = m->numframes; s->numshaders = 0;
1258
    s->numtris = head.numtris;
1259
    s->numtris = head.numtris;
1259
    s->numverts = head.numtris * 3; // oh man talk about memory effectiveness :((((
1260
    s->numverts = head.numtris * 3; // oh man talk about memory effectiveness :((((
1260
    // MD2 is actually more accurate than MD3 in term of uv-mapping, because each triangle has a triangle counterpart on the UV-map.
1261
    // MD2 is actually more accurate than MD3 in term of uv-mapping, because each triangle has a triangle counterpart on the UV-map.
1261
    // In MD3, each vertex unique UV coordinates, meaning that you have to duplicate vertices if you need non-seamless UV-mapping.
1262
    // In MD3, each vertex unique UV coordinates, meaning that you have to duplicate vertices if you need non-seamless UV-mapping.
1262
1263
1263
    maxmodelverts = max(maxmodelverts, s->numverts);
1264
    maxmodelverts = max(maxmodelverts, s->numverts);
1264
1265
1265
    Bstrcpy(s->nam, "Dummy surface from MD2");
1266
    Bstrcpy(s->nam, "Dummy surface from MD2");
1266
1267
1267
    s->shaders = NULL;
1268
    s->shaders = NULL;
1268
1269
1269
    s->tris = (md3tri_t *)Xcalloc(head.numtris, sizeof(md3tri_t));
1270
    s->tris = (md3tri_t *)Xcalloc(head.numtris, sizeof(md3tri_t));
1270
    s->uv = (md3uv_t *)Xcalloc(s->numverts, sizeof(md3uv_t));
1271
    s->uv = (md3uv_t *)Xcalloc(s->numverts, sizeof(md3uv_t));
1271
    s->xyzn = (md3xyzn_t *)Xcalloc(s->numverts * m->numframes, sizeof(md3xyzn_t));
1272
    s->xyzn = (md3xyzn_t *)Xcalloc(s->numverts * m->numframes, sizeof(md3xyzn_t));
1272
1273
1273
    //memoryusage += (s->numverts * m->numframes * sizeof(md3xyzn_t));
1274
    //memoryusage += (s->numverts * m->numframes * sizeof(md3xyzn_t));
1274
    //OSD_Printf("Current model geometry memory usage : %i.\n", memoryusage);
1275
    //OSD_Printf("Current model geometry memory usage : %i.\n", memoryusage);
1275
1276
1276
    //OSD_Printf("Number of frames : %i\n", m->numframes);
1277
    //OSD_Printf("Number of frames : %i\n", m->numframes);
1277
    //OSD_Printf("Number of triangles : %i\n", head.numtris);
1278
    //OSD_Printf("Number of triangles : %i\n", head.numtris);
1278
    //OSD_Printf("Number of vertices : %i\n", s->numverts);
1279
    //OSD_Printf("Number of vertices : %i\n", s->numverts);
1279
1280
1280
    // triangle converting
1281
    // triangle converting
1281
    i = 0;
1282
    i = 0;
1282
    while (i < head.numtris)
1283
    while (i < head.numtris)
1283
    {
1284
    {
1284
        j = 0;
1285
        j = 0;
1285
        //OSD_Printf("Triangle : %i\n", i);
1286
        //OSD_Printf("Triangle : %i\n", i);
1286
        while (j < 3)
1287
        while (j < 3)
1287
        {
1288
        {
1288
            // triangle vertex indexes
1289
            // triangle vertex indexes
1289
            s->tris[i].i[j] = i*3 + j;
1290
            s->tris[i].i[j] = i*3 + j;
1290
1291
1291
            // uv coords
1292
            // uv coords
1292
            s->uv[i*3+j].u = (float)(m->uv[m->tris[i].u[j]].u) / (float)(head.skinxsiz);
1293
            s->uv[i*3+j].u = (float)(m->uv[m->tris[i].u[j]].u) / (float)(head.skinxsiz);
1293
            s->uv[i*3+j].v = (float)(m->uv[m->tris[i].u[j]].v) / (float)(head.skinysiz);
1294
            s->uv[i*3+j].v = (float)(m->uv[m->tris[i].u[j]].v) / (float)(head.skinysiz);
1294
1295
1295
            // vertices for each frame
1296
            // vertices for each frame
1296
            k = 0;
1297
            k = 0;
1297
            while (k < m->numframes)
1298
            while (k < m->numframes)
1298
            {
1299
            {
1299
                f = (md2frame_t *)&m->frames[k*m->framebytes];
1300
                f = (md2frame_t *)&m->frames[k*m->framebytes];
1300
                s->xyzn[(k*s->numverts) + (i*3) + j].x = (int16_t) (((f->verts[m->tris[i].v[j]].v[0] * f->mul.x) + f->add.x) * 64.f);
1301
                s->xyzn[(k*s->numverts) + (i*3) + j].x = (int16_t) (((f->verts[m->tris[i].v[j]].v[0] * f->mul.x) + f->add.x) * 64.f);
1301
                s->xyzn[(k*s->numverts) + (i*3) + j].y = (int16_t) (((f->verts[m->tris[i].v[j]].v[1] * f->mul.y) + f->add.y) * 64.f);
1302
                s->xyzn[(k*s->numverts) + (i*3) + j].y = (int16_t) (((f->verts[m->tris[i].v[j]].v[1] * f->mul.y) + f->add.y) * 64.f);
1302
                s->xyzn[(k*s->numverts) + (i*3) + j].z = (int16_t) (((f->verts[m->tris[i].v[j]].v[2] * f->mul.z) + f->add.z) * 64.f);
1303
                s->xyzn[(k*s->numverts) + (i*3) + j].z = (int16_t) (((f->verts[m->tris[i].v[j]].v[2] * f->mul.z) + f->add.z) * 64.f);
1303
1304
1304
                k++;
1305
                k++;
1305
            }
1306
            }
1306
            j++;
1307
            j++;
1307
        }
1308
        }
1308
        //OSD_Printf("End triangle.\n");
1309
        //OSD_Printf("End triangle.\n");
1309
        i++;
1310
        i++;
1310
    }
1311
    }
1311
    //OSD_Printf("Finished md3 conversion.\n");
1312
    //OSD_Printf("Finished md3 conversion.\n");
1312
1313
1313
    {
1314
    {
1314
        mdskinmap_t *sk;
1315
        mdskinmap_t *sk;
1315
1316
1316
        sk = (mdskinmap_t *)Xcalloc(1,sizeof(mdskinmap_t));
1317
        sk = (mdskinmap_t *)Xcalloc(1,sizeof(mdskinmap_t));
1317
        sk->palette = 0;
1318
        sk->palette = 0;
1318
        sk->skinnum = 0;
1319
        sk->skinnum = 0;
1319
        sk->surfnum = 0;
1320
        sk->surfnum = 0;
1320
1321
1321
        if (m->numskins > 0)
1322
        if (m->numskins > 0)
1322
        {
1323
        {
1323
            sk->fn = (char *)Xmalloc(strlen(m->basepath)+strlen(m->skinfn)+1);
1324
            sk->fn = (char *)Xmalloc(strlen(m->basepath)+strlen(m->skinfn)+1);
1324
            Bstrcpy(sk->fn, m->basepath);
1325
            Bstrcpy(sk->fn, m->basepath);
1325
            Bstrcat(sk->fn, m->skinfn);
1326
            Bstrcat(sk->fn, m->skinfn);
1326
        }
1327
        }
1327
        m3->skinmap = sk;
1328
        m3->skinmap = sk;
1328
    }
1329
    }
1329
1330
1330
    m3->indexes = (uint16_t *)Xmalloc(sizeof(uint16_t) * s->numtris);
1331
    m3->indexes = (uint16_t *)Xmalloc(sizeof(uint16_t) * s->numtris);
1331
    m3->vindexes = (uint16_t *)Xmalloc(sizeof(uint16_t) * s->numtris * 3);
1332
    m3->vindexes = (uint16_t *)Xmalloc(sizeof(uint16_t) * s->numtris * 3);
1332
    m3->maxdepths = (float *)Xmalloc(sizeof(float) * s->numtris);
1333
    m3->maxdepths = (float *)Xmalloc(sizeof(float) * s->numtris);
1333
1334
1334
    m3->vbos = NULL;
1335
    m3->vbos = NULL;
1335
1336
1336
    // die MD2 ! DIE !
1337
    // die MD2 ! DIE !
1337
    Bfree(m->texid); Bfree(m->skinfn); Bfree(m->basepath); Bfree(m->uv); Bfree(m->tris); Bfree(m->glcmds); Bfree(m->frames); Bfree(m);
1338
    Bfree(m->texid); Bfree(m->skinfn); Bfree(m->basepath); Bfree(m->uv); Bfree(m->tris); Bfree(m->glcmds); Bfree(m->frames); Bfree(m);
1338
1339
1339
    return((md2model_t *)m3);
1340
    return((md2model_t *)m3);
1340
}
1341
}
1341
//---------------------------------------- MD2 LIBRARY ENDS ----------------------------------------
1342
//---------------------------------------- MD2 LIBRARY ENDS ----------------------------------------
1342
1343
1343
// DICHOTOMIC RECURSIVE SORTING - USED BY MD3DRAW
1344
// DICHOTOMIC RECURSIVE SORTING - USED BY MD3DRAW
1344
int32_t partition(uint16_t *indexes, float *depths, int32_t f, int32_t l)
1345
int32_t partition(uint16_t *indexes, float *depths, int32_t f, int32_t l)
1345
{
1346
{
1346
    int32_t up = f, down = l;
1347
    int32_t up = f, down = l;
1347
    float piv = depths[f];
1348
    float piv = depths[f];
1348
    uint16_t piv2 = indexes[f];
1349
    uint16_t piv2 = indexes[f];
1349
    do
1350
    do
1350
    {
1351
    {
1351
        while ((depths[up] <= piv) && (up < l))
1352
        while ((depths[up] <= piv) && (up < l))
1352
            up++;
1353
            up++;
1353
        while ((depths[down] > piv)  && (down > f))
1354
        while ((depths[down] > piv)  && (down > f))
1354
            down--;
1355
            down--;
1355
        if (up < down)
1356
        if (up < down)
1356
        {
1357
        {
1357
            swapfloat(&depths[up], &depths[down]);
1358
            swapfloat(&depths[up], &depths[down]);
1358
            swapshort(&indexes[up], &indexes[down]);
1359
            swapshort(&indexes[up], &indexes[down]);
1359
        }
1360
        }
1360
    }
1361
    }
1361
    while (down > up);
1362
    while (down > up);
1362
    depths[f] = depths[down], depths[down] = piv;
1363
    depths[f] = depths[down], depths[down] = piv;
1363
    indexes[f] = indexes[down], indexes[down] = piv2;
1364
    indexes[f] = indexes[down], indexes[down] = piv2;
1364
    return down;
1365
    return down;
1365
}
1366
}
1366
1367
1367
static inline void quicksort(uint16_t *indexes, float *depths, int32_t first, int32_t last)
1368
static inline void quicksort(uint16_t *indexes, float *depths, int32_t first, int32_t last)
1368
{
1369
{
1369
    int32_t pivIndex;
1370
    int32_t pivIndex;
1370
    if (first >= last) return;
1371
    if (first >= last) return;
1371
    pivIndex = partition(indexes, depths, first, last);
1372
    pivIndex = partition(indexes, depths, first, last);
1372
    if (first < (pivIndex-1)) quicksort(indexes, depths, first, (pivIndex-1));
1373
    if (first < (pivIndex-1)) quicksort(indexes, depths, first, (pivIndex-1));
1373
    if ((pivIndex+1) >= last) return;
1374
    if ((pivIndex+1) >= last) return;
1374
    quicksort(indexes, depths, (pivIndex+1), last);
1375
    quicksort(indexes, depths, (pivIndex+1), last);
1375
}
1376
}
1376
// END OF QUICKSORT LIB
1377
// END OF QUICKSORT LIB
1377
1378
1378
//--------------------------------------- MD3 LIBRARY BEGINS ---------------------------------------
1379
//--------------------------------------- MD3 LIBRARY BEGINS ---------------------------------------
1379
1380
1380
static md3model_t *md3load(int32_t fil)
1381
static md3model_t *md3load(int32_t fil)
1381
{
1382
{
1382
    int32_t i, surfi, ofsurf, offs[4], leng[4];
1383
    int32_t i, surfi, ofsurf, offs[4], leng[4];
1383
    int32_t maxtrispersurf;
1384
    int32_t maxtrispersurf;
1384
    md3model_t *m;
1385
    md3model_t *m;
1385
    md3surf_t *s;
1386
    md3surf_t *s;
1386
1387
1387
    m = (md3model_t *)Xcalloc(1,sizeof(md3model_t));
1388
    m = (md3model_t *)Xcalloc(1,sizeof(md3model_t));
1388
    m->mdnum = 3; m->texid = 0; m->scale = .01f;
1389
    m->mdnum = 3; m->texid = 0; m->scale = .01f;
1389
1390
1390
    m->muladdframes = NULL;
1391
    m->muladdframes = NULL;
1391
1392
1392
    kread(fil,&m->head,SIZEOF_MD3HEAD_T);
1393
    kread(fil,&m->head,SIZEOF_MD3HEAD_T);
1393
1394
1394
#if B_BIG_ENDIAN != 0
1395
#if B_BIG_ENDIAN != 0
1395
    m->head.id = B_LITTLE32(m->head.id);             m->head.vers = B_LITTLE32(m->head.vers);
1396
    m->head.id = B_LITTLE32(m->head.id);             m->head.vers = B_LITTLE32(m->head.vers);
1396
    m->head.flags = B_LITTLE32(m->head.flags);       m->head.numframes = B_LITTLE32(m->head.numframes);
1397
    m->head.flags = B_LITTLE32(m->head.flags);       m->head.numframes = B_LITTLE32(m->head.numframes);
1397
    m->head.numtags = B_LITTLE32(m->head.numtags);   m->head.numsurfs = B_LITTLE32(m->head.numsurfs);
1398
    m->head.numtags = B_LITTLE32(m->head.numtags);   m->head.numsurfs = B_LITTLE32(m->head.numsurfs);
1398
    m->head.numskins = B_LITTLE32(m->head.numskins); m->head.ofsframes = B_LITTLE32(m->head.ofsframes);
1399
    m->head.numskins = B_LITTLE32(m->head.numskins); m->head.ofsframes = B_LITTLE32(m->head.ofsframes);
1399
    m->head.ofstags = B_LITTLE32(m->head.ofstags); m->head.ofssurfs = B_LITTLE32(m->head.ofssurfs);
1400
    m->head.ofstags = B_LITTLE32(m->head.ofstags); m->head.ofssurfs = B_LITTLE32(m->head.ofssurfs);
1400
    m->head.eof = B_LITTLE32(m->head.eof);
1401
    m->head.eof = B_LITTLE32(m->head.eof);
1401
#endif
1402
#endif
1402
1403
1403
    if ((m->head.id != IDP3_MAGIC) && (m->head.vers != 15)) { Bfree(m); return(0); } //"IDP3"
1404
    if ((m->head.id != IDP3_MAGIC) && (m->head.vers != 15)) { Bfree(m); return(0); } //"IDP3"
1404
1405
1405
    m->numskins = m->head.numskins; //<- dead code?
1406
    m->numskins = m->head.numskins; //<- dead code?
1406
    m->numframes = m->head.numframes;
1407
    m->numframes = m->head.numframes;
1407
1408
1408
    ofsurf = m->head.ofssurfs;
1409
    ofsurf = m->head.ofssurfs;
1409
1410
1410
    klseek(fil,m->head.ofsframes,SEEK_SET); i = m->head.numframes*sizeof(md3frame_t);
1411
    klseek(fil,m->head.ofsframes,SEEK_SET); i = m->head.numframes*sizeof(md3frame_t);
1411
    m->head.frames = (md3frame_t *)Xmalloc(i);
1412
    m->head.frames = (md3frame_t *)Xmalloc(i);
1412
    kread(fil,m->head.frames,i);
1413
    kread(fil,m->head.frames,i);
1413
1414
1414
    if (m->head.numtags == 0) m->head.tags = NULL;
1415
    if (m->head.numtags == 0) m->head.tags = NULL;
1415
    else
1416
    else
1416
    {
1417
    {
1417
        klseek(fil,m->head.ofstags,SEEK_SET); i = m->head.numtags*sizeof(md3tag_t);
1418
        klseek(fil,m->head.ofstags,SEEK_SET); i = m->head.numtags*sizeof(md3tag_t);
1418
        m->head.tags = (md3tag_t *)Xmalloc(i);
1419
        m->head.tags = (md3tag_t *)Xmalloc(i);
1419
        kread(fil,m->head.tags,i);
1420
        kread(fil,m->head.tags,i);
1420
    }
1421
    }
1421
1422
1422
    klseek(fil,m->head.ofssurfs,SEEK_SET);
1423
    klseek(fil,m->head.ofssurfs,SEEK_SET);
1423
    m->head.surfs = (md3surf_t *)Xcalloc(m->head.numsurfs, sizeof(md3surf_t));
1424
    m->head.surfs = (md3surf_t *)Xcalloc(m->head.numsurfs, sizeof(md3surf_t));
1424
    // NOTE: We assume that NULL is represented by all-zeros.
1425
    // NOTE: We assume that NULL is represented by all-zeros.
1425
    // surfs[0].geometry is for POLYMER_MD_PROCESS_CHECK (else: crashes).
1426
    // surfs[0].geometry is for POLYMER_MD_PROCESS_CHECK (else: crashes).
1426
    // surfs[i].geometry is for FREE_SURFS_GEOMETRY.
1427
    // surfs[i].geometry is for FREE_SURFS_GEOMETRY.
1427
    Bassert(m->head.surfs[0].geometry == NULL);
1428
    Bassert(m->head.surfs[0].geometry == NULL);
1428
1429
1429
#if B_BIG_ENDIAN != 0
1430
#if B_BIG_ENDIAN != 0
1430
    {
1431
    {
1431
        int32_t j, *l;
1432
        int32_t j, *l;
1432
1433
1433
        for (i = m->head.numframes-1; i>=0; i--)
1434
        for (i = m->head.numframes-1; i>=0; i--)
1434
        {
1435
        {
1435
            l = (int32_t *)&m->head.frames[i].min;
1436
            l = (int32_t *)&m->head.frames[i].min;
1436
            for (j=3+3+3+1-1; j>=0; j--) l[j] = B_LITTLE32(l[j]);
1437
            for (j=3+3+3+1-1; j>=0; j--) l[j] = B_LITTLE32(l[j]);
1437
        }
1438
        }
1438
1439
1439
        for (i = m->head.numtags-1; i>=0; i--)
1440
        for (i = m->head.numtags-1; i>=0; i--)
1440
        {
1441
        {
1441
            l = (int32_t *)&m->head.tags[i].p;
1442
            l = (int32_t *)&m->head.tags[i].p;
1442
            for (j=3+3+3+3-1; j>=0; j--) l[j] = B_LITTLE32(l[j]);
1443
            for (j=3+3+3+3-1; j>=0; j--) l[j] = B_LITTLE32(l[j]);
1443
        }
1444
        }
1444
    }
1445
    }
1445
#endif
1446
#endif
1446
1447
1447
    maxtrispersurf = 0;
1448
    maxtrispersurf = 0;
1448
1449
1449
    for (surfi=0; surfi<m->head.numsurfs; surfi++)
1450
    for (surfi=0; surfi<m->head.numsurfs; surfi++)
1450
    {
1451
    {
1451
        s = &m->head.surfs[surfi];
1452
        s = &m->head.surfs[surfi];
1452
        klseek(fil,ofsurf,SEEK_SET); kread(fil,s,SIZEOF_MD3SURF_T);
1453
        klseek(fil,ofsurf,SEEK_SET); kread(fil,s,SIZEOF_MD3SURF_T);
1453
1454
1454
#if B_BIG_ENDIAN != 0
1455
#if B_BIG_ENDIAN != 0
1455
        {
1456
        {
1456
            int32_t j, *l;
1457
            int32_t j, *l;
1457
            s->id = B_LITTLE32(s->id);
1458
            s->id = B_LITTLE32(s->id);
1458
            l = (int32_t *)&s->flags;
1459
            l = (int32_t *)&s->flags;
1459
            for (j=1+1+1+1+1+1+1+1+1+1-1; j>=0; j--) l[j] = B_LITTLE32(l[j]);
1460
            for (j=1+1+1+1+1+1+1+1+1+1-1; j>=0; j--) l[j] = B_LITTLE32(l[j]);
1460
        }
1461
        }
1461
#endif
1462
#endif
1462
1463
1463
        offs[0] = ofsurf+s->ofstris;
1464
        offs[0] = ofsurf+s->ofstris;
1464
        offs[1] = ofsurf+s->ofsshaders;
1465
        offs[1] = ofsurf+s->ofsshaders;
1465
        offs[2] = ofsurf+s->ofsuv;
1466
        offs[2] = ofsurf+s->ofsuv;
1466
        offs[3] = ofsurf+s->ofsxyzn;
1467
        offs[3] = ofsurf+s->ofsxyzn;
1467
1468
1468
        leng[0] = s->numtris*sizeof(md3tri_t);
1469
        leng[0] = s->numtris*sizeof(md3tri_t);
1469
        leng[1] = s->numshaders*sizeof(md3shader_t);
1470
        leng[1] = s->numshaders*sizeof(md3shader_t);
1470
        leng[2] = s->numverts*sizeof(md3uv_t);
1471
        leng[2] = s->numverts*sizeof(md3uv_t);
1471
        leng[3] = s->numframes*s->numverts*sizeof(md3xyzn_t);
1472
        leng[3] = s->numframes*s->numverts*sizeof(md3xyzn_t);
1472
1473
1473
        //memoryusage += (s->numverts * s->numframes * sizeof(md3xyzn_t));
1474
        //memoryusage += (s->numverts * s->numframes * sizeof(md3xyzn_t));
1474
        //OSD_Printf("Current model geometry memory usage : %i.\n", memoryusage);
1475
        //OSD_Printf("Current model geometry memory usage : %i.\n", memoryusage);
1475
1476
1476
        s->tris = (md3tri_t *)Xmalloc((leng[0] + leng[1]) + (leng[2] + leng[3]));
1477
        s->tris = (md3tri_t *)Xmalloc((leng[0] + leng[1]) + (leng[2] + leng[3]));
1477
1478
1478
        s->shaders = (md3shader_t *)(((intptr_t)s->tris)+leng[0]);
1479
        s->shaders = (md3shader_t *)(((intptr_t)s->tris)+leng[0]);
1479
        s->uv      = (md3uv_t *)(((intptr_t)s->shaders)+leng[1]);
1480
        s->uv      = (md3uv_t *)(((intptr_t)s->shaders)+leng[1]);
1480
        s->xyzn    = (md3xyzn_t *)(((intptr_t)s->uv)+leng[2]);
1481
        s->xyzn    = (md3xyzn_t *)(((intptr_t)s->uv)+leng[2]);
1481
1482
1482
        klseek(fil,offs[0],SEEK_SET); kread(fil,s->tris   ,leng[0]);
1483
        klseek(fil,offs[0],SEEK_SET); kread(fil,s->tris   ,leng[0]);
1483
        klseek(fil,offs[1],SEEK_SET); kread(fil,s->shaders,leng[1]);
1484
        klseek(fil,offs[1],SEEK_SET); kread(fil,s->shaders,leng[1]);
1484
        klseek(fil,offs[2],SEEK_SET); kread(fil,s->uv     ,leng[2]);
1485
        klseek(fil,offs[2],SEEK_SET); kread(fil,s->uv     ,leng[2]);
1485
        klseek(fil,offs[3],SEEK_SET); kread(fil,s->xyzn   ,leng[3]);
1486
        klseek(fil,offs[3],SEEK_SET); kread(fil,s->xyzn   ,leng[3]);
1486
1487
1487
#if B_BIG_ENDIAN != 0
1488
#if B_BIG_ENDIAN != 0
1488
        {
1489
        {
1489
            int32_t j, *l;
1490
            int32_t j, *l;
1490
1491
1491
            for (i=s->numtris-1; i>=0; i--)
1492
            for (i=s->numtris-1; i>=0; i--)
1492
            {
1493
            {
1493
                for (j=2; j>=0; j--) s->tris[i].i[j] = B_LITTLE32(s->tris[i].i[j]);
1494
                for (j=2; j>=0; j--) s->tris[i].i[j] = B_LITTLE32(s->tris[i].i[j]);
1494
            }
1495
            }
1495
            for (i=s->numshaders-1; i>=0; i--)
1496
            for (i=s->numshaders-1; i>=0; i--)
1496
            {
1497
            {
1497
                s->shaders[i].i = B_LITTLE32(s->shaders[i].i);
1498
                s->shaders[i].i = B_LITTLE32(s->shaders[i].i);
1498
            }
1499
            }
1499
            for (i=s->numverts-1; i>=0; i--)
1500
            for (i=s->numverts-1; i>=0; i--)
1500
            {
1501
            {
1501
                l = (int32_t *)&s->uv[i].u;
1502
                l = (int32_t *)&s->uv[i].u;
1502
                l[0] = B_LITTLE32(l[0]);
1503
                l[0] = B_LITTLE32(l[0]);
1503
                l[1] = B_LITTLE32(l[1]);
1504
                l[1] = B_LITTLE32(l[1]);
1504
            }
1505
            }
1505
            for (i=s->numframes*s->numverts-1; i>=0; i--)
1506
            for (i=s->numframes*s->numverts-1; i>=0; i--)
1506
            {
1507
            {
1507
                s->xyzn[i].x = (int16_t)B_LITTLE16((uint16_t)s->xyzn[i].x);
1508
                s->xyzn[i].x = (int16_t)B_LITTLE16((uint16_t)s->xyzn[i].x);
1508
                s->xyzn[i].y = (int16_t)B_LITTLE16((uint16_t)s->xyzn[i].y);
1509
                s->xyzn[i].y = (int16_t)B_LITTLE16((uint16_t)s->xyzn[i].y);
1509
                s->xyzn[i].z = (int16_t)B_LITTLE16((uint16_t)s->xyzn[i].z);
1510
                s->xyzn[i].z = (int16_t)B_LITTLE16((uint16_t)s->xyzn[i].z);
1510
            }
1511
            }
1511
        }
1512
        }
1512
#endif
1513
#endif
1513
        maxmodelverts = max(maxmodelverts, s->numverts);
1514
        maxmodelverts = max(maxmodelverts, s->numverts);
1514
        maxmodeltris = max(maxmodeltris, s->numtris);
1515
        maxmodeltris = max(maxmodeltris, s->numtris);
1515
        maxtrispersurf = max(maxtrispersurf, s->numtris);
1516
        maxtrispersurf = max(maxtrispersurf, s->numtris);
1516
        ofsurf += s->ofsend;
1517
        ofsurf += s->ofsend;
1517
    }
1518
    }
1518
1519
1519
    m->indexes = (uint16_t *)Xmalloc(sizeof(uint16_t) * maxtrispersurf);
1520
    m->indexes = (uint16_t *)Xmalloc(sizeof(uint16_t) * maxtrispersurf);
1520
    m->vindexes = (uint16_t *)Xmalloc(sizeof(uint16_t) * maxtrispersurf * 3);
1521
    m->vindexes = (uint16_t *)Xmalloc(sizeof(uint16_t) * maxtrispersurf * 3);
1521
    m->maxdepths = (float *)Xmalloc(sizeof(float) * maxtrispersurf);
1522
    m->maxdepths = (float *)Xmalloc(sizeof(float) * maxtrispersurf);
1522
1523
1523
    m->vbos = NULL;
1524
    m->vbos = NULL;
1524
1525
1525
    return(m);
1526
    return(m);
1526
}
1527
}
1527
1528
1528
static inline void  invertmatrix(float *m, float *out)
1529
static inline void  invertmatrix(float *m, float *out)
1529
{
1530
{
1530
    float det;
1531
    float det;
1531
1532
1532
    det  = (m[0] * (m[4]*m[8] - m[5] * m[7]))
1533
    det  = (m[0] * (m[4]*m[8] - m[5] * m[7]))
1533
         - (m[1] * (m[3]*m[8] - m[5] * m[6]))
1534
         - (m[1] * (m[3]*m[8] - m[5] * m[6]))
1534
         + (m[2] * (m[3]*m[7] - m[4] * m[6]));
1535
         + (m[2] * (m[3]*m[7] - m[4] * m[6]));
1535
1536
1536
    if (det == 0.0f)
1537
    if (det == 0.0f)
1537
    {
1538
    {
1538
        Bmemset(out, 0, sizeof(float) * 9);
1539
        Bmemset(out, 0, sizeof(float) * 9);
1539
        out[8] = out[4] = out[0] = 1.f;
1540
        out[8] = out[4] = out[0] = 1.f;
1540
        return;
1541
        return;
1541
    }
1542
    }
1542
1543
1543
    det = 1.0f / det;
1544
    det = 1.0f / det;
1544