mirror of
https://github.com/ZDoom/Raze.git
synced 2024-12-02 00:53:16 +00:00
Merge commit 'a5ed7ba8a3eb26d3e3aa46bc87044608eacba57f' into whaven
This commit is contained in:
commit
aedb17e539
104 changed files with 1844 additions and 1739 deletions
|
@ -1075,7 +1075,6 @@ set (FASTMATH_SOURCES ${FASTMATH_SOURCES})
|
||||||
set (PCH_SOURCES
|
set (PCH_SOURCES
|
||||||
|
|
||||||
glbackend/glbackend.cpp
|
glbackend/glbackend.cpp
|
||||||
glbackend/gl_palmanager.cpp
|
|
||||||
glbackend/gl_texture.cpp
|
glbackend/gl_texture.cpp
|
||||||
|
|
||||||
thirdparty/src/md4.cpp
|
thirdparty/src/md4.cpp
|
||||||
|
@ -1086,7 +1085,6 @@ set (PCH_SOURCES
|
||||||
build/src/engine.cpp
|
build/src/engine.cpp
|
||||||
build/src/mdsprite.cpp
|
build/src/mdsprite.cpp
|
||||||
build/src/polymost.cpp
|
build/src/polymost.cpp
|
||||||
build/src/voxmodel.cpp
|
|
||||||
|
|
||||||
core/movie/playmve.cpp
|
core/movie/playmve.cpp
|
||||||
core/automap.cpp
|
core/automap.cpp
|
||||||
|
@ -1134,6 +1132,8 @@ set (PCH_SOURCES
|
||||||
|
|
||||||
core/rendering/hw_entrypoint.cpp
|
core/rendering/hw_entrypoint.cpp
|
||||||
core/rendering/hw_models.cpp
|
core/rendering/hw_models.cpp
|
||||||
|
core/rendering/hw_voxels.cpp
|
||||||
|
core/rendering/hw_palmanager.cpp
|
||||||
core/rendering/scene/hw_clipper.cpp
|
core/rendering/scene/hw_clipper.cpp
|
||||||
core/rendering/scene/hw_walls.cpp
|
core/rendering/scene/hw_walls.cpp
|
||||||
core/rendering/scene/hw_flats.cpp
|
core/rendering/scene/hw_flats.cpp
|
||||||
|
|
|
@ -200,7 +200,7 @@ enum {
|
||||||
PALETTE_TRANSLUC = 1<<2,
|
PALETTE_TRANSLUC = 1<<2,
|
||||||
};
|
};
|
||||||
|
|
||||||
EXTERN int32_t g_visibility, parallaxvisibility;
|
EXTERN int32_t g_visibility;
|
||||||
|
|
||||||
// blendtable[1] to blendtable[numalphatabs] are considered to be
|
// blendtable[1] to blendtable[numalphatabs] are considered to be
|
||||||
// alpha-blending tables:
|
// alpha-blending tables:
|
||||||
|
@ -269,12 +269,6 @@ extern FixedBitArray<MAXSECTORS> gotsector;
|
||||||
|
|
||||||
extern uint32_t drawlinepat;
|
extern uint32_t drawlinepat;
|
||||||
|
|
||||||
extern int32_t novoxmips;
|
|
||||||
|
|
||||||
extern int16_t tiletovox[MAXTILES];
|
|
||||||
extern int32_t voxscale[MAXVOXELS];
|
|
||||||
extern char g_haveVoxels;
|
|
||||||
|
|
||||||
extern uint8_t globalr, globalg, globalb;
|
extern uint8_t globalr, globalg, globalb;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
@ -362,10 +356,6 @@ void engineLoadBoard(const char *filename, int flags, vec3_t *dapos, int16_t *da
|
||||||
void loadMapBackup(const char* filename);
|
void loadMapBackup(const char* filename);
|
||||||
void G_LoadMapHack(const char* filename, const unsigned char*);
|
void G_LoadMapHack(const char* filename, const unsigned char*);
|
||||||
|
|
||||||
int32_t qloadkvx(int32_t voxindex, const char *filename);
|
|
||||||
void vox_undefine(int32_t const);
|
|
||||||
void vox_deinit();
|
|
||||||
|
|
||||||
void videoSetCorrectedAspect();
|
void videoSetCorrectedAspect();
|
||||||
void videoSetViewableArea(int32_t x1, int32_t y1, int32_t x2, int32_t y2);
|
void videoSetViewableArea(int32_t x1, int32_t y1, int32_t x2, int32_t y2);
|
||||||
void renderSetAspect(int32_t daxrange, int32_t daaspect);
|
void renderSetAspect(int32_t daxrange, int32_t daaspect);
|
||||||
|
@ -448,7 +438,6 @@ inline int32_t ksqrt(uint32_t num)
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t getangle(int32_t xvect, int32_t yvect);
|
int32_t getangle(int32_t xvect, int32_t yvect);
|
||||||
fixed_t gethiq16angle(int32_t xvect, int32_t yvect);
|
|
||||||
|
|
||||||
inline constexpr uint32_t uhypsq(int32_t const dx, int32_t const dy)
|
inline constexpr uint32_t uhypsq(int32_t const dx, int32_t const dy)
|
||||||
{
|
{
|
||||||
|
@ -598,7 +587,6 @@ int32_t md_setmisc(int32_t modelid, float scale, int32_t shadeoff, float zadd, f
|
||||||
|
|
||||||
EXTERN int32_t nextvoxid;
|
EXTERN int32_t nextvoxid;
|
||||||
EXTERN int8_t voxreserve[(MAXVOXELS+7)>>3];
|
EXTERN int8_t voxreserve[(MAXVOXELS+7)>>3];
|
||||||
EXTERN int8_t voxrotate[(MAXVOXELS+7)>>3];
|
|
||||||
|
|
||||||
#ifdef USE_OPENGL
|
#ifdef USE_OPENGL
|
||||||
// TODO: dynamically allocate this
|
// TODO: dynamically allocate this
|
||||||
|
@ -628,13 +616,7 @@ inline int32_t md_tilehasmodel(int32_t const tilenume, int32_t const pal)
|
||||||
}
|
}
|
||||||
#endif // defined USE_OPENGL
|
#endif // defined USE_OPENGL
|
||||||
|
|
||||||
inline int tilehasmodelorvoxel(int const tilenume, int pal)
|
int tilehasmodelorvoxel(int const tilenume, int pal);
|
||||||
{
|
|
||||||
UNREFERENCED_PARAMETER(pal);
|
|
||||||
return
|
|
||||||
(mdinited && hw_models && tile2model[Ptile2tile(tilenume, pal)].modelid != -1) ||
|
|
||||||
(r_voxels && tiletovox[tilenume] != -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t md_defineframe(int32_t modelid, const char *framename, int32_t tilenume,
|
int32_t md_defineframe(int32_t modelid, const char *framename, int32_t tilenume,
|
||||||
int32_t skinnum, float smoothduration, int32_t pal);
|
int32_t skinnum, float smoothduration, int32_t pal);
|
||||||
|
@ -647,7 +629,7 @@ int32_t md_definehud (int32_t modelid, int32_t tilex, vec3f_t add,
|
||||||
int32_t md_undefinetile(int32_t tile);
|
int32_t md_undefinetile(int32_t tile);
|
||||||
int32_t md_undefinemodel(int32_t modelid);
|
int32_t md_undefinemodel(int32_t modelid);
|
||||||
|
|
||||||
int32_t loaddefinitionsfile(const char *fn, bool loadadds = false);
|
int32_t loaddefinitionsfile(const char *fn, bool loadadds = false, bool cumulative = false);
|
||||||
|
|
||||||
#ifdef USE_OPENGL
|
#ifdef USE_OPENGL
|
||||||
# include "polymost.h"
|
# include "polymost.h"
|
||||||
|
@ -735,9 +717,6 @@ extern int32_t(*insertsprite_replace)(int16_t sectnum, int16_t statnum);
|
||||||
extern int32_t(*deletesprite_replace)(int16_t spritenum);
|
extern int32_t(*deletesprite_replace)(int16_t spritenum);
|
||||||
extern int32_t(*changespritesect_replace)(int16_t spritenum, int16_t newsectnum);
|
extern int32_t(*changespritesect_replace)(int16_t spritenum, int16_t newsectnum);
|
||||||
extern int32_t(*changespritestat_replace)(int16_t spritenum, int16_t newstatnum);
|
extern int32_t(*changespritestat_replace)(int16_t spritenum, int16_t newstatnum);
|
||||||
#ifdef USE_OPENGL
|
|
||||||
extern void(*PolymostProcessVoxels_Callback)(void);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Masking these into the object index to keep it in 16 bit was probably the single most dumbest and pointless thing Build ever did.
|
// Masking these into the object index to keep it in 16 bit was probably the single most dumbest and pointless thing Build ever did.
|
||||||
// Gonna be fun to globally replace these to finally lift the limit this imposes on map size.
|
// Gonna be fun to globally replace these to finally lift the limit this imposes on map size.
|
||||||
|
|
|
@ -1,43 +0,0 @@
|
||||||
#pragma once
|
|
||||||
// nobody uses these. What's so cool about naked numbers? :(
|
|
||||||
#if 0
|
|
||||||
// system defines for status bits
|
|
||||||
#define CEILING_STAT_PLAX BIT(0)
|
|
||||||
#define CEILING_STAT_SLOPE BIT(1)
|
|
||||||
#define CEILING_STAT_SWAPXY BIT(2)
|
|
||||||
#define CEILING_STAT_SMOOSH BIT(3)
|
|
||||||
#define CEILING_STAT_XFLIP BIT(4)
|
|
||||||
#define CEILING_STAT_YFLIP BIT(5)
|
|
||||||
#define CEILING_STAT_RELATIVE BIT(6)
|
|
||||||
#define CEILING_STAT_TYPE_MASK (BIT(7)|BIT(8))
|
|
||||||
#define CEILING_STAT_MASKED BIT(7)
|
|
||||||
#define CEILING_STAT_TRANS BIT(8)
|
|
||||||
#define CEILING_STAT_TRANS_FLIP (BIT(7)|BIT(8))
|
|
||||||
#define CEILING_STAT_FAF_BLOCK_HITSCAN BIT(15)
|
|
||||||
|
|
||||||
#define FLOOR_STAT_PLAX BIT(0)
|
|
||||||
#define FLOOR_STAT_SLOPE BIT(1)
|
|
||||||
#define FLOOR_STAT_SWAPXY BIT(2)
|
|
||||||
#define FLOOR_STAT_SMOOSH BIT(3)
|
|
||||||
#define FLOOR_STAT_XFLIP BIT(4)
|
|
||||||
#define FLOOR_STAT_YFLIP BIT(5)
|
|
||||||
#define FLOOR_STAT_RELATIVE BIT(6)
|
|
||||||
#define FLOOR_STAT_TYPE_MASK (BIT(7)|BIT(8))
|
|
||||||
#define FLOOR_STAT_MASKED BIT(7)
|
|
||||||
#define FLOOR_STAT_TRANS BIT(8)
|
|
||||||
#define FLOOR_STAT_TRANS_FLIP (BIT(7)|BIT(8))
|
|
||||||
#define FLOOR_STAT_FAF_BLOCK_HITSCAN BIT(15)
|
|
||||||
|
|
||||||
#define CSTAT_WALL_BLOCK BIT(0)
|
|
||||||
#define CSTAT_WALL_BOTTOM_SWAP BIT(1)
|
|
||||||
#define CSTAT_WALL_ALIGN_BOTTOM BIT(2)
|
|
||||||
#define CSTAT_WALL_XFLIP BIT(3)
|
|
||||||
#define CSTAT_WALL_MASKED BIT(4)
|
|
||||||
#define CSTAT_WALL_1WAY BIT(5)
|
|
||||||
#define CSTAT_WALL_BLOCK_HITSCAN BIT(6)
|
|
||||||
#define CSTAT_WALL_TRANSLUCENT BIT(7)
|
|
||||||
#define CSTAT_WALL_YFLIP BIT(8)
|
|
||||||
#define CSTAT_WALL_TRANS_FLIP BIT(9)
|
|
||||||
#define CSTAT_WALL_BLOCK_ACTOR (BIT(14)) // my def
|
|
||||||
#define CSTAT_WALL_WARP_HITSCAN (BIT(15)) // my def
|
|
||||||
#endif
|
|
|
@ -177,25 +177,6 @@ struct md3model_t : public idmodel_t
|
||||||
*/
|
*/
|
||||||
};
|
};
|
||||||
|
|
||||||
#define VOXBORDWIDTH 1 //use 0 to save memory, but has texture artifacts; 1 looks better...
|
|
||||||
#define VOXUSECHAR 0
|
|
||||||
|
|
||||||
#if (VOXUSECHAR != 0)
|
|
||||||
typedef struct { uint8_t x, y, z, u, v; } vert_t;
|
|
||||||
#else
|
|
||||||
typedef struct { uint16_t x, y, z, u, v; } vert_t;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct { vert_t v[4]; } voxrect_t;
|
|
||||||
|
|
||||||
struct voxmodel_t : public mdmodel_t
|
|
||||||
{
|
|
||||||
FVoxelModel* model = nullptr;
|
|
||||||
vec3_t siz;
|
|
||||||
vec3f_t piv;
|
|
||||||
int32_t is8bit;
|
|
||||||
};
|
|
||||||
|
|
||||||
EXTERN mdmodel_t **models;
|
EXTERN mdmodel_t **models;
|
||||||
|
|
||||||
FGameTexture* mdloadskin(idmodel_t* m, int32_t number, int32_t pal, int32_t surf, bool* exact);
|
FGameTexture* mdloadskin(idmodel_t* m, int32_t number, int32_t pal, int32_t surf, bool* exact);
|
||||||
|
@ -206,11 +187,6 @@ EXTERN void md3_vox_calcmat_common(tspriteptr_t tspr, const vec3f_t *a0, float f
|
||||||
|
|
||||||
EXTERN int32_t mdpause;
|
EXTERN int32_t mdpause;
|
||||||
EXTERN int32_t nextmodelid;
|
EXTERN int32_t nextmodelid;
|
||||||
EXTERN voxmodel_t *voxmodels[MAXVOXELS];
|
|
||||||
|
|
||||||
void voxfree(voxmodel_t *m);
|
|
||||||
voxmodel_t *voxload(int lumpnum);
|
|
||||||
int32_t polymost_voxdraw(voxmodel_t *m, tspriteptr_t const tspr, bool rotate);
|
|
||||||
|
|
||||||
#endif // defined USE_OPENGL
|
#endif // defined USE_OPENGL
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,6 @@ void polymost_deletesprite(int num);
|
||||||
|
|
||||||
int32_t polymost_maskWallHasTranslucency(walltype const * const wall);
|
int32_t polymost_maskWallHasTranslucency(walltype const * const wall);
|
||||||
int32_t polymost_spriteHasTranslucency(spritetype const * const tspr);
|
int32_t polymost_spriteHasTranslucency(spritetype const * const tspr);
|
||||||
int32_t polymost_spriteIsModelOrVoxel(spritetype const * const tspr);
|
|
||||||
|
|
||||||
void polymost_glreset(void);
|
void polymost_glreset(void);
|
||||||
void polymost_scansector(int32_t sectnum);
|
void polymost_scansector(int32_t sectnum);
|
||||||
|
|
|
@ -113,12 +113,6 @@ inline void scriptfile_close(scriptfile *sf)
|
||||||
delete sf;
|
delete sf;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int32_t scriptfile_addsymbolvalue(scriptfile *sf, char const *name, int32_t val)
|
|
||||||
{
|
|
||||||
sf->AddSymbol(name, val);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
const char *text;
|
const char *text;
|
||||||
|
|
|
@ -17,11 +17,8 @@
|
||||||
#include "gamecontrol.h"
|
#include "gamecontrol.h"
|
||||||
#include "palettecontainer.h"
|
#include "palettecontainer.h"
|
||||||
#include "mapinfo.h"
|
#include "mapinfo.h"
|
||||||
|
#include "hw_voxels.h"
|
||||||
int tileSetHightileReplacement(int picnum, int palnum, const char* filename, float alphacut, float xscale, float yscale, float specpower, float specfactor, uint8_t flags);
|
#include "parsefuncs.h"
|
||||||
int tileSetSkybox(int picnum, int palnum, const char** facenames, int flags);
|
|
||||||
void tileRemoveReplacement(int num);
|
|
||||||
|
|
||||||
|
|
||||||
int32_t getatoken(scriptfile *sf, const tokenlist *tl, int32_t ntokens)
|
int32_t getatoken(scriptfile *sf, const tokenlist *tl, int32_t ntokens)
|
||||||
{
|
{
|
||||||
|
@ -39,68 +36,6 @@ int32_t getatoken(scriptfile *sf, const tokenlist *tl, int32_t ntokens)
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddUserMapHack(usermaphack_t&);
|
void AddUserMapHack(usermaphack_t&);
|
||||||
#if 0
|
|
||||||
// For later
|
|
||||||
{
|
|
||||||
if (sc.Compare("music"))
|
|
||||||
{
|
|
||||||
FString id, mus;
|
|
||||||
sc.MustGetToken('{');
|
|
||||||
while (!sc.CheckToken('}'))
|
|
||||||
{
|
|
||||||
sc.MustGetToken(TK_Identifier);
|
|
||||||
if (sc.Compare("id"))
|
|
||||||
{
|
|
||||||
sc.MustGetString();
|
|
||||||
id = sc.String;
|
|
||||||
}
|
|
||||||
else if (sc.Compare("file"))
|
|
||||||
{
|
|
||||||
sc.MustGetString();
|
|
||||||
mus = sc.String;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!SetMusicForMap(id, mus, true))
|
|
||||||
{
|
|
||||||
sc.ScriptError("Map %s not found in music definition", id.GetChars());
|
|
||||||
}
|
|
||||||
|
|
||||||
char* tokenPtr = pScript->ltextptr;
|
|
||||||
char* musicID = NULL;
|
|
||||||
char* fileName = NULL;
|
|
||||||
char* musicEnd;
|
|
||||||
|
|
||||||
if (scriptfile_getbraces(pScript, &musicEnd))
|
|
||||||
break;
|
|
||||||
|
|
||||||
while (pScript->textptr < musicEnd)
|
|
||||||
{
|
|
||||||
switch (getatoken(pScript, soundTokens, countof(soundTokens)))
|
|
||||||
{
|
|
||||||
case T_ID: scriptfile_getstring(pScript, &musicID); break;
|
|
||||||
case T_FILE: scriptfile_getstring(pScript, &fileName); break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!firstPass)
|
|
||||||
{
|
|
||||||
if (musicID == NULL)
|
|
||||||
{
|
|
||||||
pos.Message(MSG_ERROR, "missing ID for music definition\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fileName == NULL || fileSystem.FileExists(fileName))
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (S_DefineMusic(musicID, fileName) == -1)
|
|
||||||
pos.Message(MSG_ERROR, "invalid music ID");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
enum scripttoken_t
|
enum scripttoken_t
|
||||||
{
|
{
|
||||||
|
@ -388,186 +323,44 @@ static int32_t defsparser(scriptfile *script)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case T_INCLUDEDEFAULT:
|
case T_INCLUDEDEFAULT:
|
||||||
{
|
|
||||||
defsparser_include(G_DefaultDefFile(), script, &pos);
|
defsparser_include(G_DefaultDefFile(), script, &pos);
|
||||||
break;
|
break;
|
||||||
}
|
case T_LOADGRP:
|
||||||
case T_DEFINE:
|
case T_CACHESIZE:
|
||||||
{
|
case T_SHADEFACTOR:
|
||||||
FString name;
|
case T_GLOBALGAMEFLAGS:
|
||||||
int32_t number;
|
parseSkip<1>(*script, pos);
|
||||||
|
|
||||||
if (scriptfile_getstring(script,&name)) break;
|
|
||||||
if (scriptfile_getsymbol(script,&number)) break;
|
|
||||||
|
|
||||||
if (scriptfile_addsymbolvalue(script, name,number) < 0)
|
|
||||||
pos.Message(MSG_WARNING, "Warning: Symbol %s was NOT redefined to %d", name.GetChars(),number);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// OLD (DEPRECATED) DEFINITION SYNTAX
|
|
||||||
case T_DEFINETEXTURE:
|
|
||||||
{
|
|
||||||
int32_t tile,pal,fnoo;
|
|
||||||
FString fn;
|
|
||||||
|
|
||||||
if (scriptfile_getsymbol(script,&tile)) break;
|
|
||||||
if (scriptfile_getsymbol(script,&pal)) break;
|
|
||||||
if (scriptfile_getnumber(script,&fnoo)) break; //x-center
|
|
||||||
if (scriptfile_getnumber(script,&fnoo)) break; //y-center
|
|
||||||
if (scriptfile_getnumber(script,&fnoo)) break; //x-size
|
|
||||||
if (scriptfile_getnumber(script,&fnoo)) break; //y-size
|
|
||||||
if (scriptfile_getstring(script,&fn)) break;
|
|
||||||
|
|
||||||
if (!fileSystem.FileExists(fn))
|
|
||||||
break;
|
|
||||||
|
|
||||||
tileSetHightileReplacement(tile,pal,fn,-1.0,1.0,1.0,1.0,1.0,0);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case T_DEFINESKYBOX:
|
|
||||||
{
|
|
||||||
int32_t tile,pal,i;
|
|
||||||
FString fn[6];
|
|
||||||
int happy = 1;
|
|
||||||
|
|
||||||
if (scriptfile_getsymbol(script,&tile)) break;
|
|
||||||
if (scriptfile_getsymbol(script,&pal)) break;
|
|
||||||
if (scriptfile_getsymbol(script,&i)) break; //future expansion
|
|
||||||
for (i=0; i<6; i++)
|
|
||||||
{
|
|
||||||
if (scriptfile_getstring(script,&fn[i])) break; //grab the 6 faces
|
|
||||||
|
|
||||||
if (!fileSystem.FileExists(fn[i]))
|
|
||||||
happy = 0;
|
|
||||||
}
|
|
||||||
if (i < 6 || !happy) break;
|
|
||||||
tileSetSkybox(tile, pal, (const char **)fn, 0);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case T_DEFINETINT:
|
|
||||||
{
|
|
||||||
int32_t pal, r,g,b,f;
|
|
||||||
|
|
||||||
if (scriptfile_getsymbol(script,&pal)) break;
|
|
||||||
if (scriptfile_getnumber(script,&r)) break;
|
|
||||||
if (scriptfile_getnumber(script,&g)) break;
|
|
||||||
if (scriptfile_getnumber(script,&b)) break;
|
|
||||||
if (scriptfile_getnumber(script,&f)) break; //effects
|
|
||||||
lookups.setPaletteTint(pal,r,g,b,0,0,0,f);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case T_ALPHAHACK:
|
|
||||||
{
|
|
||||||
int32_t tile;
|
|
||||||
double alpha;
|
|
||||||
|
|
||||||
if (scriptfile_getsymbol(script,&tile)) break;
|
|
||||||
if (scriptfile_getdouble(script,&alpha)) break;
|
|
||||||
if ((uint32_t)tile < MAXTILES)
|
|
||||||
TileFiles.tiledata[tile].texture->alphaThreshold = (float)alpha;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case T_ALPHAHACKRANGE:
|
|
||||||
{
|
|
||||||
int32_t tilenume1,tilenume2;
|
|
||||||
double alpha;
|
|
||||||
|
|
||||||
if (scriptfile_getsymbol(script,&tilenume1)) break;
|
|
||||||
if (scriptfile_getsymbol(script,&tilenume2)) break;
|
|
||||||
if (scriptfile_getdouble(script,&alpha)) break;
|
|
||||||
|
|
||||||
if (check_tile_range("alphahackrange", &tilenume1, &tilenume2, script, pos))
|
|
||||||
break;
|
|
||||||
|
|
||||||
for (int i=tilenume1; i<=tilenume2; i++)
|
|
||||||
TileFiles.tiledata[i].texture->alphaThreshold = (float)alpha;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case T_SPRITECOL:
|
case T_SPRITECOL:
|
||||||
{
|
case T_2DCOLIDXRANGE: // NOTE: takes precedence over 2dcol, see InitCustomColors()
|
||||||
int32_t tile,col,col2;
|
parseSkip<3>(*script, pos);
|
||||||
|
|
||||||
if (scriptfile_getsymbol(script,&tile)) break;
|
|
||||||
if (scriptfile_getnumber(script,&col)) break;
|
|
||||||
if (scriptfile_getnumber(script,&col2)) break;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case T_2DCOL:
|
case T_2DCOL:
|
||||||
{
|
parseSkip<4>(*script, pos);
|
||||||
int32_t col,b,g,r;
|
|
||||||
|
|
||||||
if (scriptfile_getnumber(script,&col)) break;
|
|
||||||
if (scriptfile_getnumber(script,&r)) break;
|
|
||||||
if (scriptfile_getnumber(script,&g)) break;
|
|
||||||
if (scriptfile_getnumber(script,&b)) break;
|
|
||||||
|
|
||||||
if ((unsigned)col < 256)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case T_2DCOLIDXRANGE: // NOTE: takes precedence over 2dcol, see InitCustomColors()
|
case T_DEFINE:
|
||||||
{
|
parseDefine(*script, pos);
|
||||||
int32_t col, idx, idxend;
|
break;
|
||||||
|
case T_DEFINETEXTURE:
|
||||||
if (scriptfile_getnumber(script,&col)) break;
|
parseDefineTexture(*script, pos);
|
||||||
if (scriptfile_getnumber(script,&idx)) break;
|
break;
|
||||||
if (scriptfile_getnumber(script,&idxend)) break;
|
case T_DEFINESKYBOX:
|
||||||
|
parseDefineSkybox(*script, pos);
|
||||||
}
|
break;
|
||||||
|
case T_DEFINETINT:
|
||||||
|
parseDefineTint(*script, pos);
|
||||||
|
break;
|
||||||
|
case T_ALPHAHACK:
|
||||||
|
parseAlphahack(*script, pos);
|
||||||
|
break;
|
||||||
|
case T_ALPHAHACKRANGE:
|
||||||
|
parseAlphahackRange(*script, pos);
|
||||||
break;
|
break;
|
||||||
case T_FOGPAL:
|
case T_FOGPAL:
|
||||||
{
|
parseFogpal(*script, pos);
|
||||||
int32_t p,r,g,b;
|
|
||||||
|
|
||||||
if (scriptfile_getsymbol(script,&p)) break;
|
|
||||||
if (scriptfile_getnumber(script,&r)) break;
|
|
||||||
if (scriptfile_getnumber(script,&g)) break;
|
|
||||||
if (scriptfile_getnumber(script,&b)) break;
|
|
||||||
|
|
||||||
r = clamp(r, 0, 63);
|
|
||||||
g = clamp(g, 0, 63);
|
|
||||||
b = clamp(b, 0, 63);
|
|
||||||
|
|
||||||
lookups.makeTable(p, NULL, r<<2, g<<2, b<<2, 1);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case T_NOFLOORPALRANGE:
|
case T_NOFLOORPALRANGE:
|
||||||
{
|
parseNoFloorpalRange(*script, pos);
|
||||||
int32_t b,e,i;
|
|
||||||
|
|
||||||
if (scriptfile_getsymbol(script,&b)) break;
|
|
||||||
if (scriptfile_getsymbol(script,&e)) break;
|
|
||||||
|
|
||||||
b = max(b, 1);
|
|
||||||
e = min(e, MAXPALOOKUPS-1);
|
|
||||||
|
|
||||||
for (i = b; i <= e; i++)
|
|
||||||
lookups.tables[i].noFloorPal = true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case T_LOADGRP:
|
|
||||||
{
|
|
||||||
scriptfile_getstring(script,nullptr);
|
|
||||||
#if 0
|
|
||||||
if (!scriptfile_getstring(pScript, &fileName) && firstPass)
|
|
||||||
{
|
|
||||||
fileSystem.AddAdditionalFile(fileName);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case T_CACHESIZE:
|
|
||||||
{
|
|
||||||
int32_t j;
|
|
||||||
|
|
||||||
if (scriptfile_getnumber(script,&j)) break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case T_SHADEFACTOR:
|
|
||||||
//scriptfile_getnumber(script, &realmaxshade);
|
|
||||||
//frealmaxshade = (float)realmaxshade;
|
|
||||||
break;
|
break;
|
||||||
case T_ARTFILE:
|
case T_ARTFILE:
|
||||||
{
|
{
|
||||||
|
@ -609,59 +402,17 @@ static int32_t defsparser(scriptfile *script)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case T_SETUPTILE:
|
case T_SETUPTILE:
|
||||||
{
|
parseSetupTile(*script, pos);
|
||||||
int tile, tmp;
|
break;
|
||||||
|
|
||||||
if (scriptfile_getsymbol(script,&tile)) break;
|
|
||||||
if (check_tile("setuptile", tile, script, pos))
|
|
||||||
break;
|
|
||||||
auto& tiled = TileFiles.tiledata[tile];
|
|
||||||
if (scriptfile_getsymbol(script,&tmp)) break; // XXX
|
|
||||||
tiled.h_xsize = tmp;
|
|
||||||
if (scriptfile_getsymbol(script,&tmp)) break;
|
|
||||||
tiled.h_ysize = tmp;
|
|
||||||
if (scriptfile_getsymbol(script,&tmp)) break;
|
|
||||||
tiled.h_xoffs = tmp;
|
|
||||||
if (scriptfile_getsymbol(script,&tmp)) break;
|
|
||||||
tiled.h_yoffs = tmp;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case T_SETUPTILERANGE:
|
case T_SETUPTILERANGE:
|
||||||
{
|
parseSetupTileRange(*script, pos);
|
||||||
int tile1,tile2,xsiz,ysiz,xoffs,yoffs,i;
|
|
||||||
|
|
||||||
if (scriptfile_getsymbol(script,&tile1)) break;
|
|
||||||
if (scriptfile_getsymbol(script,&tile2)) break;
|
|
||||||
if (scriptfile_getnumber(script,&xsiz)) break;
|
|
||||||
if (scriptfile_getnumber(script,&ysiz)) break;
|
|
||||||
if (scriptfile_getsymbol(script,&xoffs)) break;
|
|
||||||
if (scriptfile_getsymbol(script,&yoffs)) break;
|
|
||||||
|
|
||||||
if (check_tile_range("setuptilerange", &tile1, &tile2, script, pos))
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
for (i=tile1; i<=tile2; i++)
|
|
||||||
{
|
|
||||||
auto& tiled = TileFiles.tiledata[i];
|
|
||||||
|
|
||||||
tiled.h_xsize = xsiz;
|
|
||||||
tiled.h_ysize = ysiz;
|
|
||||||
tiled.h_xoffs = xoffs;
|
|
||||||
tiled.h_yoffs = yoffs;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case T_ANIMTILERANGE:
|
case T_ANIMTILERANGE:
|
||||||
{
|
parseAnimTileRange(*script, pos);
|
||||||
SetAnim set;
|
|
||||||
if (scriptfile_getsymbol(script,&set.tile1)) break;
|
|
||||||
if (scriptfile_getsymbol(script,&set.tile2)) break;
|
|
||||||
if (scriptfile_getsymbol(script,&set.speed)) break;
|
|
||||||
if (scriptfile_getsymbol(script,&set.type)) break;
|
|
||||||
processSetAnim("animtilerange", pos, set);
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
case T_TILEFROMTEXTURE:
|
case T_TILEFROMTEXTURE:
|
||||||
{
|
{
|
||||||
auto texturepos = scriptfile_getposition(script);
|
auto texturepos = scriptfile_getposition(script);
|
||||||
|
@ -1117,7 +868,7 @@ static int32_t defsparser(scriptfile *script)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (qloadkvx(nextvoxid, fn))
|
if (voxDefine(nextvoxid, fn))
|
||||||
{
|
{
|
||||||
Printf("Failure loading voxel file \"%s\"\n",fn.GetChars());
|
Printf("Failure loading voxel file \"%s\"\n",fn.GetChars());
|
||||||
break;
|
break;
|
||||||
|
@ -1588,7 +1339,7 @@ static int32_t defsparser(scriptfile *script)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (qloadkvx(nextvoxid, fn))
|
if (voxDefine(nextvoxid, fn))
|
||||||
{
|
{
|
||||||
voxelpos.Message(MSG_ERROR, "Failure loading voxel file \"%s\"",fn.GetChars());
|
voxelpos.Message(MSG_ERROR, "Failure loading voxel file \"%s\"",fn.GetChars());
|
||||||
break;
|
break;
|
||||||
|
@ -1629,14 +1380,14 @@ static int32_t defsparser(scriptfile *script)
|
||||||
{
|
{
|
||||||
double scale=1.0;
|
double scale=1.0;
|
||||||
scriptfile_getdouble(script,&scale);
|
scriptfile_getdouble(script,&scale);
|
||||||
voxscale[lastvoxid] = (int32_t)(65536*scale);
|
voxscale[lastvoxid] = (float)scale;
|
||||||
if (voxmodels[lastvoxid])
|
if (voxmodels[lastvoxid])
|
||||||
voxmodels[lastvoxid]->scale = scale;
|
voxmodels[lastvoxid]->scale = scale;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case T_ROTATE:
|
case T_ROTATE:
|
||||||
voxrotate[lastvoxid>>3] |= (1 << (lastvoxid&7));
|
voxrotate.Set(lastvoxid);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1644,68 +1395,7 @@ static int32_t defsparser(scriptfile *script)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case T_SKYBOX:
|
case T_SKYBOX:
|
||||||
{
|
parseSkybox(*script, pos);
|
||||||
auto skyboxpos = scriptfile_getposition(script);
|
|
||||||
FString fn[6];
|
|
||||||
FScanner::SavedPos modelend;
|
|
||||||
int32_t i, tile = -1, pal = 0, happy = 1;
|
|
||||||
int flags = 0;
|
|
||||||
|
|
||||||
static const tokenlist skyboxtokens[] =
|
|
||||||
{
|
|
||||||
{ "tile" ,T_TILE },
|
|
||||||
{ "pal" ,T_PAL },
|
|
||||||
{ "ft" ,T_FRONT },{ "front" ,T_FRONT },{ "forward",T_FRONT },
|
|
||||||
{ "rt" ,T_RIGHT },{ "right" ,T_RIGHT },
|
|
||||||
{ "bk" ,T_BACK },{ "back" ,T_BACK },
|
|
||||||
{ "lf" ,T_LEFT },{ "left" ,T_LEFT },{ "lt" ,T_LEFT },
|
|
||||||
{ "up" ,T_TOP },{ "top" ,T_TOP },{ "ceiling",T_TOP },{ "ceil" ,T_TOP },
|
|
||||||
{ "dn" ,T_BOTTOM },{ "bottom" ,T_BOTTOM },{ "floor" ,T_BOTTOM },{ "down" ,T_BOTTOM },
|
|
||||||
{ "nocompress", T_NOCOMPRESS },
|
|
||||||
{ "nodownsize", T_NODOWNSIZE },
|
|
||||||
{ "forcefilter", T_FORCEFILTER },
|
|
||||||
{ "artquality", T_ARTQUALITY },
|
|
||||||
};
|
|
||||||
|
|
||||||
if (scriptfile_getbraces(script,&modelend)) break;
|
|
||||||
while (!scriptfile_endofblock(script, modelend))
|
|
||||||
{
|
|
||||||
switch (getatoken(script,skyboxtokens,countof(skyboxtokens)))
|
|
||||||
{
|
|
||||||
//case T_ERROR: Printf("Error on line %s:%d in skybox tokens\n",script->filename,linenum); break;
|
|
||||||
case T_TILE:
|
|
||||||
scriptfile_getsymbol(script,&tile); break;
|
|
||||||
case T_PAL:
|
|
||||||
scriptfile_getsymbol(script,&pal); break;
|
|
||||||
case T_FRONT:
|
|
||||||
scriptfile_getstring(script,&fn[0]); break;
|
|
||||||
case T_RIGHT:
|
|
||||||
scriptfile_getstring(script,&fn[1]); break;
|
|
||||||
case T_BACK:
|
|
||||||
scriptfile_getstring(script,&fn[2]); break;
|
|
||||||
case T_LEFT:
|
|
||||||
scriptfile_getstring(script,&fn[3]); break;
|
|
||||||
case T_TOP:
|
|
||||||
scriptfile_getstring(script,&fn[4]); break;
|
|
||||||
case T_BOTTOM:
|
|
||||||
scriptfile_getstring(script,&fn[5]); break;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tile < 0) skyboxpos.Message(MSG_ERROR, "skybox: missing 'tile number'"), happy=0;
|
|
||||||
for (i=0; i<6; i++)
|
|
||||||
{
|
|
||||||
if (fn[i].IsEmpty()) skyboxpos.Message(MSG_ERROR, "skybox: missing '%s filename'", skyfaces[i]), happy = 0;
|
|
||||||
// FIXME?
|
|
||||||
if (!fileSystem.FileExists(fn[i]))
|
|
||||||
happy = 0;
|
|
||||||
}
|
|
||||||
if (!happy) break;
|
|
||||||
|
|
||||||
const char* fns[] = { fn[0].GetChars(), fn[1].GetChars(), fn[2].GetChars(), fn[3].GetChars(), fn[4].GetChars(), fn[5].GetChars() };
|
|
||||||
tileSetSkybox(tile, pal, fns, flags);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case T_HIGHPALOOKUP:
|
case T_HIGHPALOOKUP:
|
||||||
{
|
{
|
||||||
|
@ -1914,190 +1604,7 @@ static int32_t defsparser(scriptfile *script)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case T_TEXTURE:
|
case T_TEXTURE:
|
||||||
{
|
parseTexture(*script, pos);
|
||||||
FScanner::SavedPos textureend;
|
|
||||||
int32_t tile=-1, token;
|
|
||||||
|
|
||||||
static const tokenlist texturetokens[] =
|
|
||||||
{
|
|
||||||
{ "pal", T_PAL },
|
|
||||||
{ "detail", T_DETAIL },
|
|
||||||
{ "glow", T_GLOW },
|
|
||||||
{ "specular",T_SPECULAR },
|
|
||||||
{ "normal", T_NORMAL },
|
|
||||||
};
|
|
||||||
|
|
||||||
if (scriptfile_getsymbol(script,&tile)) break;
|
|
||||||
if (scriptfile_getbraces(script,&textureend)) break;
|
|
||||||
while (!scriptfile_endofblock(script, textureend))
|
|
||||||
{
|
|
||||||
token = getatoken(script,texturetokens,countof(texturetokens));
|
|
||||||
switch (token)
|
|
||||||
{
|
|
||||||
case T_PAL:
|
|
||||||
{
|
|
||||||
auto palpos = scriptfile_getposition(script);
|
|
||||||
FScanner::SavedPos palend;
|
|
||||||
int32_t pal=-1, xsiz = 0, ysiz = 0;
|
|
||||||
FString fn;
|
|
||||||
double alphacut = -1.0, xscale = 1.0, yscale = 1.0, specpower = 1.0, specfactor = 1.0;
|
|
||||||
uint8_t flags = 0;
|
|
||||||
|
|
||||||
static const tokenlist texturetokens_pal[] =
|
|
||||||
{
|
|
||||||
{ "file", T_FILE },{ "name", T_FILE },
|
|
||||||
{ "alphacut", T_ALPHACUT },
|
|
||||||
{ "detailscale", T_XSCALE }, { "scale", T_XSCALE }, { "xscale", T_XSCALE }, { "intensity", T_XSCALE },
|
|
||||||
{ "yscale", T_YSCALE },
|
|
||||||
{ "specpower", T_SPECPOWER }, { "specularpower", T_SPECPOWER }, { "parallaxscale", T_SPECPOWER },
|
|
||||||
{ "specfactor", T_SPECFACTOR }, { "specularfactor", T_SPECFACTOR }, { "parallaxbias", T_SPECFACTOR },
|
|
||||||
{ "nocompress", T_NOCOMPRESS },
|
|
||||||
{ "nodownsize", T_NODOWNSIZE },
|
|
||||||
{ "forcefilter", T_FORCEFILTER },
|
|
||||||
{ "artquality", T_ARTQUALITY },
|
|
||||||
{ "orig_sizex", T_ORIGSIZEX }, { "orig_sizey", T_ORIGSIZEY }
|
|
||||||
};
|
|
||||||
|
|
||||||
if (scriptfile_getsymbol(script,&pal)) break;
|
|
||||||
if (scriptfile_getbraces(script,&palend)) break;
|
|
||||||
while (!scriptfile_endofblock(script, palend))
|
|
||||||
{
|
|
||||||
switch (getatoken(script,texturetokens_pal,countof(texturetokens_pal)))
|
|
||||||
{
|
|
||||||
case T_FILE:
|
|
||||||
scriptfile_getstring(script,&fn); break;
|
|
||||||
case T_ALPHACUT:
|
|
||||||
scriptfile_getdouble(script,&alphacut); break;
|
|
||||||
case T_XSCALE:
|
|
||||||
scriptfile_getdouble(script,&xscale); break;
|
|
||||||
case T_YSCALE:
|
|
||||||
scriptfile_getdouble(script,&yscale); break;
|
|
||||||
case T_SPECPOWER:
|
|
||||||
scriptfile_getdouble(script,&specpower); break;
|
|
||||||
case T_SPECFACTOR:
|
|
||||||
scriptfile_getdouble(script,&specfactor); break;
|
|
||||||
case T_ORIGSIZEX:
|
|
||||||
scriptfile_getnumber(script, &xsiz);
|
|
||||||
break;
|
|
||||||
case T_ORIGSIZEY:
|
|
||||||
scriptfile_getnumber(script, &ysiz);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((unsigned)tile >= MAXUSERTILES) break; // message is printed later
|
|
||||||
if ((unsigned)pal >= MAXPALOOKUPS - RESERVEDPALS)
|
|
||||||
{
|
|
||||||
palpos.Message(MSG_ERROR, "missing or invalid 'palette number' for texture definition");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (fn.IsEmpty())
|
|
||||||
{
|
|
||||||
palpos.Message(MSG_ERROR, "missing 'file name' for texture definition");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!fileSystem.FileExists(fn))
|
|
||||||
{
|
|
||||||
palpos.Message(MSG_ERROR, "%s not found in replacement for tile %d", fn.GetChars(), tile);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (xsiz > 0 && ysiz > 0)
|
|
||||||
{
|
|
||||||
tileSetDummy(tile, xsiz, ysiz);
|
|
||||||
}
|
|
||||||
xscale = 1.0f / xscale;
|
|
||||||
yscale = 1.0f / yscale;
|
|
||||||
|
|
||||||
tileSetHightileReplacement(tile,pal,fn,alphacut,xscale,yscale, specpower, specfactor,flags);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case T_DETAIL: case T_GLOW: case T_SPECULAR: case T_NORMAL:
|
|
||||||
{
|
|
||||||
auto detailpos = scriptfile_getposition(script);
|
|
||||||
FScanner::SavedPos detailend;
|
|
||||||
int32_t pal = 0;
|
|
||||||
char flags = 0;
|
|
||||||
FString fn;
|
|
||||||
double xscale = 1.0, yscale = 1.0, specpower = 1.0, specfactor = 1.0;
|
|
||||||
|
|
||||||
static const tokenlist texturetokens_pal[] =
|
|
||||||
{
|
|
||||||
{ "file", T_FILE },{ "name", T_FILE },
|
|
||||||
{ "alphacut", T_ALPHACUT },
|
|
||||||
{ "detailscale", T_XSCALE }, { "scale", T_XSCALE }, { "xscale", T_XSCALE }, { "intensity", T_XSCALE },
|
|
||||||
{ "yscale", T_YSCALE },
|
|
||||||
{ "specpower", T_SPECPOWER }, { "specularpower", T_SPECPOWER }, { "parallaxscale", T_SPECPOWER },
|
|
||||||
{ "specfactor", T_SPECFACTOR }, { "specularfactor", T_SPECFACTOR }, { "parallaxbias", T_SPECFACTOR },
|
|
||||||
{ "nocompress", T_NOCOMPRESS },
|
|
||||||
{ "nodownsize", T_NODOWNSIZE },
|
|
||||||
{ "forcefilter", T_FORCEFILTER },
|
|
||||||
{ "artquality", T_ARTQUALITY },
|
|
||||||
};
|
|
||||||
|
|
||||||
if (scriptfile_getbraces(script,&detailend)) break;
|
|
||||||
while (!scriptfile_endofblock(script, detailend))
|
|
||||||
{
|
|
||||||
switch (getatoken(script,texturetokens_pal,countof(texturetokens_pal)))
|
|
||||||
{
|
|
||||||
case T_FILE:
|
|
||||||
scriptfile_getstring(script,&fn); break;
|
|
||||||
case T_XSCALE:
|
|
||||||
scriptfile_getdouble(script,&xscale); break;
|
|
||||||
case T_YSCALE:
|
|
||||||
scriptfile_getdouble(script,&yscale); break;
|
|
||||||
case T_SPECPOWER:
|
|
||||||
scriptfile_getdouble(script,&specpower); break;
|
|
||||||
case T_SPECFACTOR:
|
|
||||||
scriptfile_getdouble(script,&specfactor); break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((unsigned)tile >= MAXUSERTILES) break; // message is printed later
|
|
||||||
if (fn.IsEmpty())
|
|
||||||
{
|
|
||||||
detailpos.Message(MSG_ERROR, "missing 'file name' for texture definition");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!fileSystem.FileExists(fn))
|
|
||||||
break;
|
|
||||||
|
|
||||||
switch (token)
|
|
||||||
{
|
|
||||||
case T_DETAIL:
|
|
||||||
pal = DETAILPAL;
|
|
||||||
xscale = 1.0f / xscale;
|
|
||||||
yscale = 1.0f / yscale;
|
|
||||||
break;
|
|
||||||
case T_GLOW:
|
|
||||||
pal = GLOWPAL;
|
|
||||||
break;
|
|
||||||
case T_SPECULAR:
|
|
||||||
pal = SPECULARPAL;
|
|
||||||
break;
|
|
||||||
case T_NORMAL:
|
|
||||||
pal = NORMALPAL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
tileSetHightileReplacement(tile,pal,fn,-1.0f,xscale,yscale, specpower, specfactor,flags);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((unsigned)tile >= MAXUSERTILES)
|
|
||||||
{
|
|
||||||
pos.Message(MSG_ERROR, "missing or invalid 'tile number' for texture definition");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case T_UNDEFMODEL:
|
case T_UNDEFMODEL:
|
||||||
|
@ -2290,13 +1797,6 @@ static int32_t defsparser(scriptfile *script)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case T_GLOBALGAMEFLAGS:
|
|
||||||
{
|
|
||||||
int32_t dummy;
|
|
||||||
if (scriptfile_getnumber(script,&dummy)) break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case T_MULTIPSKY:
|
case T_MULTIPSKY:
|
||||||
{
|
{
|
||||||
FScanner::SavedPos blockend;
|
FScanner::SavedPos blockend;
|
||||||
|
@ -3159,7 +2659,7 @@ static int32_t defsparser(scriptfile *script)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
FStringf name("%s.%s", resName.GetChars(), resType.GetChars());
|
FStringf name("%s.%s", resName.GetChars(), resType.GetChars());
|
||||||
fileSystem.CreatePathlessCopy(resName, resID, 0);
|
fileSystem.CreatePathlessCopy(name, resID, 0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -3172,34 +2672,44 @@ static int32_t defsparser(scriptfile *script)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t loaddefinitionsfile(const char *fn, bool loadadds, bool cumulative)
|
||||||
int32_t loaddefinitionsfile(const char *fn, bool loadadds)
|
|
||||||
{
|
{
|
||||||
scriptfile *script;
|
bool done = false;
|
||||||
|
auto parseit = [&](int lump)
|
||||||
script = scriptfile_fromfile(fn);
|
|
||||||
|
|
||||||
if (script)
|
|
||||||
{
|
{
|
||||||
Printf(PRINT_NONOTIFY, "Loading \"%s\"\n",fn);
|
FScanner sc;
|
||||||
|
sc.OpenLumpNum(lump);
|
||||||
|
sc.SetNoOctals(true);
|
||||||
|
sc.SetNoFatalErrors(true);
|
||||||
|
defsparser(&sc);
|
||||||
|
done = true;
|
||||||
|
Printf(PRINT_NONOTIFY, "\n");
|
||||||
|
};
|
||||||
|
|
||||||
defsparser(script);
|
if (!cumulative)
|
||||||
|
{
|
||||||
|
int lump = fileSystem.FindFile(fn);
|
||||||
|
if (lump >= 0)
|
||||||
|
{
|
||||||
|
Printf(PRINT_NONOTIFY, "Loading \"%s\"\n", fn);
|
||||||
|
parseit(lump);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int lump, lastlump = 0;
|
||||||
|
while ((lump = fileSystem.FindLumpFullName(fn, &lastlump)) >= 0)
|
||||||
|
{
|
||||||
|
Printf(PRINT_NONOTIFY, "Loading \"%s\"\n", fileSystem.GetFileFullPath(lump).GetChars());
|
||||||
|
parseit(lump);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (userConfig.AddDefs && loadadds) for (auto& m : *userConfig.AddDefs)
|
if (userConfig.AddDefs && loadadds) for (auto& m : *userConfig.AddDefs)
|
||||||
{
|
{
|
||||||
Printf("Loading module \"%s\"\n",m.GetChars());
|
Printf("Loading module \"%s\"\n",m.GetChars());
|
||||||
defsparser_include(m, NULL, NULL); // Q: should we let the external script see our symbol table?
|
defsparser_include(m, nullptr, nullptr); // Q: should we let the external script see our symbol table?
|
||||||
}
|
|
||||||
|
|
||||||
if (script)
|
|
||||||
scriptfile_close(script);
|
|
||||||
|
|
||||||
if (!script) return -1;
|
|
||||||
|
|
||||||
Printf(PRINT_NONOTIFY, "\n");
|
Printf(PRINT_NONOTIFY, "\n");
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// vim:ts=4:
|
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#include "gamecontrol.h"
|
#include "gamecontrol.h"
|
||||||
#include "rendering/render.h"
|
#include "rendering/render.h"
|
||||||
#include "gamefuncs.h"
|
#include "gamefuncs.h"
|
||||||
|
#include "hw_voxels.h"
|
||||||
|
|
||||||
#ifdef USE_OPENGL
|
#ifdef USE_OPENGL
|
||||||
# include "mdsprite.h"
|
# include "mdsprite.h"
|
||||||
|
@ -53,18 +54,6 @@ uint8_t globalr = 255, globalg = 255, globalb = 255;
|
||||||
|
|
||||||
int16_t pskybits_override = -1;
|
int16_t pskybits_override = -1;
|
||||||
|
|
||||||
// This was on the cache but is permanently allocated, so put it into something static. This needs some rethinking anyway
|
|
||||||
static TArray<TArray<uint8_t>> voxelmemory;
|
|
||||||
|
|
||||||
int16_t tiletovox[MAXTILES];
|
|
||||||
int voxlumps[MAXVOXELS];
|
|
||||||
char g_haveVoxels;
|
|
||||||
//#define kloadvoxel loadvoxel
|
|
||||||
|
|
||||||
int32_t novoxmips = 1;
|
|
||||||
|
|
||||||
int32_t voxscale[MAXVOXELS];
|
|
||||||
|
|
||||||
static int32_t beforedrawrooms = 1;
|
static int32_t beforedrawrooms = 1;
|
||||||
|
|
||||||
int32_t globalflags;
|
int32_t globalflags;
|
||||||
|
@ -73,7 +62,6 @@ static int8_t tempbuf[MAXWALLS];
|
||||||
|
|
||||||
static int32_t no_radarang2 = 0;
|
static int32_t no_radarang2 = 0;
|
||||||
static int16_t radarang[1280];
|
static int16_t radarang[1280];
|
||||||
static int32_t qradarang[10240];
|
|
||||||
|
|
||||||
const char *engineerrstr = "No error";
|
const char *engineerrstr = "No error";
|
||||||
|
|
||||||
|
@ -151,7 +139,6 @@ fixed_t qglobalang;
|
||||||
int32_t globalpal, globalfloorpal, cosglobalang, singlobalang;
|
int32_t globalpal, globalfloorpal, cosglobalang, singlobalang;
|
||||||
int32_t cosviewingrangeglobalang, sinviewingrangeglobalang;
|
int32_t cosviewingrangeglobalang, sinviewingrangeglobalang;
|
||||||
|
|
||||||
int32_t xyaspect;
|
|
||||||
int32_t viewingrangerecip;
|
int32_t viewingrangerecip;
|
||||||
|
|
||||||
static int32_t globalxpanning, globalypanning;
|
static int32_t globalxpanning, globalypanning;
|
||||||
|
@ -227,11 +214,6 @@ static int32_t engineLoadTables(void)
|
||||||
for (i=0; i<640; i++)
|
for (i=0; i<640; i++)
|
||||||
radarang[1279-i] = -radarang[i];
|
radarang[1279-i] = -radarang[i];
|
||||||
|
|
||||||
for (i=0; i<5120; i++)
|
|
||||||
qradarang[i] = FloatToFixed(atan((5119.5 - i) / 1280.) * (-64. / BAngRadian));
|
|
||||||
for (i=0; i<5120; i++)
|
|
||||||
qradarang[10239-i] = -qradarang[i];
|
|
||||||
|
|
||||||
tablesloaded = 1;
|
tablesloaded = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -671,26 +653,8 @@ int32_t enginePreInit(void)
|
||||||
//
|
//
|
||||||
int32_t engineInit(void)
|
int32_t engineInit(void)
|
||||||
{
|
{
|
||||||
if (engineLoadTables())
|
engineLoadTables();
|
||||||
return 1;
|
|
||||||
|
|
||||||
xyaspect = -1;
|
|
||||||
|
|
||||||
voxelmemory.Reset();
|
|
||||||
|
|
||||||
for (int i=0; i<MAXTILES; i++)
|
|
||||||
tiletovox[i] = -1;
|
|
||||||
for (auto& v : voxscale) v = 65536;
|
|
||||||
memset(voxrotate, 0, sizeof(voxrotate));
|
|
||||||
|
|
||||||
paletteloaded = 0;
|
|
||||||
|
|
||||||
g_visibility = 512;
|
g_visibility = 512;
|
||||||
parallaxvisibility = 512;
|
|
||||||
|
|
||||||
GPalette.Init(MAXPALOOKUPS + 1); // one slot for each translation, plus a separate one for the base palettes.
|
|
||||||
gi->loadPalette();
|
|
||||||
|
|
||||||
if (!mdinited) mdinit();
|
if (!mdinited) mdinit();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -750,80 +714,6 @@ void initspritelists(void)
|
||||||
Numsprites = 0;
|
Numsprites = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// qloadkvx
|
|
||||||
//
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int32_t qloadkvx(int32_t voxindex, const char *filename)
|
|
||||||
{
|
|
||||||
if ((unsigned)voxindex >= MAXVOXELS)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
auto fil = fileSystem.OpenFileReader(filename);
|
|
||||||
if (!fil.isOpen())
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
int32_t lengcnt = 0;
|
|
||||||
const int32_t lengtot = fil.GetLength();
|
|
||||||
|
|
||||||
for (bssize_t i=0; i<MAXVOXMIPS; i++)
|
|
||||||
{
|
|
||||||
int32_t dasiz = fil.ReadInt32();
|
|
||||||
|
|
||||||
voxelmemory.Reserve(1);
|
|
||||||
voxelmemory.Last() = fil.Read(dasiz);
|
|
||||||
|
|
||||||
lengcnt += dasiz+4;
|
|
||||||
if (lengcnt >= lengtot-768)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (voxmodels[voxindex])
|
|
||||||
{
|
|
||||||
voxfree(voxmodels[voxindex]);
|
|
||||||
voxmodels[voxindex] = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
voxlumps[voxindex] = fileSystem.FindFile(filename);
|
|
||||||
|
|
||||||
g_haveVoxels = 1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void vox_undefine(int32_t const tile)
|
|
||||||
{
|
|
||||||
int voxindex = tiletovox[tile];
|
|
||||||
if (voxindex < 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (voxmodels[voxindex])
|
|
||||||
{
|
|
||||||
voxfree(voxmodels[voxindex]);
|
|
||||||
voxmodels[voxindex] = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
voxscale[voxindex] = 65536;
|
|
||||||
voxrotate[voxindex>>3] &= ~(1 << (voxindex&7));
|
|
||||||
tiletovox[tile] = -1;
|
|
||||||
|
|
||||||
// TODO: nextvoxid
|
|
||||||
}
|
|
||||||
|
|
||||||
void vox_deinit()
|
|
||||||
{
|
|
||||||
for (auto &vox : voxmodels)
|
|
||||||
{
|
|
||||||
voxfree(vox);
|
|
||||||
vox = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// inside
|
// inside
|
||||||
//
|
//
|
||||||
|
@ -977,26 +867,6 @@ int32_t getangle(int32_t xvect, int32_t yvect)
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
fixed_t gethiq16angle(int32_t xvect, int32_t yvect)
|
|
||||||
{
|
|
||||||
fixed_t rv;
|
|
||||||
|
|
||||||
if ((xvect | yvect) == 0)
|
|
||||||
rv = 0;
|
|
||||||
else if (xvect == 0)
|
|
||||||
rv = IntToFixed(512 + ((yvect < 0) << 10));
|
|
||||||
else if (yvect == 0)
|
|
||||||
rv = IntToFixed(((xvect < 0) << 10));
|
|
||||||
else if (xvect == yvect)
|
|
||||||
rv = IntToFixed(256 + ((xvect < 0) << 10));
|
|
||||||
else if (xvect == -yvect)
|
|
||||||
rv = IntToFixed(768 + ((xvect > 0) << 10));
|
|
||||||
else if (abs(xvect) > abs(yvect))
|
|
||||||
rv = ((qradarang[5120 + Scale(1280, yvect, xvect)] >> 6) + IntToFixed(((xvect < 0) << 10))) & 0x7FFFFFF;
|
|
||||||
else rv = ((qradarang[5120 - Scale(1280, xvect, yvect)] >> 6) + IntToFixed(512 + ((yvect < 0) << 10))) & 0x7FFFFFF;
|
|
||||||
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Gets the BUILD unit height and z offset of a sprite.
|
// Gets the BUILD unit height and z offset of a sprite.
|
||||||
// Returns the z offset, 'height' may be NULL.
|
// Returns the z offset, 'height' may be NULL.
|
||||||
|
@ -1865,3 +1735,10 @@ void alignflorslope(int16_t dasect, int32_t x, int32_t y, int32_t z)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int tilehasmodelorvoxel(int const tilenume, int pal)
|
||||||
|
{
|
||||||
|
UNREFERENCED_PARAMETER(pal);
|
||||||
|
return
|
||||||
|
(mdinited && hw_models && tile2model[Ptile2tile(tilenume, pal)].modelid != -1) ||
|
||||||
|
(r_voxels && tiletovox[tilenume] != -1);
|
||||||
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include "texturemanager.h"
|
#include "texturemanager.h"
|
||||||
#include "hw_renderstate.h"
|
#include "hw_renderstate.h"
|
||||||
#include "printf.h"
|
#include "printf.h"
|
||||||
|
#include "hw_voxels.h"
|
||||||
#include "../../glbackend/glbackend.h"
|
#include "../../glbackend/glbackend.h"
|
||||||
|
|
||||||
static int32_t curextra=MAXTILES;
|
static int32_t curextra=MAXTILES;
|
||||||
|
@ -23,6 +24,7 @@ static int32_t curextra=MAXTILES;
|
||||||
#define MIN_CACHETIME_PRINT 10
|
#define MIN_CACHETIME_PRINT 10
|
||||||
|
|
||||||
using namespace Polymost;
|
using namespace Polymost;
|
||||||
|
int32_t polymost_voxdraw(voxmodel_t* m, tspriteptr_t const tspr, bool rotate);
|
||||||
|
|
||||||
static int32_t addtileP(int32_t model,int32_t tile,int32_t pallet)
|
static int32_t addtileP(int32_t model,int32_t tile,int32_t pallet)
|
||||||
{
|
{
|
||||||
|
@ -1538,6 +1540,11 @@ int32_t polymost_mddraw(tspriteptr_t tspr)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void voxfree(voxmodel_t* m)
|
||||||
|
{
|
||||||
|
if (m) delete m;
|
||||||
|
}
|
||||||
|
|
||||||
static void mdfree(mdmodel_t *vm)
|
static void mdfree(mdmodel_t *vm)
|
||||||
{
|
{
|
||||||
if (vm->mdnum == 1) { voxfree((voxmodel_t *)vm); return; }
|
if (vm->mdnum == 1) { voxfree((voxmodel_t *)vm); return; }
|
||||||
|
|
|
@ -26,6 +26,7 @@ Ken Silverman's official web site: http://www.advsys.net/ken
|
||||||
#include "hw_drawinfo.h"
|
#include "hw_drawinfo.h"
|
||||||
#include "gamestruct.h"
|
#include "gamestruct.h"
|
||||||
#include "gamestruct.h"
|
#include "gamestruct.h"
|
||||||
|
#include "hw_voxels.h"
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -35,11 +36,13 @@ typedef struct {
|
||||||
} vec3d_t;
|
} vec3d_t;
|
||||||
|
|
||||||
static_assert(sizeof(vec3d_t) == sizeof(double) * 3);
|
static_assert(sizeof(vec3d_t) == sizeof(double) * 3);
|
||||||
|
int32_t xyaspect = -1;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int skiptile = -1;
|
int skiptile = -1;
|
||||||
FGameTexture* GetSkyTexture(int basetile, int lognumtiles, const int16_t* tilemap, int remap = 0);
|
FGameTexture* GetSkyTexture(int basetile, int lognumtiles, const int16_t* tilemap, int remap = 0);
|
||||||
|
int32_t polymost_voxdraw(voxmodel_t* m, tspriteptr_t const tspr, bool rotate);
|
||||||
|
|
||||||
int checkTranslucentReplacement(FTextureID picnum, int pal);
|
int checkTranslucentReplacement(FTextureID picnum, int pal);
|
||||||
|
|
||||||
|
@ -2719,9 +2722,9 @@ void polymost_drawsprite(int32_t snum)
|
||||||
|
|
||||||
if ((globalorientation & 48) != 48) // only non-voxel sprites should do this
|
if ((globalorientation & 48) != 48) // only non-voxel sprites should do this
|
||||||
{
|
{
|
||||||
int const flag = hw_hightile && TileFiles.tiledata[globalpicnum].h_xsize;
|
int const flag = hw_hightile && TileFiles.tiledata[globalpicnum].hiofs.xsize;
|
||||||
off = { (int32_t)tspr->xoffset + (flag ? TileFiles.tiledata[globalpicnum].h_xoffs : tileLeftOffset(globalpicnum)),
|
off = { (int32_t)tspr->xoffset + (flag ? TileFiles.tiledata[globalpicnum].hiofs.xoffs : tileLeftOffset(globalpicnum)),
|
||||||
(int32_t)tspr->yoffset + (flag ? TileFiles.tiledata[globalpicnum].h_yoffs : tileTopOffset(globalpicnum)) };
|
(int32_t)tspr->yoffset + (flag ? TileFiles.tiledata[globalpicnum].hiofs.yoffs : tileTopOffset(globalpicnum)) };
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t method = DAMETH_MASK | DAMETH_CLAMPED;
|
int32_t method = DAMETH_MASK | DAMETH_CLAMPED;
|
||||||
|
@ -2750,14 +2753,14 @@ void polymost_drawsprite(int32_t snum)
|
||||||
if ((tspr->cstat & 48) != 48 && tiletovox[tspr->picnum] >= 0 && voxmodels[tiletovox[tspr->picnum]])
|
if ((tspr->cstat & 48) != 48 && tiletovox[tspr->picnum] >= 0 && voxmodels[tiletovox[tspr->picnum]])
|
||||||
{
|
{
|
||||||
int num = tiletovox[tspr->picnum];
|
int num = tiletovox[tspr->picnum];
|
||||||
if (polymost_voxdraw(voxmodels[num], tspr, voxrotate[num>>3] & (1<<(num&7)))) return;
|
if (polymost_voxdraw(voxmodels[num], tspr, voxrotate[num])) return;
|
||||||
break; // else, render as flat sprite
|
break; // else, render as flat sprite
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((tspr->cstat & 48) == 48 && tspr->picnum < MAXVOXELS && voxmodels[tspr->picnum])
|
if ((tspr->cstat & 48) == 48 && tspr->picnum < MAXVOXELS && voxmodels[tspr->picnum])
|
||||||
{
|
{
|
||||||
int num = tspr->picnum;
|
int num = tspr->picnum;
|
||||||
polymost_voxdraw(voxmodels[tspr->picnum], tspr, voxrotate[num >> 3] & (1 << (num & 7)));
|
polymost_voxdraw(voxmodels[tspr->picnum], tspr, voxrotate[num]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2781,8 +2784,8 @@ void polymost_drawsprite(int32_t snum)
|
||||||
|
|
||||||
vec2_t tsiz;
|
vec2_t tsiz;
|
||||||
|
|
||||||
if (hw_hightile && TileFiles.tiledata[globalpicnum].h_xsize)
|
if (hw_hightile && TileFiles.tiledata[globalpicnum].hiofs.xsize)
|
||||||
tsiz = { TileFiles.tiledata[globalpicnum].h_xsize, TileFiles.tiledata[globalpicnum].h_ysize };
|
tsiz = { TileFiles.tiledata[globalpicnum].hiofs.xsize, TileFiles.tiledata[globalpicnum].hiofs.ysize };
|
||||||
else
|
else
|
||||||
tsiz = { tileWidth(globalpicnum), tileHeight(globalpicnum) };
|
tsiz = { tileWidth(globalpicnum), tileHeight(globalpicnum) };
|
||||||
|
|
||||||
|
@ -3312,7 +3315,7 @@ void renderPrepareMirror(int32_t dax, int32_t day, int32_t daz, fixed_t daang, f
|
||||||
|
|
||||||
*tposx = (x << 1) + Scale(dx, i, j) - dax;
|
*tposx = (x << 1) + Scale(dx, i, j) - dax;
|
||||||
*tposy = (y << 1) + Scale(dy, i, j) - day;
|
*tposy = (y << 1) + Scale(dy, i, j) - day;
|
||||||
*tang = ((gethiq16angle(dx, dy) << 1) - daang) & 0x7FFFFFF;
|
*tang = ((bvectangbam(dx, dy).asq16() << 1) - daang) & 0x7FFFFFF;
|
||||||
|
|
||||||
inpreparemirror = 1;
|
inpreparemirror = 1;
|
||||||
|
|
||||||
|
@ -3494,6 +3497,23 @@ static void sortsprites(int const start, int const end)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool spriteIsModelOrVoxel(const spritetype* tspr)
|
||||||
|
{
|
||||||
|
if ((unsigned)tspr->owner < MAXSPRITES && spriteext[tspr->owner].flags & SPREXT_NOTMD)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (hw_models)
|
||||||
|
{
|
||||||
|
auto& mdinfo = tile2model[Ptile2tile(tspr->picnum, tspr->pal)];
|
||||||
|
if (mdinfo.modelid >= 0 && mdinfo.framenum >= 0) return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto slabalign = (tspr->cstat & CSTAT_SPRITE_ALIGNMENT) == CSTAT_SPRITE_ALIGNMENT_SLAB;
|
||||||
|
if (r_voxels && !slabalign && tiletovox[tspr->picnum] >= 0 && voxmodels[tiletovox[tspr->picnum]]) return true;
|
||||||
|
return (slabalign && voxmodels[tspr->picnum]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// drawmasks
|
// drawmasks
|
||||||
//
|
//
|
||||||
|
@ -3817,4 +3837,151 @@ void renderSetAspect(int32_t daxrange, int32_t daaspect)
|
||||||
xdimscale = Scale(320, xyaspect, xdimen);
|
xdimscale = Scale(320, xyaspect, xdimen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Draw voxel model as perfect cubes
|
||||||
|
int32_t polymost_voxdraw(voxmodel_t* m, tspriteptr_t const tspr, bool rotate)
|
||||||
|
{
|
||||||
|
float f, g, k0, zoff;
|
||||||
|
|
||||||
|
if ((intptr_t)m == (intptr_t)(-1)) // hackhackhack
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if ((tspr->cstat & 48) == 32)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if ((tspr->cstat & CSTAT_SPRITE_MDLROTATE) || rotate)
|
||||||
|
{
|
||||||
|
int myclock = (PlayClock << 3) + MulScale(4 << 3, pm_smoothratio, 16);
|
||||||
|
tspr->ang = (tspr->ang + myclock) & 2047; // will be applied in md3_vox_calcmat_common.
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
vec3f_t m0 = { m->scale, m->scale, m->scale };
|
||||||
|
vec3f_t a0 = { 0, 0, m->zadd * m->scale };
|
||||||
|
|
||||||
|
k0 = m->bscale / 64.f;
|
||||||
|
f = (float)tspr->xrepeat * (256.f / 320.f) * k0;
|
||||||
|
if ((sprite[tspr->owner].cstat & 48) == 16)
|
||||||
|
{
|
||||||
|
f *= 1.25f;
|
||||||
|
a0.y -= tspr->xoffset * bcosf(spriteext[tspr->owner].angoff, -20);
|
||||||
|
a0.x += tspr->xoffset * bsinf(spriteext[tspr->owner].angoff, -20);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (globalorientation & 8) { m0.z = -m0.z; a0.z = -a0.z; } //y-flipping
|
||||||
|
if (globalorientation & 4) { m0.x = -m0.x; a0.x = -a0.x; a0.y = -a0.y; } //x-flipping
|
||||||
|
|
||||||
|
m0.x *= f; a0.x *= f; f = -f;
|
||||||
|
m0.y *= f; a0.y *= f;
|
||||||
|
f = (float)tspr->yrepeat * k0;
|
||||||
|
m0.z *= f; a0.z *= f;
|
||||||
|
|
||||||
|
k0 = (float)(tspr->z + spriteext[tspr->owner].position_offset.z);
|
||||||
|
f = ((globalorientation & 8) && (sprite[tspr->owner].cstat & 48) != 0) ? -4.f : 4.f;
|
||||||
|
k0 -= (tspr->yoffset * tspr->yrepeat) * f * m->bscale;
|
||||||
|
zoff = m->siz.z * .5f;
|
||||||
|
if (!(tspr->cstat & 128))
|
||||||
|
zoff += m->piv.z;
|
||||||
|
else if ((tspr->cstat & 48) != 48)
|
||||||
|
{
|
||||||
|
zoff += m->piv.z;
|
||||||
|
zoff -= m->siz.z * .5f;
|
||||||
|
}
|
||||||
|
if (globalorientation & 8) zoff = m->siz.z - zoff;
|
||||||
|
|
||||||
|
f = (65536.f * 512.f) / ((float)xdimen * viewingrange);
|
||||||
|
g = 32.f / ((float)xdimen * Polymost::gxyaspect);
|
||||||
|
|
||||||
|
int const shadowHack = !!(tspr->clipdist & TSPR_FLAGS_MDHACK);
|
||||||
|
|
||||||
|
m0.y *= f; a0.y = (((float)(tspr->x + spriteext[tspr->owner].position_offset.x - globalposx)) * (1.f / 1024.f) + a0.y) * f;
|
||||||
|
m0.x *= -f; a0.x = (((float)(tspr->y + spriteext[tspr->owner].position_offset.y - globalposy)) * -(1.f / 1024.f) + a0.x) * -f;
|
||||||
|
m0.z *= g; a0.z = (((float)(k0 - globalposz - shadowHack)) * -(1.f / 16384.f) + a0.z) * g;
|
||||||
|
|
||||||
|
float mat[16];
|
||||||
|
md3_vox_calcmat_common(tspr, &a0, f, mat);
|
||||||
|
|
||||||
|
//Mirrors
|
||||||
|
if (Polymost::grhalfxdown10x < 0)
|
||||||
|
{
|
||||||
|
mat[0] = -mat[0];
|
||||||
|
mat[4] = -mat[4];
|
||||||
|
mat[8] = -mat[8];
|
||||||
|
mat[12] = -mat[12];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shadowHack)
|
||||||
|
{
|
||||||
|
GLInterface.SetDepthFunc(DF_LEqual);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int winding = ((Polymost::grhalfxdown10x >= 0) ^ ((globalorientation & 8) != 0) ^ ((globalorientation & 4) != 0)) ? Winding_CW : Winding_CCW;
|
||||||
|
GLInterface.SetCull(Cull_Back, winding);
|
||||||
|
|
||||||
|
float pc[4];
|
||||||
|
|
||||||
|
pc[0] = pc[1] = pc[2] = 1.f;
|
||||||
|
|
||||||
|
|
||||||
|
if (!shadowHack)
|
||||||
|
{
|
||||||
|
pc[3] = (tspr->cstat & 2) ? glblend[tspr->blend].def[!!(tspr->cstat & 512)].alpha : 1.0f;
|
||||||
|
pc[3] *= 1.0f - spriteext[tspr->owner].alpha;
|
||||||
|
|
||||||
|
SetRenderStyleFromBlend(!!(tspr->cstat & 2), tspr->blend, !!(tspr->cstat & 512));
|
||||||
|
|
||||||
|
if (!(tspr->cstat & 2) || spriteext[tspr->owner].alpha > 0.f || pc[3] < 1.0f)
|
||||||
|
GLInterface.EnableBlend(true); // else GLInterface.EnableBlend(false);
|
||||||
|
}
|
||||||
|
else pc[3] = 1.f;
|
||||||
|
GLInterface.SetShade(std::max(0, globalshade), numshades);
|
||||||
|
//------------
|
||||||
|
|
||||||
|
//transform to Build coords
|
||||||
|
float omat[16];
|
||||||
|
memcpy(omat, mat, sizeof(omat));
|
||||||
|
|
||||||
|
f = 1.f / 64.f;
|
||||||
|
g = m0.x * f; mat[0] *= g; mat[1] *= g; mat[2] *= g;
|
||||||
|
g = m0.y * f; mat[4] = omat[8] * g; mat[5] = omat[9] * g; mat[6] = omat[10] * g;
|
||||||
|
g = -m0.z * f; mat[8] = omat[4] * g; mat[9] = omat[5] * g; mat[10] = omat[6] * g;
|
||||||
|
//
|
||||||
|
mat[12] -= (m->piv.x * mat[0] + m->piv.y * mat[4] + zoff * mat[8]);
|
||||||
|
mat[13] -= (m->piv.x * mat[1] + m->piv.y * mat[5] + zoff * mat[9]);
|
||||||
|
mat[14] -= (m->piv.x * mat[2] + m->piv.y * mat[6] + zoff * mat[10]);
|
||||||
|
//
|
||||||
|
//Let OpenGL (and perhaps hardware :) handle the matrix rotation
|
||||||
|
mat[3] = mat[7] = mat[11] = 0.f; mat[15] = 1.f;
|
||||||
|
|
||||||
|
for (int i = 0; i < 15; i++) mat[i] *= 1024.f;
|
||||||
|
|
||||||
|
// Adjust to backend coordinate system being used by the vertex buffer.
|
||||||
|
for (int i = 4; i < 8; i++)
|
||||||
|
{
|
||||||
|
float f = mat[i];
|
||||||
|
mat[i] = -mat[i + 4];
|
||||||
|
mat[i + 4] = -f;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLInterface.SetMatrix(Matrix_Model, mat);
|
||||||
|
|
||||||
|
int palId = TRANSLATION(Translation_Remap + curbasepal, globalpal);
|
||||||
|
GLInterface.SetPalswap(globalpal);
|
||||||
|
GLInterface.SetFade(sector[tspr->sectnum].floorpal);
|
||||||
|
|
||||||
|
auto tex = TexMan.GetGameTexture(m->model->GetPaletteTexture());
|
||||||
|
GLInterface.SetTexture(tex, TRANSLATION(Translation_Remap + curbasepal, globalpal), CLAMP_NOFILTER_XY, true);
|
||||||
|
GLInterface.SetModel(m->model, 0, 0, 0);
|
||||||
|
GLInterface.Draw(DT_Triangles, 0, 0);
|
||||||
|
GLInterface.SetModel(nullptr, 0, 0, 0);
|
||||||
|
GLInterface.SetCull(Cull_None);
|
||||||
|
|
||||||
|
if (shadowHack)
|
||||||
|
{
|
||||||
|
GLInterface.SetDepthFunc(DF_Less);
|
||||||
|
}
|
||||||
|
GLInterface.SetIdentityMatrix(Matrix_Model);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,230 +0,0 @@
|
||||||
//--------------------------------------- VOX LIBRARY BEGINS ---------------------------------------
|
|
||||||
|
|
||||||
#ifdef USE_OPENGL
|
|
||||||
|
|
||||||
#include "compat.h"
|
|
||||||
#include "build.h"
|
|
||||||
#include "engine_priv.h"
|
|
||||||
#include "polymost.h"
|
|
||||||
#include "mdsprite.h"
|
|
||||||
#include "v_video.h"
|
|
||||||
#include "flatvertices.h"
|
|
||||||
#include "hw_renderstate.h"
|
|
||||||
#include "texturemanager.h"
|
|
||||||
#include "voxels.h"
|
|
||||||
#include "gamecontrol.h"
|
|
||||||
#include "hw_models.h"
|
|
||||||
#include "printf.h"
|
|
||||||
|
|
||||||
#include "palette.h"
|
|
||||||
#include "../../glbackend/glbackend.h"
|
|
||||||
|
|
||||||
using namespace Polymost;
|
|
||||||
|
|
||||||
void voxfree(voxmodel_t *m)
|
|
||||||
{
|
|
||||||
if (m) delete m;
|
|
||||||
}
|
|
||||||
|
|
||||||
voxmodel_t *voxload(int lumpnum)
|
|
||||||
{
|
|
||||||
FVoxel* voxel = R_LoadKVX(lumpnum);
|
|
||||||
if (voxel != nullptr)
|
|
||||||
{
|
|
||||||
voxmodel_t* vm = new voxmodel_t;
|
|
||||||
*vm = {};
|
|
||||||
auto pivot = voxel->Mips[0].Pivot;
|
|
||||||
vm->mdnum = 1; //VOXel model id
|
|
||||||
vm->scale = vm->bscale = 1.f;
|
|
||||||
vm->piv.x = float(pivot.X);
|
|
||||||
vm->piv.y = float(pivot.Y);
|
|
||||||
vm->piv.z = float(pivot.Z);
|
|
||||||
vm->siz.x = voxel->Mips[0].SizeX;
|
|
||||||
vm->siz.y = voxel->Mips[0].SizeY;
|
|
||||||
vm->siz.z = voxel->Mips[0].SizeZ;
|
|
||||||
vm->is8bit = true;
|
|
||||||
voxel->Mips[0].Pivot.Zero(); // Needs to be taken out of the voxel data because it gets baked into the vertex buffer which we cannot use here.
|
|
||||||
vm->model = new FVoxelModel(voxel, true);
|
|
||||||
return vm;
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Draw voxel model as perfect cubes
|
|
||||||
int32_t polymost_voxdraw(voxmodel_t* m, tspriteptr_t const tspr, bool rotate)
|
|
||||||
{
|
|
||||||
float f, g, k0, zoff;
|
|
||||||
|
|
||||||
if ((intptr_t)m == (intptr_t)(-1)) // hackhackhack
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if ((tspr->cstat & 48) == 32)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if ((tspr->cstat & CSTAT_SPRITE_MDLROTATE) || rotate)
|
|
||||||
{
|
|
||||||
int myclock = (PlayClock << 3) + MulScale(4 << 3, pm_smoothratio, 16);
|
|
||||||
tspr->ang = (tspr->ang + myclock) & 2047; // will be applied in md3_vox_calcmat_common.
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
vec3f_t m0 = { m->scale, m->scale, m->scale };
|
|
||||||
vec3f_t a0 = { 0, 0, m->zadd*m->scale };
|
|
||||||
|
|
||||||
k0 = m->bscale / 64.f;
|
|
||||||
f = (float) tspr->xrepeat * (256.f/320.f) * k0;
|
|
||||||
if ((sprite[tspr->owner].cstat&48)==16)
|
|
||||||
{
|
|
||||||
f *= 1.25f;
|
|
||||||
a0.y -= tspr->xoffset * bcosf(spriteext[tspr->owner].angoff, -20);
|
|
||||||
a0.x += tspr->xoffset * bsinf(spriteext[tspr->owner].angoff, -20);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (globalorientation&8) { m0.z = -m0.z; a0.z = -a0.z; } //y-flipping
|
|
||||||
if (globalorientation&4) { m0.x = -m0.x; a0.x = -a0.x; a0.y = -a0.y; } //x-flipping
|
|
||||||
|
|
||||||
m0.x *= f; a0.x *= f; f = -f;
|
|
||||||
m0.y *= f; a0.y *= f;
|
|
||||||
f = (float) tspr->yrepeat * k0;
|
|
||||||
m0.z *= f; a0.z *= f;
|
|
||||||
|
|
||||||
k0 = (float) (tspr->z+spriteext[tspr->owner].position_offset.z);
|
|
||||||
f = ((globalorientation&8) && (sprite[tspr->owner].cstat&48)!=0) ? -4.f : 4.f;
|
|
||||||
k0 -= (tspr->yoffset*tspr->yrepeat)*f*m->bscale;
|
|
||||||
zoff = m->siz.z*.5f;
|
|
||||||
if (!(tspr->cstat&128))
|
|
||||||
zoff += m->piv.z;
|
|
||||||
else if ((tspr->cstat&48) != 48)
|
|
||||||
{
|
|
||||||
zoff += m->piv.z;
|
|
||||||
zoff -= m->siz.z*.5f;
|
|
||||||
}
|
|
||||||
if (globalorientation&8) zoff = m->siz.z-zoff;
|
|
||||||
|
|
||||||
f = (65536.f*512.f) / ((float)xdimen*viewingrange);
|
|
||||||
g = 32.f / ((float)xdimen*gxyaspect);
|
|
||||||
|
|
||||||
int const shadowHack = !!(tspr->clipdist & TSPR_FLAGS_MDHACK);
|
|
||||||
|
|
||||||
m0.y *= f; a0.y = (((float)(tspr->x+spriteext[tspr->owner].position_offset.x-globalposx)) * (1.f/1024.f) + a0.y) * f;
|
|
||||||
m0.x *=-f; a0.x = (((float)(tspr->y+spriteext[tspr->owner].position_offset.y-globalposy)) * -(1.f/1024.f) + a0.x) * -f;
|
|
||||||
m0.z *= g; a0.z = (((float)(k0 -globalposz - shadowHack)) * -(1.f/16384.f) + a0.z) * g;
|
|
||||||
|
|
||||||
float mat[16];
|
|
||||||
md3_vox_calcmat_common(tspr, &a0, f, mat);
|
|
||||||
|
|
||||||
//Mirrors
|
|
||||||
if (grhalfxdown10x < 0)
|
|
||||||
{
|
|
||||||
mat[0] = -mat[0];
|
|
||||||
mat[4] = -mat[4];
|
|
||||||
mat[8] = -mat[8];
|
|
||||||
mat[12] = -mat[12];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (shadowHack)
|
|
||||||
{
|
|
||||||
GLInterface.SetDepthFunc(DF_LEqual);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int winding = ((grhalfxdown10x >= 0) ^ ((globalorientation & 8) != 0) ^ ((globalorientation & 4) != 0)) ? Winding_CW : Winding_CCW;
|
|
||||||
GLInterface.SetCull(Cull_Back, winding);
|
|
||||||
|
|
||||||
float pc[4];
|
|
||||||
|
|
||||||
pc[0] = pc[1] = pc[2] = 1.f;
|
|
||||||
|
|
||||||
|
|
||||||
if (!shadowHack)
|
|
||||||
{
|
|
||||||
pc[3] = (tspr->cstat & 2) ? glblend[tspr->blend].def[!!(tspr->cstat & 512)].alpha : 1.0f;
|
|
||||||
pc[3] *= 1.0f - spriteext[tspr->owner].alpha;
|
|
||||||
|
|
||||||
SetRenderStyleFromBlend(!!(tspr->cstat & 2), tspr->blend, !!(tspr->cstat & 512));
|
|
||||||
|
|
||||||
if (!(tspr->cstat & 2) || spriteext[tspr->owner].alpha > 0.f || pc[3] < 1.0f)
|
|
||||||
GLInterface.EnableBlend(true); // else GLInterface.EnableBlend(false);
|
|
||||||
}
|
|
||||||
else pc[3] = 1.f;
|
|
||||||
GLInterface.SetShade(std::max(0, globalshade), numshades);
|
|
||||||
//------------
|
|
||||||
|
|
||||||
//transform to Build coords
|
|
||||||
float omat[16];
|
|
||||||
memcpy(omat, mat, sizeof(omat));
|
|
||||||
|
|
||||||
f = 1.f/64.f;
|
|
||||||
g = m0.x*f; mat[0] *= g; mat[1] *= g; mat[2] *= g;
|
|
||||||
g = m0.y*f; mat[4] = omat[8]*g; mat[5] = omat[9]*g; mat[6] = omat[10]*g;
|
|
||||||
g =-m0.z*f; mat[8] = omat[4]*g; mat[9] = omat[5]*g; mat[10] = omat[6]*g;
|
|
||||||
//
|
|
||||||
mat[12] -= (m->piv.x*mat[0] + m->piv.y*mat[4] + zoff*mat[8]);
|
|
||||||
mat[13] -= (m->piv.x*mat[1] + m->piv.y*mat[5] + zoff*mat[9]);
|
|
||||||
mat[14] -= (m->piv.x*mat[2] + m->piv.y*mat[6] + zoff*mat[10]);
|
|
||||||
//
|
|
||||||
//Let OpenGL (and perhaps hardware :) handle the matrix rotation
|
|
||||||
mat[3] = mat[7] = mat[11] = 0.f; mat[15] = 1.f;
|
|
||||||
|
|
||||||
for (int i = 0; i < 15; i++) mat[i] *= 1024.f;
|
|
||||||
|
|
||||||
// Adjust to backend coordinate system being used by the vertex buffer.
|
|
||||||
for (int i = 4; i < 8; i++)
|
|
||||||
{
|
|
||||||
float f = mat[i];
|
|
||||||
mat[i] = -mat[i + 4];
|
|
||||||
mat[i + 4] = -f;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLInterface.SetMatrix(Matrix_Model, mat);
|
|
||||||
|
|
||||||
int palId = TRANSLATION(Translation_Remap + curbasepal, globalpal);
|
|
||||||
GLInterface.SetPalswap(globalpal);
|
|
||||||
GLInterface.SetFade(sector[tspr->sectnum].floorpal);
|
|
||||||
|
|
||||||
auto tex = TexMan.GetGameTexture(m->model->GetPaletteTexture());
|
|
||||||
GLInterface.SetTexture(tex, TRANSLATION(Translation_Remap + curbasepal, globalpal), CLAMP_NOFILTER_XY, true);
|
|
||||||
GLInterface.SetModel(m->model, 0, 0, 0);
|
|
||||||
GLInterface.Draw(DT_Triangles, 0, 0);
|
|
||||||
GLInterface.SetModel(nullptr, 0, 0, 0);
|
|
||||||
GLInterface.SetCull(Cull_None);
|
|
||||||
|
|
||||||
if (shadowHack)
|
|
||||||
{
|
|
||||||
GLInterface.SetDepthFunc(DF_Less);
|
|
||||||
}
|
|
||||||
GLInterface.SetIdentityMatrix(Matrix_Model);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern int voxlumps[MAXVOXELS];
|
|
||||||
void (*PolymostProcessVoxels_Callback)(void) = NULL;
|
|
||||||
void PolymostProcessVoxels(void)
|
|
||||||
{
|
|
||||||
if (PolymostProcessVoxels_Callback)
|
|
||||||
PolymostProcessVoxels_Callback();
|
|
||||||
|
|
||||||
if (g_haveVoxels != 1)
|
|
||||||
return;
|
|
||||||
|
|
||||||
g_haveVoxels = 2;
|
|
||||||
|
|
||||||
Printf(PRINT_NONOTIFY, "Generating voxel models for Polymost. This may take a while...\n");
|
|
||||||
|
|
||||||
for (int i = 0; i < MAXVOXELS; i++)
|
|
||||||
{
|
|
||||||
int lumpnum = voxlumps[i];
|
|
||||||
if (lumpnum > 0)
|
|
||||||
{
|
|
||||||
voxmodels[i] = voxload(lumpnum);
|
|
||||||
if (voxmodels[i])
|
|
||||||
voxmodels[i]->scale = voxscale[i] * (1.f / 65536.f);
|
|
||||||
else
|
|
||||||
Printf("Unable to load voxel from %s\n", fileSystem.GetFileFullPath(lumpnum));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//---------------------------------------- VOX LIBRARY ENDS ----------------------------------------
|
|
|
@ -85,17 +85,17 @@ CUSTOM_CVAR(Bool, adl_fullpan, 1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUA
|
||||||
FORWARD_BOOL_CVAR(adl_fullpan);
|
FORWARD_BOOL_CVAR(adl_fullpan);
|
||||||
}
|
}
|
||||||
|
|
||||||
CUSTOM_CVAR(Int, adl_bank, 14, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL)
|
CUSTOM_CVAR(Int, adl_bank, 14, CVAR_ARCHIVE | CVAR_VIRTUAL)
|
||||||
{
|
{
|
||||||
FORWARD_CVAR(adl_bank);
|
FORWARD_CVAR(adl_bank);
|
||||||
}
|
}
|
||||||
|
|
||||||
CUSTOM_CVAR(Bool, adl_use_custom_bank, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL)
|
CUSTOM_CVAR(Bool, adl_use_custom_bank, 0, CVAR_ARCHIVE | CVAR_VIRTUAL)
|
||||||
{
|
{
|
||||||
FORWARD_BOOL_CVAR(adl_use_custom_bank);
|
FORWARD_BOOL_CVAR(adl_use_custom_bank);
|
||||||
}
|
}
|
||||||
|
|
||||||
CUSTOM_CVAR(String, adl_custom_bank, "", CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL)
|
CUSTOM_CVAR(String, adl_custom_bank, "", CVAR_ARCHIVE | CVAR_VIRTUAL)
|
||||||
{
|
{
|
||||||
FORWARD_STRING_CVAR(adl_custom_bank);
|
FORWARD_STRING_CVAR(adl_custom_bank);
|
||||||
}
|
}
|
||||||
|
@ -261,12 +261,12 @@ CUSTOM_CVAR(Bool, opn_fullpan, 1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUA
|
||||||
FORWARD_BOOL_CVAR(opn_fullpan);
|
FORWARD_BOOL_CVAR(opn_fullpan);
|
||||||
}
|
}
|
||||||
|
|
||||||
CUSTOM_CVAR(Bool, opn_use_custom_bank, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL)
|
CUSTOM_CVAR(Bool, opn_use_custom_bank, 0, CVAR_ARCHIVE | CVAR_VIRTUAL)
|
||||||
{
|
{
|
||||||
FORWARD_BOOL_CVAR(opn_use_custom_bank);
|
FORWARD_BOOL_CVAR(opn_use_custom_bank);
|
||||||
}
|
}
|
||||||
|
|
||||||
CUSTOM_CVAR(String, opn_custom_bank, "", CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL)
|
CUSTOM_CVAR(String, opn_custom_bank, "", CVAR_ARCHIVE | CVAR_VIRTUAL)
|
||||||
{
|
{
|
||||||
FORWARD_STRING_CVAR(opn_custom_bank);
|
FORWARD_STRING_CVAR(opn_custom_bank);
|
||||||
}
|
}
|
||||||
|
|
|
@ -707,6 +707,12 @@ void ReadBindings(int lump, bool override)
|
||||||
dest = &AutomapBindings;
|
dest = &AutomapBindings;
|
||||||
sc.MustGetString();
|
sc.MustGetString();
|
||||||
}
|
}
|
||||||
|
else if (sc.Compare("unbind"))
|
||||||
|
{
|
||||||
|
sc.MustGetString();
|
||||||
|
dest->UnbindKey(sc.String);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
key = GetConfigKeyFromName(sc.String);
|
key = GetConfigKeyFromName(sc.String);
|
||||||
sc.MustGetString();
|
sc.MustGetString();
|
||||||
dest->SetBind(key, sc.String, override);
|
dest->SetBind(key, sc.String, override);
|
||||||
|
|
|
@ -1287,6 +1287,42 @@ void FScanner::AddSymbol(const char* name, double value)
|
||||||
symbols.Insert(name, sym);
|
symbols.Insert(name, sym);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
int FScanner::StartBraces(FScanner::SavedPos* braceend)
|
||||||
|
{
|
||||||
|
if (CheckString("{"))
|
||||||
|
{
|
||||||
|
auto here = SavePos();
|
||||||
|
SkipToEndOfBlock();
|
||||||
|
*braceend = SavePos();
|
||||||
|
RestorePos(here);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ScriptError("'{' expected");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
bool FScanner::FoundEndBrace(FScanner::SavedPos& braceend)
|
||||||
|
{
|
||||||
|
auto here = SavePos();
|
||||||
|
return here.SavedScriptPtr >= braceend.SavedScriptPtr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// a class that remembers a parser position
|
// a class that remembers a parser position
|
||||||
|
|
|
@ -94,6 +94,8 @@ public:
|
||||||
inline void AddSymbol(const char* name, uint32_t value) { return AddSymbol(name, uint64_t(value)); }
|
inline void AddSymbol(const char* name, uint32_t value) { return AddSymbol(name, uint64_t(value)); }
|
||||||
void AddSymbol(const char* name, double value);
|
void AddSymbol(const char* name, double value);
|
||||||
void SkipToEndOfBlock();
|
void SkipToEndOfBlock();
|
||||||
|
int StartBraces(FScanner::SavedPos* braceend);
|
||||||
|
bool FoundEndBrace(FScanner::SavedPos& braceend);
|
||||||
|
|
||||||
static FString TokenName(int token, const char *string=NULL);
|
static FString TokenName(int token, const char *string=NULL);
|
||||||
|
|
||||||
|
@ -113,7 +115,30 @@ public:
|
||||||
void MustGetNumber(bool evaluate = false);
|
void MustGetNumber(bool evaluate = false);
|
||||||
bool CheckNumber(bool evaluate = false);
|
bool CheckNumber(bool evaluate = false);
|
||||||
|
|
||||||
|
bool GetNumber(int& var, bool evaluate = false)
|
||||||
|
{
|
||||||
|
if (!GetNumber(evaluate)) return false;
|
||||||
|
var = Number;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GetString(FString& var)
|
||||||
|
{
|
||||||
|
if (!GetString()) return false;
|
||||||
|
var = String;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool GetFloat(bool evaluate = false);
|
bool GetFloat(bool evaluate = false);
|
||||||
|
|
||||||
|
bool GetFloat(double& var, bool evaluate = false)
|
||||||
|
{
|
||||||
|
if (!GetFloat(evaluate)) return false;
|
||||||
|
var = Float;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void MustGetFloat(bool evaluate = false);
|
void MustGetFloat(bool evaluate = false);
|
||||||
bool CheckFloat(bool evaluate = false);
|
bool CheckFloat(bool evaluate = false);
|
||||||
|
|
||||||
|
|
|
@ -233,12 +233,14 @@ bool FZipFile::Open(bool quiet, LumpFilterInfo* filter)
|
||||||
}
|
}
|
||||||
|
|
||||||
name.ToLower();
|
name.ToLower();
|
||||||
|
if (name.IndexOf("__macosx") == 0)
|
||||||
|
continue; // skip Apple garbage. At this stage only the root folder matters,
|
||||||
if (i == 0)
|
if (i == 0)
|
||||||
{
|
{
|
||||||
// check for special names, if one of these gets found this must be treated as a normal zip.
|
// check for special names, if one of these gets found this must be treated as a normal zip.
|
||||||
bool isspecial = name.IndexOf("/") < 0 || (filter && filter->reservedFolders.Find(name) < filter->reservedFolders.Size());
|
bool isspecial = name.IndexOf("/") < 0 || (filter && filter->reservedFolders.Find(name) < filter->reservedFolders.Size());
|
||||||
if (isspecial) break;
|
if (isspecial) break;
|
||||||
name0 = name;
|
name0 = name.Left(name.LastIndexOf("/")+1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -252,7 +254,7 @@ bool FZipFile::Open(bool quiet, LumpFilterInfo* filter)
|
||||||
// at least one of the more common definition lumps must be present.
|
// at least one of the more common definition lumps must be present.
|
||||||
for (auto &p : filter->requiredPrefixes)
|
for (auto &p : filter->requiredPrefixes)
|
||||||
{
|
{
|
||||||
if (name.IndexOf(name0 + p) == 0)
|
if (name.IndexOf(name0 + p) == 0 || name.LastIndexOf(p) == name.Len() - strlen(p))
|
||||||
{
|
{
|
||||||
foundspeciallump = true;
|
foundspeciallump = true;
|
||||||
break;
|
break;
|
||||||
|
@ -272,7 +274,6 @@ bool FZipFile::Open(bool quiet, LumpFilterInfo* filter)
|
||||||
|
|
||||||
int len = LittleShort(zip_fh->NameLength);
|
int len = LittleShort(zip_fh->NameLength);
|
||||||
FString name(dirptr + sizeof(FZipCentralDirectoryInfo), len);
|
FString name(dirptr + sizeof(FZipCentralDirectoryInfo), len);
|
||||||
if (name0.IsNotEmpty()) name = name.Mid(name0.Len());
|
|
||||||
dirptr += sizeof(FZipCentralDirectoryInfo) +
|
dirptr += sizeof(FZipCentralDirectoryInfo) +
|
||||||
LittleShort(zip_fh->NameLength) +
|
LittleShort(zip_fh->NameLength) +
|
||||||
LittleShort(zip_fh->ExtraLength) +
|
LittleShort(zip_fh->ExtraLength) +
|
||||||
|
@ -285,6 +286,13 @@ bool FZipFile::Open(bool quiet, LumpFilterInfo* filter)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (name.IndexOf("__macosx") == 0 || name.IndexOf("__MACOSX") == 0)
|
||||||
|
{
|
||||||
|
skipped++;
|
||||||
|
continue; // Weed out Apple's resource fork garbage right here because it interferes with safe operation.
|
||||||
|
}
|
||||||
|
if (name0.IsNotEmpty()) name = name.Mid(name0.Len());
|
||||||
|
|
||||||
// skip Directories
|
// skip Directories
|
||||||
if (name.IsEmpty() || (name.Back() == '/' && LittleLong(zip_fh->UncompressedSize) == 0))
|
if (name.IsEmpty() || (name.Back() == '/' && LittleLong(zip_fh->UncompressedSize) == 0))
|
||||||
{
|
{
|
||||||
|
|
|
@ -76,14 +76,14 @@ struct FileSystem::LumpRecord
|
||||||
shortName.String[8] = 0;
|
shortName.String[8] = 0;
|
||||||
longName = "";
|
longName = "";
|
||||||
Namespace = lump->GetNamespace();
|
Namespace = lump->GetNamespace();
|
||||||
resourceId = 0;
|
resourceId = -1;
|
||||||
}
|
}
|
||||||
else if ((lump->Flags & LUMPF_EMBEDDED) || !lump->getName() || !*lump->getName())
|
else if ((lump->Flags & LUMPF_EMBEDDED) || !lump->getName() || !*lump->getName())
|
||||||
{
|
{
|
||||||
shortName.qword = 0;
|
shortName.qword = 0;
|
||||||
longName = "";
|
longName = "";
|
||||||
Namespace = ns_hidden;
|
Namespace = ns_hidden;
|
||||||
resourceId = 0;
|
resourceId = -1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -175,10 +175,11 @@ void I_PrintStr(const char *cp)
|
||||||
{
|
{
|
||||||
const char * srcp = cp;
|
const char * srcp = cp;
|
||||||
FString printData = "";
|
FString printData = "";
|
||||||
|
bool terminal = isatty(STDOUT_FILENO);
|
||||||
|
|
||||||
while (*srcp != 0)
|
while (*srcp != 0)
|
||||||
{
|
{
|
||||||
if (*srcp == 0x1c && con_printansi)
|
if (*srcp == 0x1c && con_printansi && terminal)
|
||||||
{
|
{
|
||||||
srcp += 1;
|
srcp += 1;
|
||||||
EColorRange range = V_ParseFontColor((const uint8_t*&)srcp, CR_UNTRANSLATED, CR_YELLOW);
|
EColorRange range = V_ParseFontColor((const uint8_t*&)srcp, CR_UNTRANSLATED, CR_YELLOW);
|
||||||
|
@ -224,7 +225,7 @@ void I_PrintStr(const char *cp)
|
||||||
|
|
||||||
if (StartScreen) CleanProgressBar();
|
if (StartScreen) CleanProgressBar();
|
||||||
fputs(printData.GetChars(),stdout);
|
fputs(printData.GetChars(),stdout);
|
||||||
fputs("\033[0m",stdout);
|
if (terminal) fputs("\033[0m",stdout);
|
||||||
if (StartScreen) RedrawProgressBar(ProgressBarCurPos,ProgressBarMaxPos);
|
if (StartScreen) RedrawProgressBar(ProgressBarCurPos,ProgressBarMaxPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -80,6 +80,8 @@ FFlatVertexBuffer::FFlatVertexBuffer(int width, int height)
|
||||||
|
|
||||||
mVertexBuffer = screen->CreateVertexBuffer();
|
mVertexBuffer = screen->CreateVertexBuffer();
|
||||||
mIndexBuffer = screen->CreateIndexBuffer();
|
mIndexBuffer = screen->CreateIndexBuffer();
|
||||||
|
int data[4] = {};
|
||||||
|
mIndexBuffer->SetData(4, data); // On Vulkan this may not be empty, so set some dummy defaults to avoid crashes.
|
||||||
|
|
||||||
unsigned int bytesize = BUFFER_SIZE * sizeof(FFlatVertex);
|
unsigned int bytesize = BUFFER_SIZE * sizeof(FFlatVertex);
|
||||||
mVertexBuffer->SetData(bytesize, nullptr, false);
|
mVertexBuffer->SetData(bytesize, nullptr, false);
|
||||||
|
|
|
@ -200,9 +200,8 @@ struct StreamData
|
||||||
FVector4 uSplitBottomPlane;
|
FVector4 uSplitBottomPlane;
|
||||||
|
|
||||||
FVector4 uDetailParms;
|
FVector4 uDetailParms;
|
||||||
#ifdef NPOT_EMULATION
|
FVector4 uNpotEmulation;
|
||||||
FVector2 uNpotEmulation;
|
FVector4 padding1, padding2, padding3;
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class FRenderState
|
class FRenderState
|
||||||
|
@ -274,7 +273,7 @@ public:
|
||||||
mSpecialEffect = EFF_NONE;
|
mSpecialEffect = EFF_NONE;
|
||||||
mLightIndex = -1;
|
mLightIndex = -1;
|
||||||
mStreamData.uInterpolationFactor = 0;
|
mStreamData.uInterpolationFactor = 0;
|
||||||
mRenderStyle = LegacyRenderStyles[STYLE_Translucent];
|
mRenderStyle = DefaultRenderStyle();
|
||||||
mMaterial.Reset();
|
mMaterial.Reset();
|
||||||
mBias.Reset();
|
mBias.Reset();
|
||||||
mPassType = NORMAL_PASS;
|
mPassType = NORMAL_PASS;
|
||||||
|
@ -295,7 +294,7 @@ public:
|
||||||
mStreamData.uDynLightColor = { 0.0f, 0.0f, 0.0f, 1.0f };
|
mStreamData.uDynLightColor = { 0.0f, 0.0f, 0.0f, 1.0f };
|
||||||
mStreamData.uDetailParms = { 0.0f, 0.0f, 0.0f, 0.0f };
|
mStreamData.uDetailParms = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||||
#ifdef NPOT_EMULATION
|
#ifdef NPOT_EMULATION
|
||||||
mStreamData.uNpotEmulation = { 0,0 };
|
mStreamData.uNpotEmulation = { 0,0,0,0 };
|
||||||
#endif
|
#endif
|
||||||
mModelMatrix.loadIdentity();
|
mModelMatrix.loadIdentity();
|
||||||
mTextureMatrix.loadIdentity();
|
mTextureMatrix.loadIdentity();
|
||||||
|
@ -490,7 +489,7 @@ public:
|
||||||
void SetNpotEmulation(float factor, float offset)
|
void SetNpotEmulation(float factor, float offset)
|
||||||
{
|
{
|
||||||
#ifdef NPOT_EMULATION
|
#ifdef NPOT_EMULATION
|
||||||
mStreamData.uNpotEmulation = { offset, factor };
|
mStreamData.uNpotEmulation = { offset, factor, 0, 0 };
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -202,7 +202,7 @@ void FSkyVertexBuffer::SkyVertexBuild(int r, int c, bool zflip)
|
||||||
|
|
||||||
// And the texture coordinates.
|
// And the texture coordinates.
|
||||||
if (zflip) r = mRows * 2 - r;
|
if (zflip) r = mRows * 2 - r;
|
||||||
vert.u = 0.5 + (-c / (float)mColumns);
|
vert.u = 0.5f + (-c / (float)mColumns);
|
||||||
vert.v = (r / (float)(2*mRows));
|
vert.v = (r / (float)(2*mRows));
|
||||||
|
|
||||||
// And finally the vertex.
|
// And finally the vertex.
|
||||||
|
@ -413,11 +413,13 @@ void FSkyVertexBuffer::SetupMatrices(FGameTexture *tex, float x_offset, float y_
|
||||||
{
|
{
|
||||||
modelMatrix.translate(0.f, -1250.f, 0.f);
|
modelMatrix.translate(0.f, -1250.f, 0.f);
|
||||||
modelMatrix.scale(1.f, texh / 230.f, 1.f);
|
modelMatrix.scale(1.f, texh / 230.f, 1.f);
|
||||||
|
yscale = 1.f;
|
||||||
}
|
}
|
||||||
else if (texh <= 240)
|
else if (texh <= 240)
|
||||||
{
|
{
|
||||||
modelMatrix.translate(0.f, (200 - texh + texskyoffset) * skyoffsetfactor, 0.f);
|
modelMatrix.translate(0.f, (200 - texh + texskyoffset) * skyoffsetfactor, 0.f);
|
||||||
modelMatrix.scale(1.f, 1.f + ((texh - 200.f) / 200.f) * 1.17f, 1.f);
|
modelMatrix.scale(1.f, 1.f + ((texh - 200.f) / 200.f) * 1.17f, 1.f);
|
||||||
|
yscale = 1.f;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -152,6 +152,10 @@ void PolyFrameBuffer::FlushDrawCommands()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EXTERN_CVAR(Float, vid_brightness)
|
||||||
|
EXTERN_CVAR(Float, vid_contrast)
|
||||||
|
EXTERN_CVAR(Float, vid_saturation)
|
||||||
|
|
||||||
void PolyFrameBuffer::Update()
|
void PolyFrameBuffer::Update()
|
||||||
{
|
{
|
||||||
twoD.Reset();
|
twoD.Reset();
|
||||||
|
@ -177,8 +181,9 @@ void PolyFrameBuffer::Update()
|
||||||
if (dst)
|
if (dst)
|
||||||
{
|
{
|
||||||
#if 1
|
#if 1
|
||||||
|
// [GEC] with the help of dpJudas a new system of copying and applying gamma in the video buffer
|
||||||
auto copyqueue = std::make_shared<DrawerCommandQueue>(&mFrameMemory);
|
auto copyqueue = std::make_shared<DrawerCommandQueue>(&mFrameMemory);
|
||||||
copyqueue->Push<MemcpyCommand>(dst, pitch / pixelsize, src, w, h, w, pixelsize);
|
copyqueue->Push<CopyAndApplyGammaCommand>(dst, pitch / pixelsize, src, w, h, w, vid_gamma, vid_contrast, vid_brightness, vid_saturation);
|
||||||
DrawerThreads::Execute(copyqueue);
|
DrawerThreads::Execute(copyqueue);
|
||||||
#else
|
#else
|
||||||
for (int y = 0; y < h; y++)
|
for (int y = 0; y < h; y++)
|
||||||
|
@ -366,6 +371,40 @@ FTexture *PolyFrameBuffer::WipeEndScreen()
|
||||||
|
|
||||||
TArray<uint8_t> PolyFrameBuffer::GetScreenshotBuffer(int &pitch, ESSType &color_type, float &gamma)
|
TArray<uint8_t> PolyFrameBuffer::GetScreenshotBuffer(int &pitch, ESSType &color_type, float &gamma)
|
||||||
{
|
{
|
||||||
|
// [GEC] Really necessary to apply gamma, brightness, contrast and saturation for screenshot
|
||||||
|
|
||||||
|
std::vector<uint8_t> gammatablebuf(256);
|
||||||
|
uint8_t* gammatable = gammatablebuf.data();
|
||||||
|
|
||||||
|
float InvGamma = 1.0f / clamp<float>(vid_gamma, 0.1f, 4.f);
|
||||||
|
float Brightness = clamp<float>(vid_brightness, -0.8f, 0.8f);
|
||||||
|
float Contrast = clamp<float>(vid_contrast, 0.1f, 3.f);
|
||||||
|
float Saturation = clamp<float>(vid_saturation, -15.0f, 15.f);
|
||||||
|
|
||||||
|
for (int x = 0; x < 256; x++)
|
||||||
|
{
|
||||||
|
float ramp = (float)(x / 255.f);
|
||||||
|
// Apply Contrast
|
||||||
|
// vec4 finalColor = vec4((((originalColor.rgb - vec3(0.5)) * Contrast) + vec3(0.5)), 1.0);
|
||||||
|
if(vid_contrast != 1.0f)
|
||||||
|
ramp = (((ramp - 0.5f) * Contrast) + 0.5f);
|
||||||
|
|
||||||
|
// Apply Brightness
|
||||||
|
// vec4 finalColor = vec4(originalColor.rgb + Brightness, 1.0);
|
||||||
|
if (vid_brightness != 0.0f)
|
||||||
|
ramp += (Brightness / 2.0f);
|
||||||
|
|
||||||
|
// Apply Gamma
|
||||||
|
// FragColor.rgb = pow(fragColor.rgb, vec3(1.0/gamma));
|
||||||
|
if (vid_gamma != 1.0f)
|
||||||
|
ramp = pow(ramp, InvGamma);
|
||||||
|
|
||||||
|
// Clamp ramp
|
||||||
|
ramp = clamp<float>(ramp, 0.0f, 1.f);
|
||||||
|
|
||||||
|
gammatable[x] = (uint8_t)(ramp * 255);
|
||||||
|
}
|
||||||
|
|
||||||
int w = SCREENWIDTH;
|
int w = SCREENWIDTH;
|
||||||
int h = SCREENHEIGHT;
|
int h = SCREENHEIGHT;
|
||||||
|
|
||||||
|
@ -380,9 +419,44 @@ TArray<uint8_t> PolyFrameBuffer::GetScreenshotBuffer(int &pitch, ESSType &color_
|
||||||
|
|
||||||
for (int x = 0; x < w; x++)
|
for (int x = 0; x < w; x++)
|
||||||
{
|
{
|
||||||
ScreenshotBuffer[dindex ] = pixels[sindex + 2];
|
uint32_t red = pixels[sindex + 2];
|
||||||
ScreenshotBuffer[dindex + 1] = pixels[sindex + 1];
|
uint32_t green = pixels[sindex + 1];
|
||||||
ScreenshotBuffer[dindex + 2] = pixels[sindex ];
|
uint32_t blue = pixels[sindex];
|
||||||
|
|
||||||
|
if (vid_saturation != 1.0f)
|
||||||
|
{
|
||||||
|
float NewR = (float)(red / 255.f);
|
||||||
|
float NewG = (float)(green / 255.f);
|
||||||
|
float NewB = (float)(blue / 255.f);
|
||||||
|
|
||||||
|
// Apply Saturation
|
||||||
|
// float luma = dot(In, float3(0.2126729, 0.7151522, 0.0721750));
|
||||||
|
// Out = luma.xxx + Saturation.xxx * (In - luma.xxx);
|
||||||
|
//float luma = (NewR * 0.2126729f) + (NewG * 0.7151522f) + (NewB * 0.0721750f); // Rec. 709
|
||||||
|
float luma = (NewR * 0.299f) + (NewG * 0.587f) + (NewB * 0.114f); //Rec. 601
|
||||||
|
NewR = luma + (Saturation * (NewR - luma));
|
||||||
|
NewG = luma + (Saturation * (NewG - luma));
|
||||||
|
NewB = luma + (Saturation * (NewB - luma));
|
||||||
|
|
||||||
|
// Clamp All
|
||||||
|
NewR = clamp<float>(NewR, 0.0f, 1.f);
|
||||||
|
NewG = clamp<float>(NewG, 0.0f, 1.f);
|
||||||
|
NewB = clamp<float>(NewB, 0.0f, 1.f);
|
||||||
|
|
||||||
|
red = (uint32_t)(NewR * 255.f);
|
||||||
|
green = (uint32_t)(NewG * 255.f);
|
||||||
|
blue = (uint32_t)(NewB * 255.f);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply Contrast / Brightness / Gamma
|
||||||
|
red = gammatable[red];
|
||||||
|
green = gammatable[green];
|
||||||
|
blue = gammatable[blue];
|
||||||
|
|
||||||
|
ScreenshotBuffer[dindex ] = red;
|
||||||
|
ScreenshotBuffer[dindex + 1] = green;
|
||||||
|
ScreenshotBuffer[dindex + 2] = blue;
|
||||||
|
|
||||||
dindex += 3;
|
dindex += 3;
|
||||||
sindex += 4;
|
sindex += 4;
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,3 +96,119 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
inline PolyFrameBuffer *GetPolyFrameBuffer() { return static_cast<PolyFrameBuffer*>(screen); }
|
inline PolyFrameBuffer *GetPolyFrameBuffer() { return static_cast<PolyFrameBuffer*>(screen); }
|
||||||
|
|
||||||
|
// [GEC] Original code of dpJudas, I add the formulas of gamma, brightness, contrast and saturation.
|
||||||
|
class CopyAndApplyGammaCommand : public DrawerCommand
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CopyAndApplyGammaCommand(void* dest, int destpitch, const void* src, int width, int height, int srcpitch,
|
||||||
|
float gamma, float contrast, float brightness, float saturation) : dest(dest), src(src), destpitch(destpitch), width(width), height(height), srcpitch(srcpitch),
|
||||||
|
gamma(gamma), contrast(contrast), brightness(brightness), saturation(saturation)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Execute(DrawerThread* thread)
|
||||||
|
{
|
||||||
|
float Saturation = clamp<float>(saturation, -15.0f, 15.f);
|
||||||
|
|
||||||
|
std::vector<uint8_t> gammatablebuf(256);
|
||||||
|
uint8_t* gammatable = gammatablebuf.data();
|
||||||
|
InitGammaTable(gammatable);
|
||||||
|
|
||||||
|
int w = width;
|
||||||
|
int start = thread->skipped_by_thread(0);
|
||||||
|
int count = thread->count_for_thread(0, height);
|
||||||
|
int sstep = thread->num_cores * srcpitch;
|
||||||
|
int dstep = thread->num_cores * destpitch;
|
||||||
|
uint32_t* d = (uint32_t*)dest + start * destpitch;
|
||||||
|
const uint32_t* s = (const uint32_t*)src + start * srcpitch;
|
||||||
|
for (int y = 0; y < count; y++)
|
||||||
|
{
|
||||||
|
for (int x = 0; x < w; x++)
|
||||||
|
{
|
||||||
|
uint32_t red = RPART(s[x]);
|
||||||
|
uint32_t green = GPART(s[x]);
|
||||||
|
uint32_t blue = BPART(s[x]);
|
||||||
|
uint32_t alpha = APART(s[x]);
|
||||||
|
|
||||||
|
if (saturation != 1.0f)
|
||||||
|
{
|
||||||
|
float NewR = (float)(red / 255.f);
|
||||||
|
float NewG = (float)(green / 255.f);
|
||||||
|
float NewB = (float)(blue / 255.f);
|
||||||
|
|
||||||
|
// Apply Saturation
|
||||||
|
// float luma = dot(In, float3(0.2126729, 0.7151522, 0.0721750));
|
||||||
|
// Out = luma.xxx + Saturation.xxx * (In - luma.xxx);
|
||||||
|
//float luma = (NewR * 0.2126729f) + (NewG * 0.7151522f) + (NewB * 0.0721750f); // Rec. 709
|
||||||
|
float luma = (NewR * 0.299f) + (NewG * 0.587f) + (NewB * 0.114f); //Rec. 601
|
||||||
|
NewR = luma + (Saturation * (NewR - luma));
|
||||||
|
NewG = luma + (Saturation * (NewG - luma));
|
||||||
|
NewB = luma + (Saturation * (NewB - luma));
|
||||||
|
|
||||||
|
// Clamp All
|
||||||
|
NewR = clamp<float>(NewR, 0.0f, 1.f);
|
||||||
|
NewG = clamp<float>(NewG, 0.0f, 1.f);
|
||||||
|
NewB = clamp<float>(NewB, 0.0f, 1.f);
|
||||||
|
|
||||||
|
red = (uint32_t)(NewR * 255.f);
|
||||||
|
green = (uint32_t)(NewG * 255.f);
|
||||||
|
blue = (uint32_t)(NewB * 255.f);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply Contrast / Brightness / Gamma
|
||||||
|
red = gammatable[red];
|
||||||
|
green = gammatable[green];
|
||||||
|
blue = gammatable[blue];
|
||||||
|
|
||||||
|
d[x] = MAKEARGB(alpha, (uint8_t)red, (uint8_t)green, (uint8_t)blue);
|
||||||
|
}
|
||||||
|
d += dstep;
|
||||||
|
s += sstep;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void InitGammaTable(uint8_t *gammatable)
|
||||||
|
{
|
||||||
|
float InvGamma = 1.0f / clamp<float>(gamma, 0.1f, 4.f);
|
||||||
|
float Brightness = clamp<float>(brightness, -0.8f, 0.8f);
|
||||||
|
float Contrast = clamp<float>(contrast, 0.1f, 3.f);
|
||||||
|
|
||||||
|
for (int x = 0; x < 256; x++)
|
||||||
|
{
|
||||||
|
float ramp = (float)(x / 255.f);
|
||||||
|
|
||||||
|
// Apply Contrast
|
||||||
|
// vec4 finalColor = vec4((((originalColor.rgb - vec3(0.5)) * Contrast) + vec3(0.5)), 1.0);
|
||||||
|
if (contrast != 1.0f)
|
||||||
|
ramp = (((ramp - 0.5f) * Contrast) + 0.5f);
|
||||||
|
|
||||||
|
// Apply Brightness
|
||||||
|
// vec4 finalColor = vec4(originalColor.rgb + Brightness, 1.0);
|
||||||
|
if (brightness != 0.0f)
|
||||||
|
ramp += (Brightness / 2.0f);
|
||||||
|
|
||||||
|
// Apply Gamma
|
||||||
|
// FragColor.rgb = pow(fragColor.rgb, vec3(1.0/gamma));
|
||||||
|
if (gamma != 1.0f)
|
||||||
|
ramp = pow(ramp, InvGamma);
|
||||||
|
|
||||||
|
// Clamp ramp
|
||||||
|
ramp = clamp<float>(ramp, 0.0f, 1.f);
|
||||||
|
|
||||||
|
gammatable[x] = (uint8_t)(ramp * 255);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void* dest;
|
||||||
|
const void* src;
|
||||||
|
int destpitch;
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
int srcpitch;
|
||||||
|
float gamma;
|
||||||
|
float contrast;
|
||||||
|
float brightness;
|
||||||
|
float saturation;
|
||||||
|
};
|
||||||
|
|
|
@ -538,12 +538,13 @@ static void MainFP(int x0, int x1, PolyTriangleThreadData* thread)
|
||||||
// frag = frag * vColor;
|
// frag = frag * vColor;
|
||||||
// frag.rgb = frag.rgb + uFogColor.rgb;
|
// frag.rgb = frag.rgb + uFogColor.rgb;
|
||||||
|
|
||||||
uint32_t startR = (int)((thread->mainVertexShader.Data.uObjectColor.r) * 255.0f);
|
// [GEC] I leave the default floating values.
|
||||||
uint32_t startG = (int)((thread->mainVertexShader.Data.uObjectColor.g) * 255.0f);
|
float startR = thread->mainVertexShader.Data.uObjectColor.r;
|
||||||
uint32_t startB = (int)((thread->mainVertexShader.Data.uObjectColor.b) * 255.0f);
|
float startG = thread->mainVertexShader.Data.uObjectColor.g;
|
||||||
uint32_t rangeR = (int)((thread->mainVertexShader.Data.uAddColor.r) * 255.0f) - startR;
|
float startB = thread->mainVertexShader.Data.uObjectColor.b;
|
||||||
uint32_t rangeG = (int)((thread->mainVertexShader.Data.uAddColor.g) * 255.0f) - startG;
|
float rangeR = thread->mainVertexShader.Data.uAddColor.r - startR;
|
||||||
uint32_t rangeB = (int)((thread->mainVertexShader.Data.uAddColor.b) * 255.0f) - startB;
|
float rangeG = thread->mainVertexShader.Data.uAddColor.g - startG;
|
||||||
|
float rangeB = thread->mainVertexShader.Data.uAddColor.b - startB;
|
||||||
|
|
||||||
for (int x = x0; x < x1; x++)
|
for (int x = x0; x < x1; x++)
|
||||||
{
|
{
|
||||||
|
@ -555,15 +556,22 @@ static void MainFP(int x0, int x1, PolyTriangleThreadData* thread)
|
||||||
uint32_t gray = (r * 77 + g * 143 + b * 37) >> 8;
|
uint32_t gray = (r * 77 + g * 143 + b * 37) >> 8;
|
||||||
gray += (gray >> 7); // gray*=256/255
|
gray += (gray >> 7); // gray*=256/255
|
||||||
|
|
||||||
r = (startR + ((gray * rangeR) >> 8)) << 1;
|
// [GEC] I use the same method as in shaders using floating values.
|
||||||
g = (startG + ((gray * rangeG) >> 8)) << 1;
|
// This avoids errors in the invulneravility colormap in Doom and Heretic.
|
||||||
b = (startB + ((gray * rangeB) >> 8)) << 1;
|
float fgray = (float)(gray / 255.f);
|
||||||
|
float fr = (startR + (fgray * rangeR)) * 2;
|
||||||
|
float fg = (startG + (fgray * rangeG)) * 2;
|
||||||
|
float fb = (startB + (fgray * rangeB)) * 2;
|
||||||
|
|
||||||
r = MIN(r, (uint32_t)255);
|
fr = clamp<float>(fr, 0.0f, 1.0f);
|
||||||
g = MIN(g, (uint32_t)255);
|
fg = clamp<float>(fg, 0.0f, 1.0f);
|
||||||
b = MIN(b, (uint32_t)255);
|
fb = clamp<float>(fb, 0.0f, 1.0f);
|
||||||
|
|
||||||
fragcolor[x] = MAKEARGB(a, r, g, b);
|
r = (uint32_t)(fr * 255.f);
|
||||||
|
g = (uint32_t)(fg * 255.f);
|
||||||
|
b = (uint32_t)(fb * 255.f);
|
||||||
|
|
||||||
|
fragcolor[x] = MAKEARGB(a, (uint8_t)r, (uint8_t)g, (uint8_t)b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -212,13 +212,18 @@ void VkRenderBuffers::CreateSceneNormal(int width, int height, VkSampleCountFlag
|
||||||
ImageBuilder builder;
|
ImageBuilder builder;
|
||||||
builder.setSize(width, height);
|
builder.setSize(width, height);
|
||||||
builder.setSamples(samples);
|
builder.setSamples(samples);
|
||||||
builder.setFormat(VK_FORMAT_A2R10G10B10_UNORM_PACK32);
|
builder.setFormat(SceneNormalFormat);
|
||||||
builder.setUsage(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT);
|
builder.setUsage(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT);
|
||||||
|
if (!builder.isFormatSupported(fb->device, VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT))
|
||||||
|
{
|
||||||
|
SceneNormalFormat = VK_FORMAT_R8G8B8A8_UNORM;
|
||||||
|
builder.setFormat(SceneNormalFormat);
|
||||||
|
}
|
||||||
SceneNormal.Image = builder.create(fb->device);
|
SceneNormal.Image = builder.create(fb->device);
|
||||||
SceneNormal.Image->SetDebugName("VkRenderBuffers.SceneNormal");
|
SceneNormal.Image->SetDebugName("VkRenderBuffers.SceneNormal");
|
||||||
|
|
||||||
ImageViewBuilder viewbuilder;
|
ImageViewBuilder viewbuilder;
|
||||||
viewbuilder.setImage(SceneNormal.Image.get(), VK_FORMAT_A2R10G10B10_UNORM_PACK32);
|
viewbuilder.setImage(SceneNormal.Image.get(), SceneNormalFormat);
|
||||||
SceneNormal.View = viewbuilder.create(fb->device);
|
SceneNormal.View = viewbuilder.create(fb->device);
|
||||||
SceneNormal.View->SetDebugName("VkRenderBuffers.SceneNormalView");
|
SceneNormal.View->SetDebugName("VkRenderBuffers.SceneNormalView");
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@ public:
|
||||||
VkTextureImage SceneFog;
|
VkTextureImage SceneFog;
|
||||||
|
|
||||||
VkFormat SceneDepthStencilFormat = VK_FORMAT_D24_UNORM_S8_UINT;
|
VkFormat SceneDepthStencilFormat = VK_FORMAT_D24_UNORM_S8_UINT;
|
||||||
|
VkFormat SceneNormalFormat = VK_FORMAT_A2R10G10B10_UNORM_PACK32;
|
||||||
|
|
||||||
static const int NumPipelineImages = 2;
|
static const int NumPipelineImages = 2;
|
||||||
VkTextureImage PipelineImage[NumPipelineImages];
|
VkTextureImage PipelineImage[NumPipelineImages];
|
||||||
|
|
|
@ -281,7 +281,7 @@ std::unique_ptr<VulkanRenderPass> VkRenderPassSetup::CreateRenderPass(int clearT
|
||||||
{
|
{
|
||||||
auto buffers = GetVulkanFrameBuffer()->GetBuffers();
|
auto buffers = GetVulkanFrameBuffer()->GetBuffers();
|
||||||
|
|
||||||
VkFormat drawBufferFormats[] = { VK_FORMAT_R16G16B16A16_SFLOAT, VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_A2R10G10B10_UNORM_PACK32 };
|
VkFormat drawBufferFormats[] = { VK_FORMAT_R16G16B16A16_SFLOAT, VK_FORMAT_R8G8B8A8_UNORM, buffers->SceneNormalFormat };
|
||||||
|
|
||||||
RenderPassBuilder builder;
|
RenderPassBuilder builder;
|
||||||
|
|
||||||
|
@ -420,6 +420,7 @@ std::unique_ptr<VulkanPipeline> VkRenderPassSetup::CreatePipeline(const VkPipeli
|
||||||
builder.setTopology(vktopology[key.DrawType]);
|
builder.setTopology(vktopology[key.DrawType]);
|
||||||
builder.setDepthStencilEnable(key.DepthTest, key.DepthWrite, key.StencilTest);
|
builder.setDepthStencilEnable(key.DepthTest, key.DepthWrite, key.StencilTest);
|
||||||
builder.setDepthFunc(depthfunc2vk[key.DepthFunc]);
|
builder.setDepthFunc(depthfunc2vk[key.DepthFunc]);
|
||||||
|
if (fb->device->UsedDeviceFeatures.depthClamp)
|
||||||
builder.setDepthClampEnable(key.DepthClamp);
|
builder.setDepthClampEnable(key.DepthClamp);
|
||||||
builder.setDepthBias(key.DepthBias, 0.0f, 0.0f, 0.0f);
|
builder.setDepthBias(key.DepthBias, 0.0f, 0.0f, 0.0f);
|
||||||
|
|
||||||
|
|
|
@ -163,9 +163,8 @@ static const char *shaderBindings = R"(
|
||||||
vec4 uSplitBottomPlane;
|
vec4 uSplitBottomPlane;
|
||||||
|
|
||||||
vec4 uDetailParms;
|
vec4 uDetailParms;
|
||||||
#ifdef NPOT_EMULATION
|
vec4 uNpotEmulation;
|
||||||
vec2 uNpotEmulation;
|
vec4 padding1, padding2, padding3;
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
layout(set = 0, binding = 3, std140) uniform StreamUBO {
|
layout(set = 0, binding = 3, std140) uniform StreamUBO {
|
||||||
|
@ -297,6 +296,9 @@ std::unique_ptr<VulkanShader> VkShaderManager::LoadFragShader(FString shadername
|
||||||
code << defines;
|
code << defines;
|
||||||
code << "\n$placeholder$"; // here the code can later add more needed #defines.
|
code << "\n$placeholder$"; // here the code can later add more needed #defines.
|
||||||
code << "\n#define MAX_STREAM_DATA " << std::to_string(MAX_STREAM_DATA).c_str() << "\n";
|
code << "\n#define MAX_STREAM_DATA " << std::to_string(MAX_STREAM_DATA).c_str() << "\n";
|
||||||
|
#ifdef NPOT_EMULATION
|
||||||
|
code << "#define NPOT_EMULATION\n";
|
||||||
|
#endif
|
||||||
code << shaderBindings;
|
code << shaderBindings;
|
||||||
FString placeholder = "\n";
|
FString placeholder = "\n";
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,7 @@ public:
|
||||||
void setMemoryType(VkMemoryPropertyFlags requiredFlags, VkMemoryPropertyFlags preferredFlags, uint32_t memoryTypeBits = 0);
|
void setMemoryType(VkMemoryPropertyFlags requiredFlags, VkMemoryPropertyFlags preferredFlags, uint32_t memoryTypeBits = 0);
|
||||||
void setLinearTiling();
|
void setLinearTiling();
|
||||||
|
|
||||||
bool isFormatSupported(VulkanDevice *device);
|
bool isFormatSupported(VulkanDevice *device, VkFormatFeatureFlags bufferFeatures = 0);
|
||||||
|
|
||||||
std::unique_ptr<VulkanImage> create(VulkanDevice *device, VkDeviceSize* allocatedBytes = nullptr);
|
std::unique_ptr<VulkanImage> create(VulkanDevice *device, VkDeviceSize* allocatedBytes = nullptr);
|
||||||
std::unique_ptr<VulkanImage> tryCreate(VulkanDevice *device);
|
std::unique_ptr<VulkanImage> tryCreate(VulkanDevice *device);
|
||||||
|
@ -410,7 +410,7 @@ inline void ImageBuilder::setMemoryType(VkMemoryPropertyFlags requiredFlags, VkM
|
||||||
allocInfo.memoryTypeBits = memoryTypeBits;
|
allocInfo.memoryTypeBits = memoryTypeBits;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool ImageBuilder::isFormatSupported(VulkanDevice *device)
|
inline bool ImageBuilder::isFormatSupported(VulkanDevice *device, VkFormatFeatureFlags bufferFeatures)
|
||||||
{
|
{
|
||||||
VkImageFormatProperties properties = { };
|
VkImageFormatProperties properties = { };
|
||||||
VkResult result = vkGetPhysicalDeviceImageFormatProperties(device->PhysicalDevice.Device, imageInfo.format, imageInfo.imageType, imageInfo.tiling, imageInfo.usage, imageInfo.flags, &properties);
|
VkResult result = vkGetPhysicalDeviceImageFormatProperties(device->PhysicalDevice.Device, imageInfo.format, imageInfo.imageType, imageInfo.tiling, imageInfo.usage, imageInfo.flags, &properties);
|
||||||
|
@ -421,6 +421,13 @@ inline bool ImageBuilder::isFormatSupported(VulkanDevice *device)
|
||||||
if (imageInfo.mipLevels > properties.maxMipLevels) return false;
|
if (imageInfo.mipLevels > properties.maxMipLevels) return false;
|
||||||
if (imageInfo.arrayLayers > properties.maxArrayLayers) return false;
|
if (imageInfo.arrayLayers > properties.maxArrayLayers) return false;
|
||||||
if ((imageInfo.samples & properties.sampleCounts) != imageInfo.samples) return false;
|
if ((imageInfo.samples & properties.sampleCounts) != imageInfo.samples) return false;
|
||||||
|
if (bufferFeatures != 0)
|
||||||
|
{
|
||||||
|
VkFormatProperties formatProperties = { };
|
||||||
|
vkGetPhysicalDeviceFormatProperties(device->PhysicalDevice.Device, imageInfo.format, &formatProperties);
|
||||||
|
if ((formatProperties.bufferFeatures & bufferFeatures) != bufferFeatures)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -108,8 +108,7 @@ bool VulkanDevice::CheckRequiredFeatures(const VkPhysicalDeviceFeatures &f)
|
||||||
{
|
{
|
||||||
return
|
return
|
||||||
f.samplerAnisotropy == VK_TRUE &&
|
f.samplerAnisotropy == VK_TRUE &&
|
||||||
f.fragmentStoresAndAtomics == VK_TRUE &&
|
f.fragmentStoresAndAtomics == VK_TRUE;
|
||||||
f.depthClamp == VK_TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VulkanDevice::SelectPhysicalDevice()
|
void VulkanDevice::SelectPhysicalDevice()
|
||||||
|
|
|
@ -390,7 +390,7 @@ void VulkanFrameBuffer::PrecacheMaterial(FMaterial *mat, int translation)
|
||||||
|
|
||||||
IHardwareTexture *VulkanFrameBuffer::CreateHardwareTexture(int numchannels)
|
IHardwareTexture *VulkanFrameBuffer::CreateHardwareTexture(int numchannels)
|
||||||
{
|
{
|
||||||
return new VkHardwareTexture();
|
return new VkHardwareTexture(numchannels);
|
||||||
}
|
}
|
||||||
|
|
||||||
FMaterial* VulkanFrameBuffer::CreateMaterial(FGameTexture* tex, int scaleflags)
|
FMaterial* VulkanFrameBuffer::CreateMaterial(FGameTexture* tex, int scaleflags)
|
||||||
|
|
|
@ -37,8 +37,9 @@
|
||||||
|
|
||||||
VkHardwareTexture *VkHardwareTexture::First = nullptr;
|
VkHardwareTexture *VkHardwareTexture::First = nullptr;
|
||||||
|
|
||||||
VkHardwareTexture::VkHardwareTexture()
|
VkHardwareTexture::VkHardwareTexture(int numchannels)
|
||||||
{
|
{
|
||||||
|
mTexelsize = numchannels;
|
||||||
Next = First;
|
Next = First;
|
||||||
First = this;
|
First = this;
|
||||||
if (Next) Next->Prev = this;
|
if (Next) Next->Prev = this;
|
||||||
|
@ -126,7 +127,8 @@ void VkHardwareTexture::CreateImage(FTexture *tex, int translation, int flags)
|
||||||
if (!tex->isHardwareCanvas())
|
if (!tex->isHardwareCanvas())
|
||||||
{
|
{
|
||||||
FTextureBuffer texbuffer = tex->CreateTexBuffer(translation, flags | CTF_ProcessData);
|
FTextureBuffer texbuffer = tex->CreateTexBuffer(translation, flags | CTF_ProcessData);
|
||||||
CreateTexture(texbuffer.mWidth, texbuffer.mHeight, 4, VK_FORMAT_B8G8R8A8_UNORM, texbuffer.mBuffer);
|
bool indexed = flags & CTF_Indexed;
|
||||||
|
CreateTexture(texbuffer.mWidth, texbuffer.mHeight,indexed? 1 : 4, indexed? VK_FORMAT_R8_UNORM : VK_FORMAT_B8G8R8A8_UNORM, texbuffer.mBuffer, !indexed);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -156,7 +158,7 @@ void VkHardwareTexture::CreateImage(FTexture *tex, int translation, int flags)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VkHardwareTexture::CreateTexture(int w, int h, int pixelsize, VkFormat format, const void *pixels)
|
void VkHardwareTexture::CreateTexture(int w, int h, int pixelsize, VkFormat format, const void *pixels, bool mipmap)
|
||||||
{
|
{
|
||||||
if (w <= 0 || h <= 0)
|
if (w <= 0 || h <= 0)
|
||||||
throw CVulkanError("Trying to create zero size texture");
|
throw CVulkanError("Trying to create zero size texture");
|
||||||
|
@ -177,7 +179,7 @@ void VkHardwareTexture::CreateTexture(int w, int h, int pixelsize, VkFormat form
|
||||||
|
|
||||||
ImageBuilder imgbuilder;
|
ImageBuilder imgbuilder;
|
||||||
imgbuilder.setFormat(format);
|
imgbuilder.setFormat(format);
|
||||||
imgbuilder.setSize(w, h, GetMipLevels(w, h));
|
imgbuilder.setSize(w, h, !mipmap ? 1 : GetMipLevels(w, h));
|
||||||
imgbuilder.setUsage(VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT);
|
imgbuilder.setUsage(VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT);
|
||||||
mImage.Image = imgbuilder.create(fb->device);
|
mImage.Image = imgbuilder.create(fb->device);
|
||||||
mImage.Image->SetDebugName("VkHardwareTexture.mImage");
|
mImage.Image->SetDebugName("VkHardwareTexture.mImage");
|
||||||
|
@ -203,7 +205,7 @@ void VkHardwareTexture::CreateTexture(int w, int h, int pixelsize, VkFormat form
|
||||||
|
|
||||||
fb->FrameDeleteList.Buffers.push_back(std::move(stagingBuffer));
|
fb->FrameDeleteList.Buffers.push_back(std::move(stagingBuffer));
|
||||||
|
|
||||||
mImage.GenerateMipmaps(cmdbuffer);
|
if (mipmap) mImage.GenerateMipmaps(cmdbuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
int VkHardwareTexture::GetMipLevels(int w, int h)
|
int VkHardwareTexture::GetMipLevels(int w, int h)
|
||||||
|
@ -268,6 +270,7 @@ uint8_t *VkHardwareTexture::MapBuffer()
|
||||||
|
|
||||||
unsigned int VkHardwareTexture::CreateTexture(unsigned char * buffer, int w, int h, int texunit, bool mipmap, const char *name)
|
unsigned int VkHardwareTexture::CreateTexture(unsigned char * buffer, int w, int h, int texunit, bool mipmap, const char *name)
|
||||||
{
|
{
|
||||||
|
CreateTexture(w, h, mTexelsize, mTexelsize == 4 ? VK_FORMAT_B8G8R8A8_UNORM : VK_FORMAT_R8_UNORM, buffer, mipmap);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -371,10 +374,6 @@ VulkanDescriptorSet* VkMaterial::GetDescriptorSet(const FMaterialState& state)
|
||||||
int clampmode = state.mClampMode;
|
int clampmode = state.mClampMode;
|
||||||
int translation = state.mTranslation;
|
int translation = state.mTranslation;
|
||||||
|
|
||||||
auto remap = translation <= 0 ? nullptr : GPalette.TranslationToTable(translation);
|
|
||||||
if (remap)
|
|
||||||
translation = remap->Index;
|
|
||||||
|
|
||||||
clampmode = base->GetClampMode(clampmode);
|
clampmode = base->GetClampMode(clampmode);
|
||||||
|
|
||||||
for (auto& set : mDescriptorSets)
|
for (auto& set : mDescriptorSets)
|
||||||
|
@ -395,11 +394,24 @@ VulkanDescriptorSet* VkMaterial::GetDescriptorSet(const FMaterialState& state)
|
||||||
MaterialLayerInfo *layer;
|
MaterialLayerInfo *layer;
|
||||||
auto systex = static_cast<VkHardwareTexture*>(GetLayer(0, state.mTranslation, &layer));
|
auto systex = static_cast<VkHardwareTexture*>(GetLayer(0, state.mTranslation, &layer));
|
||||||
update.addCombinedImageSampler(descriptor.get(), 0, systex->GetImage(layer->layerTexture, state.mTranslation, layer->scaleFlags)->View.get(), sampler, systex->mImage.Layout);
|
update.addCombinedImageSampler(descriptor.get(), 0, systex->GetImage(layer->layerTexture, state.mTranslation, layer->scaleFlags)->View.get(), sampler, systex->mImage.Layout);
|
||||||
|
|
||||||
|
if (!(layer->scaleFlags & CTF_Indexed))
|
||||||
|
{
|
||||||
for (int i = 1; i < numLayers; i++)
|
for (int i = 1; i < numLayers; i++)
|
||||||
{
|
{
|
||||||
auto systex = static_cast<VkHardwareTexture*>(GetLayer(i, 0, &layer));
|
auto systex = static_cast<VkHardwareTexture*>(GetLayer(i, 0, &layer));
|
||||||
update.addCombinedImageSampler(descriptor.get(), i, systex->GetImage(layer->layerTexture, 0, layer->scaleFlags)->View.get(), sampler, systex->mImage.Layout);
|
update.addCombinedImageSampler(descriptor.get(), i, systex->GetImage(layer->layerTexture, 0, layer->scaleFlags)->View.get(), sampler, systex->mImage.Layout);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (int i = 1; i < 3; i++)
|
||||||
|
{
|
||||||
|
auto systex = static_cast<VkHardwareTexture*>(GetLayer(i, translation, &layer));
|
||||||
|
update.addCombinedImageSampler(descriptor.get(), i, systex->GetImage(layer->layerTexture, 0, layer->scaleFlags)->View.get(), sampler, systex->mImage.Layout);
|
||||||
|
}
|
||||||
|
numLayers = 3;
|
||||||
|
}
|
||||||
|
|
||||||
auto dummyImage = fb->GetRenderPassManager()->GetNullTextureView();
|
auto dummyImage = fb->GetRenderPassManager()->GetNullTextureView();
|
||||||
for (int i = numLayers; i < SHADER_MIN_REQUIRED_TEXTURE_LAYERS; i++)
|
for (int i = numLayers; i < SHADER_MIN_REQUIRED_TEXTURE_LAYERS; i++)
|
||||||
|
|
|
@ -24,7 +24,7 @@ class VkHardwareTexture : public IHardwareTexture
|
||||||
{
|
{
|
||||||
friend class VkMaterial;
|
friend class VkMaterial;
|
||||||
public:
|
public:
|
||||||
VkHardwareTexture();
|
VkHardwareTexture(int numchannels);
|
||||||
~VkHardwareTexture();
|
~VkHardwareTexture();
|
||||||
|
|
||||||
static void ResetAll();
|
static void ResetAll();
|
||||||
|
@ -45,7 +45,7 @@ public:
|
||||||
private:
|
private:
|
||||||
void CreateImage(FTexture *tex, int translation, int flags);
|
void CreateImage(FTexture *tex, int translation, int flags);
|
||||||
|
|
||||||
void CreateTexture(int w, int h, int pixelsize, VkFormat format, const void *pixels);
|
void CreateTexture(int w, int h, int pixelsize, VkFormat format, const void *pixels, bool mipmap);
|
||||||
static int GetMipLevels(int w, int h);
|
static int GetMipLevels(int w, int h);
|
||||||
|
|
||||||
static VkHardwareTexture *First;
|
static VkHardwareTexture *First;
|
||||||
|
|
|
@ -605,13 +605,13 @@ void DStatusBarCore::DrawGraphic(FGameTexture* tex, double x, double y, int flag
|
||||||
//
|
//
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
void DStatusBarCore::DrawRotated(FTextureID texture, double x, double y, double angle, int flags, double Alpha, double scaleX, double scaleY, PalEntry color, int translation, ERenderStyle style)
|
void DStatusBarCore::DrawRotated(FTextureID texture, double x, double y, int flags, double angle, double Alpha, double scaleX, double scaleY, PalEntry color, int translation, ERenderStyle style)
|
||||||
{
|
{
|
||||||
if (!texture.isValid())
|
if (!texture.isValid())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
FGameTexture* tex = TexMan.GetGameTexture(texture, !(flags & DI_DONTANIMATE));
|
FGameTexture* tex = TexMan.GetGameTexture(texture, !(flags & DI_DONTANIMATE));
|
||||||
DrawRotated(tex, x, y, angle, flags, Alpha, scaleX, scaleY, color, translation, style);
|
DrawRotated(tex, x, y, flags, angle, Alpha, scaleX, scaleY, color, translation, style);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DStatusBarCore::DrawRotated(FGameTexture* tex, double x, double y, int flags, double angle, double Alpha, double scaleX, double scaleY, PalEntry color, int translation, ERenderStyle style)
|
void DStatusBarCore::DrawRotated(FGameTexture* tex, double x, double y, int flags, double angle, double Alpha, double scaleX, double scaleY, PalEntry color, int translation, ERenderStyle style)
|
||||||
|
|
|
@ -186,7 +186,7 @@ public:
|
||||||
void StatusbarToRealCoords(double& x, double& y, double& w, double& h) const;
|
void StatusbarToRealCoords(double& x, double& y, double& w, double& h) const;
|
||||||
void DrawGraphic(FGameTexture* texture, double x, double y, int flags, double Alpha, double boxwidth, double boxheight, double scaleX, double scaleY, PalEntry color = 0xffffffff, int translation = 0, ERenderStyle style = STYLE_Translucent, double clipwidth = -1.0);
|
void DrawGraphic(FGameTexture* texture, double x, double y, int flags, double Alpha, double boxwidth, double boxheight, double scaleX, double scaleY, PalEntry color = 0xffffffff, int translation = 0, ERenderStyle style = STYLE_Translucent, double clipwidth = -1.0);
|
||||||
void DrawGraphic(FTextureID texture, double x, double y, int flags, double Alpha, double boxwidth, double boxheight, double scaleX, double scaleY, PalEntry color = 0xffffffff, int translation = 0, ERenderStyle style = STYLE_Translucent, double clipwidth = -1.0);
|
void DrawGraphic(FTextureID texture, double x, double y, int flags, double Alpha, double boxwidth, double boxheight, double scaleX, double scaleY, PalEntry color = 0xffffffff, int translation = 0, ERenderStyle style = STYLE_Translucent, double clipwidth = -1.0);
|
||||||
void DrawRotated(FTextureID texture, double x, double y, double angle, int flags, double Alpha, double scaleX, double scaleY, PalEntry color = 0xffffffff, int translation = 0, ERenderStyle style = STYLE_Translucent);
|
void DrawRotated(FTextureID texture, double x, double y, int flags, double angle, double Alpha, double scaleX, double scaleY, PalEntry color = 0xffffffff, int translation = 0, ERenderStyle style = STYLE_Translucent);
|
||||||
void DrawRotated(FGameTexture* tex, double x, double y, int flags, double angle, double Alpha, double scaleX, double scaleY, PalEntry color = 0xffffffff, int translation = 0, ERenderStyle style = STYLE_Translucent);
|
void DrawRotated(FGameTexture* tex, double x, double y, int flags, double angle, double Alpha, double scaleX, double scaleY, PalEntry color = 0xffffffff, int translation = 0, ERenderStyle style = STYLE_Translucent);
|
||||||
void DrawString(FFont* font, const FString& cstring, double x, double y, int flags, double Alpha, int translation, int spacing, EMonospacing monospacing, int shadowX, int shadowY, double scaleX, double scaleY, int pt);
|
void DrawString(FFont* font, const FString& cstring, double x, double y, int flags, double Alpha, int translation, int spacing, EMonospacing monospacing, int shadowX, int shadowY, double scaleX, double scaleY, int pt);
|
||||||
void TransformRect(double& x, double& y, double& w, double& h, int flags = 0);
|
void TransformRect(double& x, double& y, double& w, double& h, int flags = 0);
|
||||||
|
|
|
@ -48,7 +48,6 @@ void AnimTexture::SetFrameSize(int format, int width, int height)
|
||||||
FTexture::SetSize(width, height);
|
FTexture::SetSize(width, height);
|
||||||
Image.Resize(width * height * (format == Paletted ? 1 : 3));
|
Image.Resize(width * height * (format == Paletted ? 1 : 3));
|
||||||
memset(Image.Data(), 0, Image.Size());
|
memset(Image.Data(), 0, Image.Size());
|
||||||
CleanHardwareTextures();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AnimTexture::SetFrame(const uint8_t* palette, const void* data_)
|
void AnimTexture::SetFrame(const uint8_t* palette, const void* data_)
|
||||||
|
@ -81,7 +80,6 @@ void AnimTexture::SetFrame(const uint8_t* palette, const void* data_)
|
||||||
}
|
}
|
||||||
else memcpy(Image.Data(), data_, Width * Height * (pixelformat == Paletted ? 1 : 3));
|
else memcpy(Image.Data(), data_, Width * Height * (pixelformat == Paletted ? 1 : 3));
|
||||||
}
|
}
|
||||||
CleanHardwareTextures();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
@ -156,10 +154,13 @@ void AnimTextures::SetSize(int format, int width, int height)
|
||||||
static_cast<AnimTexture*>(tex[1]->GetTexture())->SetFrameSize(format, width, height);
|
static_cast<AnimTexture*>(tex[1]->GetTexture())->SetFrameSize(format, width, height);
|
||||||
tex[0]->SetSize(width, height);
|
tex[0]->SetSize(width, height);
|
||||||
tex[1]->SetSize(width, height);
|
tex[1]->SetSize(width, height);
|
||||||
|
tex[0]->CleanHardwareData();
|
||||||
|
tex[1]->CleanHardwareData();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AnimTextures::SetFrame(const uint8_t* palette, const void* data)
|
void AnimTextures::SetFrame(const uint8_t* palette, const void* data)
|
||||||
{
|
{
|
||||||
active ^= 1;
|
active ^= 1;
|
||||||
static_cast<AnimTexture*>(tex[active]->GetTexture())->SetFrame(palette, data);
|
static_cast<AnimTexture*>(tex[active]->GetTexture())->SetFrame(palette, data);
|
||||||
|
tex[active]->CleanHardwareData();
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#include "v_video.h"
|
#include "v_video.h"
|
||||||
|
|
||||||
static IHardwareTexture* (*layercallback)(int layer, int translation);
|
static IHardwareTexture* (*layercallback)(int layer, int translation);
|
||||||
|
TArray<UserShaderDesc> usershaders;
|
||||||
|
|
||||||
void FMaterial::SetLayerCallback(IHardwareTexture* (*cb)(int layer, int translation))
|
void FMaterial::SetLayerCallback(IHardwareTexture* (*cb)(int layer, int translation))
|
||||||
{
|
{
|
||||||
|
|
|
@ -27,7 +27,6 @@ Modifications for JonoF's port by Jonathon Fowler (jf@jonof.id.au)
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
|
|
||||||
#include "automap.h"
|
#include "automap.h"
|
||||||
#include "cstat.h"
|
|
||||||
#include "c_dispatch.h"
|
#include "c_dispatch.h"
|
||||||
#include "c_cvars.h"
|
#include "c_cvars.h"
|
||||||
#include "gstrings.h"
|
#include "gstrings.h"
|
||||||
|
|
|
@ -366,24 +366,14 @@ inline FSerializer &Serialize(FSerializer &arc, const char *key, binangle &obj,
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// Constants and functions for use with fixedhoriz and friendly functions.
|
// Functions for use with fixedhoriz and friendly functions.
|
||||||
//
|
//
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
// 280039127 is the maximum horizon in Q16.16 the engine will handle before wrapping around.
|
inline double HorizToPitch(double horiz) { return atan2(horiz, 128) * (180. / pi::pi()); }
|
||||||
constexpr double horizDiff = 280039127 * 3. / 100.;
|
inline double HorizToPitch(fixed_t q16horiz) { return atan2(q16horiz, IntToFixed(128)) * (180. / pi::pi()); }
|
||||||
|
inline fixed_t PitchToHoriz(double pitch) { return xs_CRoundToInt(IntToFixed(128) * tan(pitch * (pi::pi() / 180.))); }
|
||||||
// Degrees needed to convert horizAngle into pitch degrees.
|
inline int32_t PitchToBAM(double pitch) { return xs_CRoundToInt(clamp(pitch * (1073741823.5 / 45.), -INT32_MAX, INT32_MAX)); }
|
||||||
constexpr double horizDegrees = 183.503609961216825;
|
|
||||||
|
|
||||||
// Ratio to convert inverse tangent to -90/90 degrees of pitch.
|
|
||||||
constexpr double horizRatio = horizDegrees / pi::pi();
|
|
||||||
|
|
||||||
// Horizon conversion functions.
|
|
||||||
inline double HorizToPitch(double horiz) { return atan2(horiz, horizDiff / 65536.) * horizRatio; }
|
|
||||||
inline double HorizToPitch(fixed_t q16horiz) { return atan2(q16horiz, horizDiff) * horizRatio; }
|
|
||||||
inline fixed_t PitchToHoriz(double horizAngle) { return xs_CRoundToInt(horizDiff * tan(horizAngle * (pi::pi() / horizDegrees))); }
|
|
||||||
inline int32_t PitchToBAM(double horizAngle) { return xs_CRoundToInt(clamp(horizAngle * (1073741823.5 / 45.), -INT32_MAX, INT32_MAX)); }
|
|
||||||
inline constexpr double BAMToPitch(int32_t bam) { return bam * (45. / 1073741823.5); }
|
inline constexpr double BAMToPitch(int32_t bam) { return bam * (45. / 1073741823.5); }
|
||||||
|
|
||||||
|
|
||||||
|
@ -512,54 +502,11 @@ inline FSerializer &Serialize(FSerializer &arc, const char *key, fixedhoriz &obj
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// Double-precision implementation of `getangle()` with associated wrappers and helper functions.
|
// High precision vector angle function, mainly for the renderer.
|
||||||
//
|
//
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
inline double bradarangf(double vect)
|
|
||||||
{
|
|
||||||
return atan(vect) * BRadAngScale;
|
|
||||||
}
|
|
||||||
inline double bvectangf(int32_t x, int32_t y)
|
|
||||||
{
|
|
||||||
if ((x | y) == 0)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else if (x == 0)
|
|
||||||
{
|
|
||||||
return 512 + ((y < 0) << 10);
|
|
||||||
}
|
|
||||||
else if (y == 0)
|
|
||||||
{
|
|
||||||
return ((x < 0) << 10);
|
|
||||||
}
|
|
||||||
else if (x == y)
|
|
||||||
{
|
|
||||||
return 256 + ((x < 0) << 10);
|
|
||||||
}
|
|
||||||
else if (x == -y)
|
|
||||||
{
|
|
||||||
return 768 + ((x > 0) << 10);
|
|
||||||
}
|
|
||||||
else if (abs(x) > abs(y))
|
|
||||||
{
|
|
||||||
return fmod(bradarangf(double(y) / x) + ((x < 0) << 10), 2048.);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return fmod(bradarangf(double(x) / -y) + 512 + ((y < 0) << 10), 2048.);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
inline int32_t bvectang(int32_t x, int32_t y)
|
|
||||||
{
|
|
||||||
return xs_CRoundToInt(bvectangf(x, y));
|
|
||||||
}
|
|
||||||
inline fixed_t bvectangq16(int32_t x, int32_t y)
|
|
||||||
{
|
|
||||||
return FloatToFixed(bvectangf(x, y));
|
|
||||||
}
|
|
||||||
inline binangle bvectangbam(int32_t x, int32_t y)
|
inline binangle bvectangbam(int32_t x, int32_t y)
|
||||||
{
|
{
|
||||||
return bamang(xs_CRoundToUInt(bvectangf(x, y) * BAMUNIT));
|
return radang(atan2(y, x));
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,6 +74,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
#include "v_draw.h"
|
#include "v_draw.h"
|
||||||
#include "gi.h"
|
#include "gi.h"
|
||||||
#include "gamefuncs.h"
|
#include "gamefuncs.h"
|
||||||
|
#include "hw_voxels.h"
|
||||||
|
#include "hw_palmanager.h"
|
||||||
|
|
||||||
CVAR(Bool, autoloadlights, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
CVAR(Bool, autoloadlights, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||||
CVAR(Bool, autoloadbrightmaps, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
CVAR(Bool, autoloadbrightmaps, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
||||||
|
@ -135,6 +137,7 @@ void SetConsoleNotifyBuffer();
|
||||||
bool PreBindTexture(FRenderState* state, FGameTexture*& tex, EUpscaleFlags& flags, int& scaleflags, int& clampmode, int& translation, int& overrideshader);
|
bool PreBindTexture(FRenderState* state, FGameTexture*& tex, EUpscaleFlags& flags, int& scaleflags, int& clampmode, int& translation, int& overrideshader);
|
||||||
void PostLoadSetup();
|
void PostLoadSetup();
|
||||||
void FontCharCreated(FGameTexture* base, FGameTexture* untranslated, FGameTexture* translated);
|
void FontCharCreated(FGameTexture* base, FGameTexture* untranslated, FGameTexture* translated);
|
||||||
|
void LoadVoxelModels();
|
||||||
|
|
||||||
DBaseStatusBar* StatusBar;
|
DBaseStatusBar* StatusBar;
|
||||||
|
|
||||||
|
@ -358,7 +361,7 @@ void UserConfig::ProcessOptions()
|
||||||
|
|
||||||
static const char* defs[] = { "-def", "-h", nullptr };
|
static const char* defs[] = { "-def", "-h", nullptr };
|
||||||
Args->CollectFiles("-def", defs, ".def");
|
Args->CollectFiles("-def", defs, ".def");
|
||||||
DefaultDef = Args->CheckValue("-def");
|
UserDef = Args->CheckValue("-def");
|
||||||
|
|
||||||
if (DefaultCon.IsEmpty())
|
if (DefaultCon.IsEmpty())
|
||||||
{
|
{
|
||||||
|
@ -582,10 +585,10 @@ int GameMain()
|
||||||
G_SaveConfig();
|
G_SaveConfig();
|
||||||
C_DeinitConsole();
|
C_DeinitConsole();
|
||||||
V_ClearFonts();
|
V_ClearFonts();
|
||||||
vox_deinit();
|
voxClear();
|
||||||
|
ClearPalManager();
|
||||||
TexMan.DeleteAll();
|
TexMan.DeleteAll();
|
||||||
TileFiles.CloseAll(); // delete the texture data before shutting down graphics.
|
TileFiles.CloseAll(); // delete the texture data before shutting down graphics.
|
||||||
GLInterface.Deinit();
|
|
||||||
I_ShutdownGraphics();
|
I_ShutdownGraphics();
|
||||||
freeallmodels();
|
freeallmodels();
|
||||||
if (gi)
|
if (gi)
|
||||||
|
@ -932,6 +935,12 @@ int RunGame()
|
||||||
enginePreInit();
|
enginePreInit();
|
||||||
SetupGameButtons();
|
SetupGameButtons();
|
||||||
gameinfo.mBackButton = "engine/graphics/m_back.png";
|
gameinfo.mBackButton = "engine/graphics/m_back.png";
|
||||||
|
|
||||||
|
GPalette.Init(MAXPALOOKUPS + 1); // one slot for each translation, plus a separate one for the base palettes.
|
||||||
|
gi->loadPalette();
|
||||||
|
voxInit();
|
||||||
|
TileFiles.LoadArtSet("tiles%03d.art"); // it's the same for all games.
|
||||||
|
engineInit();
|
||||||
gi->app_init();
|
gi->app_init();
|
||||||
CreateStatusBar();
|
CreateStatusBar();
|
||||||
SetDefaultMenuColors();
|
SetDefaultMenuColors();
|
||||||
|
@ -943,7 +952,22 @@ int RunGame()
|
||||||
V_LoadTranslations(); // loading the translations must be delayed until the palettes have been fully set up.
|
V_LoadTranslations(); // loading the translations must be delayed until the palettes have been fully set up.
|
||||||
lookups.postLoadTables();
|
lookups.postLoadTables();
|
||||||
PostLoadSetup();
|
PostLoadSetup();
|
||||||
videoInit();
|
lookups.postLoadLookups();
|
||||||
|
FMaterial::SetLayerCallback(setpalettelayer);
|
||||||
|
|
||||||
|
V_Init2();
|
||||||
|
twod->Begin(screen->GetWidth(), screen->GetHeight());
|
||||||
|
twod->End();
|
||||||
|
UpdateJoystickMenu(NULL);
|
||||||
|
UpdateVRModes();
|
||||||
|
|
||||||
|
setVideoMode();
|
||||||
|
|
||||||
|
LoadVoxelModels();
|
||||||
|
GLInterface.Init(screen->GetWidth());
|
||||||
|
screen->BeginFrame();
|
||||||
|
screen->SetTextureFilterMode();
|
||||||
|
setViewport(hud_size);
|
||||||
|
|
||||||
D_CheckNetGame();
|
D_CheckNetGame();
|
||||||
UpdateGenericUI(ui_generic);
|
UpdateGenericUI(ui_generic);
|
||||||
|
@ -1011,7 +1035,7 @@ void updatePauseStatus()
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
void PolymostProcessVoxels(void);
|
void LoadVoxelModels(void);
|
||||||
|
|
||||||
void setVideoMode()
|
void setVideoMode()
|
||||||
{
|
{
|
||||||
|
@ -1022,24 +1046,6 @@ void setVideoMode()
|
||||||
videoClearScreen(0);
|
videoClearScreen(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void videoInit()
|
|
||||||
{
|
|
||||||
lookups.postLoadLookups();
|
|
||||||
V_Init2();
|
|
||||||
setVideoMode();
|
|
||||||
|
|
||||||
PolymostProcessVoxels();
|
|
||||||
GLInterface.Init(screen->GetWidth());
|
|
||||||
screen->BeginFrame();
|
|
||||||
screen->SetTextureFilterMode();
|
|
||||||
setViewport(hud_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void G_FatalEngineError(void)
|
|
||||||
{
|
|
||||||
I_FatalError("There was a problem initializing the engine: %s\n\nThe application will now close.", engineerrstr);
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
|
@ -1326,27 +1332,50 @@ void DrawCrosshair(int deftile, int health, double xdelta, double ydelta, double
|
||||||
|
|
||||||
void LoadDefinitions()
|
void LoadDefinitions()
|
||||||
{
|
{
|
||||||
loaddefinitionsfile("engine/engine.def"); // Internal stuff that is required.
|
|
||||||
|
|
||||||
const char* defsfile = G_DefFile();
|
|
||||||
|
|
||||||
cycle_t deftimer;
|
cycle_t deftimer;
|
||||||
deftimer.Reset();
|
deftimer.Reset();
|
||||||
deftimer.Clock();
|
deftimer.Clock();
|
||||||
if (!loaddefinitionsfile(defsfile, true))
|
const char* loaded = nullptr;
|
||||||
|
|
||||||
|
const char* defsfile = G_DefFile();
|
||||||
|
FString razedefsfile = defsfile;
|
||||||
|
razedefsfile.Substitute(".def", "-raze.def");
|
||||||
|
|
||||||
|
loaddefinitionsfile("engine/engine.def", false); // Internal stuff that is required.
|
||||||
|
|
||||||
|
// check what we have.
|
||||||
|
// user .defs override the default ones and are not cumulative.
|
||||||
|
// if we fine even one Raze-specific file, all of those will be loaded cumulatively.
|
||||||
|
// otherwise the default rules inherited from older ports apply.
|
||||||
|
if (userConfig.UserDef.IsNotEmpty())
|
||||||
|
{
|
||||||
|
if (!loaddefinitionsfile(userConfig.UserDef, true, false)) loaded = userConfig.UserDef;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (fileSystem.FileExists(razedefsfile))
|
||||||
|
{
|
||||||
|
if (!loaddefinitionsfile(razedefsfile, true, true)) loaded = razedefsfile;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!loaddefinitionsfile(defsfile, true, false)) loaded = defsfile;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (loaded)
|
||||||
{
|
{
|
||||||
deftimer.Unclock();
|
deftimer.Unclock();
|
||||||
Printf(PRINT_NONOTIFY, "Definitions file \"%s\" loaded in %.3f ms.\n", defsfile, deftimer.TimeMS());
|
DPrintf(DMSG_SPAMMY, "Definitions file \"%s\" loaded, %f ms.\n", loaded, deftimer.TimeMS());
|
||||||
}
|
}
|
||||||
userConfig.AddDefs.reset();
|
userConfig.AddDefs.reset();
|
||||||
|
|
||||||
// load the widescreen replacements last so that they do not clobber the CRC for the original items so that mod-side replacement are picked up.
|
// load the widescreen replacements last. This ensures that mods still get the correct CRCs for their own tile replacements.
|
||||||
if (fileSystem.FindFile("engine/widescreen.def") >= 0 && !Args->CheckParm("-nowidescreen"))
|
if (fileSystem.FindFile("engine/widescreen.def") >= 0 && !Args->CheckParm("-nowidescreen"))
|
||||||
{
|
{
|
||||||
loaddefinitionsfile("engine/widescreen.def");
|
loaddefinitionsfile("engine/widescreen.def");
|
||||||
}
|
}
|
||||||
|
fileSystem.InitHashChains(); // make sure that any resources that got added can be found again.
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool M_Active()
|
bool M_Active()
|
||||||
|
@ -1417,3 +1446,10 @@ DEFINE_GLOBAL(gameaction)
|
||||||
DEFINE_GLOBAL(gamestate)
|
DEFINE_GLOBAL(gamestate)
|
||||||
DEFINE_GLOBAL(demoplayback)
|
DEFINE_GLOBAL(demoplayback)
|
||||||
DEFINE_GLOBAL(consoleplayer)
|
DEFINE_GLOBAL(consoleplayer)
|
||||||
|
|
||||||
|
|
||||||
|
void InitBuildTiles()
|
||||||
|
{
|
||||||
|
// need to find a better way to handle this thing.
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -65,6 +65,7 @@ struct UserConfig
|
||||||
{
|
{
|
||||||
FString gamegrp;
|
FString gamegrp;
|
||||||
FString CommandMap;
|
FString CommandMap;
|
||||||
|
FString UserDef;
|
||||||
FString DefaultDef;
|
FString DefaultDef;
|
||||||
FString DefaultCon;
|
FString DefaultCon;
|
||||||
FString CommandDemo;
|
FString CommandDemo;
|
||||||
|
@ -221,7 +222,6 @@ void S_PauseSound(bool notmusic, bool notsfx);
|
||||||
void S_ResumeSound(bool notsfx);
|
void S_ResumeSound(bool notsfx);
|
||||||
void S_SetSoundPaused(int state);
|
void S_SetSoundPaused(int state);
|
||||||
|
|
||||||
void G_FatalEngineError(void);
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
MaxSmoothRatio = FRACUNIT
|
MaxSmoothRatio = FRACUNIT
|
||||||
|
|
|
@ -148,28 +148,6 @@ bool calcChaseCamPos(int* px, int* py, int* pz, spritetype* pspr, short *psectnu
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
bool spriteIsModelOrVoxel(const spritetype * tspr)
|
|
||||||
{
|
|
||||||
if ((unsigned)tspr->owner < MAXSPRITES && spriteext[tspr->owner].flags & SPREXT_NOTMD)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (hw_models)
|
|
||||||
{
|
|
||||||
auto& mdinfo = tile2model[Ptile2tile(tspr->picnum, tspr->pal)];
|
|
||||||
if (mdinfo.modelid >= 0 && mdinfo.framenum >= 0) return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto slabalign = (tspr->cstat & CSTAT_SPRITE_ALIGNMENT) == CSTAT_SPRITE_ALIGNMENT_SLAB;
|
|
||||||
if (r_voxels && !slabalign && tiletovox[tspr->picnum] >= 0 && voxmodels[tiletovox[tspr->picnum]]) return true;
|
|
||||||
return (slabalign && voxmodels[tspr->picnum]);
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// note that this returns values in renderer coordinate space with inverted sign!
|
// note that this returns values in renderer coordinate space with inverted sign!
|
||||||
|
@ -213,10 +191,10 @@ void GetWallSpritePosition(const spritetype* spr, vec2_t pos, vec2_t* out, bool
|
||||||
auto tex = tileGetTexture(spr->picnum);
|
auto tex = tileGetTexture(spr->picnum);
|
||||||
|
|
||||||
int width, leftofs;
|
int width, leftofs;
|
||||||
if (render && hw_hightile && TileFiles.tiledata[spr->picnum].h_xsize)
|
if (render && hw_hightile && TileFiles.tiledata[spr->picnum].hiofs.xsize)
|
||||||
{
|
{
|
||||||
width = TileFiles.tiledata[spr->picnum].h_xsize;
|
width = TileFiles.tiledata[spr->picnum].hiofs.xsize;
|
||||||
leftofs = (TileFiles.tiledata[spr->picnum].h_xoffs + spr->xoffset);
|
leftofs = (TileFiles.tiledata[spr->picnum].hiofs.xoffs + spr->xoffset);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -249,12 +227,12 @@ void GetFlatSpritePosition(const spritetype* spr, vec2_t pos, vec2_t* out, bool
|
||||||
auto tex = tileGetTexture(spr->picnum);
|
auto tex = tileGetTexture(spr->picnum);
|
||||||
|
|
||||||
int width, height, leftofs, topofs;
|
int width, height, leftofs, topofs;
|
||||||
if (render && hw_hightile && TileFiles.tiledata[spr->picnum].h_xsize)
|
if (render && hw_hightile && TileFiles.tiledata[spr->picnum].hiofs.xsize)
|
||||||
{
|
{
|
||||||
width = TileFiles.tiledata[spr->picnum].h_xsize * spr->xrepeat;
|
width = TileFiles.tiledata[spr->picnum].hiofs.xsize * spr->xrepeat;
|
||||||
height = TileFiles.tiledata[spr->picnum].h_ysize * spr->yrepeat;
|
height = TileFiles.tiledata[spr->picnum].hiofs.ysize * spr->yrepeat;
|
||||||
leftofs = (TileFiles.tiledata[spr->picnum].h_xoffs + spr->xoffset) * spr->xrepeat;
|
leftofs = (TileFiles.tiledata[spr->picnum].hiofs.xoffs + spr->xoffset) * spr->xrepeat;
|
||||||
topofs = (TileFiles.tiledata[spr->picnum].h_yoffs + spr->yoffset) * spr->yrepeat;
|
topofs = (TileFiles.tiledata[spr->picnum].hiofs.yoffs + spr->yoffset) * spr->yrepeat;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
extern int cameradist, cameraclock;
|
extern int cameradist, cameraclock;
|
||||||
|
|
||||||
bool calcChaseCamPos(int* px, int* py, int* pz, spritetype* pspr, short *psectnum, binangle ang, fixedhoriz horiz, double const smoothratio);
|
bool calcChaseCamPos(int* px, int* py, int* pz, spritetype* pspr, short *psectnum, binangle ang, fixedhoriz horiz, double const smoothratio);
|
||||||
bool spriteIsModelOrVoxel(const spritetype* tspr);
|
|
||||||
void PlanesAtPoint(const sectortype* sec, float dax, float day, float* ceilz, float* florz);
|
void PlanesAtPoint(const sectortype* sec, float dax, float day, float* ceilz, float* florz);
|
||||||
void setWallSectors();
|
void setWallSectors();
|
||||||
void GetWallSpritePosition(const spritetype* spr, vec2_t pos, vec2_t* out, bool render = false);
|
void GetWallSpritePosition(const spritetype* spr, vec2_t pos, vec2_t* out, bool render = false);
|
||||||
|
|
|
@ -274,6 +274,18 @@ static void DeleteStuff(FileSystem &fileSystem, const TArray<FString>& deletelum
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
const char* iwad_folders[13] = { "textures/", "hires/", "sounds/", "music/", "maps/" };
|
||||||
|
const char* iwad_reserved_duke[12] = { ".map", ".con", "menudef", "gldefs", "zscript", "maps/", nullptr };
|
||||||
|
const char* iwad_reserved_blood[12] = { ".map", ".ini", "menudef", "gldefs", "zscript", "maps/", nullptr };
|
||||||
|
const char* iwad_reserved_sw[12] = { ".map", "swcustom.txt", "menudef", "gldefs", "zscript", "maps/", nullptr };
|
||||||
|
const char* iwad_reserved_ex[12] = { ".map", "menudef", "gldefs", "zscript", "maps/", nullptr };
|
||||||
|
|
||||||
|
const char** iwad_reserved()
|
||||||
|
{
|
||||||
|
return (g_gameType & GAMEFLAG_PSEXHUMED) ? iwad_reserved_ex :
|
||||||
|
(g_gameType & GAMEFLAG_SW) ? iwad_reserved_sw :
|
||||||
|
(g_gameType & GAMEFLAG_BLOOD) ? iwad_reserved_blood : iwad_reserved_duke;
|
||||||
|
}
|
||||||
|
|
||||||
void InitFileSystem(TArray<GrpEntry>& groups)
|
void InitFileSystem(TArray<GrpEntry>& groups)
|
||||||
{
|
{
|
||||||
|
@ -374,6 +386,8 @@ void InitFileSystem(TArray<GrpEntry>& groups)
|
||||||
}
|
}
|
||||||
todelete.Append(userConfig.toBeDeleted);
|
todelete.Append(userConfig.toBeDeleted);
|
||||||
LumpFilterInfo lfi;
|
LumpFilterInfo lfi;
|
||||||
|
for (auto p : iwad_folders) lfi.reservedFolders.Push(p);
|
||||||
|
for (auto p = iwad_reserved(); *p; p++) lfi.requiredPrefixes.Push(*p);
|
||||||
|
|
||||||
lfi.dotFilter = LumpFilter;
|
lfi.dotFilter = LumpFilter;
|
||||||
|
|
||||||
|
|
|
@ -189,6 +189,7 @@ static void GameTicker()
|
||||||
case ga_newgame:
|
case ga_newgame:
|
||||||
FX_StopAllSounds();
|
FX_StopAllSounds();
|
||||||
case ga_newgamenostopsound:
|
case ga_newgamenostopsound:
|
||||||
|
DeleteScreenJob();
|
||||||
newGameStarted = true;
|
newGameStarted = true;
|
||||||
FX_SetReverb(0);
|
FX_SetReverb(0);
|
||||||
gi->FreeLevelData();
|
gi->FreeLevelData();
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
#include "raze_music.h"
|
#include "raze_music.h"
|
||||||
#include "filesystem.h"
|
#include "filesystem.h"
|
||||||
#include "printf.h"
|
#include "printf.h"
|
||||||
|
#include "raze_sound.h"
|
||||||
|
|
||||||
FString gSkillNames[MAXSKILLS];
|
FString gSkillNames[MAXSKILLS];
|
||||||
FString gVolumeNames[MAXVOLUMES];
|
FString gVolumeNames[MAXVOLUMES];
|
||||||
|
@ -109,7 +110,8 @@ bool SetMusicForMap(const char* mapname, const char* music, bool namehack)
|
||||||
{
|
{
|
||||||
if (!stricmp(mapname, specials[i]))
|
if (!stricmp(mapname, specials[i]))
|
||||||
{
|
{
|
||||||
// todo: store this properly.
|
if (specialmusic.Size() <= i) specialmusic.Resize(i + 1);
|
||||||
|
specialmusic[i] = music;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -127,7 +129,7 @@ bool SetMusicForMap(const char* mapname, const char* music, bool namehack)
|
||||||
if (numMatches != 4 || toupper(b1) != 'E' || toupper(b2) != 'L')
|
if (numMatches != 4 || toupper(b1) != 'E' || toupper(b2) != 'L')
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
index = FindMapByLevelNum(ep*100 + lev);
|
index = FindMapByLevelNum(levelnum(ep - 1, lev - 1));
|
||||||
|
|
||||||
}
|
}
|
||||||
if (index != nullptr)
|
if (index != nullptr)
|
||||||
|
|
|
@ -742,3 +742,29 @@ DEFINE_ACTION_FUNCTION(_PlayerMenu, DrawPlayerSprite)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
EXTERN_CVAR(Bool, vr_enable_quadbuffered)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void UpdateVRModes(bool considerQuadBuffered)
|
||||||
|
{
|
||||||
|
FOptionValues** pVRModes = OptionValues.CheckKey("VRMode");
|
||||||
|
if (pVRModes == nullptr) return;
|
||||||
|
|
||||||
|
TArray<FOptionValues::Pair>& vals = (*pVRModes)->mValues;
|
||||||
|
TArray<FOptionValues::Pair> filteredValues;
|
||||||
|
int cnt = vals.Size();
|
||||||
|
for (int i = 0; i < cnt; ++i) {
|
||||||
|
auto const& mode = vals[i];
|
||||||
|
if (mode.Value == 7) { // Quad-buffered stereo
|
||||||
|
#ifdef _WIN32
|
||||||
|
if (!vr_enable_quadbuffered) continue;
|
||||||
|
#else
|
||||||
|
continue; // Remove quad-buffered option on Mac and Linux
|
||||||
|
#endif
|
||||||
|
if (!considerQuadBuffered) continue; // Probably no compatible screen mode was found
|
||||||
|
}
|
||||||
|
filteredValues.Push(mode);
|
||||||
|
}
|
||||||
|
vals = filteredValues;
|
||||||
|
}
|
||||||
|
|
406
source/core/parsefuncs.h
Normal file
406
source/core/parsefuncs.h
Normal file
|
@ -0,0 +1,406 @@
|
||||||
|
|
||||||
|
/*
|
||||||
|
** parsefuncs.h
|
||||||
|
** handlers for .def parser
|
||||||
|
** only to be included by the actual parser
|
||||||
|
**
|
||||||
|
**---------------------------------------------------------------------------
|
||||||
|
** Copyright 2021 Christoph Oelckers
|
||||||
|
** All rights reserved.
|
||||||
|
**
|
||||||
|
** Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions
|
||||||
|
** are met:
|
||||||
|
**
|
||||||
|
** 1. Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in the
|
||||||
|
** documentation and/or other materials provided with the distribution.
|
||||||
|
** 3. The name of the author may not be used to endorse or promote products
|
||||||
|
** derived from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
**---------------------------------------------------------------------------
|
||||||
|
**
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
|
||||||
|
int tileSetHightileReplacement(int picnum, int palnum, const char* filename, float alphacut, float xscale, float yscale, float specpower, float specfactor);
|
||||||
|
int tileSetSkybox(int picnum, int palnum, FString* facenames);
|
||||||
|
void tileRemoveReplacement(int num);
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
template<int cnt>
|
||||||
|
void parseSkip(FScanner& sc, FScriptPosition& pos)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < cnt; i++) if (!sc.GetString()) return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void parseDefine(FScanner& sc, FScriptPosition& pos)
|
||||||
|
{
|
||||||
|
FString name;
|
||||||
|
if (!sc.GetString(name)) return;
|
||||||
|
if (!sc.GetNumber()) return;
|
||||||
|
sc.AddSymbol(name, sc.Number);
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
void parseDefineTexture(FScanner& sc, FScriptPosition& pos)
|
||||||
|
{
|
||||||
|
int tile, palette;
|
||||||
|
|
||||||
|
if (!sc.GetNumber(tile, true)) return;
|
||||||
|
if (!sc.GetNumber(palette, true)) return;
|
||||||
|
if (!sc.GetNumber(true)) return; //formerly x-center, unused
|
||||||
|
if (!sc.GetNumber(true)) return; //formerly y-center, unused
|
||||||
|
if (!sc.GetNumber(true)) return; //formerly x-size, unused
|
||||||
|
if (!sc.GetNumber(true)) return; //formerly y-size, unused
|
||||||
|
if (!sc.GetString()) return;
|
||||||
|
|
||||||
|
tileSetHightileReplacement(tile, palette, sc.String, -1.0, 1.0, 1.0, 1.0, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
static void parseTexturePaletteBlock(FScanner& sc, FScriptPosition& pos, int tile)
|
||||||
|
{
|
||||||
|
FScanner::SavedPos blockend;
|
||||||
|
|
||||||
|
int pal = -1, xsiz = 0, ysiz = 0;
|
||||||
|
FString fn;
|
||||||
|
double alphacut = -1.0, xscale = 1.0, yscale = 1.0, specpower = 1.0, specfactor = 1.0;
|
||||||
|
|
||||||
|
if (!sc.GetNumber(pal, true)) return;
|
||||||
|
|
||||||
|
if (sc.StartBraces(&blockend)) return;
|
||||||
|
while (!sc.FoundEndBrace(blockend))
|
||||||
|
{
|
||||||
|
sc.GetString();
|
||||||
|
if (sc.Compare("file")) sc.GetString(fn);
|
||||||
|
else if (sc.Compare("alphacut")) sc.GetFloat(alphacut, true);
|
||||||
|
else if (sc.Compare({ "xscale", "scale", "intensity", "detailscale" })) sc.GetFloat(xscale, true); // what's the point of all of these names?
|
||||||
|
else if (sc.Compare("yscale")) sc.GetFloat(yscale, true);
|
||||||
|
else if (sc.Compare({ "specpower", "specularpower", "parallaxscale" })) sc.GetFloat(specpower, true);
|
||||||
|
else if (sc.Compare({ "specfactor", "specularfactor", "parallaxbias" })) sc.GetFloat(specfactor, true);
|
||||||
|
else if (sc.Compare("orig_sizex")) sc.GetNumber(xsiz, true);
|
||||||
|
else if (sc.Compare("orig_sizey")) sc.GetNumber(ysiz, true);
|
||||||
|
};
|
||||||
|
|
||||||
|
if ((unsigned)tile < MAXUSERTILES)
|
||||||
|
{
|
||||||
|
if ((unsigned)pal >= MAXPALOOKUPS - RESERVEDPALS)
|
||||||
|
{
|
||||||
|
pos.Message(MSG_ERROR, "missing or invalid 'palette number' for texture definition");
|
||||||
|
}
|
||||||
|
else if (fn.IsEmpty())
|
||||||
|
{
|
||||||
|
pos.Message(MSG_ERROR, "missing 'file name' for texture definition");
|
||||||
|
}
|
||||||
|
else if (!fileSystem.FileExists(fn))
|
||||||
|
{
|
||||||
|
pos.Message(MSG_ERROR, "%s not found in replacement for tile %d", fn.GetChars(), tile);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (xsiz > 0 && ysiz > 0)
|
||||||
|
{
|
||||||
|
tileSetDummy(tile, xsiz, ysiz);
|
||||||
|
}
|
||||||
|
xscale = 1.0f / xscale;
|
||||||
|
yscale = 1.0f / yscale;
|
||||||
|
|
||||||
|
tileSetHightileReplacement(tile, pal, fn, alphacut, xscale, yscale, specpower, specfactor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void parseTextureSpecialBlock(FScanner& sc, FScriptPosition& pos, int tile, int specialpal)
|
||||||
|
{
|
||||||
|
FScanner::SavedPos blockend;
|
||||||
|
|
||||||
|
int pal = -1;
|
||||||
|
FString fn;
|
||||||
|
double xscale = 1.0, yscale = 1.0, specpower = 1.0, specfactor = 1.0;
|
||||||
|
|
||||||
|
if (!sc.GetNumber(pal, true)) return;
|
||||||
|
|
||||||
|
if (sc.StartBraces(&blockend)) return;
|
||||||
|
while (!sc.FoundEndBrace(blockend))
|
||||||
|
{
|
||||||
|
sc.GetString();
|
||||||
|
if (sc.Compare("file")) sc.GetString(fn);
|
||||||
|
else if (sc.Compare({ "xscale", "scale", "intensity", "detailscale" })) sc.GetFloat(xscale, true); // what's the point of all of these names?
|
||||||
|
else if (sc.Compare("yscale")) sc.GetFloat(yscale, true);
|
||||||
|
else if (sc.Compare({ "specpower", "specularpower", "parallaxscale" })) sc.GetFloat(specpower, true);
|
||||||
|
else if (sc.Compare({ "specfactor", "specularfactor", "parallaxbias" })) sc.GetFloat(specfactor, true);
|
||||||
|
};
|
||||||
|
|
||||||
|
if ((unsigned)tile < MAXUSERTILES)
|
||||||
|
{
|
||||||
|
if (fn.IsEmpty())
|
||||||
|
{
|
||||||
|
pos.Message(MSG_ERROR, "missing 'file name' for texture definition");
|
||||||
|
}
|
||||||
|
else if (!fileSystem.FileExists(fn))
|
||||||
|
{
|
||||||
|
pos.Message(MSG_ERROR, "%s not found in replacement for tile %d", fn.GetChars(), tile);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (pal == DETAILPAL)
|
||||||
|
{
|
||||||
|
xscale = 1.0f / xscale;
|
||||||
|
yscale = 1.0f / yscale;
|
||||||
|
}
|
||||||
|
|
||||||
|
tileSetHightileReplacement(tile, pal, fn, -1.f, xscale, yscale, specpower, specfactor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void parseTexture(FScanner& sc, FScriptPosition& pos)
|
||||||
|
{
|
||||||
|
FScanner::SavedPos blockend;
|
||||||
|
int tile = -1;
|
||||||
|
|
||||||
|
if (!sc.GetNumber(tile, true)) return;
|
||||||
|
ValidateTilenum("texture", tile, pos); // do not abort, we still need to parse over the data.
|
||||||
|
|
||||||
|
if (sc.StartBraces(&blockend)) return;
|
||||||
|
while (!sc.FoundEndBrace(blockend))
|
||||||
|
{
|
||||||
|
sc.MustGetString();
|
||||||
|
if (sc.Compare("pal")) parseTexturePaletteBlock(sc, pos, tile);
|
||||||
|
else if (sc.Compare("detail")) parseTextureSpecialBlock(sc, pos, tile, DETAILPAL);
|
||||||
|
else if (sc.Compare("glow")) parseTextureSpecialBlock(sc, pos, tile, GLOWPAL);
|
||||||
|
else if (sc.Compare("specular")) parseTextureSpecialBlock(sc, pos, tile, SPECULARPAL);
|
||||||
|
else if (sc.Compare("normal")) parseTextureSpecialBlock(sc, pos, tile, NORMALPAL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
void parseDefineSkybox(FScanner& sc, FScriptPosition& pos)
|
||||||
|
{
|
||||||
|
int tile, palette;
|
||||||
|
FString fn[6];
|
||||||
|
|
||||||
|
if (!sc.GetNumber(tile, true)) return;
|
||||||
|
if (!sc.GetNumber(palette, true)) return;
|
||||||
|
if (!sc.GetNumber(true)) return; //'future extension' (for what?)
|
||||||
|
for (int i = 0; i < 6; i++)
|
||||||
|
{
|
||||||
|
if (!sc.GetString()) return;
|
||||||
|
fn[i] = sc.String;
|
||||||
|
}
|
||||||
|
tileSetSkybox(tile, palette, fn);
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
void parseSkybox(FScanner& sc, FScriptPosition& pos)
|
||||||
|
{
|
||||||
|
FString faces[6];
|
||||||
|
FScanner::SavedPos blockend;
|
||||||
|
int tile = -1, pal = 0;
|
||||||
|
|
||||||
|
if (sc.StartBraces(&blockend)) return;
|
||||||
|
while (!sc.FoundEndBrace(blockend))
|
||||||
|
{
|
||||||
|
sc.MustGetString();
|
||||||
|
if (sc.Compare("tile")) sc.GetNumber(tile, true);
|
||||||
|
else if (sc.Compare("pal")) sc.GetNumber(pal, true);
|
||||||
|
else if (sc.Compare({ "ft", "front", "forward" })) sc.GetString(faces[0]);
|
||||||
|
else if (sc.Compare({ "rt", "right" })) sc.GetString(faces[1]);
|
||||||
|
else if (sc.Compare({ "bk", "back" })) sc.GetString(faces[2]);
|
||||||
|
else if (sc.Compare({ "lt", "lf", "left" })) sc.GetString(faces[3]);
|
||||||
|
else if (sc.Compare({ "up", "ceiling", "top", "ceil" })) sc.GetString(faces[4]);
|
||||||
|
else if (sc.Compare({ "dn", "floor", "bottom", "down" })) sc.GetString(faces[5]);
|
||||||
|
// skip over everything else.
|
||||||
|
}
|
||||||
|
if (tile < 0)
|
||||||
|
{
|
||||||
|
pos.Message(MSG_ERROR, "skybox: missing tile number");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
tileSetSkybox(tile, pal, faces);
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
void parseSetupTile(FScanner& sc, FScriptPosition& pos)
|
||||||
|
{
|
||||||
|
int tile;
|
||||||
|
if (!sc.GetNumber(tile, true)) return;
|
||||||
|
if (!ValidateTilenum("setuptile", tile, pos)) return;
|
||||||
|
auto& tiled = TileFiles.tiledata[tile];
|
||||||
|
if (!sc.GetNumber(tiled.hiofs.xsize, true)) return;
|
||||||
|
if (!sc.GetNumber(tiled.hiofs.ysize, true)) return;
|
||||||
|
if (!sc.GetNumber(tiled.hiofs.xoffs, true)) return;
|
||||||
|
if (!sc.GetNumber(tiled.hiofs.yoffs, true)) return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
void parseSetupTileRange(FScanner& sc, FScriptPosition& pos)
|
||||||
|
{
|
||||||
|
int tilestart, tileend;
|
||||||
|
if (!sc.GetNumber(tilestart, true)) return;
|
||||||
|
if (!sc.GetNumber(tileend, true)) return;
|
||||||
|
if (!ValidateTileRange("setuptilerange", tilestart, tileend, pos)) return;
|
||||||
|
|
||||||
|
TileOffs hiofs;
|
||||||
|
if (!sc.GetNumber(hiofs.xsize, true)) return;
|
||||||
|
if (!sc.GetNumber(hiofs.ysize, true)) return;
|
||||||
|
if (!sc.GetNumber(hiofs.xoffs, true)) return;
|
||||||
|
if (!sc.GetNumber(hiofs.yoffs, true)) return;
|
||||||
|
|
||||||
|
for (int i = tilestart; i <= tileend; i++) TileFiles.tiledata[i].hiofs = hiofs;
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
void parseAnimTileRange(FScanner& sc, FScriptPosition& pos)
|
||||||
|
{
|
||||||
|
SetAnim set;
|
||||||
|
if (!sc.GetNumber(set.tile1, true)) return;
|
||||||
|
if (!sc.GetNumber(set.tile2, true)) return;
|
||||||
|
if (!sc.GetNumber(set.speed, true)) return;
|
||||||
|
if (!sc.GetNumber(set.type, true)) return;
|
||||||
|
processSetAnim("animtilerange", pos, set);
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
void parseAlphahack(FScanner& sc, FScriptPosition& pos)
|
||||||
|
{
|
||||||
|
int tile;
|
||||||
|
|
||||||
|
if (!sc.GetNumber(tile, true)) return;
|
||||||
|
if (!sc.GetFloat(true)) return;
|
||||||
|
if ((unsigned)tile < MAXTILES) TileFiles.tiledata[tile].texture->alphaThreshold = (float)sc.Float;
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
void parseAlphahackRange(FScanner& sc, FScriptPosition& pos)
|
||||||
|
{
|
||||||
|
int tilestart, tileend;
|
||||||
|
|
||||||
|
if (!sc.GetNumber(tilestart, true)) return;
|
||||||
|
if (!sc.GetNumber(tileend, true)) return;
|
||||||
|
if (!sc.GetFloat(true)) return;
|
||||||
|
if (!ValidateTileRange("alphahackrange", tilestart, tileend, pos)) return;
|
||||||
|
|
||||||
|
for (int i = tilestart; i <= tileend; i++)
|
||||||
|
TileFiles.tiledata[i].texture->alphaThreshold = (float)sc.Number;
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
void parseDefineTint(FScanner& sc, FScriptPosition& pos)
|
||||||
|
{
|
||||||
|
int pal, r, g, b, f;
|
||||||
|
|
||||||
|
if (!sc.GetNumber(pal, true)) return;
|
||||||
|
if (!sc.GetNumber(r)) return;
|
||||||
|
if (!sc.GetNumber(g)) return;
|
||||||
|
if (!sc.GetNumber(b)) return;
|
||||||
|
if (!sc.GetNumber(f)) return;
|
||||||
|
lookups.setPaletteTint(pal, r, g, b, 0, 0, 0, f);
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
void parseFogpal(FScanner& sc, FScriptPosition& pos)
|
||||||
|
{
|
||||||
|
int pal, r, g, b;
|
||||||
|
|
||||||
|
if (!sc.GetNumber(pal, true)) return;
|
||||||
|
if (!sc.GetNumber(r)) return;
|
||||||
|
if (!sc.GetNumber(g)) return;
|
||||||
|
if (!sc.GetNumber(b)) return;
|
||||||
|
|
||||||
|
r = clamp(r, 0, 63);
|
||||||
|
g = clamp(g, 0, 63);
|
||||||
|
b = clamp(b, 0, 63);
|
||||||
|
|
||||||
|
lookups.makeTable(pal, nullptr, r << 2, g << 2, b << 2, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
void parseNoFloorpalRange(FScanner& sc, FScriptPosition& pos)
|
||||||
|
{
|
||||||
|
int start, end;
|
||||||
|
if (!sc.GetNumber(start, true)) return;
|
||||||
|
if (!sc.GetNumber(end, true)) return;
|
||||||
|
if (start > 1) start = 1;
|
||||||
|
if (end > MAXPALOOKUPS - 1) end = MAXPALOOKUPS - 1;
|
||||||
|
for (int i = start; i <= end; i++)
|
||||||
|
lookups.tables[i].noFloorPal = true;
|
||||||
|
}
|
|
@ -46,6 +46,7 @@
|
||||||
|
|
||||||
static bool mus_blocked;
|
static bool mus_blocked;
|
||||||
static FString lastStartedMusic;
|
static FString lastStartedMusic;
|
||||||
|
TArray<FString> specialmusic;
|
||||||
|
|
||||||
MusicAliasMap MusicAliases;
|
MusicAliasMap MusicAliases;
|
||||||
MusicAliasMap LevelMusicAliases;
|
MusicAliasMap LevelMusicAliases;
|
||||||
|
@ -132,23 +133,27 @@ FileReader OpenMusic(const char* musicname)
|
||||||
if (!reader.isOpen())
|
if (!reader.isOpen())
|
||||||
{
|
{
|
||||||
int lumpnum = LookupMusic(musicname);
|
int lumpnum = LookupMusic(musicname);
|
||||||
if (mus_extendedlookup && lumpnum >= 0)
|
if (mus_extendedlookup || lumpnum < 0)
|
||||||
|
{
|
||||||
|
if (lumpnum >= 0)
|
||||||
{
|
{
|
||||||
// EDuke also looks in a subfolder named after the main game resource. Do this as well if extended lookup is active.
|
// EDuke also looks in a subfolder named after the main game resource. Do this as well if extended lookup is active.
|
||||||
auto rfn = fileSystem.GetResourceFileName(fileSystem.GetFileContainer(lumpnum));
|
auto rfn = fileSystem.GetResourceFileName(fileSystem.GetFileContainer(lumpnum));
|
||||||
auto rfbase = ExtractFileBase(rfn);
|
auto rfbase = ExtractFileBase(rfn);
|
||||||
FStringf aliasMusicname("music/%s/%s", rfbase.GetChars(), musicname);
|
FStringf aliasMusicname("music/%s/%s", rfbase.GetChars(), musicname);
|
||||||
lumpnum = LookupMusic(aliasMusicname);
|
int newlumpnum = LookupMusic(aliasMusicname);
|
||||||
|
if (newlumpnum >= 0) lumpnum = newlumpnum;
|
||||||
}
|
}
|
||||||
if (lumpnum == -1)
|
|
||||||
{
|
|
||||||
// Always look in the 'music' subfolder as well. This gets used by multiple setups to store ripped CD tracks.
|
// Always look in the 'music' subfolder as well. This gets used by multiple setups to store ripped CD tracks.
|
||||||
FStringf aliasMusicname("music/%s", musicname);
|
FStringf aliasMusicname("music/%s", musicname);
|
||||||
lumpnum = LookupMusic(aliasMusicname);
|
int newlumpnum = LookupMusic(aliasMusicname, lumpnum >= 0);
|
||||||
|
if (newlumpnum >= 0) lumpnum = newlumpnum;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lumpnum == -1 && (g_gameType & GAMEFLAG_SW))
|
if (lumpnum == -1 && (g_gameType & GAMEFLAG_SW))
|
||||||
{
|
{
|
||||||
// Some Shadow Warrioe distributions have the music in a subfolder named 'classic'. Check that, too.
|
// Some Shadow Warrior distributions have the music in a subfolder named 'classic'. Check that, too.
|
||||||
FStringf aliasMusicname("classic/music/%s", musicname);
|
FStringf aliasMusicname("classic/music/%s", musicname);
|
||||||
lumpnum = fileSystem.FindFile(aliasMusicname);
|
lumpnum = fileSystem.FindFile(aliasMusicname);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
typedef TMap<FName, FName> MusicAliasMap;
|
typedef TMap<FName, FName> MusicAliasMap;
|
||||||
extern MusicAliasMap MusicAliases;
|
extern MusicAliasMap MusicAliases;
|
||||||
|
extern TArray<FString> specialmusic;
|
||||||
|
|
||||||
// Totally minimalistic interface - should be all the game modules need.
|
// Totally minimalistic interface - should be all the game modules need.
|
||||||
void Mus_InitMusic();
|
void Mus_InitMusic();
|
||||||
|
|
|
@ -142,7 +142,11 @@ int S_LookupSound(const char* fn)
|
||||||
static const char * const sndformats[] = { "OGG", "FLAC", "WAV" };
|
static const char * const sndformats[] = { "OGG", "FLAC", "WAV" };
|
||||||
if (snd_extendedlookup)
|
if (snd_extendedlookup)
|
||||||
{
|
{
|
||||||
int lump = fileSystem.FindFileWithExtensions(StripExtension(fn), sndformats, countof(sndformats));
|
auto newfn = StripExtension(fn);
|
||||||
|
int lump = fileSystem.FindFileWithExtensions(newfn, sndformats, countof(sndformats));
|
||||||
|
if (lump >= 0) return lump;
|
||||||
|
newfn = "sound/" + newfn;
|
||||||
|
lump = fileSystem.FindFileWithExtensions(newfn, sndformats, countof(sndformats));
|
||||||
if (lump >= 0) return lump;
|
if (lump >= 0) return lump;
|
||||||
}
|
}
|
||||||
return fileSystem.FindFile(fn);
|
return fileSystem.FindFile(fn);
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include "m_crc32.h"
|
#include "m_crc32.h"
|
||||||
#include "glbackend.h"
|
#include "hw_palmanager.h"
|
||||||
|
|
||||||
#include "resourcefile.h"
|
#include "resourcefile.h"
|
||||||
#include "imagehelpers.h"
|
#include "imagehelpers.h"
|
||||||
|
@ -44,6 +44,8 @@
|
||||||
#include "build.h"
|
#include "build.h"
|
||||||
#include "v_video.h"
|
#include "v_video.h"
|
||||||
|
|
||||||
|
static PaletteManager* palmanager;
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
//
|
//
|
||||||
// This class manages the hardware data for the indexed render mode.
|
// This class manages the hardware data for the indexed render mode.
|
||||||
|
@ -138,4 +140,24 @@ IHardwareTexture* PaletteManager::GetLookup(int index)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
IHardwareTexture *setpalettelayer(int layer, int translation)
|
||||||
|
{
|
||||||
|
if (!palmanager) palmanager = new PaletteManager;
|
||||||
|
if (layer == 1)
|
||||||
|
return palmanager->GetPalette(GetTranslationType(translation) - Translation_Remap);
|
||||||
|
else if (layer == 2)
|
||||||
|
return palmanager->GetLookup(GetTranslationIndex(translation));
|
||||||
|
else return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClearPalManager()
|
||||||
|
{
|
||||||
|
if (palmanager) delete palmanager;
|
||||||
|
palmanager = nullptr;
|
||||||
|
}
|
24
source/core/rendering/hw_palmanager.h
Normal file
24
source/core/rendering/hw_palmanager.h
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "gl_hwtexture.h"
|
||||||
|
|
||||||
|
struct palette_t;
|
||||||
|
|
||||||
|
class PaletteManager
|
||||||
|
{
|
||||||
|
IHardwareTexture* palettetextures[256] = {};
|
||||||
|
IHardwareTexture* lookuptextures[256] = {};
|
||||||
|
|
||||||
|
unsigned FindPalswap(const uint8_t* paldata, palette_t& fadecolor);
|
||||||
|
|
||||||
|
public:
|
||||||
|
~PaletteManager();
|
||||||
|
void DeleteAll();
|
||||||
|
IHardwareTexture *GetPalette(int index);
|
||||||
|
IHardwareTexture* GetLookup(int index);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
IHardwareTexture* setpalettelayer(int layer, int translation);
|
||||||
|
void ClearPalManager();
|
||||||
|
|
114
source/core/rendering/hw_voxels.cpp
Normal file
114
source/core/rendering/hw_voxels.cpp
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Copyright(C) 2021 Christoph Oelckers
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 2 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
|
// along with this program. If not, see http://www.gnu.org/licenses/
|
||||||
|
//
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
/*
|
||||||
|
** hw_voxels.cpp
|
||||||
|
**
|
||||||
|
** voxel handling.
|
||||||
|
**
|
||||||
|
**/
|
||||||
|
|
||||||
|
#include "build.h"
|
||||||
|
#include "voxels.h"
|
||||||
|
#include "hw_voxels.h"
|
||||||
|
#include "gamecontrol.h"
|
||||||
|
|
||||||
|
int16_t tiletovox[MAXTILES];
|
||||||
|
static int voxlumps[MAXVOXELS];
|
||||||
|
float voxscale[MAXVOXELS];
|
||||||
|
voxmodel_t* voxmodels[MAXVOXELS];
|
||||||
|
FixedBitArray<MAXVOXELS> voxrotate;
|
||||||
|
|
||||||
|
|
||||||
|
void voxInit()
|
||||||
|
{
|
||||||
|
for (auto& v : tiletovox) v = -1;
|
||||||
|
for (auto& v : voxscale) v = 1.f;
|
||||||
|
voxrotate.Zero();
|
||||||
|
}
|
||||||
|
|
||||||
|
void voxClear()
|
||||||
|
{
|
||||||
|
for (auto& vox : voxmodels)
|
||||||
|
{
|
||||||
|
if (vox) delete vox;
|
||||||
|
vox = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int voxDefine(int voxindex, const char* filename)
|
||||||
|
{
|
||||||
|
if ((unsigned)voxindex >= MAXVOXELS)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
int i = fileSystem.FindFile(filename);
|
||||||
|
voxlumps[voxindex] = i;
|
||||||
|
return i < 0 ? -1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static voxmodel_t* voxload(int lumpnum)
|
||||||
|
{
|
||||||
|
FVoxel* voxel = R_LoadKVX(lumpnum);
|
||||||
|
if (voxel != nullptr)
|
||||||
|
{
|
||||||
|
voxmodel_t* vm = new voxmodel_t;
|
||||||
|
*vm = {};
|
||||||
|
auto pivot = voxel->Mips[0].Pivot;
|
||||||
|
vm->mdnum = 1; //VOXel model id
|
||||||
|
vm->scale = vm->bscale = 1.f;
|
||||||
|
vm->piv.x = float(pivot.X);
|
||||||
|
vm->piv.y = float(pivot.Y);
|
||||||
|
vm->piv.z = float(pivot.Z);
|
||||||
|
vm->siz.x = voxel->Mips[0].SizeX;
|
||||||
|
vm->siz.y = voxel->Mips[0].SizeY;
|
||||||
|
vm->siz.z = voxel->Mips[0].SizeZ;
|
||||||
|
vm->is8bit = true;
|
||||||
|
voxel->Mips[0].Pivot.Zero(); // Needs to be taken out of the voxel data because it gets baked into the vertex buffer which we cannot use here.
|
||||||
|
vm->model = new FVoxelModel(voxel, true);
|
||||||
|
return vm;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LoadVoxelModels()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < MAXVOXELS; i++)
|
||||||
|
{
|
||||||
|
int lumpnum = voxlumps[i];
|
||||||
|
if (lumpnum > 0)
|
||||||
|
{
|
||||||
|
voxmodels[i] = voxload(lumpnum);
|
||||||
|
if (voxmodels[i])
|
||||||
|
voxmodels[i]->scale = voxscale[i];
|
||||||
|
else
|
||||||
|
Printf("Unable to load voxel from %s\n", fileSystem.GetFileFullPath(lumpnum));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto index = fileSystem.FindResource(i, "KVX");
|
||||||
|
if (index >= 0)
|
||||||
|
{
|
||||||
|
voxmodels[i] = voxload(index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
24
source/core/rendering/hw_voxels.h
Normal file
24
source/core/rendering/hw_voxels.h
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "mdsprite.h"
|
||||||
|
|
||||||
|
// We still need the relation to mdmodel_t as long as the model code hasn't been redone.
|
||||||
|
struct voxmodel_t : public mdmodel_t
|
||||||
|
{
|
||||||
|
FVoxelModel* model = nullptr;
|
||||||
|
vec3_t siz;
|
||||||
|
vec3f_t piv;
|
||||||
|
int32_t is8bit;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
extern int16_t tiletovox[];
|
||||||
|
extern float voxscale[];
|
||||||
|
extern voxmodel_t* voxmodels[MAXVOXELS];
|
||||||
|
extern FixedBitArray<MAXVOXELS> voxrotate;
|
||||||
|
|
||||||
|
void voxInit();
|
||||||
|
void voxClear();
|
||||||
|
int voxDefine(int voxindex, const char* filename);
|
|
@ -40,6 +40,7 @@
|
||||||
#include "gamefuncs.h"
|
#include "gamefuncs.h"
|
||||||
#include "hw_portal.h"
|
#include "hw_portal.h"
|
||||||
#include "gamestruct.h"
|
#include "gamestruct.h"
|
||||||
|
#include "hw_voxels.h"
|
||||||
|
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -48,8 +49,10 @@
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
void BunchDrawer::Init(HWDrawInfo *_di, Clipper* c, vec2_t& view)
|
void BunchDrawer::Init(HWDrawInfo *_di, Clipper* c, vec2_t& view, binangle a1, binangle a2)
|
||||||
{
|
{
|
||||||
|
ang1 = a1;
|
||||||
|
ang2 = a2;
|
||||||
di = _di;
|
di = _di;
|
||||||
clipper = c;
|
clipper = c;
|
||||||
viewx = view.x * (1/ 16.f);
|
viewx = view.x * (1/ 16.f);
|
||||||
|
@ -82,6 +85,8 @@ void BunchDrawer::StartScene()
|
||||||
Bunches.Clear();
|
Bunches.Clear();
|
||||||
CompareData.Clear();
|
CompareData.Clear();
|
||||||
gotsector.Zero();
|
gotsector.Zero();
|
||||||
|
gotsector2.Zero();
|
||||||
|
gotwall.Zero();
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -90,14 +95,16 @@ void BunchDrawer::StartScene()
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
void BunchDrawer::StartBunch(int sectnum, int linenum, binangle startan, binangle endan)
|
bool BunchDrawer::StartBunch(int sectnum, int linenum, binangle startan, binangle endan, bool portal)
|
||||||
{
|
{
|
||||||
FBunch* bunch = &Bunches[LastBunch = Bunches.Reserve(1)];
|
FBunch* bunch = &Bunches[LastBunch = Bunches.Reserve(1)];
|
||||||
|
|
||||||
bunch->sectnum = sectnum;
|
bunch->sectnum = sectnum;
|
||||||
bunch->startline = bunch->endline = linenum;
|
bunch->startline = bunch->endline = linenum;
|
||||||
bunch->startangle = startan;
|
bunch->startangle = (startan.asbam() - ang1.asbam()) > ANGLE_180? ang1 :startan;
|
||||||
bunch->endangle = endan;
|
bunch->endangle = (endan.asbam() - ang2.asbam()) < ANGLE_180 ? ang2 : endan;
|
||||||
|
bunch->portal = portal;
|
||||||
|
return bunch->endangle != ang2;
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -106,10 +113,11 @@ void BunchDrawer::StartBunch(int sectnum, int linenum, binangle startan, binangl
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
void BunchDrawer::AddLineToBunch(int line, binangle newan)
|
bool BunchDrawer::AddLineToBunch(int line, binangle newan)
|
||||||
{
|
{
|
||||||
Bunches[LastBunch].endline++;
|
Bunches[LastBunch].endline++;
|
||||||
Bunches[LastBunch].endangle = newan;
|
Bunches[LastBunch].endangle = (newan.asbam() - ang2.asbam()) < ANGLE_180 ? ang2 : newan;
|
||||||
|
return Bunches[LastBunch].endangle != ang2;
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -181,7 +189,7 @@ bool BunchDrawer::CheckClip(walltype* wal)
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
int BunchDrawer::ClipLine(int line)
|
int BunchDrawer::ClipLine(int line, bool portal)
|
||||||
{
|
{
|
||||||
auto wal = &wall[line];
|
auto wal = &wall[line];
|
||||||
|
|
||||||
|
@ -194,7 +202,7 @@ int BunchDrawer::ClipLine(int line)
|
||||||
return CL_Skip;
|
return CL_Skip;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!clipper->SafeCheckRange(startAngle, endAngle))
|
if (!portal && !clipper->SafeCheckRange(startAngle, endAngle))
|
||||||
{
|
{
|
||||||
return CL_Skip;
|
return CL_Skip;
|
||||||
}
|
}
|
||||||
|
@ -202,7 +210,7 @@ int BunchDrawer::ClipLine(int line)
|
||||||
if (wal->nextwall == -1 || (wal->cstat & CSTAT_WALL_1WAY) || CheckClip(wal))
|
if (wal->nextwall == -1 || (wal->cstat & CSTAT_WALL_1WAY) || CheckClip(wal))
|
||||||
{
|
{
|
||||||
// one-sided
|
// one-sided
|
||||||
clipper->SafeAddClipRange(startAngle, endAngle);
|
if (!portal) clipper->SafeAddClipRange(startAngle, endAngle);
|
||||||
return CL_Draw;
|
return CL_Draw;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -224,14 +232,15 @@ void BunchDrawer::ProcessBunch(int bnch)
|
||||||
ClipWall.Clock();
|
ClipWall.Clock();
|
||||||
for (int i = bunch->startline; i <= bunch->endline; i++)
|
for (int i = bunch->startline; i <= bunch->endline; i++)
|
||||||
{
|
{
|
||||||
int clipped = ClipLine(i);
|
int clipped = ClipLine(i, bunch->portal);
|
||||||
|
|
||||||
if (clipped & CL_Draw)
|
if (clipped & CL_Draw)
|
||||||
{
|
{
|
||||||
show2dwall.Set(i);
|
show2dwall.Set(i);
|
||||||
|
|
||||||
//if (gl_render_walls)
|
if (!gotwall[i])
|
||||||
{
|
{
|
||||||
|
gotwall.Set(i);
|
||||||
ClipWall.Unclock();
|
ClipWall.Unclock();
|
||||||
Bsp.Unclock();
|
Bsp.Unclock();
|
||||||
SetupWall.Clock();
|
SetupWall.Clock();
|
||||||
|
@ -249,7 +258,7 @@ void BunchDrawer::ProcessBunch(int bnch)
|
||||||
if (clipped & CL_Pass)
|
if (clipped & CL_Pass)
|
||||||
{
|
{
|
||||||
ClipWall.Unclock();
|
ClipWall.Unclock();
|
||||||
ProcessSector(wall[i].nextsector);
|
ProcessSector(wall[i].nextsector, false);
|
||||||
ClipWall.Clock();
|
ClipWall.Clock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -288,7 +297,7 @@ int BunchDrawer::WallInFront(int wall1, int wall2)
|
||||||
if ((t1 * t2) >= 0)
|
if ((t1 * t2) >= 0)
|
||||||
{
|
{
|
||||||
t2 = PointOnLineSide(viewx, viewy, x1s, y1s, dx, dy);
|
t2 = PointOnLineSide(viewx, viewy, x1s, y1s, dx, dy);
|
||||||
return((t2 * t1) < 0);
|
return((t2 * t1) <= 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
dx = x2e - x2s;
|
dx = x2e - x2s;
|
||||||
|
@ -304,7 +313,7 @@ int BunchDrawer::WallInFront(int wall1, int wall2)
|
||||||
if ((t1 * t2) >= 0)
|
if ((t1 * t2) >= 0)
|
||||||
{
|
{
|
||||||
t2 = PointOnLineSide(viewx, viewy, x2s, y2s, dx, dy);
|
t2 = PointOnLineSide(viewx, viewy, x2s, y2s, dx, dy);
|
||||||
return((t2 * t1) >= 0);
|
return((t2 * t1) > 0);
|
||||||
}
|
}
|
||||||
return(-2);
|
return(-2);
|
||||||
}
|
}
|
||||||
|
@ -415,6 +424,7 @@ int BunchDrawer::FindClosestBunch()
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//Printf("picked bunch starting at %d\n", Bunches[closest].startline);
|
||||||
return closest;
|
return closest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -424,10 +434,10 @@ int BunchDrawer::FindClosestBunch()
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
void BunchDrawer::ProcessSector(int sectnum)
|
void BunchDrawer::ProcessSector(int sectnum, bool portal)
|
||||||
{
|
{
|
||||||
if (gotsector[sectnum]) return;
|
if (gotsector2[sectnum]) return;
|
||||||
gotsector.Set(sectnum);
|
gotsector2.Set(sectnum);
|
||||||
|
|
||||||
auto sect = §or[sectnum];
|
auto sect = §or[sectnum];
|
||||||
bool inbunch;
|
bool inbunch;
|
||||||
|
@ -436,6 +446,9 @@ void BunchDrawer::ProcessSector(int sectnum)
|
||||||
SetupSprite.Clock();
|
SetupSprite.Clock();
|
||||||
|
|
||||||
int z;
|
int z;
|
||||||
|
if (!gotsector[sectnum])
|
||||||
|
{
|
||||||
|
gotsector.Set(sectnum);
|
||||||
SectIterator it(sectnum);
|
SectIterator it(sectnum);
|
||||||
while ((z = it.NextIndex()) >= 0)
|
while ((z = it.NextIndex()) >= 0)
|
||||||
{
|
{
|
||||||
|
@ -458,6 +471,7 @@ void BunchDrawer::ProcessSector(int sectnum)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SetupSprite.Unclock();
|
SetupSprite.Unclock();
|
||||||
|
}
|
||||||
|
|
||||||
if (automapping)
|
if (automapping)
|
||||||
show2dsector.Set(sectnum);
|
show2dsector.Set(sectnum);
|
||||||
|
@ -478,36 +492,26 @@ void BunchDrawer::ProcessSector(int sectnum)
|
||||||
DVector2 start = { WallStartX(thiswall), WallStartY(thiswall) };
|
DVector2 start = { WallStartX(thiswall), WallStartY(thiswall) };
|
||||||
DVector2 end = { WallStartX(thiswall->point2), WallStartY(thiswall->point2) };
|
DVector2 end = { WallStartX(thiswall->point2), WallStartY(thiswall->point2) };
|
||||||
#endif
|
#endif
|
||||||
binangle ang1 = thiswall->clipangle;
|
binangle walang1 = thiswall->clipangle;
|
||||||
binangle ang2 = wall[thiswall->point2].clipangle;
|
binangle walang2 = wall[thiswall->point2].clipangle;
|
||||||
|
|
||||||
if (ang1.asbam() - ang2.asbam() < ANGLE_180)
|
// outside the visible area or seen from the backside.
|
||||||
|
if ((walang1.asbam() - ang1.asbam() > ANGLE_180 && walang2.asbam() - ang1.asbam() > ANGLE_180) ||
|
||||||
|
(walang1.asbam() - ang2.asbam() < ANGLE_180 && walang2.asbam() - ang2.asbam() < ANGLE_180) ||
|
||||||
|
(walang1.asbam() - walang2.asbam() < ANGLE_180))
|
||||||
{
|
{
|
||||||
// Backside
|
|
||||||
inbunch = false;
|
inbunch = false;
|
||||||
}
|
}
|
||||||
/* disabled because it only fragments the bunches without any performance gain.
|
else if (!inbunch)
|
||||||
else if (!clipper->SafeCheckRange(ang1, ang2))
|
|
||||||
{
|
{
|
||||||
// is it visible?
|
startangle = walang1;
|
||||||
inbunch = false;
|
//Printf("Starting bunch:\n\tWall %d\n", sect->wallptr + i);
|
||||||
}
|
inbunch = StartBunch(sectnum, sect->wallptr + i, walang1, walang2, portal);
|
||||||
*/
|
|
||||||
else if (!inbunch || ang2.asbam() - startangle.asbam() >= ANGLE_180)
|
|
||||||
{
|
|
||||||
// don't let a bunch span more than 180° to avoid problems.
|
|
||||||
// This limitation ensures that the combined range of 2
|
|
||||||
// bunches will always be less than 360° which simplifies
|
|
||||||
// the distance comparison code because it prevents a
|
|
||||||
// situation where 2 bunches may overlap at both ends.
|
|
||||||
|
|
||||||
startangle = ang1;
|
|
||||||
StartBunch(sectnum, sect->wallptr + i, ang1, ang2);
|
|
||||||
inbunch = true;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
AddLineToBunch(sect->wallptr + i, ang2);
|
//Printf("\tWall %d\n", sect->wallptr + i);
|
||||||
|
inbunch = AddLineToBunch(sect->wallptr + i, walang2);
|
||||||
}
|
}
|
||||||
if (thiswall->point2 != sect->wallptr + i + 1) inbunch = false;
|
if (thiswall->point2 != sect->wallptr + i + 1) inbunch = false;
|
||||||
}
|
}
|
||||||
|
@ -519,16 +523,39 @@ void BunchDrawer::ProcessSector(int sectnum)
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
void BunchDrawer::RenderScene(const int* viewsectors, unsigned sectcount)
|
void BunchDrawer::RenderScene(const int* viewsectors, unsigned sectcount, bool portal)
|
||||||
{
|
{
|
||||||
Bsp.Clock();
|
//Printf("----------------------------------------- \nstart at sector %d\n", viewsectors[0]);
|
||||||
for(unsigned i=0;i<sectcount;i++)
|
auto process = [&]()
|
||||||
ProcessSector(viewsectors[i]);
|
{
|
||||||
|
for (unsigned i = 0; i < sectcount; i++)
|
||||||
|
ProcessSector(viewsectors[i], portal);
|
||||||
while (Bunches.Size() > 0)
|
while (Bunches.Size() > 0)
|
||||||
{
|
{
|
||||||
int closest = FindClosestBunch();
|
int closest = FindClosestBunch();
|
||||||
ProcessBunch(closest);
|
ProcessBunch(closest);
|
||||||
DeleteBunch(closest);
|
DeleteBunch(closest);
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Bsp.Clock();
|
||||||
|
if (ang1.asbam() != 0 || ang2.asbam() != 0)
|
||||||
|
{
|
||||||
|
process();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// with a 360° field of view we need to split the scene into two halves.
|
||||||
|
// The BunchInFront check can fail with angles that may wrap around.
|
||||||
|
auto rotang = di->Viewpoint.RotAngle;
|
||||||
|
ang1 = bamang(rotang - ANGLE_90);
|
||||||
|
ang2 = bamang(rotang + ANGLE_90);
|
||||||
|
process();
|
||||||
|
clipper->Clear();
|
||||||
|
gotsector2.Zero();
|
||||||
|
ang1 = bamang(rotang + ANGLE_90);
|
||||||
|
ang2 = bamang(rotang - ANGLE_90);
|
||||||
|
process();
|
||||||
|
}
|
||||||
Bsp.Unclock();
|
Bsp.Unclock();
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,8 @@ struct FBunch
|
||||||
int sectnum;
|
int sectnum;
|
||||||
int startline;
|
int startline;
|
||||||
int endline;
|
int endline;
|
||||||
binangle startangle; // in pseudo angles for the clipper
|
bool portal;
|
||||||
|
binangle startangle;
|
||||||
binangle endangle;
|
binangle endangle;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -27,6 +28,9 @@ class BunchDrawer
|
||||||
vec2_t iview;
|
vec2_t iview;
|
||||||
float gcosang, gsinang;
|
float gcosang, gsinang;
|
||||||
FixedBitArray<MAXSECTORS> gotsector;
|
FixedBitArray<MAXSECTORS> gotsector;
|
||||||
|
FixedBitArray<MAXSECTORS> gotsector2;
|
||||||
|
FixedBitArray<MAXWALLS> gotwall;
|
||||||
|
binangle ang1, ang2;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -38,19 +42,19 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
void StartScene();
|
void StartScene();
|
||||||
void StartBunch(int sectnum, int linenum, binangle startan, binangle endan);
|
bool StartBunch(int sectnum, int linenum, binangle startan, binangle endan, bool portal);
|
||||||
void AddLineToBunch(int line, binangle newan);
|
bool AddLineToBunch(int line, binangle newan);
|
||||||
void DeleteBunch(int index);
|
void DeleteBunch(int index);
|
||||||
bool CheckClip(walltype* wal);
|
bool CheckClip(walltype* wal);
|
||||||
int ClipLine(int line);
|
int ClipLine(int line, bool portal);
|
||||||
void ProcessBunch(int bnch);
|
void ProcessBunch(int bnch);
|
||||||
int WallInFront(int wall1, int wall2);
|
int WallInFront(int wall1, int wall2);
|
||||||
int BunchInFront(FBunch* b1, FBunch* b2);
|
int BunchInFront(FBunch* b1, FBunch* b2);
|
||||||
int FindClosestBunch();
|
int FindClosestBunch();
|
||||||
void ProcessSector(int sectnum);
|
void ProcessSector(int sectnum, bool portal);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void Init(HWDrawInfo* _di, Clipper* c, vec2_t& view);
|
void Init(HWDrawInfo* _di, Clipper* c, vec2_t& view, binangle a1, binangle a2);
|
||||||
void RenderScene(const int* viewsectors, unsigned sectcount);
|
void RenderScene(const int* viewsectors, unsigned sectcount, bool portal);
|
||||||
const FixedBitArray<MAXSECTORS>& GotSector() const { return gotsector; }
|
const FixedBitArray<MAXSECTORS>& GotSector() const { return gotsector; }
|
||||||
};
|
};
|
||||||
|
|
|
@ -358,29 +358,6 @@ void Clipper::DoRemoveClipRange(angle_t start, angle_t end)
|
||||||
//
|
//
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
binangle Clipper::PointToAngle(const vec2_t& pos)
|
|
||||||
{
|
|
||||||
vec2_t vec = pos - viewpoint;
|
|
||||||
#if 0
|
|
||||||
|
|
||||||
if (vec.x == 0 && vec.y == 0)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
double result = vec.y / double(abs(vec.x) + fabs(vec.y));
|
|
||||||
if (vec.x < 0)
|
|
||||||
{
|
|
||||||
result = 2. - result;
|
|
||||||
}
|
|
||||||
return bamang(xs_Fix<30>::ToFix(result));
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
return q16ang(gethiq16angle(vec.x, vec.y));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void Clipper::DumpClipper()
|
void Clipper::DumpClipper()
|
||||||
{
|
{
|
||||||
for (auto node = cliphead; node; node = node->next)
|
for (auto node = cliphead; node; node = node->next)
|
||||||
|
|
|
@ -144,7 +144,29 @@ public:
|
||||||
|
|
||||||
void DumpClipper();
|
void DumpClipper();
|
||||||
|
|
||||||
binangle PointToAngle(const vec2_t& point);
|
binangle PointToAngle(const vec2_t& pos)
|
||||||
|
{
|
||||||
|
vec2_t vec = pos - viewpoint;
|
||||||
|
#if 0
|
||||||
|
|
||||||
|
if (vec.x == 0 && vec.y == 0)
|
||||||
|
{
|
||||||
|
return bamang(0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
double result = vec.y / double(abs(vec.x) + fabs(vec.y));
|
||||||
|
if (vec.x < 0)
|
||||||
|
{
|
||||||
|
result = 2. - result;
|
||||||
|
}
|
||||||
|
return bamang(xs_Fix<30>::ToFix(result));
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
return bvectangbam(vec.x, vec.y);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
#include "gamecvars.h"
|
#include "gamecvars.h"
|
||||||
#include "gamestruct.h"
|
#include "gamestruct.h"
|
||||||
#include "automap.h"
|
#include "automap.h"
|
||||||
|
#include "hw_voxels.h"
|
||||||
|
|
||||||
EXTERN_CVAR(Float, r_visibility)
|
EXTERN_CVAR(Float, r_visibility)
|
||||||
CVAR(Bool, gl_no_skyclear, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
CVAR(Bool, gl_no_skyclear, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
||||||
|
@ -210,7 +211,7 @@ angle_t HWDrawInfo::FrustumAngle()
|
||||||
// but at least it doesn't overestimate too much...
|
// but at least it doesn't overestimate too much...
|
||||||
double floatangle = 2.0 + (45.0 + ((tilt / 1.9)))*Viewpoint.FieldOfView.Degrees*48.0 / AspectMultiplier(WidescreenRatio) / 90.0;
|
double floatangle = 2.0 + (45.0 + ((tilt / 1.9)))*Viewpoint.FieldOfView.Degrees*48.0 / AspectMultiplier(WidescreenRatio) / 90.0;
|
||||||
angle_t a1 = DAngle(floatangle).BAMs();
|
angle_t a1 = DAngle(floatangle).BAMs();
|
||||||
if (a1 >= ANGLE_180) return 0xffffffff;
|
if (a1 >= ANGLE_90) return 0xffffffff; // it's either below 90 or bust.
|
||||||
return a1;
|
return a1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -300,14 +301,14 @@ void HWDrawInfo::DispatchSprites()
|
||||||
{
|
{
|
||||||
HWSprite hwsprite;
|
HWSprite hwsprite;
|
||||||
int num = tiletovox[tspr->picnum];
|
int num = tiletovox[tspr->picnum];
|
||||||
if (hwsprite.ProcessVoxel(this, voxmodels[tiletovox[tspr->picnum]], tspr, §or[tspr->sectnum], voxrotate[num >> 3] & (1 << (num & 7))))
|
if (hwsprite.ProcessVoxel(this, voxmodels[tiletovox[tspr->picnum]], tspr, §or[tspr->sectnum], voxrotate[num]))
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if ((tspr->cstat & CSTAT_SPRITE_ALIGNMENT) == CSTAT_SPRITE_ALIGNMENT_SLAB && tspr->picnum < MAXVOXELS && voxmodels[tspr->picnum])
|
else if ((tspr->cstat & CSTAT_SPRITE_ALIGNMENT) == CSTAT_SPRITE_ALIGNMENT_SLAB && tspr->picnum < MAXVOXELS && voxmodels[tspr->picnum])
|
||||||
{
|
{
|
||||||
HWSprite hwsprite;
|
HWSprite hwsprite;
|
||||||
int num = tspr->picnum;
|
int num = tspr->picnum;
|
||||||
hwsprite.ProcessVoxel(this, voxmodels[tspr->picnum], tspr, §or[tspr->sectnum], voxrotate[num >> 3] & (1 << (num & 7)));
|
hwsprite.ProcessVoxel(this, voxmodels[tspr->picnum], tspr, §or[tspr->sectnum], voxrotate[num]);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -363,12 +364,12 @@ void HWDrawInfo::DispatchSprites()
|
||||||
//
|
//
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
void HWDrawInfo::CreateScene()
|
void HWDrawInfo::CreateScene(bool portal)
|
||||||
{
|
{
|
||||||
const auto& vp = Viewpoint;
|
const auto& vp = Viewpoint;
|
||||||
|
|
||||||
angle_t a1 = FrustumAngle();
|
angle_t a1 = FrustumAngle();
|
||||||
mClipper->SafeAddClipRange(bamang(vp.RotAngle + a1), bamang(vp.RotAngle - a1));
|
if (a1 != 0xffffffff) mClipper->SafeAddClipRange(bamang(vp.RotAngle + a1), bamang(vp.RotAngle - a1));
|
||||||
|
|
||||||
// reset the portal manager
|
// reset the portal manager
|
||||||
portalState.StartFrame();
|
portalState.StartFrame();
|
||||||
|
@ -384,11 +385,12 @@ void HWDrawInfo::CreateScene()
|
||||||
geoofs = { 0,0 };
|
geoofs = { 0,0 };
|
||||||
|
|
||||||
vec2_t view = { int(vp.Pos.X * 16), int(vp.Pos.Y * -16) };
|
vec2_t view = { int(vp.Pos.X * 16), int(vp.Pos.Y * -16) };
|
||||||
mDrawer.Init(this, mClipper, view);
|
if (a1 != 0xffffffff) mDrawer.Init(this, mClipper, view, bamang(vp.RotAngle - a1), bamang(vp.RotAngle + a1));
|
||||||
|
else mDrawer.Init(this, mClipper, view, bamang(0), bamang(0));
|
||||||
if (vp.SectNums)
|
if (vp.SectNums)
|
||||||
mDrawer.RenderScene(vp.SectNums, vp.SectCount);
|
mDrawer.RenderScene(vp.SectNums, vp.SectCount, portal);
|
||||||
else
|
else
|
||||||
mDrawer.RenderScene(&vp.SectCount, 1);
|
mDrawer.RenderScene(&vp.SectCount, 1, portal);
|
||||||
|
|
||||||
SetupSprite.Clock();
|
SetupSprite.Clock();
|
||||||
gi->processSprites(tsprite, spritesortcnt, view.x, view.y, vp.Pos.Z * -256, bamang(vp.RotAngle), vp.TicFrac * 65536);
|
gi->processSprites(tsprite, spritesortcnt, view.x, view.y, vp.Pos.Z * -256, bamang(vp.RotAngle), vp.TicFrac * 65536);
|
||||||
|
@ -420,8 +422,9 @@ void HWDrawInfo::CreateScene()
|
||||||
|
|
||||||
mClipper->Clear();
|
mClipper->Clear();
|
||||||
mClipper->SafeAddClipRange(bamang(vp.RotAngle + a1), bamang(vp.RotAngle - a1));
|
mClipper->SafeAddClipRange(bamang(vp.RotAngle + a1), bamang(vp.RotAngle - a1));
|
||||||
mDrawer.Init(this, mClipper, view);
|
if (a1 != 0xffffffff) mDrawer.Init(this, mClipper, view, bamang(vp.RotAngle - a1), bamang(vp.RotAngle + a1));
|
||||||
mDrawer.RenderScene(&drawsect, 1);
|
else mDrawer.Init(this, mClipper, view, bamang(0), bamang(0));
|
||||||
|
mDrawer.RenderScene(&drawsect, 1, false);
|
||||||
|
|
||||||
for (int i = 0; i < eff.geocnt; i++)
|
for (int i = 0; i < eff.geocnt; i++)
|
||||||
{
|
{
|
||||||
|
@ -451,8 +454,9 @@ void HWDrawInfo::CreateScene()
|
||||||
|
|
||||||
mClipper->Clear();
|
mClipper->Clear();
|
||||||
mClipper->SafeAddClipRange(bamang(vp.RotAngle + a1), bamang(vp.RotAngle - a1));
|
mClipper->SafeAddClipRange(bamang(vp.RotAngle + a1), bamang(vp.RotAngle - a1));
|
||||||
mDrawer.Init(this, mClipper, view);
|
if (a1 != 0xffffffff) mDrawer.Init(this, mClipper, view, bamang(vp.RotAngle - a1), bamang(vp.RotAngle + a1));
|
||||||
mDrawer.RenderScene(&drawsect, 1);
|
else mDrawer.Init(this, mClipper, view, bamang(0), bamang(0));
|
||||||
|
mDrawer.RenderScene(&drawsect, 1, false);
|
||||||
|
|
||||||
for (int i = 0; i < eff.geocnt; i++)
|
for (int i = 0; i < eff.geocnt; i++)
|
||||||
{
|
{
|
||||||
|
@ -669,7 +673,7 @@ void HWDrawInfo::Set3DViewport(FRenderState &state)
|
||||||
//
|
//
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
void HWDrawInfo::DrawScene(int drawmode)
|
void HWDrawInfo::DrawScene(int drawmode, bool portal)
|
||||||
{
|
{
|
||||||
static int recursion = 0;
|
static int recursion = 0;
|
||||||
static int ssao_portals_available = 0;
|
static int ssao_portals_available = 0;
|
||||||
|
@ -691,7 +695,7 @@ void HWDrawInfo::DrawScene(int drawmode)
|
||||||
ssao_portals_available--;
|
ssao_portals_available--;
|
||||||
}
|
}
|
||||||
|
|
||||||
CreateScene();
|
CreateScene(portal);
|
||||||
auto& RenderState = *screen->RenderState();
|
auto& RenderState = *screen->RenderState();
|
||||||
|
|
||||||
RenderState.SetDepthMask(true);
|
RenderState.SetDepthMask(true);
|
||||||
|
@ -724,7 +728,7 @@ void HWDrawInfo::DrawScene(int drawmode)
|
||||||
void HWDrawInfo::ProcessScene(bool toscreen)
|
void HWDrawInfo::ProcessScene(bool toscreen)
|
||||||
{
|
{
|
||||||
portalState.BeginScene();
|
portalState.BeginScene();
|
||||||
DrawScene(toscreen ? DM_MAINVIEW : DM_OFFSCREEN);
|
DrawScene(toscreen ? DM_MAINVIEW : DM_OFFSCREEN, false);
|
||||||
if (toscreen && isBlood())
|
if (toscreen && isBlood())
|
||||||
{
|
{
|
||||||
gotsector = mDrawer.GotSector(); // Blood needs this to implement some lighting effect hacks. Needs to be refactored to use better info.
|
gotsector = mDrawer.GotSector(); // Blood needs this to implement some lighting effect hacks. Needs to be refactored to use better info.
|
||||||
|
|
|
@ -158,8 +158,8 @@ public:
|
||||||
void ClearBuffers();
|
void ClearBuffers();
|
||||||
HWDrawInfo *EndDrawInfo();
|
HWDrawInfo *EndDrawInfo();
|
||||||
|
|
||||||
void DrawScene(int drawmode);
|
void DrawScene(int drawmode, bool portal);
|
||||||
void CreateScene();
|
void CreateScene(bool portal);
|
||||||
void DispatchSprites();
|
void DispatchSprites();
|
||||||
void RenderScene(FRenderState &state);
|
void RenderScene(FRenderState &state);
|
||||||
void RenderTranslucent(FRenderState &state);
|
void RenderTranslucent(FRenderState &state);
|
||||||
|
|
|
@ -95,7 +95,7 @@ void HWDrawInfo::AddFlat(HWFlat *flat)
|
||||||
{
|
{
|
||||||
int list;;
|
int list;;
|
||||||
|
|
||||||
if (flat->RenderStyle != LegacyRenderStyles[STYLE_Translucent] || flat->alpha < 1.f - FLT_EPSILON) // flat->texture->GetTranslucency() - fixme
|
if (flat->RenderStyle != LegacyRenderStyles[STYLE_Translucent] || flat->alpha < 1.f - FLT_EPSILON || checkTranslucentReplacement(flat->texture->GetID(), flat->palette))
|
||||||
{
|
{
|
||||||
// translucent portals go into the translucent border list.
|
// translucent portals go into the translucent border list.
|
||||||
list = flat->sprite? GLDL_TRANSLUCENT : GLDL_TRANSLUCENTBORDER;
|
list = flat->sprite? GLDL_TRANSLUCENT : GLDL_TRANSLUCENTBORDER;
|
||||||
|
|
|
@ -11,6 +11,9 @@
|
||||||
#include "gamefuncs.h"
|
#include "gamefuncs.h"
|
||||||
#include "render.h"
|
#include "render.h"
|
||||||
#include "matrix.h"
|
#include "matrix.h"
|
||||||
|
#include "gamecontrol.h"
|
||||||
|
#include "hw_renderstate.h"
|
||||||
|
#include "hw_cvars.h"
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#pragma warning(disable:4244)
|
#pragma warning(disable:4244)
|
||||||
|
@ -26,6 +29,7 @@ struct FDynLightData;
|
||||||
class VSMatrix;
|
class VSMatrix;
|
||||||
struct FSpriteModelFrame;
|
struct FSpriteModelFrame;
|
||||||
class FRenderState;
|
class FRenderState;
|
||||||
|
struct voxmodel_t;
|
||||||
|
|
||||||
struct HWSectorPlane
|
struct HWSectorPlane
|
||||||
{
|
{
|
||||||
|
@ -192,7 +196,6 @@ public:
|
||||||
void SetupLights(HWDrawInfo *di, FDynLightData &lightdata);
|
void SetupLights(HWDrawInfo *di, FDynLightData &lightdata);
|
||||||
|
|
||||||
void MakeVertices(HWDrawInfo *di, bool nosplit);
|
void MakeVertices(HWDrawInfo *di, bool nosplit);
|
||||||
void SetLightAndFog(FRenderState& state);
|
|
||||||
|
|
||||||
void SkyPlane(HWDrawInfo *di, sectortype *sector, int plane, bool allowmirror);
|
void SkyPlane(HWDrawInfo *di, sectortype *sector, int plane, bool allowmirror);
|
||||||
void SkyLine(HWDrawInfo *di, sectortype *sec, walltype *line);
|
void SkyLine(HWDrawInfo *di, sectortype *sec, walltype *line);
|
||||||
|
@ -356,3 +359,71 @@ inline float sectorVisibility(sectortype* sec)
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const float hw_density = 0.35f;
|
inline const float hw_density = 0.35f;
|
||||||
|
|
||||||
|
int checkTranslucentReplacement(FTextureID picnum, int pal);
|
||||||
|
|
||||||
|
inline bool maskWallHasTranslucency(const walltype* wall)
|
||||||
|
{
|
||||||
|
return (wall->cstat & CSTAT_WALL_TRANSLUCENT) || checkTranslucentReplacement(tileGetTexture(wall->picnum)->GetID(), wall->pal);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool spriteHasTranslucency(const spritetype* tspr)
|
||||||
|
{
|
||||||
|
if ((tspr->cstat & CSTAT_SPRITE_TRANSLUCENT) || //(tspr->clipdist & TSPR_FLAGS_DRAW_LAST) ||
|
||||||
|
((unsigned)tspr->owner < MAXSPRITES && spriteext[tspr->owner].alpha))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return checkTranslucentReplacement(tileGetTexture(tspr->picnum)->GetID(), tspr->pal);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void SetSpriteTranslucency(const spritetype* sprite, float& alpha, FRenderStyle& RenderStyle)
|
||||||
|
{
|
||||||
|
bool trans = (sprite->cstat & CSTAT_SPRITE_TRANSLUCENT);
|
||||||
|
if (trans)
|
||||||
|
{
|
||||||
|
RenderStyle = GetRenderStyle(0, !!(sprite->cstat & CSTAT_SPRITE_TRANSLUCENT_INVERT));
|
||||||
|
alpha = GetAlphaFromBlend((sprite->cstat & CSTAT_SPRITE_TRANSLUCENT_INVERT) ? DAMETH_TRANS2 : DAMETH_TRANS1, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RenderStyle = LegacyRenderStyles[STYLE_Translucent];
|
||||||
|
alpha = 1.f;
|
||||||
|
}
|
||||||
|
alpha *= 1.f - spriteext[sprite->owner].alpha;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
extern PalEntry GlobalMapFog;
|
||||||
|
extern float GlobalFogDensity;
|
||||||
|
|
||||||
|
__forceinline void SetLightAndFog(FRenderState& state, PalEntry fade, int palette, int shade, int visibility, float alpha, bool setcolor = true)
|
||||||
|
{
|
||||||
|
// Fog must be done before the texture so that the texture selector can override it.
|
||||||
|
bool foggy = (GlobalMapFog || (fade & 0xffffff));
|
||||||
|
auto ShadeDiv = lookups.tables[palette].ShadeFactor;
|
||||||
|
shade = clamp(shade, 0, numshades - 1);
|
||||||
|
// Disable brightmaps if non-black fog is used.
|
||||||
|
if (ShadeDiv >= 1 / 1000.f && foggy)
|
||||||
|
{
|
||||||
|
state.EnableFog(1);
|
||||||
|
float density = GlobalMapFog ? GlobalFogDensity : 350.f - Scale(numshades - shade, 150, numshades);
|
||||||
|
state.SetFog((GlobalMapFog) ? GlobalMapFog : fade, density * hw_density);
|
||||||
|
state.SetSoftLightLevel(255);
|
||||||
|
state.SetLightParms(128.f, 1 / 1000.f);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
state.EnableFog(0);
|
||||||
|
state.SetFog(0, 0);
|
||||||
|
state.SetSoftLightLevel(gl_fogmode != 0 && ShadeDiv >= 1 / 1000.f ? 255 - Scale(shade, 255, numshades) : 255);
|
||||||
|
state.SetLightParms(visibility, ShadeDiv / (numshades - 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
// The shade rgb from the tint is ignored here.
|
||||||
|
state.SetColor(globalr * (1 / 255.f), globalg * (1 / 255.f), globalb * (1 / 255.f), alpha);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,9 +41,6 @@
|
||||||
CVAR(Int, gl_breaksec, -1, 0)
|
CVAR(Int, gl_breaksec, -1, 0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern PalEntry GlobalMapFog;
|
|
||||||
extern float GlobalFogDensity;
|
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
|
@ -124,8 +121,8 @@ void HWFlat::MakeVertices()
|
||||||
|
|
||||||
auto ret = screen->mVertexData->AllocVertices(6);
|
auto ret = screen->mVertexData->AllocVertices(6);
|
||||||
auto vp = ret.first;
|
auto vp = ret.first;
|
||||||
float x = !(sprite->cstat & CSTAT_SECTOR_XFLIP) ? 0.f : 1.f;
|
float x = !(sprite->cstat & CSTAT_SPRITE_XFLIP) ? 0.f : 1.f;
|
||||||
float y = !(sprite->cstat & CSTAT_SECTOR_YFLIP) ? 0.f : 1.f;
|
float y = !(sprite->cstat & CSTAT_SPRITE_YFLIP) ? 0.f : 1.f;
|
||||||
for (unsigned i = 0; i < 6; i++)
|
for (unsigned i = 0; i < 6; i++)
|
||||||
{
|
{
|
||||||
const static unsigned indices[] = { 0, 1, 2, 0, 2, 3 };
|
const static unsigned indices[] = { 0, 1, 2, 0, 2, 3 };
|
||||||
|
@ -170,28 +167,7 @@ void HWFlat::DrawFlat(HWDrawInfo *di, FRenderState &state, bool translucent)
|
||||||
else state.SetNormal({ 0, -1, 0 });
|
else state.SetNormal({ 0, -1, 0 });
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fog must be done before the texture so that the texture selector can override it.
|
SetLightAndFog(state, fade, palette, shade, visibility, alpha);
|
||||||
bool foggy = (GlobalMapFog || (fade & 0xffffff));
|
|
||||||
auto ShadeDiv = lookups.tables[palette].ShadeFactor;
|
|
||||||
// Disable brightmaps if non-black fog is used.
|
|
||||||
if (ShadeDiv >= 1 / 1000.f && foggy)
|
|
||||||
{
|
|
||||||
state.EnableFog(1);
|
|
||||||
float density = GlobalMapFog ? GlobalFogDensity : 350.f - Scale(numshades - shade, 150, numshades);
|
|
||||||
state.SetFog((GlobalMapFog) ? GlobalMapFog : fade, density * hw_density);
|
|
||||||
state.SetSoftLightLevel(255);
|
|
||||||
state.SetLightParms(128.f, 1 / 1000.f);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
state.EnableFog(0);
|
|
||||||
state.SetFog(0, 0);
|
|
||||||
state.SetSoftLightLevel(ShadeDiv >= 1 / 1000.f ? 255 - Scale(shade, 255, numshades) : 255);
|
|
||||||
state.SetLightParms(visibility, ShadeDiv / (numshades - 2));
|
|
||||||
}
|
|
||||||
|
|
||||||
// The shade rgb from the tint is ignored here.
|
|
||||||
state.SetColorAlpha(PalEntry(255, globalr, globalg, globalb), alpha);
|
|
||||||
|
|
||||||
if (translucent)
|
if (translucent)
|
||||||
{
|
{
|
||||||
|
@ -202,7 +178,8 @@ void HWFlat::DrawFlat(HWDrawInfo *di, FRenderState &state, bool translucent)
|
||||||
|
|
||||||
state.SetRenderStyle(RenderStyle);
|
state.SetRenderStyle(RenderStyle);
|
||||||
state.SetTextureMode(RenderStyle);
|
state.SetTextureMode(RenderStyle);
|
||||||
if (!texture->GetTranslucency()) state.AlphaFunc(Alpha_GEqual, gl_mask_threshold);
|
|
||||||
|
if (!texture || !checkTranslucentReplacement(texture->GetID(), palette)) state.AlphaFunc(Alpha_GEqual, texture->alphaThreshold);
|
||||||
else state.AlphaFunc(Alpha_GEqual, 0.f);
|
else state.AlphaFunc(Alpha_GEqual, 0.f);
|
||||||
}
|
}
|
||||||
state.SetMaterial(texture, UF_Texture, 0, sprite == nullptr? CLAMP_NONE : CLAMP_XY, TRANSLATION(Translation_Remap + curbasepal, palette), -1);
|
state.SetMaterial(texture, UF_Texture, 0, sprite == nullptr? CLAMP_NONE : CLAMP_XY, TRANSLATION(Translation_Remap + curbasepal, palette), -1);
|
||||||
|
@ -366,7 +343,7 @@ void HWFlat::ProcessFlatSprite(HWDrawInfo* di, spritetype* sprite, sectortype* s
|
||||||
z = sprite->z * (1 / -256.f);
|
z = sprite->z * (1 / -256.f);
|
||||||
if (z == di->Viewpoint.Pos.Z) return; // looking right at the edge.
|
if (z == di->Viewpoint.Pos.Z) return; // looking right at the edge.
|
||||||
|
|
||||||
visibility = sectorVisibility(§or[sprite->sectnum]);// *(4.f / 5.f); // The factor comes directly from Polymost. No idea why this uses a different visibility setting. Bad projection math?
|
visibility = sectorVisibility(§or[sprite->sectnum]) *(4.f / 5.f); // The factor comes directly from Polymost. What is it with Build and these magic factors?
|
||||||
|
|
||||||
// Weird Build logic that really makes no sense.
|
// Weird Build logic that really makes no sense.
|
||||||
if ((sprite->cstat & CSTAT_SPRITE_ONE_SIDED) != 0 && (di->Viewpoint.Pos.Z < z) == ((sprite->cstat & CSTAT_SPRITE_YFLIP) == 0))
|
if ((sprite->cstat & CSTAT_SPRITE_ONE_SIDED) != 0 && (di->Viewpoint.Pos.Z < z) == ((sprite->cstat & CSTAT_SPRITE_YFLIP) == 0))
|
||||||
|
@ -380,17 +357,8 @@ void HWFlat::ProcessFlatSprite(HWDrawInfo* di, spritetype* sprite, sectortype* s
|
||||||
palette = sprite->pal;
|
palette = sprite->pal;
|
||||||
fade = lookups.getFade(sector[sprite->sectnum].floorpal); // fog is per sector.
|
fade = lookups.getFade(sector[sprite->sectnum].floorpal); // fog is per sector.
|
||||||
|
|
||||||
bool trans = (sprite->cstat & CSTAT_SPRITE_TRANSLUCENT);
|
SetSpriteTranslucency(sprite, alpha, RenderStyle);
|
||||||
if (trans)
|
|
||||||
{
|
|
||||||
RenderStyle = GetRenderStyle(0, !!(sprite->cstat & CSTAT_SPRITE_TRANSLUCENT_INVERT));
|
|
||||||
alpha = GetAlphaFromBlend((sprite->cstat & CSTAT_SPRITE_TRANSLUCENT_INVERT) ? DAMETH_TRANS2 : DAMETH_TRANS1, 0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
RenderStyle = LegacyRenderStyles[STYLE_Translucent];
|
|
||||||
alpha = 1.f;
|
|
||||||
}
|
|
||||||
PutFlat(di, 0);
|
PutFlat(di, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -400,9 +400,10 @@ void HWScenePortalBase::DrawContents(HWDrawInfo* di, FRenderState& state)
|
||||||
{
|
{
|
||||||
if (Setup(di, state, di->mClipper))
|
if (Setup(di, state, di->mClipper))
|
||||||
{
|
{
|
||||||
gi->EnterPortal(di->Viewpoint.CameraSprite, GetType());
|
auto type = GetType();
|
||||||
di->DrawScene(DM_PORTAL);
|
gi->EnterPortal(di->Viewpoint.CameraSprite, type);
|
||||||
gi->LeavePortal(di->Viewpoint.CameraSprite, GetType());
|
di->DrawScene(DM_PORTAL, type == PORTAL_SECTOR_CEILING);
|
||||||
|
gi->LeavePortal(di->Viewpoint.CameraSprite, type);
|
||||||
Shutdown(di, state);
|
Shutdown(di, state);
|
||||||
}
|
}
|
||||||
else state.ClearScreen();
|
else state.ClearScreen();
|
||||||
|
@ -430,8 +431,8 @@ void HWScenePortalBase::ClearClipper(HWDrawInfo *di, Clipper *clipper)
|
||||||
clipper->SafeAddClipRange(bamang(0), bamang(0xffffffff));
|
clipper->SafeAddClipRange(bamang(0), bamang(0xffffffff));
|
||||||
for (unsigned int i = 0; i < lines.Size(); i++)
|
for (unsigned int i = 0; i < lines.Size(); i++)
|
||||||
{
|
{
|
||||||
binangle startang = q16ang(gethiq16angle(lines[i].seg->x - view.x, lines[i].seg->y - view.y));
|
binangle startang = bvectangbam(lines[i].seg->x - view.x, lines[i].seg->y - view.y);
|
||||||
binangle endang = q16ang(gethiq16angle(wall[lines[i].seg->point2].x - view.x, wall[lines[i].seg->point2].y - view.y));
|
binangle endang = bvectangbam(wall[lines[i].seg->point2].x - view.x, wall[lines[i].seg->point2].y - view.y);
|
||||||
|
|
||||||
if (endang.asbam() - startang.asbam() >= ANGLE_180)
|
if (endang.asbam() - startang.asbam() >= ANGLE_180)
|
||||||
{
|
{
|
||||||
|
@ -573,14 +574,17 @@ bool HWMirrorPortal::Setup(HWDrawInfo *di, FRenderState &rstate, Clipper *clippe
|
||||||
|
|
||||||
int newx = int((x << 1) + Scale(dx, i, j) - view.x);
|
int newx = int((x << 1) + Scale(dx, i, j) - view.x);
|
||||||
int newy = int((y << 1) + Scale(dy, i, j) - view.y);
|
int newy = int((y << 1) + Scale(dy, i, j) - view.y);
|
||||||
int newan = ((gethiq16angle(dx, dy) << 1) - bamang(vp.RotAngle).asq16()) & 0x7FFFFFF;
|
|
||||||
vp.RotAngle = q16ang(newan).asbam();
|
auto myan = bvectangbam(dx, dy);
|
||||||
|
auto newan = myan + myan - bamang(vp.RotAngle);
|
||||||
|
|
||||||
|
vp.RotAngle = newan.asbam();
|
||||||
vp.SectNums = nullptr;
|
vp.SectNums = nullptr;
|
||||||
vp.SectCount = line->sector;
|
vp.SectCount = line->sector;
|
||||||
|
|
||||||
vp.Pos.X = newx / 16.f;
|
vp.Pos.X = newx / 16.f;
|
||||||
vp.Pos.Y = newy / -16.f;
|
vp.Pos.Y = newy / -16.f;
|
||||||
vp.HWAngles.Yaw = -90.f + q16ang(newan).asdeg();
|
vp.HWAngles.Yaw = -90.f + newan.asdeg();
|
||||||
|
|
||||||
double FocalTangent = tan(vp.FieldOfView.Radians() / 2);
|
double FocalTangent = tan(vp.FieldOfView.Radians() / 2);
|
||||||
DAngle an = 270. - vp.HWAngles.Yaw.Degrees;
|
DAngle an = 270. - vp.HWAngles.Yaw.Degrees;
|
||||||
|
@ -597,9 +601,9 @@ bool HWMirrorPortal::Setup(HWDrawInfo *di, FRenderState &rstate, Clipper *clippe
|
||||||
angle_t af = di->FrustumAngle();
|
angle_t af = di->FrustumAngle();
|
||||||
if (af < ANGLE_180) clipper->SafeAddClipRange(bamang(vp.RotAngle + af), bamang(vp.RotAngle - af));
|
if (af < ANGLE_180) clipper->SafeAddClipRange(bamang(vp.RotAngle + af), bamang(vp.RotAngle - af));
|
||||||
|
|
||||||
auto startan = gethiq16angle(line->x - newx, line->y - newy);
|
auto startan = bvectangbam(line->x - newx, line->y - newy);
|
||||||
auto endan = gethiq16angle(wall[line->point2].x - newx, wall[line->point2].y - newy);
|
auto endan = bvectangbam(wall[line->point2].x - newx, wall[line->point2].y - newy);
|
||||||
clipper->SafeAddClipRange(q16ang(startan), q16ang(endan)); // we check the line from the backside so angles are reversed.
|
clipper->SafeAddClipRange(startan, endan); // we check the line from the backside so angles are reversed.
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -646,10 +650,10 @@ bool HWLineToLinePortal::Setup(HWDrawInfo *di, FRenderState &rstate, Clipper *cl
|
||||||
int dx2 = wall[line->point2].x - line->x;
|
int dx2 = wall[line->point2].x - line->x;
|
||||||
int dy2 = wall[line->point2].y - line->y;
|
int dy2 = wall[line->point2].y - line->y;
|
||||||
|
|
||||||
int srcang = gethiq16angle(dx, dy);
|
auto srcang = bvectangbam(dx, dy);
|
||||||
int destang = gethiq16angle(-dx, -dy);
|
auto destang = bvectangbam(-dx, -dy);
|
||||||
|
|
||||||
vp.RotAngle += q16ang(destang - srcang).asbam();
|
vp.RotAngle += (destang - srcang).asbam();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Nothing in the entire setup mandates that both lines have the same length.
|
// Nothing in the entire setup mandates that both lines have the same length.
|
||||||
|
@ -669,9 +673,9 @@ bool HWLineToLinePortal::Setup(HWDrawInfo *di, FRenderState &rstate, Clipper *cl
|
||||||
angle_t af = di->FrustumAngle();
|
angle_t af = di->FrustumAngle();
|
||||||
if (af < ANGLE_180) clipper->SafeAddClipRange(bamang(vp.RotAngle + af), bamang(vp.RotAngle - af));
|
if (af < ANGLE_180) clipper->SafeAddClipRange(bamang(vp.RotAngle + af), bamang(vp.RotAngle - af));
|
||||||
|
|
||||||
auto startan = gethiq16angle(origin->x - origx, origin->y - origy);
|
auto startan = bvectangbam(origin->x - origx, origin->y - origy);
|
||||||
auto endan = gethiq16angle(wall[origin->point2].x - origx, wall[origin->point2].y - origy);
|
auto endan = bvectangbam(wall[origin->point2].x - origx, wall[origin->point2].y - origy);
|
||||||
clipper->SafeAddClipRange(q16ang(endan), q16ang(startan));
|
clipper->SafeAddClipRange(endan, startan);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -723,9 +727,9 @@ bool HWLineToSpritePortal::Setup(HWDrawInfo* di, FRenderState& rstate, Clipper*
|
||||||
angle_t af = di->FrustumAngle();
|
angle_t af = di->FrustumAngle();
|
||||||
if (af < ANGLE_180) clipper->SafeAddClipRange(bamang(vp.RotAngle + af), bamang(vp.RotAngle - af));
|
if (af < ANGLE_180) clipper->SafeAddClipRange(bamang(vp.RotAngle + af), bamang(vp.RotAngle - af));
|
||||||
|
|
||||||
auto startan = gethiq16angle(origin->x - origx, origin->y - origy);
|
auto startan = bvectangbam(origin->x - origx, origin->y - origy);
|
||||||
auto endan = gethiq16angle(wall[origin->point2].x - origx, wall[origin->point2].y - origy);
|
auto endan = bvectangbam(wall[origin->point2].x - origx, wall[origin->point2].y - origy);
|
||||||
clipper->SafeAddClipRange(q16ang(endan), q16ang(startan));
|
clipper->SafeAddClipRange(endan, startan);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
|
|
||||||
CVAR(Bool,gl_noskyboxes, false, 0)
|
CVAR(Bool,gl_noskyboxes, false, 0)
|
||||||
FGameTexture* GetSkyTexture(int basetile, int lognumtiles, const int16_t* tilemap, int remap);
|
FGameTexture* GetSkyTexture(int basetile, int lognumtiles, const int16_t* tilemap, int remap);
|
||||||
|
FGameTexture* SkyboxReplacement(FTextureID picnum, int palnum);
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
|
@ -42,14 +43,14 @@ FGameTexture* GetSkyTexture(int basetile, int lognumtiles, const int16_t* tilema
|
||||||
void initSkyInfo(HWDrawInfo *di, HWSkyInfo* sky, sectortype* sector, int plane, PalEntry FadeColor)
|
void initSkyInfo(HWDrawInfo *di, HWSkyInfo* sky, sectortype* sector, int plane, PalEntry FadeColor)
|
||||||
{
|
{
|
||||||
int picnum = plane == plane_ceiling ? sector->ceilingpicnum : sector->floorpicnum;
|
int picnum = plane == plane_ceiling ? sector->ceilingpicnum : sector->floorpicnum;
|
||||||
|
int palette = plane == plane_ceiling ? sector->ceilingpal : sector->floorpal;
|
||||||
|
|
||||||
int32_t dapyscale = 0, dapskybits = 0, dapyoffs = 0, daptileyscale = 0;
|
int32_t dapyscale = 0, dapskybits = 0, dapyoffs = 0, daptileyscale = 0;
|
||||||
FGameTexture* skytex = nullptr;
|
FGameTexture* skytex = SkyboxReplacement(tileGetTexture(picnum)->GetID(), palette);
|
||||||
int realskybits = 0;
|
int realskybits = 0;
|
||||||
// todo: check for skybox replacement.
|
// todo: check for skybox replacement.
|
||||||
if (!skytex)
|
if (!skytex)
|
||||||
{
|
{
|
||||||
int palette = plane == plane_ceiling ? sector->ceilingpal : sector->floorpal;
|
|
||||||
int remap = TRANSLATION(Translation_Remap + curbasepal, palette);
|
int remap = TRANSLATION(Translation_Remap + curbasepal, palette);
|
||||||
|
|
||||||
int16_t const* dapskyoff = getpsky(picnum, &dapyscale, &dapskybits, &dapyoffs, &daptileyscale);
|
int16_t const* dapskyoff = getpsky(picnum, &dapyscale, &dapskybits, &dapyoffs, &daptileyscale);
|
||||||
|
@ -179,12 +180,7 @@ void HWWall::SkyTop(HWDrawInfo *di, walltype * seg,sectortype * fs,sectortype *
|
||||||
{
|
{
|
||||||
if (bs->ceilingstat & CSTAT_SECTOR_SKY)
|
if (bs->ceilingstat & CSTAT_SECTOR_SKY)
|
||||||
{
|
{
|
||||||
float c1, c2, f1, f2;
|
return;
|
||||||
PlanesAtPoint(bs, v1.X * 16.f, v1.Y * -16.f, &c1, &f1);
|
|
||||||
PlanesAtPoint(bs, v2.X * 16.f, v2.Y * -16.f, &c2, &f2);
|
|
||||||
|
|
||||||
// if the back sector is closed the sky must be drawn!
|
|
||||||
if (c1 > f1 || c2 > f2) return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
flags |= HWF_SKYHACK; // mid textures on such lines need special treatment!
|
flags |= HWF_SKYHACK; // mid textures on such lines need special treatment!
|
||||||
|
@ -231,14 +227,10 @@ void HWWall::SkyBottom(HWDrawInfo *di, walltype * seg,sectortype * fs,sectortype
|
||||||
}
|
}
|
||||||
else if (fs->floorstat & CSTAT_SECTOR_SKY)
|
else if (fs->floorstat & CSTAT_SECTOR_SKY)
|
||||||
{
|
{
|
||||||
float c1, c2, f1, f2;
|
|
||||||
PlanesAtPoint(bs, v1.X * 16.f, v1.Y * -16.f, &c1, &f1);
|
|
||||||
PlanesAtPoint(bs, v2.X * 16.f, v2.Y * -16.f, &c2, &f2);
|
|
||||||
|
|
||||||
if (bs->floorstat & CSTAT_SECTOR_SKY)
|
if (bs->floorstat & CSTAT_SECTOR_SKY)
|
||||||
{
|
{
|
||||||
// if the back sector is closed the sky must be drawn!
|
return;
|
||||||
if (c1 > f1 || c2 > f2) return;
|
|
||||||
}
|
}
|
||||||
flags |= HWF_SKYHACK; // mid textures on such lines need special treatment!
|
flags |= HWF_SKYHACK; // mid textures on such lines need special treatment!
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,8 @@
|
||||||
#include "hw_renderstate.h"
|
#include "hw_renderstate.h"
|
||||||
#include "skyboxtexture.h"
|
#include "skyboxtexture.h"
|
||||||
|
|
||||||
CVAR(Float, skyoffsettest, 0, 0)
|
CVAR(Float, skyoffsettest, 0, 0)
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
|
@ -34,6 +35,8 @@
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void HWSkyPortal::DrawContents(HWDrawInfo *di, FRenderState &state)
|
void HWSkyPortal::DrawContents(HWDrawInfo *di, FRenderState &state)
|
||||||
{
|
{
|
||||||
|
int indexed = hw_int_useindexedcolortextures;
|
||||||
|
hw_int_useindexedcolortextures = false; // this code does not work with indexed textures.
|
||||||
bool drawBoth = false;
|
bool drawBoth = false;
|
||||||
auto &vp = di->Viewpoint;
|
auto &vp = di->Viewpoint;
|
||||||
|
|
||||||
|
@ -101,6 +104,7 @@ void HWSkyPortal::DrawContents(HWDrawInfo *di, FRenderState &state)
|
||||||
|
|
||||||
//di->lightmode = oldlightmode;
|
//di->lightmode = oldlightmode;
|
||||||
state.SetDepthClamp(oldClamp);
|
state.SetDepthClamp(oldClamp);
|
||||||
}
|
hw_int_useindexedcolortextures = indexed;
|
||||||
|
}
|
||||||
|
|
||||||
const char *HWSkyPortal::GetName() { return "Sky"; }
|
const char *HWSkyPortal::GetName() { return "Sky"; }
|
||||||
|
|
|
@ -44,10 +44,7 @@
|
||||||
#include "hw_renderstate.h"
|
#include "hw_renderstate.h"
|
||||||
#include "hw_models.h"
|
#include "hw_models.h"
|
||||||
#include "hw_viewpointbuffer.h"
|
#include "hw_viewpointbuffer.h"
|
||||||
|
#include "hw_voxels.h"
|
||||||
extern PalEntry GlobalMapFog;
|
|
||||||
extern float GlobalFogDensity;
|
|
||||||
|
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
|
@ -74,7 +71,7 @@ void HWSprite::DrawSprite(HWDrawInfo* di, FRenderState& state, bool translucent)
|
||||||
state.SetRenderStyle(RenderStyle);
|
state.SetRenderStyle(RenderStyle);
|
||||||
state.SetTextureMode(RenderStyle);
|
state.SetTextureMode(RenderStyle);
|
||||||
|
|
||||||
if (!texture || !texture->GetTranslucency()) state.AlphaFunc(Alpha_GEqual, gl_mask_sprite_threshold);
|
if (!texture || !checkTranslucentReplacement(texture->GetID(), palette)) state.AlphaFunc(Alpha_GEqual, texture->alphaThreshold);
|
||||||
else state.AlphaFunc(Alpha_Greater, 0.f);
|
else state.AlphaFunc(Alpha_Greater, 0.f);
|
||||||
|
|
||||||
if (RenderStyle.BlendOp == STYLEOP_Add && RenderStyle.DestAlpha == STYLEALPHA_One)
|
if (RenderStyle.BlendOp == STYLEOP_Add && RenderStyle.DestAlpha == STYLEALPHA_One)
|
||||||
|
@ -113,36 +110,15 @@ void HWSprite::DrawSprite(HWDrawInfo* di, FRenderState& state, bool translucent)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fog must be done before the texture so that the texture selector can override it.
|
// Fog must be done before the texture so that the texture selector can override it.
|
||||||
bool foggy = (GlobalMapFog || (fade & 0xffffff));
|
|
||||||
auto ShadeDiv = lookups.tables[palette].ShadeFactor;
|
|
||||||
// Disable brightmaps if non-black fog is used.
|
// Disable brightmaps if non-black fog is used.
|
||||||
int shade = this->shade;
|
int shade = this->shade;
|
||||||
PalEntry color(255, globalr, globalg, globalb);
|
|
||||||
if (this->shade > numshades) // handling of SW's shadow hack using a shade of 127.
|
if (this->shade > numshades) // handling of SW's shadow hack using a shade of 127.
|
||||||
{
|
{
|
||||||
shade = sector[sprite->sectnum].floorshade;
|
shade = sector[sprite->sectnum].floorshade;
|
||||||
color = 0xff000000;
|
state.SetColor(0, 0, 0, alpha);
|
||||||
}
|
|
||||||
shade = clamp(shade, 0, numshades - 1);
|
|
||||||
|
|
||||||
if (ShadeDiv >= 1 / 1000.f && foggy && !foglayer)
|
|
||||||
{
|
|
||||||
state.EnableFog(1);
|
|
||||||
float density = GlobalMapFog ? GlobalFogDensity : 350.f - Scale(numshades - shade, 150, numshades);
|
|
||||||
state.SetFog((GlobalMapFog) ? GlobalMapFog : fade, density * hw_density);
|
|
||||||
state.SetSoftLightLevel(255);
|
|
||||||
state.SetLightParms(128.f, 1 / 1000.f);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
state.EnableFog(0);
|
|
||||||
state.SetFog(0, 0);
|
|
||||||
state.SetSoftLightLevel(ShadeDiv >= 1 / 1000.f ? 255 - Scale(shade, 255, numshades) : 255);
|
|
||||||
state.SetLightParms(visibility, ShadeDiv / (numshades - 2));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// The shade rgb from the tint is ignored here.
|
SetLightAndFog(state, fade, palette, shade, visibility, alpha, this->shade <= numshades);
|
||||||
state.SetColorAlpha(color, alpha);
|
|
||||||
|
|
||||||
if (modelframe == 0)
|
if (modelframe == 0)
|
||||||
{
|
{
|
||||||
|
@ -157,7 +133,11 @@ void HWSprite::DrawSprite(HWDrawInfo* di, FRenderState& state, bool translucent)
|
||||||
state.SetLightIndex(-1);
|
state.SetLightIndex(-1);
|
||||||
state.Draw(DT_TriangleStrip, vertexindex, 4);
|
state.Draw(DT_TriangleStrip, vertexindex, 4);
|
||||||
|
|
||||||
if (ShadeDiv >= 1 / 1000.f && foggy && foglayer)
|
if (foglayer)
|
||||||
|
{
|
||||||
|
bool foggy = (GlobalMapFog || (fade & 0xffffff));
|
||||||
|
auto ShadeDiv = lookups.tables[palette].ShadeFactor;
|
||||||
|
if (ShadeDiv >= 1 / 1000.f && foggy)
|
||||||
{
|
{
|
||||||
// If we get here we know that we have colored fog and no fixed colormap.
|
// If we get here we know that we have colored fog and no fixed colormap.
|
||||||
float density = GlobalMapFog ? GlobalFogDensity : 350.f - Scale(numshades - shade, 150, numshades);
|
float density = GlobalMapFog ? GlobalFogDensity : 350.f - Scale(numshades - shade, 150, numshades);
|
||||||
|
@ -168,6 +148,7 @@ void HWSprite::DrawSprite(HWDrawInfo* di, FRenderState& state, bool translucent)
|
||||||
state.SetTextureMode(TM_NORMAL);
|
state.SetTextureMode(TM_NORMAL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
state.EnableModelMatrix(true);
|
state.EnableModelMatrix(true);
|
||||||
|
@ -352,17 +333,7 @@ void HWSprite::Process(HWDrawInfo* di, spritetype* spr, sectortype* sector, int
|
||||||
fade = lookups.getFade(sector->floorpal); // fog is per sector.
|
fade = lookups.getFade(sector->floorpal); // fog is per sector.
|
||||||
visibility = sectorVisibility(sector);
|
visibility = sectorVisibility(sector);
|
||||||
|
|
||||||
bool trans = (spr->cstat & CSTAT_SPRITE_TRANSLUCENT);
|
SetSpriteTranslucency(spr, alpha, RenderStyle);
|
||||||
if (trans)
|
|
||||||
{
|
|
||||||
RenderStyle = GetRenderStyle(0, !!(spr->cstat & CSTAT_SPRITE_TRANSLUCENT_INVERT));
|
|
||||||
alpha = GetAlphaFromBlend((spr->cstat & CSTAT_SPRITE_TRANSLUCENT_INVERT) ? DAMETH_TRANS2 : DAMETH_TRANS1, 0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
RenderStyle = LegacyRenderStyles[STYLE_Translucent];
|
|
||||||
alpha = 1.f;
|
|
||||||
}
|
|
||||||
|
|
||||||
x = spr->x * (1 / 16.f);
|
x = spr->x * (1 / 16.f);
|
||||||
z = spr->z * (1 / -256.f);
|
z = spr->z * (1 / -256.f);
|
||||||
|
@ -375,12 +346,12 @@ void HWSprite::Process(HWDrawInfo* di, spritetype* spr, sectortype* sector, int
|
||||||
int tilenum = spr->picnum;
|
int tilenum = spr->picnum;
|
||||||
|
|
||||||
int xsize, ysize, tilexoff, tileyoff;
|
int xsize, ysize, tilexoff, tileyoff;
|
||||||
if (hw_hightile && TileFiles.tiledata[tilenum].h_xsize)
|
if (hw_hightile && TileFiles.tiledata[tilenum].hiofs.xsize)
|
||||||
{
|
{
|
||||||
xsize = TileFiles.tiledata[tilenum].h_xsize;
|
xsize = TileFiles.tiledata[tilenum].hiofs.xsize;
|
||||||
ysize = TileFiles.tiledata[tilenum].h_ysize;
|
ysize = TileFiles.tiledata[tilenum].hiofs.ysize;
|
||||||
tilexoff = TileFiles.tiledata[tilenum].h_xoffs;
|
tilexoff = TileFiles.tiledata[tilenum].hiofs.xoffs;
|
||||||
tileyoff = TileFiles.tiledata[tilenum].h_yoffs;
|
tileyoff = TileFiles.tiledata[tilenum].hiofs.yoffs;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -436,6 +407,12 @@ void HWSprite::Process(HWDrawInfo* di, spritetype* spr, sectortype* sector, int
|
||||||
|
|
||||||
z1 = z + yoff;
|
z1 = z + yoff;
|
||||||
z2 = z + height + yoff;
|
z2 = z + height + yoff;
|
||||||
|
if (z1 < z2)
|
||||||
|
{
|
||||||
|
// Make sure that z1 is the higher one. Some utilities expect it to be oriented this way.
|
||||||
|
std::swap(z1, z2);
|
||||||
|
std::swap(vt, vb);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -459,7 +436,7 @@ void HWSprite::Process(HWDrawInfo* di, spritetype* spr, sectortype* sector, int
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
PutSprite(di, alpha < 1.f-FLT_EPSILON || modelframe == 0);
|
PutSprite(di, true);
|
||||||
rendered_sprites++;
|
rendered_sprites++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -487,23 +464,13 @@ bool HWSprite::ProcessVoxel(HWDrawInfo* di, voxmodel_t* vox, spritetype* spr, se
|
||||||
if ((spr->cstat & CSTAT_SPRITE_MDLROTATE) || rotate)
|
if ((spr->cstat & CSTAT_SPRITE_MDLROTATE) || rotate)
|
||||||
{
|
{
|
||||||
int myclock = (PlayClock << 3) + MulScale(4 << 3, (int)di->Viewpoint.TicFrac, 16);
|
int myclock = (PlayClock << 3) + MulScale(4 << 3, (int)di->Viewpoint.TicFrac, 16);
|
||||||
ang = (ang + myclock) & 2047; // will be applied in md3_vox_calcmat_common.
|
ang = (ang + myclock) & 2047;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (!vox || (spr->cstat & CSTAT_SPRITE_ALIGNMENT) == CSTAT_SPRITE_ALIGNMENT_FLOOR) return false;
|
if (!vox || (spr->cstat & CSTAT_SPRITE_ALIGNMENT) == CSTAT_SPRITE_ALIGNMENT_FLOOR) return false;
|
||||||
|
|
||||||
bool trans = (spr->cstat & CSTAT_SPRITE_TRANSLUCENT);
|
SetSpriteTranslucency(spr, alpha, RenderStyle);
|
||||||
if (trans)
|
|
||||||
{
|
|
||||||
RenderStyle = GetRenderStyle(0, !!(spr->cstat & CSTAT_SPRITE_TRANSLUCENT_INVERT));
|
|
||||||
alpha = GetAlphaFromBlend((spr->cstat & CSTAT_SPRITE_TRANSLUCENT_INVERT) ? DAMETH_TRANS2 : DAMETH_TRANS1, 0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
RenderStyle = LegacyRenderStyles[STYLE_Translucent];
|
|
||||||
alpha = 1.f;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto sprext = &spriteext[spr->owner];
|
auto sprext = &spriteext[spr->owner];
|
||||||
|
|
||||||
|
@ -568,7 +535,7 @@ bool HWSprite::ProcessVoxel(HWDrawInfo* di, voxmodel_t* vox, spritetype* spr, se
|
||||||
|
|
||||||
auto vp = di->Viewpoint;
|
auto vp = di->Viewpoint;
|
||||||
depth = (float)((x - vp.Pos.X) * vp.TanCos + (y - vp.Pos.Y) * vp.TanSin);
|
depth = (float)((x - vp.Pos.X) * vp.TanCos + (y - vp.Pos.Y) * vp.TanSin);
|
||||||
PutSprite(di, alpha < 1.f - FLT_EPSILON);
|
PutSprite(di, spriteHasTranslucency(sprite));
|
||||||
rendered_sprites++;
|
rendered_sprites++;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,9 +39,6 @@
|
||||||
#include "flatvertices.h"
|
#include "flatvertices.h"
|
||||||
#include "glbackend/glbackend.h"
|
#include "glbackend/glbackend.h"
|
||||||
|
|
||||||
extern PalEntry GlobalMapFog;
|
|
||||||
extern float GlobalFogDensity;
|
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// Create vertices for one wall
|
// Create vertices for one wall
|
||||||
|
@ -104,7 +101,7 @@ void HWWall::RenderFogBoundary(HWDrawInfo *di, FRenderState &state)
|
||||||
if (gl_fogmode)// && !di->isFullbrightScene())
|
if (gl_fogmode)// && !di->isFullbrightScene())
|
||||||
{
|
{
|
||||||
state.EnableDrawBufferAttachments(false);
|
state.EnableDrawBufferAttachments(false);
|
||||||
SetLightAndFog(state);
|
SetLightAndFog(state, fade, palette, shade, visibility, alpha);
|
||||||
state.SetEffect(EFF_FOGBOUNDARY);
|
state.SetEffect(EFF_FOGBOUNDARY);
|
||||||
state.AlphaFunc(Alpha_GEqual, 0.f);
|
state.AlphaFunc(Alpha_GEqual, 0.f);
|
||||||
state.SetDepthBias(-1, -128);
|
state.SetDepthBias(-1, -128);
|
||||||
|
@ -115,38 +112,6 @@ void HWWall::RenderFogBoundary(HWDrawInfo *di, FRenderState &state)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
void HWWall::SetLightAndFog(FRenderState& state)
|
|
||||||
{
|
|
||||||
// Fog must be done before the texture so that the texture selector can override it.
|
|
||||||
bool foggy = (GlobalMapFog || (fade & 0xffffff));
|
|
||||||
auto ShadeDiv = lookups.tables[palette].ShadeFactor;
|
|
||||||
// Disable brightmaps if non-black fog is used.
|
|
||||||
if (ShadeDiv >= 1 / 1000.f && foggy)
|
|
||||||
{
|
|
||||||
state.EnableFog(1);
|
|
||||||
float density = GlobalMapFog ? GlobalFogDensity : 350.f - Scale(numshades - shade, 150, numshades);
|
|
||||||
state.SetFog((GlobalMapFog) ? GlobalMapFog : fade, density * hw_density);
|
|
||||||
state.SetSoftLightLevel(255);
|
|
||||||
state.SetLightParms(128.f, 1 / 1000.f);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
state.EnableFog(0);
|
|
||||||
state.SetFog(0, 0);
|
|
||||||
state.SetSoftLightLevel(ShadeDiv >= 1 / 1000.f ? 255 - Scale(shade, 255, numshades) : 255);
|
|
||||||
state.SetLightParms(visibility, ShadeDiv / (numshades - 2));
|
|
||||||
}
|
|
||||||
|
|
||||||
// The shade rgb from the tint is ignored here.
|
|
||||||
state.SetColorAlpha(PalEntry(255, globalr, globalg, globalb), alpha);
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
|
@ -163,7 +128,7 @@ void HWWall::RenderMirrorSurface(HWDrawInfo *di, FRenderState &state)
|
||||||
|
|
||||||
// Use sphere mapping for this
|
// Use sphere mapping for this
|
||||||
state.SetEffect(EFF_SPHEREMAP);
|
state.SetEffect(EFF_SPHEREMAP);
|
||||||
SetLightAndFog(state);
|
SetLightAndFog(state, fade, palette, shade, visibility, alpha, false);
|
||||||
state.SetColor(PalEntry(25, globalr >> 1, globalg >> 1, globalb >> 1));
|
state.SetColor(PalEntry(25, globalr >> 1, globalg >> 1, globalb >> 1));
|
||||||
|
|
||||||
state.SetRenderStyle(STYLE_Add);
|
state.SetRenderStyle(STYLE_Add);
|
||||||
|
@ -176,7 +141,7 @@ void HWWall::RenderMirrorSurface(HWDrawInfo *di, FRenderState &state)
|
||||||
|
|
||||||
state.EnableTextureMatrix(false);
|
state.EnableTextureMatrix(false);
|
||||||
state.SetEffect(EFF_NONE);
|
state.SetEffect(EFF_NONE);
|
||||||
state.AlphaFunc(Alpha_GEqual, gl_mask_sprite_threshold);
|
state.AlphaFunc(Alpha_GEqual, 0.5f);
|
||||||
|
|
||||||
state.SetDepthFunc(DF_Less);
|
state.SetDepthFunc(DF_Less);
|
||||||
state.SetRenderStyle(STYLE_Translucent);
|
state.SetRenderStyle(STYLE_Translucent);
|
||||||
|
@ -190,11 +155,8 @@ void HWWall::RenderMirrorSurface(HWDrawInfo *di, FRenderState &state)
|
||||||
|
|
||||||
void HWWall::RenderTexturedWall(HWDrawInfo *di, FRenderState &state, int rflags)
|
void HWWall::RenderTexturedWall(HWDrawInfo *di, FRenderState &state, int rflags)
|
||||||
{
|
{
|
||||||
//int tmode = state.GetTextureMode();
|
SetLightAndFog(state, fade, palette, shade, visibility, alpha);
|
||||||
|
state.SetMaterial(texture, UF_Texture, 0, sprite == nullptr ? (flags & (HWF_CLAMPX | HWF_CLAMPY)) : CLAMP_XY, TRANSLATION(Translation_Remap + curbasepal, palette), -1);
|
||||||
state.SetMaterial(texture, UF_Texture, 0, sprite == nullptr? (flags & (HWF_CLAMPX | HWF_CLAMPY)) : CLAMP_XY, TRANSLATION(Translation_Remap + curbasepal, palette), -1);
|
|
||||||
|
|
||||||
SetLightAndFog(state);
|
|
||||||
|
|
||||||
int h = (int)texture->GetDisplayHeight();
|
int h = (int)texture->GetDisplayHeight();
|
||||||
int h2 = 1 << sizeToBits(h);
|
int h2 = 1 << sizeToBits(h);
|
||||||
|
@ -238,7 +200,7 @@ void HWWall::RenderTranslucentWall(HWDrawInfo *di, FRenderState &state)
|
||||||
|
|
||||||
state.SetRenderStyle(RenderStyle);
|
state.SetRenderStyle(RenderStyle);
|
||||||
state.SetTextureMode(RenderStyle);
|
state.SetTextureMode(RenderStyle);
|
||||||
if (!texture->GetTranslucency()) state.AlphaFunc(Alpha_GEqual, gl_mask_threshold);
|
if (!texture || !checkTranslucentReplacement(texture->GetID(), palette)) state.AlphaFunc(Alpha_GEqual, texture->alphaThreshold);
|
||||||
else state.AlphaFunc(Alpha_GEqual, 0.f);
|
else state.AlphaFunc(Alpha_GEqual, 0.f);
|
||||||
RenderTexturedWall(di, state, HWWall::RWF_TEXTURED);
|
RenderTexturedWall(di, state, HWWall::RWF_TEXTURED);
|
||||||
state.SetRenderStyle(STYLE_Translucent);
|
state.SetRenderStyle(STYLE_Translucent);
|
||||||
|
@ -752,7 +714,7 @@ void HWWall::DoTexture(HWDrawInfo* di, walltype* wal, walltype* refwall, float r
|
||||||
tcs[UPRGT].v = setv(topleft, topright, glseg.fracright);
|
tcs[UPRGT].v = setv(topleft, topright, glseg.fracright);
|
||||||
tcs[LORGT].v = setv(bottomleft, bottomright, glseg.fracright);
|
tcs[LORGT].v = setv(bottomleft, bottomright, glseg.fracright);
|
||||||
if (th == pow2size) CheckTexturePosition(); // for NPOT textures this adjustment can break things.
|
if (th == pow2size) CheckTexturePosition(); // for NPOT textures this adjustment can break things.
|
||||||
bool trans = type == RENDERWALL_M2S && (wal->cstat & CSTAT_WALL_TRANSLUCENT);
|
bool trans = type == RENDERWALL_M2S && maskWallHasTranslucency(wal);
|
||||||
if (trans)
|
if (trans)
|
||||||
{
|
{
|
||||||
RenderStyle = GetRenderStyle(0, !!(wal->cstat & CSTAT_WALL_TRANS_FLIP));
|
RenderStyle = GetRenderStyle(0, !!(wal->cstat & CSTAT_WALL_TRANS_FLIP));
|
||||||
|
@ -896,7 +858,7 @@ void HWWall::Process(HWDrawInfo* di, walltype* wal, sectortype* frontsector, sec
|
||||||
|
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
if (wal - wall == 843)
|
if (wal - wall == 788)
|
||||||
{
|
{
|
||||||
int a = 0;
|
int a = 0;
|
||||||
}
|
}
|
||||||
|
@ -993,12 +955,15 @@ void HWWall::Process(HWDrawInfo* di, walltype* wal, sectortype* frontsector, sec
|
||||||
{
|
{
|
||||||
float bch1a = bch1;
|
float bch1a = bch1;
|
||||||
float bch2a = bch2;
|
float bch2a = bch2;
|
||||||
if (ffh1 > bch1 && ffh2 > bch2)
|
if (ffh1 > bch1 || ffh2 > bch2)
|
||||||
|
{
|
||||||
|
// the back sector's floor obstructs part of this wall. Todo: Handle the portal case better.
|
||||||
|
if ((ffh1 > bch1 && ffh2 > bch2) || frontsector->portalflags == PORTAL_SECTOR_FLOOR)
|
||||||
{
|
{
|
||||||
// the back sector's floor obstructs part of this wall
|
|
||||||
bch2a = ffh2;
|
bch2a = ffh2;
|
||||||
bch1a = ffh1;
|
bch1a = ffh1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (bch1a < fch1 || bch2a < fch2)
|
if (bch1a < fch1 || bch2a < fch2)
|
||||||
{
|
{
|
||||||
|
@ -1028,12 +993,15 @@ void HWWall::Process(HWDrawInfo* di, walltype* wal, sectortype* frontsector, sec
|
||||||
// lower texture
|
// lower texture
|
||||||
if (!(frontsector->floorstat & backsector->floorstat & CSTAT_SECTOR_SKY))
|
if (!(frontsector->floorstat & backsector->floorstat & CSTAT_SECTOR_SKY))
|
||||||
{
|
{
|
||||||
if (fch1 < bfh1 && fch2 < bfh2)
|
if (fch1 < bfh1 || fch2 < bfh2)
|
||||||
|
{
|
||||||
|
// the back sector's ceiling obstructs part of this wall. Todo: Handle the portal case better.
|
||||||
|
if ((fch1 < bfh1 && fch2 < bfh2) || frontsector->portalflags == PORTAL_SECTOR_CEILING)
|
||||||
{
|
{
|
||||||
// the back sector's ceiling obstructs part of this wall.
|
|
||||||
bfh1 = fch1;
|
bfh1 = fch1;
|
||||||
bfh2 = fch2;
|
bfh2 = fch2;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (bfh1 > ffh1 || bfh2 > ffh2)
|
if (bfh1 > ffh1 || bfh2 > ffh2)
|
||||||
{
|
{
|
||||||
|
@ -1049,7 +1017,6 @@ void HWWall::Process(HWDrawInfo* di, walltype* wal, sectortype* frontsector, sec
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
globalr = globalg = globalb = 255;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void HWWall::ProcessWallSprite(HWDrawInfo* di, spritetype* spr, sectortype* sector)
|
void HWWall::ProcessWallSprite(HWDrawInfo* di, spritetype* spr, sectortype* sector)
|
||||||
|
@ -1090,24 +1057,13 @@ void HWWall::ProcessWallSprite(HWDrawInfo* di, spritetype* spr, sectortype* sect
|
||||||
fade = lookups.getFade(sector->floorpal); // fog is per sector.
|
fade = lookups.getFade(sector->floorpal); // fog is per sector.
|
||||||
visibility = sectorVisibility(sector);
|
visibility = sectorVisibility(sector);
|
||||||
|
|
||||||
bool trans = (sprite->cstat & CSTAT_SPRITE_TRANSLUCENT);
|
SetSpriteTranslucency(sprite, alpha, RenderStyle);
|
||||||
if (trans)
|
|
||||||
{
|
|
||||||
RenderStyle = GetRenderStyle(0, !!(sprite->cstat & CSTAT_SPRITE_TRANSLUCENT_INVERT));
|
|
||||||
alpha = GetAlphaFromBlend((sprite->cstat & CSTAT_SPRITE_TRANSLUCENT_INVERT) ? DAMETH_TRANS2 : DAMETH_TRANS1, 0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
RenderStyle = LegacyRenderStyles[STYLE_Translucent];
|
|
||||||
alpha = 1.f;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int height, topofs;
|
int height, topofs;
|
||||||
if (hw_hightile && TileFiles.tiledata[spr->picnum].h_xsize)
|
if (hw_hightile && TileFiles.tiledata[spr->picnum].hiofs.xsize)
|
||||||
{
|
{
|
||||||
height = TileFiles.tiledata[spr->picnum].h_ysize;
|
height = TileFiles.tiledata[spr->picnum].hiofs.ysize;
|
||||||
topofs = (TileFiles.tiledata[spr->picnum].h_yoffs + spr->yoffset);
|
topofs = (TileFiles.tiledata[spr->picnum].hiofs.yoffs + spr->yoffset);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1160,5 +1116,5 @@ void HWWall::ProcessWallSprite(HWDrawInfo* di, spritetype* spr, sectortype* sect
|
||||||
zbottom[0] = zbottom[1] = floorz;
|
zbottom[0] = zbottom[1] = floorz;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PutWall(di, trans);
|
PutWall(di, spriteHasTranslucency(sprite));
|
||||||
}
|
}
|
|
@ -646,7 +646,6 @@ void SerializeMap(FSerializer& arc)
|
||||||
("numshades", numshades) // is this really needed?
|
("numshades", numshades) // is this really needed?
|
||||||
("visibility", g_visibility)
|
("visibility", g_visibility)
|
||||||
("parallaxtype", parallaxtype)
|
("parallaxtype", parallaxtype)
|
||||||
("parallaxvisibility", parallaxvisibility)
|
|
||||||
("parallaxyo", parallaxyoffs_override)
|
("parallaxyo", parallaxyoffs_override)
|
||||||
("parallaxys", parallaxyscale_override)
|
("parallaxys", parallaxyscale_override)
|
||||||
("pskybits", pskybits_override)
|
("pskybits", pskybits_override)
|
||||||
|
|
|
@ -840,7 +840,7 @@ public:
|
||||||
clock += now - lastTime;
|
clock += now - lastTime;
|
||||||
if (clock == 0) clock = 1;
|
if (clock == 0) clock = 1;
|
||||||
}
|
}
|
||||||
bool skiprequest = clock > 100'000'000 && inputState.CheckAllInput() && !processed;
|
bool skiprequest = clock > 100'000'000 && inputState.CheckAllInput() && !processed && job.job->fadestate != DScreenJob::fadeout;
|
||||||
lastTime = now;
|
lastTime = now;
|
||||||
|
|
||||||
if (screenfade < 1.f && !M_Active())
|
if (screenfade < 1.f && !M_Active())
|
||||||
|
@ -848,6 +848,7 @@ public:
|
||||||
float ms = (clock / 1'000'000) / job.job->fadetime;
|
float ms = (clock / 1'000'000) / job.job->fadetime;
|
||||||
screenfade = clamp(ms, 0.f, 1.f);
|
screenfade = clamp(ms, 0.f, 1.f);
|
||||||
twod->SetScreenFade(screenfade);
|
twod->SetScreenFade(screenfade);
|
||||||
|
if (job.job->fadestate != DScreenJob::fadeout)
|
||||||
job.job->fadestate = DScreenJob::fadein;
|
job.job->fadestate = DScreenJob::fadein;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -915,6 +916,7 @@ public:
|
||||||
startTime = -1;
|
startTime = -1;
|
||||||
clock = 0;
|
clock = 0;
|
||||||
jobs[index].job->fadestate = DScreenJob::fadeout;
|
jobs[index].job->fadestate = DScreenJob::fadeout;
|
||||||
|
gamestate = GS_INTRO; // block menu and console during fadeout - this can cause timing problems.
|
||||||
actionState = State_Fadeout;
|
actionState = State_Fadeout;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -959,6 +961,7 @@ void DeleteScreenJob()
|
||||||
delete runner;
|
delete runner;
|
||||||
runner = nullptr;
|
runner = nullptr;
|
||||||
}
|
}
|
||||||
|
twod->SetScreenFade(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RunScreenJobFrame()
|
void RunScreenJobFrame()
|
||||||
|
|
|
@ -47,6 +47,7 @@
|
||||||
#include "c_dispatch.h"
|
#include "c_dispatch.h"
|
||||||
#include "sc_man.h"
|
#include "sc_man.h"
|
||||||
#include "gamestruct.h"
|
#include "gamestruct.h"
|
||||||
|
#include "hw_voxels.h"
|
||||||
|
|
||||||
#include "hw_renderstate.h"
|
#include "hw_renderstate.h"
|
||||||
|
|
||||||
|
@ -59,7 +60,7 @@ enum
|
||||||
|
|
||||||
BuildTiles TileFiles;
|
BuildTiles TileFiles;
|
||||||
|
|
||||||
int tileSetHightileReplacement(int picnum, int palnum, const char* filename, float alphacut, float xscale, float yscale, float specpower, float specfactor, uint8_t flags);
|
int tileSetHightileReplacement(int picnum, int palnum, const char* filename, float alphacut, float xscale, float yscale, float specpower, float specfactor);
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
|
@ -144,7 +145,7 @@ void BuildTiles::Init()
|
||||||
tile.RotTile = { -1,-1 };
|
tile.RotTile = { -1,-1 };
|
||||||
tile.replacement = ReplacementType::Art;
|
tile.replacement = ReplacementType::Art;
|
||||||
tile.alphaThreshold = 0.5;
|
tile.alphaThreshold = 0.5;
|
||||||
tile.h_xsize = 0;
|
tile.hiofs = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -256,7 +257,7 @@ void BuildTiles::InvalidateTile(int num)
|
||||||
if ((unsigned) num < MAXTILES)
|
if ((unsigned) num < MAXTILES)
|
||||||
{
|
{
|
||||||
auto tex = tiledata[num].texture;
|
auto tex = tiledata[num].texture;
|
||||||
tex->GetTexture()->SystemTextures.Clean();
|
tex->CleanHardwareData();
|
||||||
tiledata[num].rawCache.data.Clear();
|
tiledata[num].rawCache.data.Clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -513,7 +514,7 @@ int tileImportFromTexture(const char* fn, int tilenum, int alphacut, int istextu
|
||||||
TexMan.AddGameTexture(tex);
|
TexMan.AddGameTexture(tex);
|
||||||
TileFiles.tiledata[tilenum].backup = TileFiles.tiledata[tilenum].texture = tex;
|
TileFiles.tiledata[tilenum].backup = TileFiles.tiledata[tilenum].texture = tex;
|
||||||
if (istexture)
|
if (istexture)
|
||||||
tileSetHightileReplacement(tilenum, 0, fn, (float)(255 - alphacut) * (1.f / 255.f), 1.0f, 1.0f, 1.0, 1.0, 0);
|
tileSetHightileReplacement(tilenum, 0, fn, (float)(255 - alphacut) * (1.f / 255.f), 1.0f, 1.0f, 1.0, 1.0);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -648,7 +649,7 @@ void artSetupMapArt(const char* filename)
|
||||||
void tileDelete(int tile)
|
void tileDelete(int tile)
|
||||||
{
|
{
|
||||||
TileFiles.tiledata[tile].texture = TileFiles.tiledata[tile].backup = TexMan.GameByIndex(0);
|
TileFiles.tiledata[tile].texture = TileFiles.tiledata[tile].backup = TexMan.GameByIndex(0);
|
||||||
vox_undefine(tile);
|
tiletovox[tile] = -1; // clear the link but don't clear the voxel. It may be in use for another tile.
|
||||||
md_undefinetile(tile);
|
md_undefinetile(tile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -257,6 +257,11 @@ struct RawCacheNode
|
||||||
uint64_t lastUseTime;
|
uint64_t lastUseTime;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct TileOffs
|
||||||
|
{
|
||||||
|
int xsize, ysize, xoffs, yoffs;
|
||||||
|
};
|
||||||
|
|
||||||
struct TileDesc
|
struct TileDesc
|
||||||
{
|
{
|
||||||
FGameTexture* texture; // the currently active tile
|
FGameTexture* texture; // the currently active tile
|
||||||
|
@ -269,8 +274,7 @@ struct TileDesc
|
||||||
float alphaThreshold;
|
float alphaThreshold;
|
||||||
|
|
||||||
// Sprite offset hackery for hires replacements. This only gets used for sprites in the 3D view, nothing else.
|
// Sprite offset hackery for hires replacements. This only gets used for sprites in the 3D view, nothing else.
|
||||||
uint16_t h_xsize, h_ysize;
|
TileOffs hiofs;
|
||||||
int8_t h_xoffs, h_yoffs;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -48,15 +48,17 @@
|
||||||
#include "sc_man.h"
|
#include "sc_man.h"
|
||||||
#include "gamestruct.h"
|
#include "gamestruct.h"
|
||||||
#include "hw_renderstate.h"
|
#include "hw_renderstate.h"
|
||||||
|
#include "skyboxtexture.h"
|
||||||
|
|
||||||
CVARD(Bool, hw_shadeinterpolate, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG, "enable/disable shade interpolation")
|
CVARD(Bool, hw_shadeinterpolate, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG, "enable/disable shade interpolation")
|
||||||
|
|
||||||
struct HightileReplacement
|
struct HightileReplacement
|
||||||
{
|
{
|
||||||
FGameTexture* faces[6]; // only one gets used by a texture, the other 5 are for skyboxes only
|
FGameTexture* image;
|
||||||
FVector2 scale;
|
FVector2 scale;
|
||||||
float alphacut, specpower, specfactor;
|
float alphacut, specpower, specfactor;
|
||||||
uint16_t palnum, flags;
|
uint16_t palnum;
|
||||||
|
bool issky;
|
||||||
};
|
};
|
||||||
|
|
||||||
static TMap<int, TArray<HightileReplacement>> tileReplacements;
|
static TMap<int, TArray<HightileReplacement>> tileReplacements;
|
||||||
|
@ -91,7 +93,7 @@ static void AddReplacement(int picnum, const HightileReplacement& replace)
|
||||||
auto& Hightiles = tileReplacements[picnum];
|
auto& Hightiles = tileReplacements[picnum];
|
||||||
for (auto& ht : Hightiles)
|
for (auto& ht : Hightiles)
|
||||||
{
|
{
|
||||||
if (replace.palnum == ht.palnum && (replace.faces[1] == nullptr) == (ht.faces[1] == nullptr))
|
if (replace.palnum == ht.palnum && replace.issky == ht.issky)
|
||||||
{
|
{
|
||||||
ht = replace;
|
ht = replace;
|
||||||
return;
|
return;
|
||||||
|
@ -125,7 +127,7 @@ static HightileReplacement* FindReplacement(FTextureID picnum, int palnum, bool
|
||||||
{
|
{
|
||||||
for (auto& rep : *Hightiles)
|
for (auto& rep : *Hightiles)
|
||||||
{
|
{
|
||||||
if (rep.palnum == palnum && (rep.faces[1] != nullptr) == skybox) return &rep;
|
if (rep.palnum == palnum && rep.issky == skybox) return &rep;
|
||||||
}
|
}
|
||||||
if (!palnum || palnum >= MAXPALOOKUPS - RESERVEDPALS) break;
|
if (!palnum || palnum >= MAXPALOOKUPS - RESERVEDPALS) break;
|
||||||
palnum = 0;
|
palnum = 0;
|
||||||
|
@ -137,11 +139,19 @@ int checkTranslucentReplacement(FTextureID picnum, int pal)
|
||||||
{
|
{
|
||||||
FGameTexture* tex = nullptr;
|
FGameTexture* tex = nullptr;
|
||||||
auto si = FindReplacement(picnum, pal, 0);
|
auto si = FindReplacement(picnum, pal, 0);
|
||||||
if (si && hw_hightile) tex = si->faces[0];
|
if (si && hw_hightile) tex = si->image;
|
||||||
if (!tex || tex->GetTexelWidth() == 0 || tex->GetTexelHeight() == 0) return false;
|
if (!tex || tex->GetTexelWidth() == 0 || tex->GetTexelHeight() == 0) return false;
|
||||||
return tex && tex->GetTranslucency();
|
return tex && tex->GetTranslucency();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FGameTexture* SkyboxReplacement(FTextureID picnum, int palnum)
|
||||||
|
{
|
||||||
|
auto hr = FindReplacement(picnum, palnum, true);
|
||||||
|
if (!hr) return nullptr;
|
||||||
|
return hr->image;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// Processes data from .def files into the textures
|
// Processes data from .def files into the textures
|
||||||
|
@ -163,19 +173,19 @@ void PostLoadSetup()
|
||||||
{
|
{
|
||||||
if (rep.palnum == GLOWPAL)
|
if (rep.palnum == GLOWPAL)
|
||||||
{
|
{
|
||||||
glowTex = rep.faces[0];
|
glowTex = rep.image;
|
||||||
}
|
}
|
||||||
if (rep.palnum == NORMALPAL)
|
if (rep.palnum == NORMALPAL)
|
||||||
{
|
{
|
||||||
normalTex = rep.faces[0];
|
normalTex = rep.image;
|
||||||
}
|
}
|
||||||
if (rep.palnum == SPECULARPAL)
|
if (rep.palnum == SPECULARPAL)
|
||||||
{
|
{
|
||||||
specTex = rep.faces[0];
|
specTex = rep.image;
|
||||||
}
|
}
|
||||||
if (rep.palnum == DETAILPAL)
|
if (rep.palnum == DETAILPAL)
|
||||||
{
|
{
|
||||||
detailTex = rep.faces[0];
|
detailTex = rep.image;
|
||||||
scalex = rep.scale.X;
|
scalex = rep.scale.X;
|
||||||
scaley = rep.scale.Y;
|
scaley = rep.scale.Y;
|
||||||
}
|
}
|
||||||
|
@ -185,10 +195,10 @@ void PostLoadSetup()
|
||||||
{
|
{
|
||||||
for (auto& rep : *Hightile)
|
for (auto& rep : *Hightile)
|
||||||
{
|
{
|
||||||
if (rep.faces[1]) continue; // do not muck around with skyboxes (yet)
|
if (rep.issky) continue; // do not muck around with skyboxes (yet)
|
||||||
if (rep.palnum < NORMALPAL)
|
if (rep.palnum < NORMALPAL)
|
||||||
{
|
{
|
||||||
auto tex = rep.faces[0];
|
auto tex = rep.image;
|
||||||
// Make a copy so that multiple appearances of the same texture with different layers can be handled. They will all refer to the same internal texture anyway.
|
// Make a copy so that multiple appearances of the same texture with different layers can be handled. They will all refer to the same internal texture anyway.
|
||||||
tex = MakeGameTexture(tex->GetTexture(), "", ETextureType::Any);
|
tex = MakeGameTexture(tex->GetTexture(), "", ETextureType::Any);
|
||||||
if (glowTex) tex->SetGlowmap(glowTex->GetTexture());
|
if (glowTex) tex->SetGlowmap(glowTex->GetTexture());
|
||||||
|
@ -196,7 +206,7 @@ void PostLoadSetup()
|
||||||
if (normalTex) tex->SetNormalmap(normalTex->GetTexture());
|
if (normalTex) tex->SetNormalmap(normalTex->GetTexture());
|
||||||
if (specTex) tex->SetSpecularmap(specTex->GetTexture());
|
if (specTex) tex->SetSpecularmap(specTex->GetTexture());
|
||||||
tex->SetDetailScale(scalex, scaley);
|
tex->SetDetailScale(scalex, scaley);
|
||||||
rep.faces[0] = tex;
|
rep.image = tex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -237,7 +247,7 @@ void PostLoadSetup()
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
int tileSetHightileReplacement(int picnum, int palnum, const char* filename, float alphacut, float xscale, float yscale, float specpower, float specfactor, uint8_t flags)
|
int tileSetHightileReplacement(int picnum, int palnum, const char* filename, float alphacut, float xscale, float yscale, float specpower, float specfactor)
|
||||||
{
|
{
|
||||||
if ((uint32_t)picnum >= (uint32_t)MAXTILES) return -1;
|
if ((uint32_t)picnum >= (uint32_t)MAXTILES) return -1;
|
||||||
if ((uint32_t)palnum >= (uint32_t)MAXPALOOKUPS) return -1;
|
if ((uint32_t)palnum >= (uint32_t)MAXPALOOKUPS) return -1;
|
||||||
|
@ -257,13 +267,12 @@ int tileSetHightileReplacement(int picnum, int palnum, const char* filename, flo
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
replace.faces[0] = TexMan.GetGameTexture(texid);
|
replace.image = TexMan.GetGameTexture(texid);
|
||||||
if (replace.faces[0] == nullptr)
|
|
||||||
replace.alphacut = min(alphacut,1.f);
|
replace.alphacut = min(alphacut,1.f);
|
||||||
replace.scale = { xscale, yscale };
|
replace.scale = { xscale, yscale };
|
||||||
replace.specpower = specpower; // currently unused
|
replace.specpower = specpower; // currently unused
|
||||||
replace.specfactor = specfactor; // currently unused
|
replace.specfactor = specfactor; // currently unused
|
||||||
replace.flags = flags;
|
replace.issky = 0;
|
||||||
replace.palnum = (uint16_t)palnum;
|
replace.palnum = (uint16_t)palnum;
|
||||||
AddReplacement(picnum, replace);
|
AddReplacement(picnum, replace);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -276,7 +285,7 @@ int tileSetHightileReplacement(int picnum, int palnum, const char* filename, flo
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
int tileSetSkybox(int picnum, int palnum, const char **facenames, int flags )
|
int tileSetSkybox(int picnum, int palnum, FString* facenames)
|
||||||
{
|
{
|
||||||
if ((uint32_t)picnum >= (uint32_t)MAXTILES) return -1;
|
if ((uint32_t)picnum >= (uint32_t)MAXTILES) return -1;
|
||||||
if ((uint32_t)palnum >= (uint32_t)MAXPALOOKUPS) return -1;
|
if ((uint32_t)palnum >= (uint32_t)MAXPALOOKUPS) return -1;
|
||||||
|
@ -289,17 +298,24 @@ int tileSetSkybox(int picnum, int palnum, const char **facenames, int flags )
|
||||||
}
|
}
|
||||||
HightileReplacement replace = {};
|
HightileReplacement replace = {};
|
||||||
|
|
||||||
for (auto &face : replace.faces)
|
FGameTexture *faces[6];
|
||||||
|
for (int i = 0; i < 6; i++)
|
||||||
{
|
{
|
||||||
FTextureID texid = TexMan.CheckForTexture(*facenames, ETextureType::Any);
|
FTextureID texid = TexMan.CheckForTexture(facenames[i], ETextureType::Any);
|
||||||
if (!texid.isValid())
|
if (!texid.isValid())
|
||||||
{
|
{
|
||||||
Printf("%s: Skybox image for tile %d does not exist or is invalid\n", *facenames, picnum);
|
Printf("%s: Skybox image for tile %d does not exist or is invalid\n", facenames[i].GetChars(), picnum);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
face = TexMan.GetGameTexture(texid);
|
faces[i] = TexMan.GetGameTexture(texid);
|
||||||
}
|
}
|
||||||
replace.flags = flags;
|
FSkyBox* sbtex = new FSkyBox("");
|
||||||
|
memcpy(sbtex->faces, faces, sizeof(faces));
|
||||||
|
sbtex->previous = faces[0]; // won't ever be used, just to be safe.
|
||||||
|
sbtex->fliptop = true;
|
||||||
|
replace.image = MakeGameTexture(sbtex, "", ETextureType::Override);
|
||||||
|
TexMan.AddGameTexture(replace.image, false);
|
||||||
|
replace.issky = 1;
|
||||||
replace.palnum = (uint16_t)palnum;
|
replace.palnum = (uint16_t)palnum;
|
||||||
AddReplacement(picnum, replace);
|
AddReplacement(picnum, replace);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -341,7 +357,7 @@ bool PickTexture(FRenderState *state, FGameTexture* tex, int paletteid, TextureP
|
||||||
|
|
||||||
if (rep)
|
if (rep)
|
||||||
{
|
{
|
||||||
tex = rep->faces[0];
|
tex = rep->image;
|
||||||
}
|
}
|
||||||
if (!rep || rep->palnum != hipalswap || (h.tintFlags & TINTF_APPLYOVERALTPAL))
|
if (!rep || rep->palnum != hipalswap || (h.tintFlags & TINTF_APPLYOVERALTPAL))
|
||||||
applytint = true;
|
applytint = true;
|
||||||
|
|
|
@ -38,6 +38,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
#include "v_2ddrawer.h"
|
#include "v_2ddrawer.h"
|
||||||
#include "v_video.h"
|
#include "v_video.h"
|
||||||
#include "v_font.h"
|
#include "v_font.h"
|
||||||
|
#include "hw_voxels.h"
|
||||||
#include "glbackend/glbackend.h"
|
#include "glbackend/glbackend.h"
|
||||||
|
|
||||||
BEGIN_BLD_NS
|
BEGIN_BLD_NS
|
||||||
|
|
|
@ -656,7 +656,7 @@ void ParseScript(int lumpnum)
|
||||||
if (dword_44CE0[gParseLevel] == 0)
|
if (dword_44CE0[gParseLevel] == 0)
|
||||||
{
|
{
|
||||||
// In the RFS files I have seen the outermost directory is not part of what goes into the file system.
|
// In the RFS files I have seen the outermost directory is not part of what goes into the file system.
|
||||||
auto inp1 = strchr(inp, '\\');
|
auto inp1 = strpbrk(inp, "/\\");
|
||||||
if (!inp1 || !fileSystem.CreatePathlessCopy(inp1 + 1, ID, nFlags))
|
if (!inp1 || !fileSystem.CreatePathlessCopy(inp1 + 1, ID, nFlags))
|
||||||
{
|
{
|
||||||
// I'll activate this when I find evidence that it is needed. Otherwise the risk of picking up unwanted data is too high.
|
// I'll activate this when I find evidence that it is needed. Otherwise the risk of picking up unwanted data is too high.
|
||||||
|
|
|
@ -465,9 +465,6 @@ void GameInterface::app_init()
|
||||||
|
|
||||||
HookReplaceFunctions();
|
HookReplaceFunctions();
|
||||||
|
|
||||||
Printf(PRINT_NONOTIFY, "Initializing Build 3D engine\n");
|
|
||||||
engineInit();
|
|
||||||
|
|
||||||
Printf(PRINT_NONOTIFY, "Loading tiles\n");
|
Printf(PRINT_NONOTIFY, "Loading tiles\n");
|
||||||
if (!tileInit(0, NULL))
|
if (!tileInit(0, NULL))
|
||||||
I_FatalError("TILES###.ART files not found");
|
I_FatalError("TILES###.ART files not found");
|
||||||
|
|
|
@ -115,6 +115,28 @@ void levelLoadMapInfo(IniFile *pIni, MapRecord *pLevelInfo, const char *pzSectio
|
||||||
|
|
||||||
static const char* DefFile(void)
|
static const char* DefFile(void)
|
||||||
{
|
{
|
||||||
|
int found = -1;
|
||||||
|
if (userConfig.DefaultCon.IsEmpty() || userConfig.DefaultCon.CompareNoCase("blood.ini") == 0)
|
||||||
|
{
|
||||||
|
int numlumps = fileSystem.GetNumEntries();
|
||||||
|
for (int i = numlumps - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
if (fileSystem.GetFileContainer(i) <= fileSystem.GetMaxIwadNum()) break;
|
||||||
|
FString fn = fileSystem.GetFileFullName(i, false);
|
||||||
|
FString ext = fn.Right(4);
|
||||||
|
if (ext.CompareNoCase(".ini") == 0)
|
||||||
|
{
|
||||||
|
if (fileSystem.CheckNumForFullName(fn) != i) continue;
|
||||||
|
if (found == -1) found = i;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
found = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (found >= 0) return fileSystem.GetFileFullName(found);
|
||||||
// The command line parser stores this in the CON field.
|
// The command line parser stores this in the CON field.
|
||||||
return userConfig.DefaultCon.IsNotEmpty() ? userConfig.DefaultCon.GetChars() : "blood.ini";
|
return userConfig.DefaultCon.IsNotEmpty() ? userConfig.DefaultCon.GetChars() : "blood.ini";
|
||||||
}
|
}
|
||||||
|
|
|
@ -122,7 +122,6 @@ extern short voxelIndex[MAXTILES];
|
||||||
extern int nPrecacheCount;
|
extern int nPrecacheCount;
|
||||||
|
|
||||||
int tileInit(char a1, const char *a2);
|
int tileInit(char a1, const char *a2);
|
||||||
void tileProcessGLVoxels(void);
|
|
||||||
void tilePreloadTile(int nTile);
|
void tilePreloadTile(int nTile);
|
||||||
void tilePrecacheTile(int nTile, int nType, HitList& hits);
|
void tilePrecacheTile(int nTile, int nType, HitList& hits);
|
||||||
|
|
||||||
|
|
|
@ -44,14 +44,11 @@ char surfType[kMaxTiles];
|
||||||
signed char tileShade[kMaxTiles];
|
signed char tileShade[kMaxTiles];
|
||||||
short voxelIndex[kMaxTiles];
|
short voxelIndex[kMaxTiles];
|
||||||
|
|
||||||
const char *pzBaseFileName = "TILES%03i.ART"; //"TILES%03i.ART";
|
|
||||||
|
|
||||||
int tileInit(char a1, const char *a2)
|
int tileInit(char a1, const char *a2)
|
||||||
{
|
{
|
||||||
UNREFERENCED_PARAMETER(a1);
|
UNREFERENCED_PARAMETER(a1);
|
||||||
if (artLoaded)
|
if (artLoaded)
|
||||||
return 1;
|
return 1;
|
||||||
TileFiles.artLoadFiles(a2 ? a2 : pzBaseFileName);
|
|
||||||
for (int i = 0; i < kMaxTiles; i++)
|
for (int i = 0; i < kMaxTiles; i++)
|
||||||
voxelIndex[i] = 0;
|
voxelIndex[i] = 0;
|
||||||
|
|
||||||
|
@ -81,32 +78,9 @@ int tileInit(char a1, const char *a2)
|
||||||
}
|
}
|
||||||
|
|
||||||
artLoaded = 1;
|
artLoaded = 1;
|
||||||
|
|
||||||
#ifdef USE_OPENGL
|
|
||||||
PolymostProcessVoxels_Callback = tileProcessGLVoxels;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_OPENGL
|
|
||||||
void tileProcessGLVoxels(void)
|
|
||||||
{
|
|
||||||
static bool voxInit = false;
|
|
||||||
if (voxInit)
|
|
||||||
return;
|
|
||||||
voxInit = true;
|
|
||||||
for (int i = 0; i < kMaxVoxels; i++)
|
|
||||||
{
|
|
||||||
auto index = fileSystem.FindResource(i, "KVX");
|
|
||||||
if (index >= 0)
|
|
||||||
{
|
|
||||||
voxmodels[i] = voxload(index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
char tileGetSurfType(int hit)
|
char tileGetSurfType(int hit)
|
||||||
{
|
{
|
||||||
int n = hit & 0x3fff;
|
int n = hit & 0x3fff;
|
||||||
|
|
|
@ -266,7 +266,7 @@ void WeaponDraw(PLAYER *pPlayer, int shade, double xpos, double ypos, int palnum
|
||||||
if (pPlayer->weaponTimer == 0) // playing idle QAV?
|
if (pPlayer->weaponTimer == 0) // playing idle QAV?
|
||||||
{
|
{
|
||||||
// Double shotgun fix from BloodGDX.
|
// Double shotgun fix from BloodGDX.
|
||||||
if (/*!IsOriginalDemo() &&*/ (pPlayer->weaponState == -1 || (pPlayer->curWeapon == 3 && pPlayer->weaponState == 7)) && isOriginalQAV())
|
if (/*!IsOriginalDemo() &&*/ (pPlayer->weaponState == -1 || (pPlayer->curWeapon == 3 && pPlayer->weaponState == 7))/* && isOriginalQAV()*/)
|
||||||
duration = pQAV->duration - 1;
|
duration = pQAV->duration - 1;
|
||||||
else duration = (PlayClock + MulScale(4, smoothratio, 16)) % pQAV->duration;
|
else duration = (PlayClock + MulScale(4, smoothratio, 16)) % pQAV->duration;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4505,7 +4505,7 @@ void handle_se27(DDukeActor* actor)
|
||||||
//
|
//
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
void handle_se24(DDukeActor *actor, int16_t *list1, int16_t *list2, int TRIPBOMB, int LASERLINE, int CRANE, int shift)
|
void handle_se24(DDukeActor *actor, int16_t *list1, int16_t *list2, bool scroll, int TRIPBOMB, int LASERLINE, int CRANE, int shift)
|
||||||
{
|
{
|
||||||
int* t = &actor->temp_data[0];
|
int* t = &actor->temp_data[0];
|
||||||
|
|
||||||
|
@ -4575,7 +4575,7 @@ void handle_se24(DDukeActor *actor, int16_t *list1, int16_t *list2, int TRIPBOMB
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sector[actor->s.sectnum].addfloorxpan(actor->s.yvel / 128.f);
|
if (scroll) sector[actor->s.sectnum].addfloorxpan(actor->s.yvel / 128.f);
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
|
@ -3697,7 +3697,7 @@ void moveeffectors_d(void) //STATNUM 3
|
||||||
{
|
{
|
||||||
static int16_t list1[] = { BLOODPOOL, PUKE, FOOTPRINTS, FOOTPRINTS2, FOOTPRINTS3, FOOTPRINTS4, BULLETHOLE, BLOODSPLAT1, BLOODSPLAT2, BLOODSPLAT3, BLOODSPLAT4, -1 };
|
static int16_t list1[] = { BLOODPOOL, PUKE, FOOTPRINTS, FOOTPRINTS2, FOOTPRINTS3, FOOTPRINTS4, BULLETHOLE, BLOODSPLAT1, BLOODSPLAT2, BLOODSPLAT3, BLOODSPLAT4, -1 };
|
||||||
static int16_t list2[] = { BOLT1, BOLT1 + 1,BOLT1 + 2, BOLT1 + 3, SIDEBOLT1, SIDEBOLT1 + 1, SIDEBOLT1 + 2, SIDEBOLT1 + 3, -1 };
|
static int16_t list2[] = { BOLT1, BOLT1 + 1,BOLT1 + 2, BOLT1 + 3, SIDEBOLT1, SIDEBOLT1 + 1, SIDEBOLT1 + 2, SIDEBOLT1 + 3, -1 };
|
||||||
handle_se24(act, list1, list2, TRIPBOMB, LASERLINE, CRANE, 2);
|
handle_se24(act, list1, list2, false, TRIPBOMB, LASERLINE, CRANE, 2);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SE_35:
|
case SE_35:
|
||||||
|
|
|
@ -3576,7 +3576,7 @@ void moveeffectors_r(void) //STATNUM 3
|
||||||
{
|
{
|
||||||
static int16_t list1[] = { BLOODPOOL, PUKE, FOOTPRINTS, FOOTPRINTS2, FOOTPRINTS3, -1 };
|
static int16_t list1[] = { BLOODPOOL, PUKE, FOOTPRINTS, FOOTPRINTS2, FOOTPRINTS3, -1 };
|
||||||
static int16_t list2[] = { BOLT1, BOLT1 + 1,BOLT1 + 2, BOLT1 + 3, -1 };
|
static int16_t list2[] = { BOLT1, BOLT1 + 1,BOLT1 + 2, BOLT1 + 3, -1 };
|
||||||
handle_se24(act, list1, list2, BULLETHOLE, -1, CRANE, 1);
|
handle_se24(act, list1, list2, st != 156, BULLETHOLE, -1, CRANE, 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -84,7 +84,7 @@ void handle_se19(DDukeActor* i, int BIGFORCE);
|
||||||
void handle_se20(DDukeActor* i);
|
void handle_se20(DDukeActor* i);
|
||||||
void handle_se21(DDukeActor* i);
|
void handle_se21(DDukeActor* i);
|
||||||
void handle_se22(DDukeActor* i);
|
void handle_se22(DDukeActor* i);
|
||||||
void handle_se24(DDukeActor* actor, int16_t* list1, int16_t* list2, int TRIPBOMB, int LASERLINE, int CRANE, int shift);
|
void handle_se24(DDukeActor* actor, int16_t* list1, int16_t* list2, bool scroll, int TRIPBOMB, int LASERLINE, int CRANE, int shift);
|
||||||
void handle_se25(DDukeActor* a, int t_index, int snd1, int snd2);
|
void handle_se25(DDukeActor* a, int t_index, int snd1, int snd2);
|
||||||
void handle_se26(DDukeActor* i);
|
void handle_se26(DDukeActor* i);
|
||||||
void handle_se27(DDukeActor* i);
|
void handle_se27(DDukeActor* i);
|
||||||
|
|
|
@ -230,9 +230,6 @@ static void setupbackdrop()
|
||||||
|
|
||||||
static void initTiles()
|
static void initTiles()
|
||||||
{
|
{
|
||||||
if (TileFiles.artLoadFiles("tiles%03i.art") < 0)
|
|
||||||
I_FatalError("Failed loading art.");
|
|
||||||
|
|
||||||
tileDelete(TILE_MIRROR);
|
tileDelete(TILE_MIRROR);
|
||||||
skiptile = TILE_W_FORCEFIELD + 1;
|
skiptile = TILE_W_FORCEFIELD + 1;
|
||||||
|
|
||||||
|
@ -310,9 +307,6 @@ void GameInterface::app_init()
|
||||||
|
|
||||||
OnEvent(EVENT_INIT);
|
OnEvent(EVENT_INIT);
|
||||||
|
|
||||||
if (engineInit())
|
|
||||||
G_FatalEngineError();
|
|
||||||
|
|
||||||
//Net_SendClientInfo();
|
//Net_SendClientInfo();
|
||||||
|
|
||||||
initTiles();
|
initTiles();
|
||||||
|
|
|
@ -65,7 +65,6 @@ inline DDukeActor* getSndActor(const void* source)
|
||||||
return source ? &hittype[((spritetype*)source) - sprite] : nullptr;
|
return source ? &hittype[((spritetype*)source) - sprite] : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
TArray<FString> specialmusic;
|
|
||||||
static FSoundID currentCommentarySound;
|
static FSoundID currentCommentarySound;
|
||||||
static DDukeActor* currentCommentarySprite; // todo: GC this once actors become objects
|
static DDukeActor* currentCommentarySprite; // todo: GC this once actors become objects
|
||||||
|
|
||||||
|
|
|
@ -74,8 +74,6 @@ void S_ParseDeveloperCommentary();
|
||||||
void StopCommentary();
|
void StopCommentary();
|
||||||
bool StartCommentary(int tag, DDukeActor* sprnum);
|
bool StartCommentary(int tag, DDukeActor* sprnum);
|
||||||
|
|
||||||
extern TArray<FString> specialmusic;
|
|
||||||
|
|
||||||
|
|
||||||
END_DUKE_NS
|
END_DUKE_NS
|
||||||
|
|
||||||
|
|
|
@ -785,7 +785,8 @@ void spawneffector(DDukeActor* actor)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 156:
|
case 156:
|
||||||
if (!isRRRA()) break;
|
break;
|
||||||
|
|
||||||
case 34:
|
case 34:
|
||||||
StartInterpolation(sect, Interp_Sect_FloorPanX);
|
StartInterpolation(sect, Interp_Sect_FloorPanX);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -75,12 +75,6 @@ void ResetEngine()
|
||||||
|
|
||||||
void InstallEngine()
|
void InstallEngine()
|
||||||
{
|
{
|
||||||
TileFiles.LoadArtSet("tiles%03d.art");
|
|
||||||
|
|
||||||
if (engineInit())
|
|
||||||
{
|
|
||||||
G_FatalEngineError();
|
|
||||||
}
|
|
||||||
uploadCinemaPalettes();
|
uploadCinemaPalettes();
|
||||||
LoadPaletteLookups();
|
LoadPaletteLookups();
|
||||||
}
|
}
|
||||||
|
|
|
@ -193,7 +193,7 @@ static void Intermission(MapRecord *from_map, MapRecord *to_map)
|
||||||
gameaction = ga_nextlevel;
|
gameaction = ga_nextlevel;
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
}, true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1123,7 +1123,7 @@ void CameraView(PLAYERp pp, int *tx, int *ty, int *tz, short *tsectnum, binangle
|
||||||
{
|
{
|
||||||
sp = &sprite[i];
|
sp = &sprite[i];
|
||||||
|
|
||||||
ang = q16ang(gethiq16angle(*tx - sp->x, *ty - sp->y));
|
ang = bvectangbam(*tx - sp->x, *ty - sp->y);
|
||||||
ang_test = getincangle(ang.asbuild(), sp->ang) < sp->lotag;
|
ang_test = getincangle(ang.asbuild(), sp->ang) < sp->lotag;
|
||||||
|
|
||||||
FAFcansee_test =
|
FAFcansee_test =
|
||||||
|
@ -1568,7 +1568,7 @@ drawscreen(PLAYERp pp, double smoothratio)
|
||||||
if (TEST_BOOL1(pp->remote_sprite))
|
if (TEST_BOOL1(pp->remote_sprite))
|
||||||
tang = buildang(pp->remote_sprite->ang);
|
tang = buildang(pp->remote_sprite->ang);
|
||||||
else
|
else
|
||||||
tang = q16ang(gethiq16angle(pp->sop_remote->xmid - tx, pp->sop_remote->ymid - ty));
|
tang = bvectangbam(pp->sop_remote->xmid - tx, pp->sop_remote->ymid - ty);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TEST(pp->Flags, PF_VIEW_FROM_OUTSIDE))
|
if (TEST(pp->Flags, PF_VIEW_FROM_OUTSIDE))
|
||||||
|
|
|
@ -199,7 +199,6 @@ void GameInterface::app_init()
|
||||||
|
|
||||||
registerosdcommands();
|
registerosdcommands();
|
||||||
|
|
||||||
engineInit();
|
|
||||||
auto pal = fileSystem.LoadFile("3drealms.pal", 0);
|
auto pal = fileSystem.LoadFile("3drealms.pal", 0);
|
||||||
if (pal.Size() >= 768)
|
if (pal.Size() >= 768)
|
||||||
{
|
{
|
||||||
|
@ -220,8 +219,6 @@ void GameInterface::app_init()
|
||||||
"the full version. Read the Ordering Info screens for details.");
|
"the full version. Read the Ordering Info screens for details.");
|
||||||
}
|
}
|
||||||
|
|
||||||
TileFiles.LoadArtSet("tiles%03d.art");
|
|
||||||
|
|
||||||
//Connect();
|
//Connect();
|
||||||
SortBreakInfo();
|
SortBreakInfo();
|
||||||
parallaxtype = 1;
|
parallaxtype = 1;
|
||||||
|
|
|
@ -110,8 +110,10 @@ static void so_setpointinterpolation(so_interp *interp, int element)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (i = 0; i < interp->numinterpolations; i++)
|
for (i = 0; i < interp->numinterpolations; i++)
|
||||||
|
{
|
||||||
if (interp->data[i].curelement == element)
|
if (interp->data[i].curelement == element)
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
so_interp::interp_data *data = &interp->data[interp->numinterpolations++];
|
so_interp::interp_data *data = &interp->data[interp->numinterpolations++];
|
||||||
|
|
||||||
|
@ -129,7 +131,7 @@ static void so_setspriteanginterpolation(so_interp *interp, int32_t spritenum)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (i = 0; i < interp->numinterpolations; i++)
|
for (i = 0; i < interp->numinterpolations; i++)
|
||||||
if (interp->data[i].curelement == -1)
|
if (interp->data[i].curelement == -1 && interp->data[i].spriteofang == spritenum)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
so_interp::interp_data *data = &interp->data[interp->numinterpolations++];
|
so_interp::interp_data *data = &interp->data[interp->numinterpolations++];
|
||||||
|
@ -148,9 +150,16 @@ static void so_stopdatainterpolation(so_interp *interp, int element)
|
||||||
int32_t i;
|
int32_t i;
|
||||||
|
|
||||||
for (i = 0; i < interp->numinterpolations; i++)
|
for (i = 0; i < interp->numinterpolations; i++)
|
||||||
if (interp->data[i].curelement == element)
|
{
|
||||||
|
if (interp->data[i].curelement == -1)
|
||||||
|
{
|
||||||
|
if (interp->data[i].spriteofang == element) break;
|
||||||
|
}
|
||||||
|
else if (interp->data[i].curelement == element)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if (i == interp->numinterpolations)
|
if (i == interp->numinterpolations)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -219,7 +228,7 @@ void so_setspriteinterpolation(SECTOR_OBJECTp sop, spritetype *sp)
|
||||||
so_setpointinterpolation(interp, snum | soi_spry);
|
so_setpointinterpolation(interp, snum | soi_spry);
|
||||||
if (!interp->hasvator)
|
if (!interp->hasvator)
|
||||||
so_setpointinterpolation(interp, snum | soi_sprz);
|
so_setpointinterpolation(interp, snum | soi_sprz);
|
||||||
so_setspriteanginterpolation(interp, int(sp - sprite));
|
so_setspriteanginterpolation(interp, snum);
|
||||||
}
|
}
|
||||||
|
|
||||||
void so_stopspriteinterpolation(SECTOR_OBJECTp sop, spritetype *sp)
|
void so_stopspriteinterpolation(SECTOR_OBJECTp sop, spritetype *sp)
|
||||||
|
|
|
@ -5471,7 +5471,7 @@ DoPlayerStopOperate(PLAYERp pp)
|
||||||
if (TEST_BOOL1(pp->remote_sprite))
|
if (TEST_BOOL1(pp->remote_sprite))
|
||||||
pp->angle.ang = pp->angle.oang = buildang(pp->remote_sprite->ang);
|
pp->angle.ang = pp->angle.oang = buildang(pp->remote_sprite->ang);
|
||||||
else
|
else
|
||||||
pp->angle.ang = pp->angle.oang = q16ang(gethiq16angle(pp->sop_remote->xmid - pp->posx, pp->sop_remote->ymid - pp->posy));
|
pp->angle.ang = pp->angle.oang = bvectangbam(pp->sop_remote->xmid - pp->posx, pp->sop_remote->ymid - pp->posy);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pp->sop_control)
|
if (pp->sop_control)
|
||||||
|
@ -7148,7 +7148,9 @@ domovethings(void)
|
||||||
// auto tracking mode for single player multi-game
|
// auto tracking mode for single player multi-game
|
||||||
if (numplayers <= 1 && PlayerTrackingMode && pnum == screenpeek && screenpeek != myconnectindex)
|
if (numplayers <= 1 && PlayerTrackingMode && pnum == screenpeek && screenpeek != myconnectindex)
|
||||||
{
|
{
|
||||||
Player[screenpeek].angle.settarget(bvectangf(Player[myconnectindex].posx - Player[screenpeek].posx, Player[myconnectindex].posy - Player[screenpeek].posy));
|
int deltax = Player[myconnectindex].posx - Player[screenpeek].posx;
|
||||||
|
int deltay = Player[myconnectindex].posy - Player[screenpeek].posy;
|
||||||
|
Player[screenpeek].angle.settarget(bvectangbam(deltax, deltay));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!TEST(pp->Flags, PF_DEAD))
|
if (!TEST(pp->Flags, PF_DEAD))
|
||||||
|
|
|
@ -695,7 +695,7 @@ private:
|
||||||
void DisplayMinibarInventory(PLAYERp pp)
|
void DisplayMinibarInventory(PLAYERp pp)
|
||||||
{
|
{
|
||||||
int InventoryBoxX = MINI_BAR_INVENTORY_BOX_X;
|
int InventoryBoxX = MINI_BAR_INVENTORY_BOX_X;
|
||||||
int InventoryBoxY = MINI_BAR_INVENTORY_BOX_Y;
|
int InventoryBoxY = MINI_BAR_INVENTORY_BOX_Y - 200;
|
||||||
|
|
||||||
int InventoryXoff = 0;
|
int InventoryXoff = 0;
|
||||||
int InventoryYoff = 1;
|
int InventoryYoff = 1;
|
||||||
|
|
|
@ -40,6 +40,7 @@ Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms
|
||||||
#include "razemenu.h"
|
#include "razemenu.h"
|
||||||
#include "quotemgr.h"
|
#include "quotemgr.h"
|
||||||
#include "mapinfo.h"
|
#include "mapinfo.h"
|
||||||
|
#include "hw_voxels.h"
|
||||||
|
|
||||||
BEGIN_SW_NS
|
BEGIN_SW_NS
|
||||||
|
|
||||||
|
@ -231,7 +232,7 @@ void LoadKVXFromScript(const char* filename)
|
||||||
GetToken(false);
|
GetToken(false);
|
||||||
|
|
||||||
// Load the voxel file into memory
|
// Load the voxel file into memory
|
||||||
if (!qloadkvx(lNumber,token))
|
if (!voxDefine(lNumber,token))
|
||||||
{
|
{
|
||||||
// Store the sprite and voxel numbers for later use
|
// Store the sprite and voxel numbers for later use
|
||||||
aVoxelArray[lTile].Voxel = lNumber; // Voxel num
|
aVoxelArray[lTile].Voxel = lNumber; // Voxel num
|
||||||
|
|
|
@ -86,20 +86,3 @@ bool GLInstance::SetTexture(FGameTexture* tex, int paletteid, int sampler, bool
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
//
|
|
||||||
// stand-ins for the texture system. Nothing of this is used right now, but needs to be present to satisfy the linker
|
|
||||||
//
|
|
||||||
//===========================================================================
|
|
||||||
|
|
||||||
void InitBuildTiles()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
TArray<UserShaderDesc> usershaders;
|
|
||||||
|
|
||||||
void UpdateVRModes(bool considerQuadBuffered = true)
|
|
||||||
{
|
|
||||||
// should update the menu.
|
|
||||||
}
|
|
||||||
|
|
|
@ -70,33 +70,16 @@ void Draw2D(F2DDrawer* drawer, FRenderState& state);
|
||||||
GLInstance GLInterface;
|
GLInstance GLInterface;
|
||||||
|
|
||||||
GLInstance::GLInstance()
|
GLInstance::GLInstance()
|
||||||
:palmanager(this)
|
|
||||||
{
|
{
|
||||||
VSMatrix mat(0);
|
VSMatrix mat(0);
|
||||||
matrixArray.Push(mat);
|
matrixArray.Push(mat);
|
||||||
}
|
}
|
||||||
|
|
||||||
IHardwareTexture *setpalettelayer(int layer, int translation)
|
|
||||||
{
|
|
||||||
if (layer == 1)
|
|
||||||
return GLInterface.palmanager.GetPalette(GetTranslationType(translation) - Translation_Remap);
|
|
||||||
else if (layer == 2)
|
|
||||||
return GLInterface.palmanager.GetLookup(GetTranslationIndex(translation));
|
|
||||||
else return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GLInstance::Init(int ydim)
|
void GLInstance::Init(int ydim)
|
||||||
{
|
{
|
||||||
FMaterial::SetLayerCallback(setpalettelayer);
|
|
||||||
new(&renderState) PolymostRenderState; // reset to defaults.
|
new(&renderState) PolymostRenderState; // reset to defaults.
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLInstance::Deinit()
|
|
||||||
{
|
|
||||||
palmanager.DeleteAll();
|
|
||||||
lastPalswapIndex = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GLInstance::Draw(EDrawType type, size_t start, size_t count)
|
void GLInstance::Draw(EDrawType type, size_t start, size_t count)
|
||||||
{
|
{
|
||||||
assert (BufferLock > 0);
|
assert (BufferLock > 0);
|
||||||
|
|
|
@ -21,25 +21,6 @@ class F2DDrawer;
|
||||||
struct palette_t;
|
struct palette_t;
|
||||||
extern int xdim, ydim;
|
extern int xdim, ydim;
|
||||||
|
|
||||||
class PaletteManager
|
|
||||||
{
|
|
||||||
IHardwareTexture* palettetextures[256] = {};
|
|
||||||
IHardwareTexture* lookuptextures[256] = {};
|
|
||||||
|
|
||||||
GLInstance* const inst;
|
|
||||||
|
|
||||||
unsigned FindPalswap(const uint8_t* paldata, palette_t& fadecolor);
|
|
||||||
|
|
||||||
public:
|
|
||||||
PaletteManager(GLInstance *inst_) : inst(inst_)
|
|
||||||
{}
|
|
||||||
~PaletteManager();
|
|
||||||
void DeleteAll();
|
|
||||||
IHardwareTexture *GetPalette(int index);
|
|
||||||
IHardwareTexture* GetLookup(int index);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
struct glinfo_t {
|
struct glinfo_t {
|
||||||
float maxanisotropy;
|
float maxanisotropy;
|
||||||
};
|
};
|
||||||
|
@ -76,8 +57,6 @@ class GLInstance
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TArray<PolymostRenderState> rendercommands;
|
TArray<PolymostRenderState> rendercommands;
|
||||||
PaletteManager palmanager;
|
|
||||||
int lastPalswapIndex = -1;
|
|
||||||
FGameTexture* currentTexture = nullptr;
|
FGameTexture* currentTexture = nullptr;
|
||||||
int MatrixChange = 0;
|
int MatrixChange = 0;
|
||||||
|
|
||||||
|
@ -90,8 +69,6 @@ public:
|
||||||
|
|
||||||
void Init(int y);
|
void Init(int y);
|
||||||
|
|
||||||
void Deinit();
|
|
||||||
|
|
||||||
static int GetTexDimension(int value)
|
static int GetTexDimension(int value)
|
||||||
{
|
{
|
||||||
//if (value > gl.max_texturesize) return gl.max_texturesize;
|
//if (value > gl.max_texturesize) return gl.max_texturesize;
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue