Subversion Repositories eduke32

Rev

Rev 8471 | Rev 8519 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
573 terminx 1
// "Build Engine & Tools" Copyright (c) 1993-1997 Ken Silverman
2
// Ken Silverman's official web site: "http://www.advsys.net/ken"
3
// See the included license file "BUILDLIC.TXT" for license info.
4
//
5
// This file has been modified from Ken Silverman's original release
2456 hendricks2 6
// by Jonathon Fowler (jf@jonof.id.au)
7139 hendricks2 7
// by the EDuke32 team (development@voidpoint.com)
540 terminx 8
 
5664 terminx 9
#pragma once
573 terminx 10
 
4747 terminx 11
#ifndef build_h_
12
#define build_h_
573 terminx 13
 
6352 hendricks2 14
#if !defined __cplusplus || (__cplusplus < 201103L && !defined _MSC_VER)
15
# error C++11 or greater is required.
16
#endif
17
 
6470 hendricks2 18
#if defined _MSC_VER && _MSC_VER < 1800
19
# error Visual Studio 2013 is the minimum supported version.
20
#endif
21
 
7186 terminx 22
#include "collections.h"
618 terminx 23
#include "compat.h"
6656 pogokeen 24
#include "glad/glad.h"
3467 helixhorne 25
#include "glbuild.h"
5789 terminx 26
#include "palette.h"
7186 terminx 27
#include "pragmas.h"
618 terminx 28
 
7359 hendricks2 29
#include "vfs.h"
30
#include "cache1d.h"
31
 
4766 hendricks2 32
#ifdef __cplusplus
573 terminx 33
extern "C" {
34
#endif
35
 
3347 terminx 36
enum rendmode_t {
3346 terminx 37
    REND_CLASSIC,
38
    REND_POLYMOST = 3,
39
    REND_POLYMER
40
};
41
 
2988 helixhorne 42
#define PI 3.14159265358979323846
5877 hendricks2 43
#define fPI 3.14159265358979323846f
2987 helixhorne 44
 
7723 terminx 45
#define BANG2RAD (fPI * (1.f/1024.f))
46
 
573 terminx 47
#define MAXSECTORSV8 4096
48
#define MAXWALLSV8 16384
49
#define MAXSPRITESV8 16384
50
 
51
#define MAXSECTORSV7 1024
52
#define MAXWALLSV7 8192
53
#define MAXSPRITESV7 4096
54
 
8445 hendricks2 55
#define MAXVOXMIPS 5
56
 
6435 terminx 57
#if !defined GEKKO && !defined __OPENDINGUX__
2629 helixhorne 58
# define MAXSECTORS MAXSECTORSV8
59
# define MAXWALLS MAXWALLSV8
60
# define MAXSPRITES MAXSPRITESV8
61
 
62
# define MAXXDIM 7680
63
# define MAXYDIM 3200
6435 terminx 64
# define MINXDIM 640
65
# define MINYDIM 480
2645 helixhorne 66
 
67
// additional space beyond wall, in walltypes:
68
# define M32_FIXME_WALLS 512
69
# define M32_FIXME_SECTORS 2
2629 helixhorne 70
#else
71
# define MAXSECTORS MAXSECTORSV7
72
# define MAXWALLS MAXWALLSV7
73
# define MAXSPRITES MAXSPRITESV7
74
 
6435 terminx 75
#ifdef GEKKO
76
#  define MAXXDIM 860
77
#  define MAXYDIM 490
78
# else
79
#  define MAXXDIM 320
80
#  define MAXYDIM 200
81
# endif
2645 helixhorne 82
 
6435 terminx 83
# define MINXDIM MAXXDIM
84
# define MINYDIM MAXYDIM
2645 helixhorne 85
# define M32_FIXME_WALLS 0
86
# define M32_FIXME_SECTORS 0
2629 helixhorne 87
#endif
88
 
4102 hendricks2 89
#ifdef LUNATIC
90
# define NEW_MAP_FORMAT
91
// A marker for LuaJIT C function callbacks, but not merely:
92
# define LUNATIC_CB ATTRIBUTE((used))
93
// Used for variables and functions referenced from Lua:
94
# define LUNATIC_EXTERN ATTRIBUTE((used))
6023 hendricks2 95
# define LUNATIC_FASTCALL
4102 hendricks2 96
#else
97
# ifdef NEW_MAP_FORMAT
98
#  error "New map format can only be used with Lunatic"
99
# endif
100
# define LUNATIC_EXTERN static
6023 hendricks2 101
# define LUNATIC_FASTCALL __fastcall
4102 hendricks2 102
#endif
103
 
7446 terminx 104
#define MAXWALLSB ((MAXWALLS>>2)+(MAXWALLS>>3))
573 terminx 105
 
2267 helixhorne 106
#define MAXTILES 30720
4225 helixhorne 107
#define MAXUSERTILES (MAXTILES-16)  // reserve 16 tiles at the end
108
 
6292 terminx 109
#define MAXVOXELS 1024
573 terminx 110
#define MAXSTATUS 1024
111
#define MAXPLAYERS 16
3975 helixhorne 112
// Maximum number of component tiles in a multi-psky:
8448 hendricks2 113
#define MAXPSKYTILES 16
6820 terminx 114
#define MAXSPRITESONSCREEN 2560
573 terminx 115
#define MAXUNIQHUDID 256 //Extra slots so HUD models can store animation state without messing game sprites
116
 
888 terminx 117
#define TSPR_TEMP 99
886 terminx 118
 
1355 terminx 119
#define PR_LIGHT_PRIO_MAX       0
120
#define PR_LIGHT_PRIO_MAX_GAME  1
121
#define PR_LIGHT_PRIO_HIGH      2
122
#define PR_LIGHT_PRIO_HIGH_GAME 3
123
#define PR_LIGHT_PRIO_LOW       4
124
#define PR_LIGHT_PRIO_LOW_GAME  5
125
 
8171 terminx 126
#define CLOCKTICKSPERSECOND 120
127
 
3679 helixhorne 128
// Convenient sprite iterators, must not be used if any sprites inside the loop
129
// are potentially deleted or their sector changed...
2707 helixhorne 130
#define SPRITES_OF(Statnum, Iter)  Iter=headspritestat[Statnum]; Iter>=0; Iter=nextspritestat[Iter]
131
#define SPRITES_OF_SECT(Sectnum, Iter)  Iter=headspritesect[Sectnum]; Iter>=0; Iter=nextspritesect[Iter]
3679 helixhorne 132
// ... in which case this iterator may be used:
133
#define SPRITES_OF_SECT_SAFE(Sectnum, Iter, Next)  Iter=headspritesect[Sectnum]; \
3685 helixhorne 134
    Iter>=0 && (Next=nextspritesect[Iter], 1); Iter=Next
4045 helixhorne 135
#define SPRITES_OF_STAT_SAFE(Statnum, Iter, Next)  Iter=headspritestat[Statnum]; \
136
    Iter>=0 && (Next=nextspritestat[Iter], 1); Iter=Next
2707 helixhorne 137
 
3321 helixhorne 138
#define CLEARLINES2D(Startline, Numlines, Color) \
139
    clearbuf((char *)(frameplace + ((Startline)*bytesperline)), (bytesperline*(Numlines))>>2, (Color))
2707 helixhorne 140
 
3321 helixhorne 141
 
1887 helixhorne 142
////////// True Room over Room (YAX == rot -17 of "PRO") //////////
143
#define YAX_ENABLE
144
//#define YAX_DEBUG
145
//#define ENGINE_SCREENSHOT_DEBUG
146
 
3658 helixhorne 147
#ifdef YAX_ENABLE
148
# if !defined NEW_MAP_FORMAT
149
#  define YAX_ENABLE__COMPAT
150
# endif
151
#endif
152
 
1816 helixhorne 153
////////// yax defs //////////
1877 helixhorne 154
#define SECTORFLD(Sect,Fld, Cf) (*((Cf) ? (&sector[Sect].floor##Fld) : (&sector[Sect].ceiling##Fld)))
155
 
1854 helixhorne 156
#define YAX_CEILING 0  // don't change!
157
#define YAX_FLOOR 1  // don't change!
1816 helixhorne 158
 
3658 helixhorne 159
# ifdef NEW_MAP_FORMAT
160
#  define YAX_MAXBUNCHES 512
161
#  define YAX_BIT__COMPAT 1024
162
#  define YAX_NEXTWALLBIT__COMPAT(Cf) (1<<(10+Cf))
163
#  define YAX_NEXTWALLBITS__COMPAT (YAX_NEXTWALLBIT__COMPAT(0)|YAX_NEXTWALLBIT__COMPAT(1))
164
# else
165
#  define YAX_MAXBUNCHES 256
166
#  define YAX_BIT 1024
167
   // "has next wall when constrained"-bit (1<<10: ceiling, 1<<11: floor)
168
#  define YAX_NEXTWALLBIT(Cf) (1<<(10+Cf))
169
#  define YAX_NEXTWALLBITS (YAX_NEXTWALLBIT(0)|YAX_NEXTWALLBIT(1))
170
# endif
171
 
3623 helixhorne 172
int32_t get_alwaysshowgray(void);  // editor only
1877 helixhorne 173
void yax_updategrays(int32_t posze);
1816 helixhorne 174
 
1877 helixhorne 175
#ifdef YAX_ENABLE
3658 helixhorne 176
# ifdef NEW_MAP_FORMAT
177
   // New map format -- no hijacking of otherwise used members.
178
#  define YAX_PTRNEXTWALL(Ptr, Wall, Cf) (*(&Ptr[Wall].upwall + Cf))
179
#  define YAX_NEXTWALLDEFAULT(Cf) (-1)
180
# else
181
   // More user tag hijacking: lotag/extra. :/
182
#  define YAX_PTRNEXTWALL(Ptr, Wall, Cf) (*(int16_t *)(&Ptr[Wall].lotag + 2*Cf))
183
#  define YAX_NEXTWALLDEFAULT(Cf) (((Cf)==YAX_CEILING) ? 0 : -1)
184
   extern int16_t yax_bunchnum[MAXSECTORS][2];
185
   extern int16_t yax_nextwall[MAXWALLS][2];
186
# endif
187
 
2349 helixhorne 188
# define YAX_NEXTWALL(Wall, Cf) YAX_PTRNEXTWALL(wall, Wall, Cf)
1865 helixhorne 189
 
1877 helixhorne 190
# define YAX_ITER_WALLS(Wal, Itervar, Cfvar) Cfvar=0, Itervar=(Wal); Itervar!=-1; \
2896 helixhorne 191
    Itervar=yax_getnextwall(Itervar, Cfvar), \
192
        (void)(Itervar==-1 && Cfvar==0 && (Cfvar=1) && (Itervar=yax_getnextwall((Wal), Cfvar)))
1866 helixhorne 193
 
1886 helixhorne 194
# define SECTORS_OF_BUNCH(Bunchnum, Cf, Itervar) Itervar = headsectbunch[Cf][Bunchnum]; \
195
    Itervar != -1; Itervar = nextsectbunch[Cf][Itervar]
196
 
2024 helixhorne 197
extern int32_t r_tror_nomaskpass;
198
 
3658 helixhorne 199
# ifdef NEW_MAP_FORMAT
200
// Moved below declarations of sector, wall, sprite.
201
# else
1816 helixhorne 202
int16_t yax_getbunch(int16_t i, int16_t cf);
6076 hendricks2 203
static FORCE_INLINE void yax_getbunches(int16_t i, int16_t *cb, int16_t *fb)
4700 terminx 204
{
205
    *cb = yax_getbunch(i, YAX_CEILING);
206
    *fb = yax_getbunch(i, YAX_FLOOR);
207
}
3658 helixhorne 208
int16_t yax_getnextwall(int16_t wal, int16_t cf);
209
void yax_setnextwall(int16_t wal, int16_t cf, int16_t thenextwall);
210
# endif
211
 
1816 helixhorne 212
void yax_setbunch(int16_t i, int16_t cf, int16_t bunchnum);
1843 helixhorne 213
void yax_setbunches(int16_t i, int16_t cb, int16_t fb);
2018 helixhorne 214
int16_t yax_vnextsec(int16_t line, int16_t cf);
1882 helixhorne 215
void yax_update(int32_t resetstat);
3039 helixhorne 216
int32_t yax_getneighborsect(int32_t x, int32_t y, int32_t sectnum, int32_t cf);
1877 helixhorne 217
 
7587 terminx 218
static FORCE_INLINE CONSTEXPR int32_t yax_waltosecmask(int32_t const walclipmask)
1877 helixhorne 219
{
220
    // blocking: walstat&1 --> secstat&512
221
    // hitscan: walstat&64 --> secstat&2048
222
    return ((walclipmask&1)<<9) | ((walclipmask&64)<<5);
223
}
224
void yax_preparedrawrooms(void);
8428 hendricks2 225
void yax_drawrooms(void (*SpriteAnimFunc)(int32_t,int32_t,int32_t,int32_t,int32_t),
2880 helixhorne 226
                   int16_t sectnum, int32_t didmirror, int32_t smoothr);
7876 terminx 227
# define YAX_SKIPSECTOR(i) if (graysectbitmap[(i)>>3]&pow2char[(i)&7]) continue
228
# define YAX_SKIPWALL(i) if (graywallbitmap[(i)>>3]&pow2char[(i)&7]) continue
1869 helixhorne 229
#else
1877 helixhorne 230
# define yax_preparedrawrooms()
2880 helixhorne 231
# define yax_drawrooms(SpriteAnimFunc, sectnum, didmirror, smoothr)
1869 helixhorne 232
# define YAX_SKIPSECTOR(i) (i)=(i)
233
# define YAX_SKIPWALL(i) (i)=(i)
234
#endif
1816 helixhorne 235
 
573 terminx 236
#define CLIPMASK0 (((1L)<<16)+1L)
237
#define CLIPMASK1 (((256L)<<16)+64L)
238
 
7590 terminx 239
#define NEXTWALL(i) (wall[wall[i].nextwall])
240
#define POINT2(i) (wall[wall[i].point2])
241
 
1797 helixhorne 242
// max x/y val (= max editorgridextent in Mapster32)
243
#define BXY_MAX 524288
244
 
4175 helixhorne 245
// rotatesprite 'orientation' (actually much more) bits
2935 helixhorne 246
enum {
4175 helixhorne 247
    RS_TRANS1 = 1,
248
    RS_AUTO = 2,
249
    RS_YFLIP = 4,
250
    RS_NOCLIP = 8,
251
    RS_TOPLEFT = 16,
252
    RS_TRANS2 = 32,
253
    RS_NOMASK = 64,
254
    RS_PERM = 128,
255
 
256
    RS_ALIGN_L = 256,
257
    RS_ALIGN_R = 512,
258
    RS_ALIGN_MASK = 768,
259
    RS_STRETCH = 1024,
260
 
3608 hendricks2 261
    ROTATESPRITE_FULL16 = 2048,
2935 helixhorne 262
    // ROTATESPRITE_MAX-1 is the mask of all externally available orientation bits
3608 hendricks2 263
    ROTATESPRITE_MAX = 4096,
2929 helixhorne 264
 
2935 helixhorne 265
    RS_CENTERORIGIN = (1<<30),
266
};
267
 
573 terminx 268
    //Make all variables in BUILD.H defined in the ENGINE,
269
    //and externed in GAME
7186 terminx 270
#ifdef engine_c_
573 terminx 271
#  define EXTERN
272
#else
273
#  define EXTERN extern
274
#endif
275
 
3138 Plagman 276
#ifdef __cplusplus
6769 hendricks2 277
}
278
#endif
3138 Plagman 279
 
6769 hendricks2 280
#if defined __cplusplus && (defined USE_OPENGL || defined POLYMER)
7695 terminx 281
# define USE_STRUCT_TRACKERS
6769 hendricks2 282
#endif
283
 
7695 terminx 284
#ifdef USE_STRUCT_TRACKERS
6769 hendricks2 285
 
286
extern "C" {
7691 terminx 287
static FORCE_INLINE void sector_tracker_hook__(intptr_t address);
288
static FORCE_INLINE void wall_tracker_hook__(intptr_t address);
289
static FORCE_INLINE void sprite_tracker_hook__(intptr_t address);
4766 hendricks2 290
}
291
 
7690 terminx 292
#define TRACKER_NAME__ SectorTracker
7691 terminx 293
#define TRACKER_HOOK_ sector_tracker_hook__
3138 Plagman 294
#include "tracker.hpp"
7690 terminx 295
#undef TRACKER_NAME__
296
#undef TRACKER_HOOK_
3138 Plagman 297
 
7690 terminx 298
#define TRACKER_NAME__ WallTracker
7691 terminx 299
#define TRACKER_HOOK_ wall_tracker_hook__
3138 Plagman 300
#include "tracker.hpp"
7690 terminx 301
#undef TRACKER_NAME__
302
#undef TRACKER_HOOK_
3138 Plagman 303
 
7690 terminx 304
#define TRACKER_NAME__ SpriteTracker
7691 terminx 305
#define TRACKER_HOOK_ sprite_tracker_hook__
3138 Plagman 306
#include "tracker.hpp"
7690 terminx 307
#undef TRACKER_NAME__
308
#undef TRACKER_HOOK_
3138 Plagman 309
 
310
#define Tracker(Container, Type) Container##Tracker<Type>
3238 hendricks2 311
#define TrackerCast(x) x.cast()
3138 Plagman 312
 
313
#else
314
 
315
#define Tracker(Container, Type) Type
3238 hendricks2 316
#define TrackerCast(x) x
3138 Plagman 317
 
318
#endif // __cplusplus
319
 
3455 helixhorne 320
// Links to various ABIs specifying (or documenting non-normatively) the
321
// alignment requirements of aggregates:
322
//
323
//  System V AMD64: http://www.x86-64.org/documentation/abi-0.99.pdf
324
//   (x86-64.org down as of 2013-02-02?)
325
//  "An array uses the same alignment as its elements, except that a local or global
326
//   array variable of length at least 16 bytes or a C99 variable-length array variable
327
//   always has alignment of at least 16 bytes."
328
//   (Not reproducible with GCC or LuaJIT on Ubuntu)
329
//
330
//  Win64: http://msdn.microsoft.com/en-us/library/9dbwhz68.aspx
331
//
332
//  x86: http://en.wikipedia.org/wiki/Data_structure_alignment#Typical_alignment_of_C_structs_on_x86
573 terminx 333
 
3775 helixhorne 334
enum {
335
    SPR_XFLIP = 4,
336
    SPR_YFLIP = 8,
337
 
338
    SPR_WALL = 16,
339
    SPR_FLOOR = 32,
340
    SPR_ALIGN_MASK = 32+16,
341
};
342
 
7695 terminx 343
#define UNTRACKED_STRUCTS__
4909 terminx 344
#include "buildtypes.h"
7695 terminx 345
#undef UNTRACKED_STRUCTS__
4909 terminx 346
#undef buildtypes_h__
347
#include "buildtypes.h"
573 terminx 348
 
5999 hendricks2 349
#if !defined NEW_MAP_FORMAT
7602 terminx 350
using sectortype  = sectortypev7;
351
using usectortype = usectortypev7;
3658 helixhorne 352
 
7602 terminx 353
using walltype  = walltypev7;
354
using uwalltype = uwalltypev7;
5999 hendricks2 355
#else
7602 terminx 356
using sectortype  = sectortypevx;
357
using usectortype = usectortypevx;
4937 helixhorne 358
 
7602 terminx 359
using walltype  = walltypevx;
360
using uwalltype = uwalltypevx;
5999 hendricks2 361
#endif
3731 helixhorne 362
 
7602 terminx 363
using spritetype  = spritetypev7;
364
using uspritetype = uspritetypev7;
365
using tspritetype = uspritetypev7;
6768 hendricks2 366
 
7602 terminx 367
using uspriteptr_t = uspritetype const *;
368
using uwallptr_t   = uwalltype const *;
369
using usectorptr_t = usectortype const *;
370
using tspriteptr_t = tspritetype *;
371
 
6634 terminx 372
// this is probably never going to be necessary
373
EDUKE32_STATIC_ASSERT(sizeof(sectortype) == sizeof(usectortype));
374
EDUKE32_STATIC_ASSERT(sizeof(walltype) == sizeof(uwalltype));
375
EDUKE32_STATIC_ASSERT(sizeof(spritetype) == sizeof(uspritetype));
376
 
5999 hendricks2 377
#ifdef NEW_MAP_FORMAT
3731 helixhorne 378
 
379
# define SECTORVX_SZ1 offsetof(sectortypevx, ceilingpicnum)
380
# define SECTORVX_SZ4 sizeof(sectortypevx)-offsetof(sectortypevx, visibility)
3658 helixhorne 381
 
5999 hendricks2 382
static inline void copy_v7_from_vx_sector(usectortypev7 *v7sec, const sectortypevx *vxsec)
3658 helixhorne 383
{
3731 helixhorne 384
    /* [wallptr..wallnum] */
385
    Bmemcpy(v7sec, vxsec, SECTORVX_SZ1);
3658 helixhorne 386
 
3731 helixhorne 387
    /* ceiling* */
388
    v7sec->ceilingpicnum = vxsec->ceilingpicnum;
389
    v7sec->ceilingheinum = vxsec->ceilingheinum;
390
    v7sec->ceilingstat = vxsec->ceilingstat;
391
    v7sec->ceilingz = vxsec->ceilingz;
392
    v7sec->ceilingshade = vxsec->ceilingshade;
393
    v7sec->ceilingpal = vxsec->ceilingpal;
394
    v7sec->ceilingxpanning = vxsec->ceilingxpanning;
395
    v7sec->ceilingypanning = vxsec->ceilingypanning;
396
 
397
    /* floor* */
398
    v7sec->floorpicnum = vxsec->floorpicnum;
399
    v7sec->floorheinum = vxsec->floorheinum;
400
    v7sec->floorstat = vxsec->floorstat;
401
    v7sec->floorz = vxsec->floorz;
402
    v7sec->floorshade = vxsec->floorshade;
403
    v7sec->floorpal = vxsec->floorpal;
404
    v7sec->floorxpanning = vxsec->floorxpanning;
405
    v7sec->floorypanning = vxsec->floorypanning;
406
 
407
    /* [visibility..extra] */
408
    Bmemcpy(&v7sec->visibility, &vxsec->visibility, SECTORVX_SZ4);
409
 
3658 helixhorne 410
    /* Clear YAX_BIT of ceiling and floor. (New-map format build saves TROR
411
     * maps as map-text.) */
412
    v7sec->ceilingstat &= ~YAX_BIT__COMPAT;
413
    v7sec->floorstat &= ~YAX_BIT__COMPAT;
414
}
415
 
416
static inline void inplace_vx_from_v7_sector(sectortypevx *vxsec)
417
{
418
    const sectortypev7 *v7sec = (sectortypev7 *)vxsec;
5999 hendricks2 419
    usectortypev7 bakv7sec;
3658 helixhorne 420
 
3731 helixhorne 421
    // Can't do this in-place since the members were rearranged.
422
    Bmemcpy(&bakv7sec, v7sec, sizeof(sectortypev7));
423
 
424
    /* [wallptr..wallnum] is already at the right place */
425
 
426
    /* ceiling* */
427
    vxsec->ceilingpicnum = bakv7sec.ceilingpicnum;
428
    vxsec->ceilingheinum = bakv7sec.ceilingheinum;
429
    vxsec->ceilingstat = bakv7sec.ceilingstat;
430
    vxsec->ceilingz = bakv7sec.ceilingz;
431
    vxsec->ceilingshade = bakv7sec.ceilingshade;
432
    vxsec->ceilingpal = bakv7sec.ceilingpal;
433
    vxsec->ceilingxpanning = bakv7sec.ceilingxpanning;
434
    vxsec->ceilingypanning = bakv7sec.ceilingypanning;
435
 
436
    /* floor* */
437
    vxsec->floorpicnum = bakv7sec.floorpicnum;
438
    vxsec->floorheinum = bakv7sec.floorheinum;
439
    vxsec->floorstat = bakv7sec.floorstat;
440
    vxsec->floorz = bakv7sec.floorz;
441
    vxsec->floorshade = bakv7sec.floorshade;
442
    vxsec->floorpal = bakv7sec.floorpal;
443
    vxsec->floorxpanning = bakv7sec.floorxpanning;
444
    vxsec->floorypanning = bakv7sec.floorypanning;
445
 
446
    /* [visibility..extra] */
447
    Bmemmove(&vxsec->visibility, &bakv7sec.visibility, SECTORVX_SZ4);
3658 helixhorne 448
}
449
 
450
static inline void inplace_vx_tweak_sector(sectortypevx *vxsec, int32_t yaxp)
451
{
452
    if (yaxp)
453
    {
454
        int32_t cisext = (vxsec->ceilingstat&YAX_BIT__COMPAT);
455
        int32_t fisext = (vxsec->floorstat&YAX_BIT__COMPAT);
456
 
457
        vxsec->ceilingbunch = cisext ? vxsec->ceilingxpanning : -1;
458
        vxsec->floorbunch = fisext ? vxsec->floorxpanning : -1;
459
 
460
        if (cisext)
461
            vxsec->ceilingxpanning = 0;
462
        if (fisext)
463
            vxsec->floorxpanning = 0;
464
    }
465
    else
466
    {
467
        vxsec->ceilingbunch = vxsec->floorbunch = -1;
468
    }
469
 
470
    /* Clear YAX_BIT of ceiling and floor (map-int VX doesn't use it). */
471
    vxsec->ceilingstat &= ~YAX_BIT__COMPAT;
472
    vxsec->floorstat &= ~YAX_BIT__COMPAT;
473
}
474
 
3731 helixhorne 475
# undef SECTORVX_SZ1
476
# undef SECTORVX_SZ4
3658 helixhorne 477
 
4368 helixhorne 478
# define WALLVX_SZ2 offsetof(walltypevx, blend)-offsetof(walltypevx, cstat)
3658 helixhorne 479
 
5999 hendricks2 480
static inline void copy_v7_from_vx_wall(uwalltypev7 *v7wal, const walltypevx *vxwal)
3658 helixhorne 481
{
482
    /* [x..nextsector] */
483
    Bmemcpy(v7wal, vxwal, offsetof(walltypevx, upwall));
484
    /* [cstat..extra] */
485
    Bmemcpy(&v7wal->cstat, &vxwal->cstat, WALLVX_SZ2);
486
    /* Clear YAX_NEXTWALLBITS. */
487
    v7wal->cstat &= ~YAX_NEXTWALLBITS__COMPAT;
488
}
489
 
490
static inline void inplace_vx_from_v7_wall(walltypevx *vxwal)
491
{
492
    const walltypev7 *v7wal = (walltypev7 *)vxwal;
493
 
494
    /* [cstat..extra] */
495
    Bmemmove(&vxwal->cstat, &v7wal->cstat, WALLVX_SZ2);
4368 helixhorne 496
 
497
    vxwal->blend = vxwal->filler_ = 0;
3658 helixhorne 498
}
499
 
500
static inline void inplace_vx_tweak_wall(walltypevx *vxwal, int32_t yaxp)
501
{
502
    if (yaxp)
503
    {
504
        int32_t haveupwall = (vxwal->cstat & YAX_NEXTWALLBIT__COMPAT(YAX_CEILING));
505
        int32_t havednwall = (vxwal->cstat & YAX_NEXTWALLBIT__COMPAT(YAX_FLOOR));
506
 
507
        vxwal->upwall = haveupwall ? vxwal->lotag : -1;
508
        vxwal->dnwall = havednwall ? vxwal->extra : -1;
509
 
510
        if (haveupwall)
511
            vxwal->lotag = 0;
512
        if (havednwall)
513
            vxwal->extra = -1;
514
    }
515
    else
516
    {
517
        vxwal->upwall = vxwal->dnwall = -1;
518
    }
519
 
520
    /* Clear YAX_NEXTWALLBITS (map-int VX doesn't use it). */
521
    vxwal->cstat &= ~YAX_NEXTWALLBITS__COMPAT;
522
}
523
 
524
# undef WALLVX_SZ2
525
 
526
#endif
527
 
5985 hendricks2 528
#include "clip.h"
529
 
8048 terminx 530
int32_t getwalldist(vec2_t const in, int const wallnum);
531
int32_t getwalldist(vec2_t const in, int const wallnum, vec2_t * const out);
7878 terminx 532
 
6137 hendricks2 533
#ifdef __cplusplus
534
extern "C" {
535
#endif
536
 
1454 terminx 537
typedef struct {
1205 terminx 538
    uint32_t mdanimtims;
539
    int16_t mdanimcur;
1625 terminx 540
    int16_t angoff, pitch, roll;
4680 terminx 541
    vec3_t offset;
1206 terminx 542
    uint8_t flags;
543
    uint8_t xpanning, ypanning;
1341 terminx 544
    uint8_t filler;
545
    float alpha;
3455 helixhorne 546
    // NOTE: keep 'tspr' on an 8-byte boundary:
5796 terminx 547
    uspritetype *tspr;
2207 helixhorne 548
#if !defined UINTPTR_MAX
549
# error Need UINTPTR_MAX define to select between 32- and 64-bit structs
550
#endif
551
#if UINTPTR_MAX == 0xffffffff
3188 helixhorne 552
    /* On a 32-bit build, pad the struct so it has the same size everywhere. */
3116 hendricks2 553
    intptr_t dummy_;
2148 helixhorne 554
#endif
1206 terminx 555
} spriteext_t;
573 terminx 556
 
1454 terminx 557
typedef struct {
747 terminx 558
    float smoothduration;
1205 terminx 559
    int16_t mdcurframe, mdoldframe;
560
    int16_t mdsmooth;
1206 terminx 561
    uint8_t filler[2];
562
} spritesmooth_t;
573 terminx 563
 
6276 hendricks2 564
#ifndef NEW_MAP_FORMAT
565
typedef struct {
566
    uint8_t blend;
567
} wallext_t;
568
#endif
569
 
573 terminx 570
#define SPREXT_NOTMD 1
571
#define SPREXT_NOMDANIM 2
587 terminx 572
#define SPREXT_AWAY1 4
573
#define SPREXT_AWAY2 8
1010 terminx 574
#define SPREXT_TSPRACCESS 16
1968 helixhorne 575
#define SPREXT_TEMPINVISIBLE 32
853 terminx 576
 
5400 terminx 577
#define TSPR_EXTRA_MDHACK 1
3584 helixhorne 578
 
2270 helixhorne 579
EXTERN int32_t guniqhudid;
580
EXTERN int32_t spritesortcnt;
3926 helixhorne 581
extern int32_t g_loadedMapVersion;
2270 helixhorne 582
 
4884 hendricks2 583
typedef struct {
584
    char *mhkfile;
585
    char *title;
586
    uint8_t md4[16];
587
} usermaphack_t;
4933 helixhorne 588
 
589
extern usermaphack_t g_loadedMapHack;
5980 hendricks2 590
extern int compare_usermaphacks(const void *, const void *);
4884 hendricks2 591
extern usermaphack_t *usermaphacks;
592
extern int32_t num_usermaphacks;
593
 
2270 helixhorne 594
#if !defined DEBUG_MAIN_ARRAYS
1206 terminx 595
EXTERN spriteext_t *spriteext;
596
EXTERN spritesmooth_t *spritesmooth;
6276 hendricks2 597
# ifndef NEW_MAP_FORMAT
598
EXTERN wallext_t *wallext;
599
# endif
573 terminx 600
 
574 terminx 601
EXTERN sectortype *sector;
602
EXTERN walltype *wall;
2270 helixhorne 603
EXTERN spritetype *sprite;
7603 terminx 604
EXTERN tspriteptr_t tsprite;
2270 helixhorne 605
#else
606
EXTERN spriteext_t spriteext[MAXSPRITES+MAXUNIQHUDID];
607
EXTERN spritesmooth_t spritesmooth[MAXSPRITES+MAXUNIQHUDID];
6276 hendricks2 608
# ifndef NEW_MAP_FORMAT
609
EXTERN wallext_t wallext[MAXWALLS];
610
# endif
2270 helixhorne 611
 
612
EXTERN sectortype sector[MAXSECTORS + M32_FIXME_SECTORS];
613
EXTERN walltype wall[MAXWALLS + M32_FIXME_WALLS];
614
EXTERN spritetype sprite[MAXSPRITES];
5796 terminx 615
EXTERN uspritetype tsprite[MAXSPRITESONSCREEN];
2270 helixhorne 616
#endif
617
 
7695 terminx 618
#ifdef USE_STRUCT_TRACKERS
3234 Plagman 619
EXTERN uint32_t sectorchanged[MAXSECTORS + M32_FIXME_SECTORS];
620
EXTERN uint32_t wallchanged[MAXWALLS + M32_FIXME_WALLS];
621
EXTERN uint32_t spritechanged[MAXSPRITES];
6769 hendricks2 622
#endif
3138 Plagman 623
 
3658 helixhorne 624
#ifdef NEW_MAP_FORMAT
6076 hendricks2 625
static FORCE_INLINE int16_t yax_getbunch(int16_t i, int16_t cf)
3658 helixhorne 626
{
627
    return cf ? sector[i].floorbunch : sector[i].ceilingbunch;
628
}
629
 
6076 hendricks2 630
static FORCE_INLINE void yax_getbunches(int16_t i, int16_t *cb, int16_t *fb)
3658 helixhorne 631
{
632
    *cb = yax_getbunch(i, YAX_CEILING);
633
    *fb = yax_getbunch(i, YAX_FLOOR);
634
}
635
 
6076 hendricks2 636
static FORCE_INLINE int16_t yax_getnextwall(int16_t wal, int16_t cf)
3658 helixhorne 637
{
638
    return cf ? wall[wal].dnwall : wall[wal].upwall;
639
}
640
 
6076 hendricks2 641
static FORCE_INLINE void yax_setnextwall(int16_t wal, int16_t cf, int16_t thenextwall)
3658 helixhorne 642
{
643
    YAX_NEXTWALL(wal, cf) = thenextwall;
644
}
645
#endif
646
 
7695 terminx 647
#ifdef USE_STRUCT_TRACKERS
7691 terminx 648
static FORCE_INLINE void sector_tracker_hook__(intptr_t const address)
3138 Plagman 649
{
7691 terminx 650
    intptr_t const sectnum = (address - (intptr_t)sector) / sizeof(sectortype);
4680 terminx 651
 
7711 terminx 652
#if DEBUGGINGAIDS>=2
7691 terminx 653
    Bassert((unsigned)sectnum < ((MAXSECTORS + M32_FIXME_SECTORS)));
4898 terminx 654
#endif
4680 terminx 655
 
7691 terminx 656
    ++sectorchanged[sectnum];
3138 Plagman 657
}
658
 
7691 terminx 659
static FORCE_INLINE void wall_tracker_hook__(intptr_t const address)
3138 Plagman 660
{
7691 terminx 661
    intptr_t const wallnum = (address - (intptr_t)wall) / sizeof(walltype);
4680 terminx 662
 
7711 terminx 663
#if DEBUGGINGAIDS>=2
7691 terminx 664
    Bassert((unsigned)wallnum < ((MAXWALLS + M32_FIXME_WALLS)));
4898 terminx 665
#endif
4680 terminx 666
 
7691 terminx 667
    ++wallchanged[wallnum];
3138 Plagman 668
}
669
 
7691 terminx 670
static FORCE_INLINE void sprite_tracker_hook__(intptr_t const address)
3138 Plagman 671
{
7691 terminx 672
    intptr_t const spritenum = (address - (intptr_t)sprite) / sizeof(spritetype);
3138 Plagman 673
 
7711 terminx 674
#if DEBUGGINGAIDS>=2
7695 terminx 675
    Bassert((unsigned)spritenum < MAXSPRITES);
4898 terminx 676
#endif
4680 terminx 677
 
7691 terminx 678
    ++spritechanged[spritenum];
3138 Plagman 679
}
6769 hendricks2 680
#endif
3138 Plagman 681
 
4680 terminx 682
 
1205 terminx 683
EXTERN int16_t maskwall[MAXWALLSB], maskwallcnt;
684
EXTERN int16_t thewall[MAXWALLSB];
7603 terminx 685
EXTERN tspriteptr_t tspriteptr[MAXSPRITESONSCREEN + 1];
573 terminx 686
 
5790 terminx 687
EXTERN int32_t wx1, wy1, wx2, wy2;
6939 pogokeen 688
EXTERN int32_t xdim, ydim, numpages, upscalefactor;
1205 terminx 689
EXTERN int32_t yxaspect, viewingrange;
4695 terminx 690
EXTERN intptr_t *ylookup;
573 terminx 691
 
7321 terminx 692
EXTERN int32_t rotatesprite_y_offset;
693
EXTERN int32_t rotatesprite_yxaspect;
694
 
4472 hendricks2 695
#ifndef GEKKO
573 terminx 696
#define MAXVALIDMODES 256
4472 hendricks2 697
#else
698
#define MAXVALIDMODES 16
699
#endif
1205 terminx 700
EXTERN int32_t validmodecnt;
573 terminx 701
struct validmode_t {
1205 terminx 702
    int32_t xdim,ydim;
573 terminx 703
    char bpp;
704
    char fs;    // bit 0 = fullscreen flag
705
    char filler[2];
1205 terminx 706
    int32_t extra; // internal use
573 terminx 707
};
708
EXTERN struct validmode_t validmode[MAXVALIDMODES];
709
 
1854 helixhorne 710
EXTERN int32_t numyaxbunches;
711
#ifdef YAX_ENABLE
712
// Singly-linked list of sectnums grouped by bunches and ceiling (0)/floor (1)
713
// Usage e.g.:
714
//   int16_t bunchnum = yax_getbunch(somesector, YAX_CEILING);
715
// Iteration over all sectors whose floor bunchnum equals 'bunchnum' (i.e. "all
716
// floors of the other side"):
717
//   for (i=headsectbunch[1][bunchnum]; i!=-1; i=nextsectbunch[1][i])
718
//       <do stuff with sector i...>
719
 
720
EXTERN int16_t headsectbunch[2][YAX_MAXBUNCHES], nextsectbunch[2][MAXSECTORS];
721
#endif
722
 
2478 helixhorne 723
EXTERN int32_t Numsprites;
1205 terminx 724
EXTERN int16_t numsectors, numwalls;
7662 terminx 725
EXTERN int32_t display_mirror;
4450 helixhorne 726
// totalclocklock: the totalclock value that is backed up once on each
727
// drawrooms() and is used for animateoffs().
8050 pogokeen 728
EXTERN ClockTicks totalclock, totalclocklock;
729
static inline int32_t BGetTime(void) { return (int32_t) totalclock; }
4558 hendricks2 730
 
1205 terminx 731
EXTERN int32_t numframes, randomseed;
732
EXTERN int16_t sintable[2048];
5346 hendricks2 733
 
1206 terminx 734
EXTERN uint8_t palette[768];
2504 helixhorne 735
EXTERN int16_t numshades;
573 terminx 736
EXTERN char *palookup[MAXPALOOKUPS];
5348 hendricks2 737
extern uint8_t *basepaltable[MAXBASEPALS];
5346 hendricks2 738
EXTERN uint8_t paletteloaded;
5351 hendricks2 739
EXTERN char *blendtable[MAXBLENDTABS];
8433 hendricks2 740
EXTERN uint8_t whitecol, redcol, blackcol;
5346 hendricks2 741
 
6347 terminx 742
EXTERN int32_t maxspritesonscreen;
6344 terminx 743
 
5346 hendricks2 744
enum {
745
    PALETTE_MAIN = 1<<0,
746
    PALETTE_SHADE = 1<<1,
747
    PALETTE_TRANSLUC = 1<<2,
748
};
749
 
3975 helixhorne 750
EXTERN char showinvisibility;
3287 helixhorne 751
EXTERN int32_t g_visibility, parallaxvisibility;
3284 helixhorne 752
EXTERN int32_t g_rotatespriteNoWidescreen;
573 terminx 753
 
5124 hendricks2 754
// blendtable[1] to blendtable[numalphatabs] are considered to be
755
// alpha-blending tables:
756
EXTERN uint8_t numalphatabs;
757
 
5800 terminx 758
EXTERN vec2_t windowxy1, windowxy2;
4695 terminx 759
EXTERN int16_t *startumost, *startdmost;
573 terminx 760
 
3975 helixhorne 761
// The maximum tile offset ever used in any tiled parallaxed multi-sky.
5898 hendricks2 762
#define PSKYOFF_MAX 8
5255 hendricks2 763
#define DEFAULTPSKY -1
573 terminx 764
 
3975 helixhorne 765
typedef struct {
766
    // The proportion at which looking up/down affects the apparent 'horiz' of
767
    // a parallaxed sky, scaled by 65536 (so, a value of 65536 makes it align
768
    // with the drawn surrounding scene):
769
    int32_t horizfrac;
770
 
771
    // The texel index offset in the y direction of a parallaxed sky:
772
    // XXX: currently always 0.
773
    int32_t yoffs;
774
 
4171 helixhorne 775
    int8_t lognumtiles;  // 1<<lognumtiles: number of tiles in multi-sky
776
    int8_t tileofs[MAXPSKYTILES];  // for 0 <= j < (1<<lognumtiles): tile offset relative to basetile
6519 hendricks2 777
 
778
    int32_t yscale;
3975 helixhorne 779
} psky_t;
780
 
3976 helixhorne 781
// Index of map-global (legacy) multi-sky:
782
EXTERN int32_t g_pskyidx;
5255 hendricks2 783
// New multi-psky
3975 helixhorne 784
EXTERN int32_t pskynummultis;
5255 hendricks2 785
EXTERN psky_t * multipsky;
3975 helixhorne 786
// Mapping of multi-sky index to base sky tile number:
5255 hendricks2 787
EXTERN int32_t * multipskytile;
3975 helixhorne 788
 
6076 hendricks2 789
static FORCE_INLINE int32_t getpskyidx(int32_t picnum)
4006 helixhorne 790
{
791
    int32_t j;
792
 
5263 helixhorne 793
    for (j=pskynummultis-1; j>0; j--)  // NOTE: j==0 on non-early loop end
4006 helixhorne 794
        if (picnum == multipskytile[j])
795
            break;  // Have a match.
796
 
797
    return j;
798
}
799
 
6831 terminx 800
EXTERN psky_t * tileSetupSky(int32_t tilenum);
5255 hendricks2 801
 
3975 helixhorne 802
EXTERN char parallaxtype;
5211 hendricks2 803
EXTERN int32_t parallaxyoffs_override, parallaxyscale_override;
804
extern int16_t pskybits_override;
3975 helixhorne 805
 
2470 helixhorne 806
// last sprite in the freelist, that is the spritenum for which
807
//   .statnum==MAXSTATUS && nextspritestat[spritenum]==-1
808
// (or -1 if freelist is empty):
809
EXTERN int16_t tailspritefree;
810
 
1205 terminx 811
EXTERN int16_t headspritesect[MAXSECTORS+1], headspritestat[MAXSTATUS+1];
812
EXTERN int16_t prevspritesect[MAXSPRITES], prevspritestat[MAXSPRITES];
813
EXTERN int16_t nextspritesect[MAXSPRITES], nextspritestat[MAXSPRITES];
573 terminx 814
 
7694 terminx 815
EXTERN vec2_16_t tilesiz[MAXTILES];
4623 terminx 816
 
573 terminx 817
EXTERN char picsiz[MAXTILES];
818
EXTERN char walock[MAXTILES];
3202 helixhorne 819
 
7146 terminx 820
extern const char pow2char_[];
821
static CONSTEXPR const int32_t pow2long[32] =
822
{
823
    1, 2, 4, 8,
824
    16, 32, 64, 128,
825
    256, 512, 1024, 2048,
826
    4096, 8192, 16384, 32768,
827
    65536, 131072, 262144, 524288,
828
    1048576, 2097152, 4194304, 8388608,
829
    16777216, 33554432, 67108864, 134217728,
830
    268435456, 536870912, 1073741824, 2147483647
831
};
832
 
3202 helixhorne 833
// picanm[].sf:
834
// |bit(1<<7)
835
// |animtype|animtype|texhitscan|nofullbright|speed|speed|speed|speed|
836
enum {
837
    PICANM_ANIMTYPE_NONE = 0,
838
    PICANM_ANIMTYPE_OSC = (1<<6),
839
    PICANM_ANIMTYPE_FWD = (2<<6),
840
    PICANM_ANIMTYPE_BACK = (3<<6),
841
 
842
    PICANM_ANIMTYPE_SHIFT = 6,
843
    PICANM_ANIMTYPE_MASK = (3<<6),  // must be 192
844
    PICANM_MISC_MASK = (3<<4),
845
    PICANM_TEXHITSCAN_BIT = (2<<4),
846
    PICANM_NOFULLBRIGHT_BIT = (1<<4),
847
    PICANM_ANIMSPEED_MASK = 15,  // must be 15
848
};
849
 
850
// NOTE: If the layout of this struct is changed, loadpics() must be modified
851
// accordingly.
852
typedef struct {
853
    uint8_t num;  // animate number
854
    int8_t xofs, yofs;
855
    uint8_t sf;  // anim. speed and flags
856
} picanm_t;
857
EXTERN picanm_t picanm[MAXTILES];
7255 terminx 858
typedef struct { int16_t newtile; int16_t owner; } rottile_t;
7226 terminx 859
EXTERN rottile_t rottile[MAXTILES];
618 terminx 860
EXTERN intptr_t waloff[MAXTILES];  // stores pointers to cache  -- SA
573 terminx 861
 
1205 terminx 862
EXTERN int32_t windowpos, windowx, windowy;
573 terminx 863
 
864
    //These variables are for auto-mapping with the draw2dscreen function.
865
    //When you load a new board, these bits are all set to 0 - since
866
    //you haven't mapped out anything yet.  Note that these arrays are
867
    //bit-mapped.
868
    //If you want draw2dscreen() to show sprite #54 then you say:
869
    //   spritenum = 54;
870
    //   show2dsprite[spritenum>>3] |= (1<<(spritenum&7));
871
    //And if you want draw2dscreen() to not show sprite #54 then you say:
872
    //   spritenum = 54;
873
    //   show2dsprite[spritenum>>3] &= ~(1<<(spritenum&7));
874
 
7873 terminx 875
EXTERN int automapping;
573 terminx 876
EXTERN char show2dsector[(MAXSECTORS+7)>>3];
877
EXTERN char show2dwall[(MAXWALLS+7)>>3];
878
EXTERN char show2dsprite[(MAXSPRITES+7)>>3];
879
 
3136 Plagman 880
// In the editor, gotpic is only referenced from inline assembly;
881
// the compiler needs that hint or building with LTO will discard it.
4543 hendricks2 882
#if !defined __clang__ && !defined NOASM
3162 hendricks2 883
# define GOTPIC_USED ATTRIBUTE((used))
884
#else
885
# define GOTPIC_USED
886
#endif
887
 
888
EXTERN char GOTPIC_USED gotpic[(MAXTILES+7)>>3];
573 terminx 889
EXTERN char gotsector[(MAXSECTORS+7)>>3];
890
 
1190 terminx 891
EXTERN char editorcolors[256];
8490 hendricks2 892
EXTERN char editorcolorsdef[256];
1190 terminx 893
 
5079 terminx 894
EXTERN char faketile[(MAXTILES+7)>>3];
1544 terminx 895
EXTERN char *faketiledata[MAXTILES];
8193 terminx 896
EXTERN int faketilesize[MAXTILES];
1544 terminx 897
 
898
EXTERN char spritecol2d[MAXTILES][2];
5282 terminx 899
EXTERN uint8_t tilecols[MAXTILES];
900
 
7870 terminx 901
EXTERN char editwall[(MAXWALLS+7)>>3];
902
 
5349 hendricks2 903
extern uint8_t vgapal16[4*256];
1544 terminx 904
 
1205 terminx 905
extern uint32_t drawlinepat;
573 terminx 906
 
907
extern void faketimerhandler(void);
908
 
909
extern char apptitle[256];
910
 
2391 helixhorne 911
extern int32_t novoxmips;
573 terminx 912
 
3349 terminx 913
#ifdef DEBUGGINGAIDS
1702 plagman 914
extern float debug1, debug2;
3349 terminx 915
#endif
1702 plagman 916
 
2266 helixhorne 917
extern int16_t tiletovox[MAXTILES];
1205 terminx 918
extern int32_t usevoxels, voxscale[MAXVOXELS];
7961 hendricks2 919
extern char g_haveVoxels;
1820 terminx 920
 
921
#ifdef USE_OPENGL
1205 terminx 922
extern int32_t usemodels, usehightile;
923
extern int32_t rendmode;
6651 hendricks2 924
#endif
6591 hendricks2 925
extern uint8_t globalr, globalg, globalb;
5079 terminx 926
EXTERN uint16_t h_xsize[MAXTILES], h_ysize[MAXTILES];
1205 terminx 927
EXTERN int8_t h_xoffs[MAXTILES], h_yoffs[MAXTILES];
573 terminx 928
 
5789 terminx 929
EXTERN char *globalpalwritten;
930
 
5056 hendricks2 931
enum {
932
    GLOBAL_NO_GL_TILESHADES = 1<<0,
933
    GLOBAL_NO_GL_FULLBRIGHT = 1<<1,
6559 hendricks2 934
    GLOBAL_NO_GL_FOGSHADE = 1<<2,
5056 hendricks2 935
};
936
 
937
extern int32_t globalflags;
938
 
1799 helixhorne 939
extern const char *engineerrstr;
573 terminx 940
 
1205 terminx 941
EXTERN int32_t editorzrange[2];
1121 terminx 942
 
6829 terminx 943
static FORCE_INLINE int32_t videoGetRenderMode(void)
1228 terminx 944
{
1820 terminx 945
#ifndef USE_OPENGL
3347 terminx 946
    return REND_CLASSIC;
1228 terminx 947
#else
948
    return rendmode;
949
#endif
950
}
951
 
573 terminx 952
/*************************************************************************
953
POSITION VARIABLES:
954
 
955
        POSX is your x - position ranging from 0 to 65535
956
        POSY is your y - position ranging from 0 to 65535
957
            (the length of a side of the grid in EDITBORD would be 1024)
958
        POSZ is your z - position (height) ranging from 0 to 65535, 0 highest.
959
        ANG is your angle ranging from 0 to 2047.  Instead of 360 degrees, or
960
             2 * PI radians, I use 2048 different angles, so 90 degrees would
961
             be 512 in my system.
962
 
963
SPRITE VARIABLES:
964
 
965
    EXTERN short headspritesect[MAXSECTORS+1], headspritestat[MAXSTATUS+1];
966
    EXTERN short prevspritesect[MAXSPRITES], prevspritestat[MAXSPRITES];
967
    EXTERN short nextspritesect[MAXSPRITES], nextspritestat[MAXSPRITES];
968
 
969
    Example: if the linked lists look like the following:
1540 terminx 970
         ????????????????
5768 hendricks2 971
               Sector lists:               Status lists:
1540 terminx 972
         ????????????????J
5768 hendricks2 973
           Sector0:  4, 5, 8             Status0:  2, 0, 8
974
           Sector1:  16, 2, 0, 7         Status1:  4, 5, 16, 7, 3, 9
975
           Sector2:  3, 9
1540 terminx 976
         ????????????????
573 terminx 977
    Notice that each number listed above is shown exactly once on both the
978
        left and right side.  This is because any sprite that exists must
979
        be in some sector, and must have some kind of status that you define.
980
 
981
 
982
Coding example #1:
983
    To go through all the sprites in sector 1, the code can look like this:
984
 
985
        sectnum = 1;
986
        i = headspritesect[sectnum];
987
        while (i != -1)
988
        {
989
            nexti = nextspritesect[i];
990
 
991
            //your code goes here
992
            //ex: printf("Sprite %d is in sector %d\n",i,sectnum);
993
 
994
            i = nexti;
995
        }
996
 
997
Coding example #2:
998
    To go through all sprites with status = 1, the code can look like this:
999
 
1000
        statnum = 1;        //status 1
1001
        i = headspritestat[statnum];
1002
        while (i != -1)
1003
        {
1004
            nexti = nextspritestat[i];
1005
 
1006
            //your code goes here
1007
            //ex: printf("Sprite %d has a status of 1 (active)\n",i,statnum);
1008
 
1009
            i = nexti;
1010
        }
1011
 
1012
             insertsprite(short sectnum, short statnum);
1013
             deletesprite(short spritenum);
1014
             changespritesect(short spritenum, short newsectnum);
1015
             changespritestat(short spritenum, short newstatnum);
1016
 
1017
TILE VARIABLES:
1018
        NUMTILES - the number of tiles found TILES.DAT.
1019
        TILESIZX[MAXTILES] - simply the x-dimension of the tile number.
1020
        TILESIZY[MAXTILES] - simply the y-dimension of the tile number.
2471 helixhorne 1021
        WALOFF[MAXTILES] - the actual address pointing to the top-left
573 terminx 1022
                                 corner of the tile.
1023
        PICANM[MAXTILES] - flags for animating the tile.
1024
 
1025
TIMING VARIABLES:
1026
        TOTALCLOCK - When the engine is initialized, TOTALCLOCK is set to zero.
1027
            From then on, it is incremented 120 times a second by 1.  That
1028
            means that the number of seconds elapsed is totalclock / 120.
1029
        NUMFRAMES - The number of times the draw3dscreen function was called
1030
            since the engine was initialized.  This helps to determine frame
1031
            rate.  (Frame rate = numframes * 120 / totalclock.)
1032
 
1033
OTHER VARIABLES:
1034
 
1035
        STARTUMOST[320] is an array of the highest y-coordinates on each column
1036
                that my engine is allowed to write to.  You need to set it only
1037
                once.
1038
        STARTDMOST[320] is an array of the lowest y-coordinates on each column
1039
                that my engine is allowed to write to.  You need to set it only
1040
                once.
1041
        SINTABLE[2048] is a sin table with 2048 angles rather than the
1042
            normal 360 angles for higher precision.  Also since SINTABLE is in
1043
            all integers, the range is multiplied by 16383, so instead of the
1044
            normal -1<sin(x)<1, the range of sintable is -16383<sintable[]<16383
1045
            If you use this sintable, you can possibly speed up your code as
1046
            well as save space in memory.  If you plan to use sintable, 2
1047
            identities you may want to keep in mind are:
1048
                sintable[ang&2047]       = sin(ang * (3.141592/1024)) * 16383
1049
                sintable[(ang+512)&2047] = cos(ang * (3.141592/1024)) * 16383
1050
        NUMSECTORS - the total number of existing sectors.  Modified every time
1051
            you call the loadboard function.
1052
***************************************************************************/
1053
 
1454 terminx 1054
typedef struct {
1208 terminx 1055
    vec3_t pos;
2877 helixhorne 1056
    int16_t sprite, wall, sect;
1208 terminx 1057
} hitdata_t;
1058
 
5138 hendricks2 1059
typedef struct artheader_t {
1060
    int32_t tilestart, tileend, numtiles;
1061
} artheader_t;
5177 hendricks2 1062
#define ARTv1_UNITOFFSET ((signed)(4*sizeof(int32_t) + 2*sizeof(int16_t) + sizeof(picanm_t)))
1465 terminx 1063
 
6831 terminx 1064
int32_t    enginePreInit(void); // a partial setup of the engine used for launch windows
1065
int32_t    engineInit(void);
1066
int32_t enginePostInit(void);
1067
void   engineUnInit(void);
573 terminx 1068
void   initspritelists(void);
7073 terminx 1069
int32_t engineFatalError(char const * msg);
5346 hendricks2 1070
 
6831 terminx 1071
int32_t   engineLoadBoard(const char *filename, char flags, vec3_t *dapos, int16_t *daang, int16_t *dacursectnum);
1072
int32_t   engineLoadMHK(const char *filename);
1073
void engineClearLightsFromMHK();
2495 hendricks2 1074
#ifdef HAVE_CLIPSHAPE_FEATURE
6831 terminx 1075
int32_t engineLoadClipMaps(void);
2270 helixhorne 1076
#endif
3042 helixhorne 1077
int32_t   saveboard(const char *filename, const vec3_t *dapos, int16_t daang, int16_t dacursectnum);
5138 hendricks2 1078
 
7073 terminx 1079
void    tileSetupDummy(int32_t tile);
1080
void    tileSetData(int32_t tile, int32_t tsiz, char const *buffer);
1081
void    tileDelete(int32_t tile);
6831 terminx 1082
void    tileSetSize(int32_t picnum, int16_t dasizx, int16_t dasizy);
7359 hendricks2 1083
int32_t artReadHeader(buildvfs_kfd fil, char const *fn, artheader_t *local);
7073 terminx 1084
int32_t artReadHeaderFromBuffer(uint8_t const *buf, artheader_t *local);
1085
int32_t artCheckUnitFileHeader(uint8_t const *buf, int32_t length);
1086
void    tileConvertAnimFormat(int32_t picnum);
7359 hendricks2 1087
void    artReadManifest(buildvfs_kfd fil, artheader_t const *local);
1088
void    artPreloadFile(buildvfs_kfd fil, artheader_t const *local);
6831 terminx 1089
int32_t artLoadFiles(const char *filename, int32_t askedsize);
1090
void    artClearMapArt(void);
1091
void    artSetupMapArt(const char *filename);
1092
bool    tileLoad(int16_t tilenume);
1093
void    tileLoadData(int16_t tilenume, int32_t dasiz, char *buffer);
8464 hendricks2 1094
int32_t tileGetCRC32(int16_t tileNum);
8465 hendricks2 1095
vec2_16_t tileGetSize(int16_t tileNum);
6831 terminx 1096
void    artConvertRGB(palette_t *pic, uint8_t const *buf, int32_t bufsizx, int32_t sizx, int32_t sizy);
8438 hendricks2 1097
void    tileUpdatePicSiz(int32_t picnum);
5138 hendricks2 1098
 
1760 helixhorne 1099
int32_t   qloadkvx(int32_t voxindex, const char *filename);
5914 hendricks2 1100
void vox_undefine(int32_t const);
6830 terminx 1101
intptr_t   tileCreate(int16_t tilenume, int32_t xsiz, int32_t ysiz);
1102
void   tileCopySection(int32_t tilenume1, int32_t sx1, int32_t sy1, int32_t xsiz, int32_t ysiz, int32_t tilenume2, int32_t sx2, int32_t sy2);
1205 terminx 1103
void   squarerotatetile(int16_t tilenume);
573 terminx 1104
 
6939 pogokeen 1105
int32_t   videoSetGameMode(char davidoption, int32_t daupscaledxdim, int32_t daupscaledydim, int32_t dabpp, int32_t daupscalefactor);
6828 terminx 1106
void   videoNextPage(void);
1107
void   videoSetCorrectedAspect();
1108
void   videoSetViewableArea(int32_t x1, int32_t y1, int32_t x2, int32_t y2);
6831 terminx 1109
void   renderSetAspect(int32_t daxrange, int32_t daaspect);
6832 terminx 1110
void   renderFlushPerms(void);
573 terminx 1111
 
5300 terminx 1112
void plotlines2d(const int32_t *xx, const int32_t *yy, int32_t numpoints, int col) ATTRIBUTE((nonnull(1,2)));
1695 helixhorne 1113
 
1205 terminx 1114
void   plotpixel(int32_t x, int32_t y, char col);
6831 terminx 1115
void   renderSetTarget(int16_t tilenume, int32_t xsiz, int32_t ysiz);
1116
void   renderRestoreTarget(void);
7736 pogokeen 1117
void   renderPrepareMirror(int32_t dax, int32_t day, int32_t daz, fix16_t daang, fix16_t dahoriz, int16_t dawall,
1118
                           int32_t *tposx, int32_t *tposy, fix16_t *tang);
6831 terminx 1119
void   renderCompleteMirror(void);
573 terminx 1120
 
6831 terminx 1121
int32_t renderDrawRoomsQ16(int32_t daposx, int32_t daposy, int32_t daposz, fix16_t daang, fix16_t dahoriz, int16_t dacursectnum);
6735 terminx 1122
 
6759 terminx 1123
static FORCE_INLINE int32_t drawrooms(int32_t daposx, int32_t daposy, int32_t daposz, int16_t daang, int16_t dahoriz, int16_t dacursectnum)
1124
{
6831 terminx 1125
    return renderDrawRoomsQ16(daposx, daposy, daposz, fix16_from_int(daang), fix16_from_int(dahoriz), dacursectnum);
6759 terminx 1126
}
1127
 
6831 terminx 1128
void   renderDrawMasks(void);
6828 terminx 1129
void   videoClearViewableArea(int32_t dacol);
1130
void   videoClearScreen(int32_t dacol);
6831 terminx 1131
void   renderDrawMapView(int32_t dax, int32_t day, int32_t zoome, int16_t ang);
3609 hendricks2 1132
void   rotatesprite_(int32_t sx, int32_t sy, int32_t z, int16_t a, int16_t picnum,
4360 helixhorne 1133
                     int8_t dashade, char dapalnum, int32_t dastat, uint8_t daalpha, uint8_t dablend,
1134
                     int32_t cx1, int32_t cy1, int32_t cx2, int32_t cy2);
6832 terminx 1135
void   renderDrawLine(int32_t x1, int32_t y1, int32_t x2, int32_t y2, char col);
7073 terminx 1136
void   drawlinergb(int32_t x1, int32_t y1, int32_t x2, int32_t y2, palette_t p);
2896 helixhorne 1137
int32_t    printext16(int32_t xpos, int32_t ypos, int16_t col, int16_t backcol,
1138
                      const char *name, char fontsize) ATTRIBUTE((nonnull(5)));
1139
void   printext256(int32_t xpos, int32_t ypos, int16_t col, int16_t backcol,
1140
                   const char *name, char fontsize) ATTRIBUTE((nonnull(5)));
5801 terminx 1141
void   Buninitart(void);
573 terminx 1142
 
2308 helixhorne 1143
////////// specialized rotatesprite wrappers for (very) often used cases //////////
6076 hendricks2 1144
static FORCE_INLINE void rotatesprite(int32_t sx, int32_t sy, int32_t z, int16_t a, int16_t picnum,
3609 hendricks2 1145
                                int8_t dashade, char dapalnum, int32_t dastat,
1146
                                int32_t cx1, int32_t cy1, int32_t cx2, int32_t cy2)
1147
{
4360 helixhorne 1148
    rotatesprite_(sx, sy, z, a, picnum, dashade, dapalnum, dastat, 0, 0, cx1, cy1, cx2, cy2);
3609 hendricks2 1149
}
3639 helixhorne 1150
// Don't clip at all, i.e. the whole screen real estate is available:
6076 hendricks2 1151
static FORCE_INLINE void rotatesprite_fs(int32_t sx, int32_t sy, int32_t z, int16_t a, int16_t picnum,
2896 helixhorne 1152
                                   int8_t dashade, char dapalnum, int32_t dastat)
2308 helixhorne 1153
{
4360 helixhorne 1154
    rotatesprite_(sx, sy, z, a, picnum, dashade, dapalnum, dastat, 0, 0, 0,0,xdim-1,ydim-1);
2308 helixhorne 1155
}
1156
 
6076 hendricks2 1157
static FORCE_INLINE void rotatesprite_fs_alpha(int32_t sx, int32_t sy, int32_t z, int16_t a, int16_t picnum,
4919 terminx 1158
                                  int8_t dashade, char dapalnum, int32_t dastat, uint8_t alpha)
1159
{
1160
    rotatesprite_(sx, sy, z, a, picnum, dashade, dapalnum, dastat, alpha, 0, 0, 0, xdim-1, ydim-1);
1161
}
1162
 
6076 hendricks2 1163
static FORCE_INLINE void rotatesprite_win(int32_t sx, int32_t sy, int32_t z, int16_t a, int16_t picnum,
2896 helixhorne 1164
                                    int8_t dashade, char dapalnum, int32_t dastat)
2318 helixhorne 1165
{
5800 terminx 1166
    rotatesprite_(sx, sy, z, a, picnum, dashade, dapalnum, dastat, 0, 0, windowxy1.x,windowxy1.y,windowxy2.x,windowxy2.y);
2318 helixhorne 1167
}
1168
 
7073 terminx 1169
void   getzrange(const vec3_t *pos, int16_t sectnum, int32_t *ceilz, int32_t *ceilhit, int32_t *florz,
2896 helixhorne 1170
                 int32_t *florhit, int32_t walldist, uint32_t cliptype) ATTRIBUTE((nonnull(1,3,4,5,6)));
8439 hendricks2 1171
extern vec2_t hitscangoal;
2896 helixhorne 1172
int32_t   hitscan(const vec3_t *sv, int16_t sectnum, int32_t vx, int32_t vy, int32_t vz,
1173
                  hitdata_t *hitinfo, uint32_t cliptype) ATTRIBUTE((nonnull(1,6)));
2373 helixhorne 1174
void   neartag(int32_t xs, int32_t ys, int32_t zs, int16_t sectnum, int16_t ange,
1175
               int16_t *neartagsector, int16_t *neartagwall, int16_t *neartagsprite,
1176
               int32_t *neartaghitdist, int32_t neartagrange, uint8_t tagsearch,
1177
               int32_t (*blacklist_sprite_func)(int32_t)) ATTRIBUTE((nonnull(6,7,8)));
2896 helixhorne 1178
int32_t   cansee(int32_t x1, int32_t y1, int32_t z1, int16_t sect1,
1179
                 int32_t x2, int32_t y2, int32_t z2, int16_t sect2);
1205 terminx 1180
int32_t   inside(int32_t x, int32_t y, int16_t sectnum);
3394 helixhorne 1181
void   dragpoint(int16_t pointhighlight, int32_t dax, int32_t day, uint8_t flags);
1205 terminx 1182
void   setfirstwall(int16_t sectnum, int16_t newfirstwall);
7933 terminx 1183
int32_t try_facespr_intersect(uspriteptr_t const spr, vec3_t const in,
7417 terminx 1184
                                     int32_t vx, int32_t vy, int32_t vz,
7933 terminx 1185
                                     vec3_t * const intp, int32_t strictly_smaller_than_p);
1886 helixhorne 1186
 
7805 pogokeen 1187
#define MAXUPDATESECTORDIST 1536
1188
#define INITIALUPDATESECTORDIST 256
1189
void updatesector(int32_t const x, int32_t const y, int16_t * const sectnum) ATTRIBUTE((nonnull(3)));
1190
void updatesectorexclude(int32_t const x, int32_t const y, int16_t * const sectnum,
1191
                         const uint8_t * const excludesectbitmap) ATTRIBUTE((nonnull(3,4)));
1192
void updatesectorz(int32_t const x, int32_t const y, int32_t const z, int16_t * const sectnum) ATTRIBUTE((nonnull(4)));
7811 terminx 1193
void updatesectorneighbor(int32_t const x, int32_t const y, int16_t * const sectnum, int32_t initialMaxDistance = INITIALUPDATESECTORDIST, int32_t maxDistance = MAXUPDATESECTORDIST) ATTRIBUTE((nonnull(3)));
1194
void updatesectorneighborz(int32_t const x, int32_t const y, int32_t const z, int16_t * const sectnum, int32_t initialMaxDistance = INITIALUPDATESECTORDIST, int32_t maxDistance = MAXUPDATESECTORDIST) ATTRIBUTE((nonnull(4)));
7805 pogokeen 1195
 
7608 terminx 1196
int findwallbetweensectors(int sect1, int sect2);
8366 terminx 1197
static FORCE_INLINE int sectoradjacent(int sect1, int sect2) { return findwallbetweensectors(sect1, sect2) != -1; }
8048 terminx 1198
int32_t getsectordist(vec2_t const in, int const sectnum, vec2_t * const out = nullptr);
1886 helixhorne 1199
extern const int16_t *chsecptr_onextwall;
1760 helixhorne 1200
int32_t checksectorpointer(int16_t i, int16_t sectnum);
573 terminx 1201
 
6831 terminx 1202
void   mouseGetValues(int32_t *mousx, int32_t *mousy, int32_t *bstatus) ATTRIBUTE((nonnull(1,2,3)));
4744 terminx 1203
 
4759 helixhorne 1204
#if !KRANDDEBUG && !defined LUNATIC
6076 hendricks2 1205
static FORCE_INLINE int32_t krand(void)
4744 terminx 1206
{
1207
    randomseed = (randomseed * 1664525ul) + 221297ul;
1208
    return ((uint32_t) randomseed)>>16;
1209
}
1210
#else
1205 terminx 1211
int32_t    krand(void);
4744 terminx 1212
#endif
1213
 
2791 helixhorne 1214
int32_t   ksqrt(uint32_t num);
6023 hendricks2 1215
int32_t   LUNATIC_FASTCALL getangle(int32_t xvect, int32_t yvect);
1230 terminx 1216
 
7587 terminx 1217
static FORCE_INLINE CONSTEXPR uint32_t uhypsq(int32_t const dx, int32_t const dy)
2791 helixhorne 1218
{
1219
    return (uint32_t)dx*dx + (uint32_t)dy*dy;
1220
}
1221
 
7587 terminx 1222
static FORCE_INLINE int32_t logapproach(int32_t const val, int32_t const targetval)
4392 helixhorne 1223
{
7587 terminx 1224
    int32_t const dif = targetval - val;
4392 helixhorne 1225
    return (dif>>1) ? val + (dif>>1) : targetval;
1226
}
1227
 
7587 terminx 1228
void rotatepoint(vec2_t const pivot, vec2_t p, int16_t const daang, vec2_t * const p2) ATTRIBUTE((nonnull(4)));
1205 terminx 1229
int32_t   lastwall(int16_t point);
4395 helixhorne 1230
int32_t   nextsectorneighborz(int16_t sectnum, int32_t refz, int16_t topbottom, int16_t direction);
3323 helixhorne 1231
 
7603 terminx 1232
int32_t   getceilzofslopeptr(usectorptr_t sec, int32_t dax, int32_t day) ATTRIBUTE((nonnull(1)));
1233
int32_t   getflorzofslopeptr(usectorptr_t sec, int32_t dax, int32_t day) ATTRIBUTE((nonnull(1)));
1234
void   getzsofslopeptr(usectorptr_t sec, int32_t dax, int32_t day,
3323 helixhorne 1235
                       int32_t *ceilz, int32_t *florz) ATTRIBUTE((nonnull(1,4,5)));
8109 terminx 1236
void yax_getzsofslope(int sectNum, int playerX, int playerY, int32_t* pCeilZ, int32_t* pFloorZ);
3323 helixhorne 1237
 
6076 hendricks2 1238
static FORCE_INLINE int32_t getceilzofslope(int16_t sectnum, int32_t dax, int32_t day)
3323 helixhorne 1239
{
7603 terminx 1240
    return getceilzofslopeptr((usectorptr_t)&sector[sectnum], dax, day);
3323 helixhorne 1241
}
1242
 
6076 hendricks2 1243
static FORCE_INLINE int32_t getflorzofslope(int16_t sectnum, int32_t dax, int32_t day)
3323 helixhorne 1244
{
7603 terminx 1245
    return getflorzofslopeptr((usectorptr_t)&sector[sectnum], dax, day);
3323 helixhorne 1246
}
1247
 
6076 hendricks2 1248
static FORCE_INLINE void getzsofslope(int16_t sectnum, int32_t dax, int32_t day, int32_t *ceilz, int32_t *florz)
3323 helixhorne 1249
{
7603 terminx 1250
    getzsofslopeptr((usectorptr_t)&sector[sectnum], dax, day, ceilz, florz);
3323 helixhorne 1251
}
1252
 
7822 terminx 1253
static FORCE_INLINE void getcorrectzsofslope(int16_t sectnum, int32_t dax, int32_t day, int32_t *ceilz, int32_t *florz)
1254
{
1255
    vec2_t closest = { dax, day };
1256
    getsectordist(closest, sectnum, &closest);
1257
    getzsofslopeptr((usectorptr_t)&sector[sectnum], closest.x, closest.y, ceilz, florz);
1258
}
1259
 
1260
static FORCE_INLINE int32_t getcorrectceilzofslope(int16_t sectnum, int32_t dax, int32_t day)
1261
{
1262
    vec2_t closest = { dax, day };
1263
    getsectordist(closest, sectnum, &closest);
1264
    return getceilzofslopeptr((usectorptr_t)&sector[sectnum], closest.x, closest.y);
1265
}
1266
 
1267
static FORCE_INLINE int32_t getcorrectflorzofslope(int16_t sectnum, int32_t dax, int32_t day)
1268
{
1269
    vec2_t closest = { dax, day };
1270
    getsectordist(closest, sectnum, &closest);
1271
    return getflorzofslopeptr((usectorptr_t)&sector[sectnum], closest.x, closest.y);
1272
}
1273
 
3686 helixhorne 1274
// Is <wal> a red wall in a safe fashion, i.e. only if consistency invariant
1275
// ".nextsector >= 0 iff .nextwall >= 0" holds.
7603 terminx 1276
static FORCE_INLINE CONSTEXPR int32_t redwallp(uwallptr_t wal)
3362 helixhorne 1277
{
1278
    return (wal->nextwall >= 0 && wal->nextsector >= 0);
1279
}
1280
 
7587 terminx 1281
static FORCE_INLINE CONSTEXPR int32_t E_SpriteIsValid(const int32_t i)
4281 helixhorne 1282
{
1283
    return ((unsigned)i < MAXSPRITES && sprite[i].statnum != MAXSTATUS);
1284
}
1285
 
7603 terminx 1286
int clipshape_idx_for_sprite(uspriteptr_t curspr, int curidx);
4574 helixhorne 1287
 
1205 terminx 1288
void   alignceilslope(int16_t dasect, int32_t x, int32_t y, int32_t z);
1289
void   alignflorslope(int16_t dasect, int32_t x, int32_t y, int32_t z);
6794 terminx 1290
int32_t sectorofwall(int16_t wallNum);
1291
int32_t sectorofwall_noquick(int16_t wallNum);
1205 terminx 1292
int32_t   loopnumofsector(int16_t sectnum, int16_t wallnum);
1866 helixhorne 1293
void setslope(int32_t sectnum, int32_t cf, int16_t slope);
573 terminx 1294
 
7471 pogokeen 1295
int32_t lintersect(int32_t originX, int32_t originY, int32_t originZ,
1296
                   int32_t destX, int32_t destY, int32_t destZ,
1297
                   int32_t lineStartX, int32_t lineStartY, int32_t lineEndX, int32_t lineEndY,
1298
                   int32_t *intersectionX, int32_t *intersectionY, int32_t *intersectionZ);
1708 helixhorne 1299
 
1300
int32_t rayintersect(int32_t x1, int32_t y1, int32_t z1, int32_t vx, int32_t vy, int32_t vz, int32_t x3,
1301
                     int32_t y3, int32_t x4, int32_t y4, int32_t *intx, int32_t *inty, int32_t *intz);
4233 helixhorne 1302
#if !defined NETCODE_DISABLE
3443 terminx 1303
void do_insertsprite_at_headofstat(int16_t spritenum, int16_t statnum);
1304
int32_t insertspritestat(int16_t statnum);
7242 seventyfiv 1305
void do_deletespritestat(int16_t deleteme);
3443 terminx 1306
void do_insertsprite_at_headofsect(int16_t spritenum, int16_t sectnum);
1307
void do_deletespritesect(int16_t deleteme);
4233 helixhorne 1308
#endif
2465 helixhorne 1309
int32_t insertsprite(int16_t sectnum, int16_t statnum);
1310
int32_t deletesprite(int16_t spritenum);
1230 terminx 1311
 
1205 terminx 1312
int32_t   changespritesect(int16_t spritenum, int16_t newsectnum);
1313
int32_t   changespritestat(int16_t spritenum, int16_t newstatnum);
3116 hendricks2 1314
int32_t   setsprite(int16_t spritenum, const vec3_t *) ATTRIBUTE((nonnull(2)));
1315
int32_t   setspritez(int16_t spritenum, const vec3_t *) ATTRIBUTE((nonnull(2)));
573 terminx 1316
 
7603 terminx 1317
int32_t spriteheightofsptr(uspriteptr_t spr, int32_t *height, int32_t alsotileyofs);
6076 hendricks2 1318
static FORCE_INLINE int32_t spriteheightofs(int16_t i, int32_t *height, int32_t alsotileyofs)
3228 helixhorne 1319
{
7603 terminx 1320
    return spriteheightofsptr((uspriteptr_t)&sprite[i], height, alsotileyofs);
3228 helixhorne 1321
}
1816 helixhorne 1322
 
6831 terminx 1323
int videoCaptureScreen(const char *filename, char inverseit) ATTRIBUTE((nonnull(1)));
1324
int videoCaptureScreenTGA(const char *filename, char inverseit) ATTRIBUTE((nonnull(1)));
573 terminx 1325
 
6532 hendricks2 1326
struct OutputFileCounter {
1327
    uint16_t count = 0;
7359 hendricks2 1328
    buildvfs_FILE opennextfile(char *, char *);
1329
    buildvfs_FILE opennextfile_withext(char *, const char *);
6532 hendricks2 1330
};
1331
 
573 terminx 1332
// PLAG: line utility functions
7587 terminx 1333
typedef struct s_equation
1334
{
1335
    float a, b, c;
1336
} _equation;
573 terminx 1337
 
7587 terminx 1338
int32_t wallvisible(int32_t const x, int32_t const y, int16_t const wallnum);
1339
 
573 terminx 1340
#define STATUS2DSIZ 144
1359 terminx 1341
#define STATUS2DSIZ2 26
1342
 
1892 helixhorne 1343
//void   qsetmode640350(void);
1344
//void   qsetmode640480(void);
6828 terminx 1345
void   videoSet2dMode(int32_t,int32_t);
573 terminx 1346
void   clear2dscreen(void);
6831 terminx 1347
void   editorDraw2dGrid(int32_t posxe, int32_t posye, int32_t posze, int16_t cursectnum,
2896 helixhorne 1348
                  int16_t ange, int32_t zoome, int16_t gride);
6831 terminx 1349
void   editorDraw2dScreen(const vec3_t *pos, int16_t cursectnum,
2896 helixhorne 1350
                    int16_t ange, int32_t zoome, int16_t gride) ATTRIBUTE((nonnull(1)));
6831 terminx 1351
int32_t   editorDraw2dLine(int32_t x1, int32_t y1, int32_t x2, int32_t y2, int col);
1352
void   editorDraw2dCircle(int32_t x1, int32_t y1, int32_t r, int32_t eccen, char col);
573 terminx 1353
 
6831 terminx 1354
int32_t   videoSetRenderMode(int32_t renderer);
573 terminx 1355
 
1820 terminx 1356
#ifdef USE_OPENGL
6831 terminx 1357
void    renderSetRollAngle(int32_t rolla);
895 terminx 1358
#endif
573 terminx 1359
 
1360
//  pal: pass -1 to invalidate all palettes for the tile, or >=0 for a particular palette
1361
//  how: pass -1 to invalidate all instances of the tile in texture memory, or a bitfield
1362
//         bit 0: opaque or masked (non-translucent) texture, using repeating
1363
//         bit 1: ignored
1364
//         bit 2: 33% translucence, using repeating
1365
//         bit 3: 67% translucence, using repeating
1366
//         bit 4: opaque or masked (non-translucent) texture, using clamping
1367
//         bit 5: ignored
1368
//         bit 6: 33% translucence, using clamping
1369
//         bit 7: 67% translucence, using clamping
1370
//       clamping is for sprites, repeating is for walls
6831 terminx 1371
void tileInvalidate(int16_t tilenume, int32_t pal, int32_t how);
573 terminx 1372
 
6831 terminx 1373
void polymostSet2dView(void);   // sets up GL for 2D drawing
573 terminx 1374
 
1854 helixhorne 1375
int32_t polymost_drawtilescreen(int32_t tilex, int32_t tiley, int32_t wallnum, int32_t dimen, int32_t tilezoom,
1376
                                int32_t usehitile, uint8_t *loadedhitile);
573 terminx 1377
void polymost_glreset(void);
1205 terminx 1378
void polymost_precache(int32_t dapicnum, int32_t dapalnum, int32_t datype);
573 terminx 1379
 
6361 hendricks2 1380
typedef uint16_t polytintflags_t;
1381
 
6651 hendricks2 1382
enum cutsceneflags {
1383
    CUTSCENE_FORCEFILTER = 1,
1384
    CUTSCENE_FORCENOFILTER = 2,
1385
    CUTSCENE_TEXTUREFILTER = 4,
1386
};
1387
 
8082 terminx 1388
extern int32_t benchmarkScreenshot;
1389
 
1820 terminx 1390
#ifdef USE_OPENGL
1205 terminx 1391
extern int32_t glanisotropy;
1392
extern int32_t glusetexcompr;
1393
extern int32_t gltexfiltermode;
6776 pogokeen 1394
extern int32_t r_useindexedcolortextures;
5108 hendricks2 1395
 
1396
enum {
5874 terminx 1397
    TEXFILTER_OFF = 0, // GL_NEAREST
5108 hendricks2 1398
    TEXFILTER_ON = 5, // GL_LINEAR_MIPMAP_LINEAR
1399
};
1400
 
2145 helixhorne 1401
extern int32_t glusetexcache, glusememcache;
1205 terminx 1402
extern int32_t glmultisample, glnvmultisamplehint;
4607 terminx 1403
extern int32_t glprojectionhacks;
1205 terminx 1404
extern int32_t gltexmaxsize;
573 terminx 1405
void gltexapplyprops (void);
3758 terminx 1406
void texcache_invalidate(void);
573 terminx 1407
 
5526 hendricks2 1408
# ifdef USE_GLEXT
1205 terminx 1409
extern int32_t r_detailmapping;
1410
extern int32_t r_glowmapping;
5526 hendricks2 1411
# endif
5001 terminx 1412
 
1205 terminx 1413
extern int32_t r_vertexarrays;
5526 hendricks2 1414
# ifdef USE_GLEXT
1205 terminx 1415
extern int32_t r_vbos;
1416
extern int32_t r_vbocount;
5526 hendricks2 1417
# endif
1205 terminx 1418
extern int32_t r_animsmoothing;
1419
extern int32_t r_parallaxskyclamping;
1420
extern int32_t r_parallaxskypanning;
1421
extern int32_t r_fullbrights;
1422
extern int32_t r_downsize;
1357 terminx 1423
extern int32_t r_downsizevar;
1205 terminx 1424
extern int32_t mdtims, omdtims;
1275 terminx 1425
extern int32_t glrendmode;
573 terminx 1426
#endif
1427
 
1428
void hicinit(void);
6557 hendricks2 1429
void hicsetpalettetint(int32_t palnum, char r, char g, char b, char sr, char sg, char sb, polytintflags_t effect);
573 terminx 1430
// flags bitset: 1 = don't compress
2896 helixhorne 1431
int32_t hicsetsubsttex(int32_t picnum, int32_t palnum, const char *filen, float alphacut,
1432
                       float xscale, float yscale, float specpower, float specfactor, char flags);
5010 terminx 1433
int32_t hicsetskybox(int32_t picnum, int32_t palnum, char *faces[6], int32_t flags);
1205 terminx 1434
int32_t hicclearsubst(int32_t picnum, int32_t palnum);
573 terminx 1435
 
7073 terminx 1436
int32_t Ptile2tile(int32_t tile, int32_t palette) ATTRIBUTE((pure));
1205 terminx 1437
int32_t md_loadmodel(const char *fn);
2264 hendricks2 1438
int32_t md_setmisc(int32_t modelid, float scale, int32_t shadeoff, float zadd, float yoffset, int32_t flags);
1230 terminx 1439
// int32_t md_tilehasmodel(int32_t tilenume, int32_t pal);
1440
 
2796 helixhorne 1441
extern const char *G_DefaultDefFile(void);
1442
extern const char *G_DefFile(void);
1909 terminx 1443
extern char *g_defNamePtr;
1444
 
6673 hendricks2 1445
extern GrowArray<char *> g_defModules;
1937 hendricks2 1446
 
2495 hendricks2 1447
#ifdef HAVE_CLIPSHAPE_FEATURE
6673 hendricks2 1448
extern GrowArray<char *> g_clipMapFiles;
2495 hendricks2 1449
#endif
1450
 
8471 hendricks2 1451
EXTERN int32_t nextvoxid;
8445 hendricks2 1452
EXTERN intptr_t voxoff[MAXVOXELS][MAXVOXMIPS]; // used in KenBuild
1453
 
1820 terminx 1454
#ifdef USE_OPENGL
5079 terminx 1455
// TODO: dynamically allocate this
1456
 
1457
typedef struct { vec3f_t add; int16_t angadd, flags, fov; } hudtyp;
1458
 
1230 terminx 1459
typedef struct
1460
{
1461
    // maps build tiles to particular animation frames of a model
5079 terminx 1462
    int16_t     modelid;
1463
    int16_t     framenum;   // calculate the number from the name when declaring
1464
    int16_t     nexttile;
1465
    uint16_t    smoothduration;
1466
    hudtyp      *hudmem[2];
1467
    int8_t      skinnum;
1468
    char        pal;
1230 terminx 1469
} tile2model_t;
1470
 
2267 helixhorne 1471
# define EXTRATILES (MAXTILES/8)
1230 terminx 1472
 
1473
EXTERN int32_t mdinited;
1474
EXTERN tile2model_t tile2model[MAXTILES+EXTRATILES];
1475
 
7587 terminx 1476
static FORCE_INLINE int32_t md_tilehasmodel(int32_t const tilenume, int32_t const pal)
1230 terminx 1477
{
4898 terminx 1478
    return mdinited ? tile2model[Ptile2tile(tilenume,pal)].modelid : -1;
1230 terminx 1479
}
2244 helixhorne 1480
#endif  // defined USE_OPENGL
1230 terminx 1481
 
8366 terminx 1482
static FORCE_INLINE int tilehasmodelorvoxel(int const tilenume, int pal)
7767 terminx 1483
{
8082 terminx 1484
    UNREFERENCED_PARAMETER(pal);
7767 terminx 1485
    return
1486
#ifdef USE_OPENGL
1487
    (videoGetRenderMode() >= REND_POLYMOST && mdinited && usemodels && tile2model[Ptile2tile(tilenume, pal)].modelid != -1) ||
1488
#endif
1489
    (videoGetRenderMode() <= REND_POLYMOST && usevoxels && tiletovox[tilenume] != -1);
1490
}
1491
 
2896 helixhorne 1492
int32_t md_defineframe(int32_t modelid, const char *framename, int32_t tilenume,
1493
                       int32_t skinnum, float smoothduration, int32_t pal);
1494
int32_t md_defineanimation(int32_t modelid, const char *framestart, const char *frameend,
1495
                           int32_t fps, int32_t flags);
1496
int32_t md_defineskin(int32_t modelid, const char *skinfn, int32_t palnum, int32_t skinnum,
5107 hendricks2 1497
                      int32_t surfnum, float param, float specpower, float specfactor, int32_t flags);
5079 terminx 1498
int32_t md_definehud (int32_t modelid, int32_t tilex, vec3f_t add,
4607 terminx 1499
                      int32_t angadd, int32_t flags, int32_t fov);
1205 terminx 1500
int32_t md_undefinetile(int32_t tile);
1501
int32_t md_undefinemodel(int32_t modelid);
573 terminx 1502
 
1760 helixhorne 1503
int32_t loaddefinitionsfile(const char *fn);
573 terminx 1504
 
2896 helixhorne 1505
// if loadboard() fails with -2 return, try loadoldboard(). if it fails with
1506
// -2, board is dodgy
6831 terminx 1507
int32_t engineLoadBoardV5V6(const char *filename, char fromwhere, vec3_t *dapos, int16_t *daang, int16_t *dacursectnum);
573 terminx 1508
 
6137 hendricks2 1509
#ifdef __cplusplus
1510
}
1511
#endif
1512
 
5788 terminx 1513
#include "hash.h"
3710 helixhorne 1514
 
1227 plagman 1515
#ifdef POLYMER
1516
# include "polymer.h"
1517
#endif
6776 pogokeen 1518
#ifdef USE_OPENGL
1519
# include "polymost.h"
1520
#endif
1227 plagman 1521
 
6137 hendricks2 1522
#ifdef __cplusplus
1523
extern "C" {
1524
#endif
1525
 
6832 terminx 1526
static FORCE_INLINE void renderDisableFog(void)
3438 helixhorne 1527
{
1528
#ifdef USE_OPENGL
6829 terminx 1529
    if (videoGetRenderMode() >= REND_POLYMOST)
3438 helixhorne 1530
    {
6776 pogokeen 1531
        polymost_setFogEnabled(false);
3438 helixhorne 1532
    }
1533
#endif
1534
}
1535
 
6832 terminx 1536
static FORCE_INLINE void renderEnableFog(void)
3438 helixhorne 1537
{
1538
#ifdef USE_OPENGL
6829 terminx 1539
    if (videoGetRenderMode() >= REND_POLYMOST && !nofog)
6776 pogokeen 1540
        polymost_setFogEnabled(true);
3438 helixhorne 1541
#endif
1542
}
1543
 
5239 terminx 1544
static vec2_t const zerovec = { 0, 0 };
1545
 
4766 hendricks2 1546
#ifdef LUNATIC
1547
extern const int32_t engine_main_arrays_are_static;
1548
extern const int32_t engine_v8;
1549
int32_t Mulscale(int32_t a, int32_t b, int32_t sh);
1550
#endif
3438 helixhorne 1551
 
8366 terminx 1552
static FORCE_INLINE CONSTEXPR int inside_p(int32_t const x, int32_t const y, int const sectnum) { return (sectnum >= 0 && inside(x, y, sectnum) == 1); }
7546 terminx 1553
 
1554
#define SET_AND_RETURN(Lval, Rval) \
1555
    do                             \
1556
    {                              \
1557
        (Lval) = (Rval);           \
1558
        return;                    \
1559
    } while (0)
1560
 
5201 hendricks2 1561
static inline int32_t clipmove_old(int32_t *x, int32_t *y, int32_t *z, int16_t *sectnum, int32_t xvect, int32_t yvect, int32_t walldist,
1562
                   int32_t ceildist, int32_t flordist, uint32_t cliptype) ATTRIBUTE((nonnull(1,2,3,4)));
1563
 
1564
static inline int32_t clipmove_old(int32_t *x, int32_t *y, int32_t *z, int16_t *sectnum, int32_t xvect, int32_t yvect, int32_t walldist,
1565
                   int32_t ceildist, int32_t flordist, uint32_t cliptype)
1566
{
1567
    vec3_t vector = { *x, *y, *z };
1568
 
1569
    int32_t result = clipmove(&vector, sectnum, xvect, yvect, walldist, ceildist, flordist, cliptype);
1570
 
1571
    *x = vector.x;
1572
    *y = vector.y;
1573
    *z = vector.z;
1574
 
1575
    return result;
1576
}
1577
 
1578
static inline int32_t pushmove_old(int32_t *x, int32_t *y, int32_t *z, int16_t *sectnum, int32_t walldist,
1579
                   int32_t ceildist, int32_t flordist, uint32_t cliptype) ATTRIBUTE((nonnull(1,2,3,4)));
1580
 
1581
static inline int32_t pushmove_old(int32_t *x, int32_t *y, int32_t *z, int16_t *sectnum, int32_t walldist,
1582
                   int32_t ceildist, int32_t flordist, uint32_t cliptype)
1583
{
1584
    vec3_t vector = { *x, *y, *z };
1585
 
1586
    int32_t result = pushmove(&vector, sectnum, walldist, ceildist, flordist, cliptype);
1587
 
1588
    *x = vector.x;
1589
    *y = vector.y;
1590
    *z = vector.z;
1591
 
1592
    return result;
1593
}
1594
 
1595
static inline void getzrange_old(int32_t x, int32_t y, int32_t z, int16_t sectnum, int32_t *ceilz, int32_t *ceilhit, int32_t *florz,
1596
                 int32_t *florhit, int32_t walldist, uint32_t cliptype) ATTRIBUTE((nonnull(5,6,7,8)));
1597
 
1598
static inline void getzrange_old(int32_t x, int32_t y, int32_t z, int16_t sectnum, int32_t *ceilz, int32_t *ceilhit, int32_t *florz,
1599
                 int32_t *florhit, int32_t walldist, uint32_t cliptype)
1600
{
1601
    const vec3_t vector = { x, y, z };
1602
    getzrange(&vector, sectnum, ceilz, ceilhit, florz, florhit, walldist, cliptype);
1603
}
1604
 
1605
static inline int32_t setspritez_old(int16_t spritenum, int32_t x, int32_t y, int32_t z)
1606
{
1607
    const vec3_t vector = { x, y, z };
1608
    return setspritez(spritenum, &vector);
1609
}
1610
 
5792 terminx 1611
extern int32_t rintersect(int32_t x1, int32_t y1, int32_t z1,
1612
    int32_t vx_, int32_t vy_, int32_t vz,
1613
    int32_t x3, int32_t y3, int32_t x4, int32_t y4,
1614
    int32_t *intx, int32_t *inty, int32_t *intz);
1615
 
4766 hendricks2 1616
#ifdef __cplusplus
573 terminx 1617
}
1618
#endif
1619
 
4747 terminx 1620
#endif // build_h_