mirror of
https://github.com/ZDoom/qzdoom.git
synced 2025-03-13 22:33:24 +00:00
Merge remote-tracking branch 'gzdoom/master' into newmaster
This commit is contained in:
commit
d29b514985
33 changed files with 450 additions and 544 deletions
|
@ -1048,7 +1048,6 @@ set (PCH_SOURCES
|
|||
gamedata/textures/formats/tgatexture.cpp
|
||||
gamedata/textures/formats/stbtexture.cpp
|
||||
gamedata/textures/hires/hqresize.cpp
|
||||
gamedata/textures/hires/hirestex.cpp
|
||||
gamedata/fonts/singlelumpfont.cpp
|
||||
gamedata/fonts/singlepicfont.cpp
|
||||
gamedata/fonts/specialfont.cpp
|
||||
|
|
|
@ -174,6 +174,26 @@ extern bool insave;
|
|||
extern TDeletingArray<FLightDefaults *> LightDefaults;
|
||||
|
||||
|
||||
CUSTOM_CVAR(Float, i_timescale, 1.0f, CVAR_NOINITCALL)
|
||||
{
|
||||
if (netgame)
|
||||
{
|
||||
Printf("Time scale cannot be changed in net games.\n");
|
||||
self = 1.0f;
|
||||
}
|
||||
else if (self >= 0.05f)
|
||||
{
|
||||
I_FreezeTime(true);
|
||||
TimeScale = self;
|
||||
I_FreezeTime(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
Printf("Time scale must be at least 0.05!\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// PUBLIC DATA DEFINITIONS -------------------------------------------------
|
||||
|
||||
CUSTOM_CVAR (Int, fraglimit, 0, CVAR_SERVERINFO)
|
||||
|
@ -2883,6 +2903,7 @@ static int D_DoomMain_Internal (void)
|
|||
int D_DoomMain()
|
||||
{
|
||||
int ret = 0;
|
||||
GameTicRate = TICRATE;
|
||||
try
|
||||
{
|
||||
ret = D_DoomMain_Internal();
|
||||
|
|
|
@ -315,6 +315,7 @@ CCMD (slot)
|
|||
}
|
||||
|
||||
// [Nash] Option to display the name of the weapon being switched to.
|
||||
if (players[consoleplayer].playerstate != PST_LIVE) return;
|
||||
if (SendItemUse != players[consoleplayer].ReadyWeapon && (displaynametags & 2) && StatusBar && SmallFont && SendItemUse)
|
||||
{
|
||||
StatusBar->AttachMessage(Create<DHUDMessageFadeOut>(nullptr, SendItemUse->GetTag(),
|
||||
|
@ -363,6 +364,7 @@ CCMD (weapnext)
|
|||
}
|
||||
|
||||
// [BC] Option to display the name of the weapon being cycled to.
|
||||
if (players[consoleplayer].playerstate != PST_LIVE) return;
|
||||
if ((displaynametags & 2) && StatusBar && SmallFont && SendItemUse)
|
||||
{
|
||||
StatusBar->AttachMessage(Create<DHUDMessageFadeOut>(nullptr, SendItemUse->GetTag(),
|
||||
|
@ -389,6 +391,7 @@ CCMD (weapprev)
|
|||
}
|
||||
|
||||
// [BC] Option to display the name of the weapon being cycled to.
|
||||
if (players[consoleplayer].playerstate != PST_LIVE) return;
|
||||
if ((displaynametags & 2) && StatusBar && SmallFont && SendItemUse)
|
||||
{
|
||||
StatusBar->AttachMessage(Create<DHUDMessageFadeOut>(nullptr, SendItemUse->GetTag(),
|
||||
|
|
|
@ -1,414 +0,0 @@
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright(C) 2005-2016 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 3 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/
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
/*
|
||||
** external hires texture management (i.e. Doomsday style texture packs)
|
||||
**
|
||||
*/
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <io.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "w_wad.h"
|
||||
#include "m_png.h"
|
||||
#include "sbar.h"
|
||||
#include "gi.h"
|
||||
#include "cmdlib.h"
|
||||
#include "bitmap.h"
|
||||
#include "image.h"
|
||||
|
||||
#ifndef _WIN32
|
||||
#define _access(a,b) access(a,b)
|
||||
#endif
|
||||
|
||||
static int Doom2Wad = -1;
|
||||
|
||||
// quick'n dirty hack. Should be enough here...
|
||||
static void SetDoom2Wad()
|
||||
{
|
||||
if (Doom2Wad == -1)
|
||||
{
|
||||
FString iwad = Wads.GetWadFullName(Wads.GetIwadNum());
|
||||
iwad.ToLower();
|
||||
if (iwad.IndexOf("plutonia") >= 0) Doom2Wad = 1;
|
||||
else if (iwad.IndexOf("tnt") >= 0) Doom2Wad = 2;
|
||||
else Doom2Wad = 0;
|
||||
}
|
||||
}
|
||||
//==========================================================================
|
||||
//
|
||||
// Checks for the presence of a hires texture replacement in a Doomsday style PK3
|
||||
//
|
||||
//==========================================================================
|
||||
int FTexture::CheckDDPK3()
|
||||
{
|
||||
static const char * doom1texpath[]= {
|
||||
"data/jdoom/textures/doom/%s.%s", "data/jdoom/textures/doom-ult/%s.%s", "data/jdoom/textures/doom1/%s.%s", "data/jdoom/textures/%s.%s", NULL };
|
||||
|
||||
static const char * doom2texpath[]= {
|
||||
"data/jdoom/textures/doom2/%s.%s", "data/jdoom/textures/%s.%s", NULL };
|
||||
|
||||
static const char * pluttexpath[]= {
|
||||
"data/jdoom/textures/doom2-plut/%s.%s", "data/jdoom/textures/plutonia/%s.%s", "data/jdoom/textures/%s.%s", NULL };
|
||||
|
||||
static const char * tnttexpath[]= {
|
||||
"data/jdoom/textures/doom2-tnt/%s.%s", "data/jdoom/textures/tnt/%s.%s", "data/jdoom/textures/%s.%s", NULL };
|
||||
|
||||
static const char * heretictexpath[]= {
|
||||
"data/jheretic/textures/%s.%s", NULL };
|
||||
|
||||
static const char * hexentexpath[]= {
|
||||
"data/jhexen/textures/%s.%s", NULL };
|
||||
|
||||
static const char * strifetexpath[]= {
|
||||
"data/jstrife/textures/%s.%s", NULL };
|
||||
|
||||
static const char * chextexpath[]= {
|
||||
"data/jchex/textures/%s.%s", NULL };
|
||||
|
||||
static const char * doomflatpath[]= {
|
||||
"data/jdoom/flats/%s.%s", NULL };
|
||||
|
||||
static const char * hereticflatpath[]= {
|
||||
"data/jheretic/flats/%s.%s", NULL };
|
||||
|
||||
static const char * hexenflatpath[]= {
|
||||
"data/jhexen/flats/%s.%s", NULL };
|
||||
|
||||
static const char * strifeflatpath[]= {
|
||||
"data/jstrife/flats/%s.%s", NULL };
|
||||
|
||||
static const char * chexflatpath[]= {
|
||||
"data/jchex/flats/%s.%s", NULL };
|
||||
|
||||
|
||||
FString checkName;
|
||||
const char ** checklist;
|
||||
ETextureType useType=UseType;
|
||||
|
||||
if (useType==ETextureType::SkinSprite || useType==ETextureType::Decal || useType==ETextureType::FontChar)
|
||||
{
|
||||
return -3;
|
||||
}
|
||||
|
||||
bool ispatch = (useType==ETextureType::MiscPatch || useType==ETextureType::Sprite) ;
|
||||
|
||||
// for patches this doesn't work yet
|
||||
if (ispatch) return -3;
|
||||
|
||||
if (!gameinfo.ConfigName.CompareNoCase("Doom"))
|
||||
{
|
||||
if (!(gameinfo.flags & GI_MAPxx))
|
||||
{
|
||||
checklist = useType==ETextureType::Flat? doomflatpath : doom1texpath;
|
||||
}
|
||||
else
|
||||
{
|
||||
SetDoom2Wad();
|
||||
if (Doom2Wad == 1)
|
||||
checklist = useType==ETextureType::Flat? doomflatpath : pluttexpath;
|
||||
else if (Doom2Wad == 2)
|
||||
checklist = useType==ETextureType::Flat? doomflatpath : tnttexpath;
|
||||
else
|
||||
checklist = useType==ETextureType::Flat? doomflatpath : doom2texpath;
|
||||
}
|
||||
}
|
||||
else if (!gameinfo.ConfigName.CompareNoCase("Heretic"))
|
||||
{
|
||||
checklist = useType==ETextureType::Flat? hereticflatpath : heretictexpath;
|
||||
}
|
||||
else if (!gameinfo.ConfigName.CompareNoCase("Hexen"))
|
||||
{
|
||||
checklist = useType==ETextureType::Flat? hexenflatpath : hexentexpath;
|
||||
}
|
||||
else if (!gameinfo.ConfigName.CompareNoCase("Strife"))
|
||||
{
|
||||
checklist = useType==ETextureType::Flat? strifeflatpath : strifetexpath;
|
||||
}
|
||||
else if (!gameinfo.ConfigName.CompareNoCase("Chex"))
|
||||
{
|
||||
checklist = useType==ETextureType::Flat? chexflatpath : chextexpath;
|
||||
}
|
||||
else
|
||||
return -3;
|
||||
|
||||
while (*checklist)
|
||||
{
|
||||
static const char * extensions[] = { "PNG", "JPG", "TGA", "PCX", NULL };
|
||||
|
||||
for (const char ** extp=extensions; *extp; extp++)
|
||||
{
|
||||
checkName.Format(*checklist, Name.GetChars(), *extp);
|
||||
int lumpnum = Wads.CheckNumForFullName(checkName);
|
||||
if (lumpnum >= 0) return lumpnum;
|
||||
}
|
||||
checklist++;
|
||||
}
|
||||
return -3;
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Checks for the presence of a hires texture replacement
|
||||
//
|
||||
//==========================================================================
|
||||
int FTexture::CheckExternalFile(bool & hascolorkey)
|
||||
{
|
||||
static const char * doom1texpath[]= {
|
||||
"%stextures/doom/doom1/%s.%s", "%stextures/doom/doom1/%s-ck.%s",
|
||||
"%stextures/doom/%s.%s", "%stextures/doom/%s-ck.%s", "%stextures/%s.%s", "%stextures/%s-ck.%s", NULL
|
||||
};
|
||||
|
||||
static const char * doom2texpath[]= {
|
||||
"%stextures/doom/doom2/%s.%s", "%stextures/doom/doom2/%s-ck.%s",
|
||||
"%stextures/doom/%s.%s", "%stextures/doom/%s-ck.%s", "%stextures/%s.%s", "%stextures/%s-ck.%s", NULL
|
||||
};
|
||||
|
||||
static const char * pluttexpath[]= {
|
||||
"%stextures/doom/plut/%s.%s", "%stextures/doom/plut/%s-ck.%s",
|
||||
"%stextures/doom/doom2-plut/%s.%s", "%stextures/doom/doom2-plut/%s-ck.%s",
|
||||
"%stextures/doom/%s.%s", "%stextures/doom/%s-ck.%s", "%stextures/%s.%s", "%stextures/%s-ck.%s", NULL
|
||||
};
|
||||
|
||||
static const char * tnttexpath[]= {
|
||||
"%stextures/doom/tnt/%s.%s", "%stextures/doom/tnt/%s-ck.%s",
|
||||
"%stextures/doom/doom2-tnt/%s.%s", "%stextures/doom/doom2-tnt/%s-ck.%s",
|
||||
"%stextures/doom/%s.%s", "%stextures/doom/%s-ck.%s", "%stextures/%s.%s", "%stextures/%s-ck.%s", NULL
|
||||
};
|
||||
|
||||
static const char * heretictexpath[]= {
|
||||
"%stextures/heretic/%s.%s", "%stextures/heretic/%s-ck.%s", "%stextures/%s.%s", "%stextures/%s-ck.%s", NULL
|
||||
};
|
||||
|
||||
static const char * hexentexpath[]= {
|
||||
"%stextures/hexen/%s.%s", "%stextures/hexen/%s-ck.%s", "%stextures/%s.%s", "%stextures/%s-ck.%s", NULL
|
||||
};
|
||||
|
||||
static const char * strifetexpath[]= {
|
||||
"%stextures/strife/%s.%s", "%stextures/strife/%s-ck.%s", "%stextures/%s.%s", "%stextures/%s-ck.%s", NULL
|
||||
};
|
||||
|
||||
static const char * chextexpath[]= {
|
||||
"%stextures/chex/%s.%s", "%stextures/chex/%s-ck.%s", "%stextures/%s.%s", "%stextures/%s-ck.%s", NULL
|
||||
};
|
||||
|
||||
static const char * doom1flatpath[]= {
|
||||
"%sflats/doom/doom1/%s.%s", "%stextures/doom/doom1/flat-%s.%s",
|
||||
"%sflats/doom/%s.%s", "%stextures/doom/flat-%s.%s", "%sflats/%s.%s", "%stextures/flat-%s.%s", NULL
|
||||
};
|
||||
|
||||
static const char * doom2flatpath[]= {
|
||||
"%sflats/doom/doom2/%s.%s", "%stextures/doom/doom2/flat-%s.%s",
|
||||
"%sflats/doom/%s.%s", "%stextures/doom/flat-%s.%s", "%sflats/%s.%s", "%stextures/flat-%s.%s", NULL
|
||||
};
|
||||
|
||||
static const char * plutflatpath[]= {
|
||||
"%sflats/doom/plut/%s.%s", "%stextures/doom/plut/flat-%s.%s",
|
||||
"%sflats/doom/doom2-plut/%s.%s", "%stextures/doom/doom2-plut/flat-%s.%s",
|
||||
"%sflats/doom/%s.%s", "%stextures/doom/flat-%s.%s", "%sflats/%s.%s", "%stextures/flat-%s.%s", NULL
|
||||
};
|
||||
|
||||
static const char * tntflatpath[]= {
|
||||
"%sflats/doom/tnt/%s.%s", "%stextures/doom/tnt/flat-%s.%s",
|
||||
"%sflats/doom/doom2-tnt/%s.%s", "%stextures/doom/doom2-tnt/flat-%s.%s",
|
||||
"%sflats/doom/%s.%s", "%stextures/doom/flat-%s.%s", "%sflats/%s.%s", "%stextures/flat-%s.%s", NULL
|
||||
};
|
||||
|
||||
static const char * hereticflatpath[]= {
|
||||
"%sflats/heretic/%s.%s", "%stextures/heretic/flat-%s.%s", "%sflats/%s.%s", "%stextures/flat-%s.%s", NULL
|
||||
};
|
||||
|
||||
static const char * hexenflatpath[]= {
|
||||
"%sflats/hexen/%s.%s", "%stextures/hexen/flat-%s.%s", "%sflats/%s.%s", "%stextures/flat-%s.%s", NULL
|
||||
};
|
||||
|
||||
static const char * strifeflatpath[]= {
|
||||
"%sflats/strife/%s.%s", "%stextures/strife/flat-%s.%s", "%sflats/%s.%s", "%stextures/flat-%s.%s", NULL
|
||||
};
|
||||
|
||||
static const char * chexflatpath[]= {
|
||||
"%sflats/chex/%s.%s", "%stextures/chex/flat-%s.%s", "%sflats/%s.%s", "%stextures/flat-%s.%s", NULL
|
||||
};
|
||||
|
||||
static const char * doom1patchpath[]= {
|
||||
"%spatches/doom/doom1/%s.%s", "%spatches/doom/%s.%s", "%spatches/%s.%s", NULL
|
||||
};
|
||||
|
||||
static const char * doom2patchpath[]= {
|
||||
"%spatches/doom/doom2/%s.%s", "%spatches/doom/%s.%s", "%spatches/%s.%s", NULL
|
||||
};
|
||||
|
||||
static const char * plutpatchpath[]= {
|
||||
"%spatches/doom/plut/%s.%s", "%spatches/doom/%s.%s", "%spatches/%s.%s", NULL
|
||||
};
|
||||
|
||||
static const char * tntpatchpath[]= {
|
||||
"%spatches/doom/tnt/%s.%s", "%spatches/doom/%s.%s", "%spatches/%s.%s", NULL
|
||||
};
|
||||
|
||||
static const char * hereticpatchpath[]= {
|
||||
"%spatches/heretic/%s.%s", "%spatches/%s.%s", NULL
|
||||
};
|
||||
|
||||
static const char * hexenpatchpath[]= {
|
||||
"%spatches/hexen/%s.%s", "%spatches/%s.%s", NULL
|
||||
};
|
||||
|
||||
static const char * strifepatchpath[]= {
|
||||
"%spatches/strife/%s.%s", "%spatches/%s.%s", NULL
|
||||
};
|
||||
|
||||
static const char * chexpatchpath[]= {
|
||||
"%spatches/chex/%s.%s", "%spatches/%s.%s", NULL
|
||||
};
|
||||
|
||||
FString checkName;
|
||||
const char ** checklist;
|
||||
ETextureType useType = UseType;
|
||||
|
||||
if (useType == ETextureType::SkinSprite || useType == ETextureType::Decal || useType == ETextureType::FontChar)
|
||||
{
|
||||
return -3;
|
||||
}
|
||||
|
||||
bool ispatch = (useType==ETextureType::MiscPatch || useType==ETextureType::Sprite) ;
|
||||
|
||||
// for patches this doesn't work yet
|
||||
if (ispatch) return -3;
|
||||
|
||||
if (!gameinfo.ConfigName.CompareNoCase("Doom"))
|
||||
{
|
||||
if (!(gameinfo.flags & GI_MAPxx))
|
||||
{
|
||||
checklist = ispatch ? doom1patchpath : useType==ETextureType::Flat? doom1flatpath : doom1texpath;
|
||||
}
|
||||
else
|
||||
{
|
||||
SetDoom2Wad();
|
||||
if (Doom2Wad == 1)
|
||||
checklist = ispatch ? plutpatchpath : useType==ETextureType::Flat? plutflatpath : pluttexpath;
|
||||
else if (Doom2Wad == 2)
|
||||
checklist = ispatch ? tntpatchpath : useType==ETextureType::Flat? tntflatpath : tnttexpath;
|
||||
else
|
||||
checklist = ispatch ? doom2patchpath : useType==ETextureType::Flat? doom2flatpath : doom2texpath;
|
||||
}
|
||||
}
|
||||
else if (!gameinfo.ConfigName.CompareNoCase("Heretic"))
|
||||
{
|
||||
checklist = ispatch ? hereticpatchpath : useType==ETextureType::Flat? hereticflatpath : heretictexpath;
|
||||
}
|
||||
else if (!gameinfo.ConfigName.CompareNoCase("Hexen"))
|
||||
{
|
||||
checklist = ispatch ? hexenpatchpath : useType==ETextureType::Flat? hexenflatpath : hexentexpath;
|
||||
}
|
||||
else if (!gameinfo.ConfigName.CompareNoCase("Strife"))
|
||||
{
|
||||
checklist = ispatch ?strifepatchpath : useType==ETextureType::Flat? strifeflatpath : strifetexpath;
|
||||
}
|
||||
else if (!gameinfo.ConfigName.CompareNoCase("Chex"))
|
||||
{
|
||||
checklist = ispatch ?chexpatchpath : useType==ETextureType::Flat? chexflatpath : chextexpath;
|
||||
}
|
||||
else
|
||||
return -3;
|
||||
|
||||
while (*checklist)
|
||||
{
|
||||
static const char * extensions[] = { "PNG", "JPG", "TGA", "PCX", NULL };
|
||||
|
||||
for (const char ** extp=extensions; *extp; extp++)
|
||||
{
|
||||
checkName.Format(*checklist, progdir.GetChars(), Name.GetChars(), *extp);
|
||||
if (_access(checkName, 0) == 0)
|
||||
{
|
||||
hascolorkey = !!strstr(checkName, "-ck.");
|
||||
return Wads.AddExternalFile(checkName);
|
||||
}
|
||||
}
|
||||
checklist++;
|
||||
}
|
||||
return -3;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Checks for the presence of a hires texture replacement and loads it
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool FTexture::LoadHiresTexture(FTextureBuffer &texbuffer, bool checkonly)
|
||||
{
|
||||
if (HiresLump == -1)
|
||||
{
|
||||
bHiresHasColorKey = false;
|
||||
HiresLump = CheckDDPK3();
|
||||
if (HiresLump < 0) HiresLump = CheckExternalFile(bHiresHasColorKey);
|
||||
|
||||
if (HiresLump >= 0)
|
||||
{
|
||||
HiresTexture = FTexture::CreateTexture("", HiresLump, ETextureType::Any);
|
||||
TexMan.AddTexture(HiresTexture); // let the texture manager manage this.
|
||||
}
|
||||
}
|
||||
if (HiresTexture != nullptr)
|
||||
{
|
||||
int w = HiresTexture->GetWidth();
|
||||
int h = HiresTexture->GetHeight();
|
||||
|
||||
if (!checkonly)
|
||||
{
|
||||
unsigned char * buffer = new unsigned char[w*(h + 1) * 4];
|
||||
memset(buffer, 0, w * (h + 1) * 4);
|
||||
|
||||
FBitmap bmp(buffer, w * 4, w, h);
|
||||
int trans;
|
||||
auto Pixels = HiresTexture->GetBgraBitmap(nullptr, &trans);
|
||||
bmp.Blit(0, 0, Pixels);
|
||||
|
||||
HiresTexture->CheckTrans(buffer, w*h, trans);
|
||||
|
||||
if (bHiresHasColorKey)
|
||||
{
|
||||
// This is a crappy Doomsday color keyed image
|
||||
// We have to remove the key manually. :(
|
||||
uint32_t * dwdata = (uint32_t*)buffer;
|
||||
for (int i = (w*h); i > 0; i--)
|
||||
{
|
||||
if (dwdata[i] == 0xffffff00 || dwdata[i] == 0xffff00ff) dwdata[i] = 0;
|
||||
}
|
||||
}
|
||||
texbuffer.mBuffer = buffer;
|
||||
}
|
||||
FContentIdBuilder contentId;
|
||||
contentId.id = 0;
|
||||
contentId.imageID = HiresTexture->GetImage()->GetId();
|
||||
texbuffer.mWidth = w;
|
||||
texbuffer.mHeight = h;
|
||||
texbuffer.mContentId = contentId.id;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
@ -691,11 +691,6 @@ FTextureBuffer FTexture::CreateTexBuffer(int translation, int flags)
|
|||
int isTransparent = -1;
|
||||
bool checkonly = !!(flags & CTF_CheckOnly);
|
||||
|
||||
if (flags & CTF_CheckHires)
|
||||
{
|
||||
// No image means that this cannot be checked,
|
||||
if (GetImage() && LoadHiresTexture(result, checkonly)) return result;
|
||||
}
|
||||
int exx = !!(flags & CTF_Expand);
|
||||
|
||||
W = GetWidth() + 2 * exx;
|
||||
|
|
|
@ -107,7 +107,6 @@ struct FloatRect
|
|||
|
||||
enum ECreateTexBufferFlags
|
||||
{
|
||||
CTF_CheckHires = 1, // use external hires replacement if found
|
||||
CTF_Expand = 2, // create buffer with a one-pixel wide border
|
||||
CTF_ProcessData = 4, // run postprocessing on the generated buffer. This is only needed when using the data for a hardware texture.
|
||||
CTF_CheckOnly = 8, // Only runs the code to get a content ID but does not create a texture. Can be used to access a caching system for the hardware textures.
|
||||
|
@ -385,8 +384,6 @@ protected:
|
|||
FTexture *OffsetLess = nullptr;
|
||||
// Paletted variant
|
||||
FTexture *PalVersion = nullptr;
|
||||
// External hires texture
|
||||
FTexture *HiresTexture = nullptr;
|
||||
// Material layers
|
||||
FTexture *Brightmap = nullptr;
|
||||
FTexture *Normal = nullptr; // Normal map texture
|
||||
|
@ -504,8 +501,7 @@ public:
|
|||
private:
|
||||
int CheckDDPK3();
|
||||
int CheckExternalFile(bool & hascolorkey);
|
||||
bool LoadHiresTexture(FTextureBuffer &texbuffer, bool checkonly);
|
||||
|
||||
|
||||
bool bSWSkyColorDone = false;
|
||||
PalEntry FloorSkyColor;
|
||||
PalEntry CeilingSkyColor;
|
||||
|
|
|
@ -1031,8 +1031,8 @@ static int DamageMobj (AActor *target, AActor *inflictor, AActor *source, int da
|
|||
}
|
||||
FName MeansOfDeath = mod;
|
||||
|
||||
// Spectral targets only take damage from spectral projectiles.
|
||||
if (target->flags4 & MF4_SPECTRAL && !telefragDamage)
|
||||
// Spectral targets only take damage from spectral projectiles unless forced or telefragging.
|
||||
if ((target->flags4 & MF4_SPECTRAL) && !(flags & DMG_FORCED) && !telefragDamage)
|
||||
{
|
||||
if (inflictor == NULL || !(inflictor->flags4 & MF4_SPECTRAL))
|
||||
{
|
||||
|
|
|
@ -103,8 +103,6 @@ void I_DetectOS()
|
|||
|
||||
if (10 == version.majorVersion) switch (version.minorVersion)
|
||||
{
|
||||
case 7: name = "Mac OS X Lion"; break;
|
||||
case 8: name = "OS X Mountain Lion"; break;
|
||||
case 9: name = "OS X Mavericks"; break;
|
||||
case 10: name = "OS X Yosemite"; break;
|
||||
case 11: name = "OS X El Capitan"; break;
|
||||
|
|
|
@ -37,7 +37,6 @@
|
|||
#include "st_console.h"
|
||||
#include "v_text.h"
|
||||
#include "version.h"
|
||||
#include "i_time.h"
|
||||
|
||||
|
||||
static NSColor* RGB(const uint8_t red, const uint8_t green, const uint8_t blue)
|
||||
|
@ -199,6 +198,7 @@ struct TimedUpdater
|
|||
{
|
||||
explicit TimedUpdater(const Function& function)
|
||||
{
|
||||
extern uint64_t I_msTime();
|
||||
const unsigned int currentTime = I_msTime();
|
||||
|
||||
if (currentTime - m_previousTime > interval)
|
||||
|
|
|
@ -256,7 +256,8 @@ sector_t *FGLRenderer::RenderView(player_t* player)
|
|||
NoInterpolateView = false;
|
||||
|
||||
// Shader start time does not need to be handled per level. Just use the one from the camera to render from.
|
||||
gl_RenderState.CheckTimer(player->camera->Level->ShaderStartTime);
|
||||
if (player->camera)
|
||||
gl_RenderState.CheckTimer(player->camera->Level->ShaderStartTime);
|
||||
// prepare all camera textures that have been used in the last frame.
|
||||
// This must be done for all levels, not just the primary one!
|
||||
for (auto Level : AllLevels())
|
||||
|
|
|
@ -319,8 +319,7 @@ void FGLRenderState::ApplyMaterial(FMaterial *mat, int clampmode, int translatio
|
|||
int usebright = false;
|
||||
int maxbound = 0;
|
||||
|
||||
// Textures that are already scaled in the texture lump will not get replaced by hires textures.
|
||||
int flags = mat->isExpanded() ? CTF_Expand : (gl_texture_usehires && !tex->isScaled() && clampmode <= CLAMP_XY) ? CTF_CheckHires : 0;
|
||||
int flags = mat->isExpanded() ? CTF_Expand : 0;
|
||||
int numLayers = mat->GetLayers();
|
||||
auto base = static_cast<FHardwareTexture*>(mat->GetLayer(0, translation));
|
||||
|
||||
|
|
|
@ -52,7 +52,6 @@
|
|||
EXTERN_CVAR (Bool, vid_vsync)
|
||||
EXTERN_CVAR(Bool, r_drawvoxels)
|
||||
EXTERN_CVAR(Int, gl_tonemap)
|
||||
EXTERN_CVAR(Bool, gl_texture_usehires)
|
||||
|
||||
void gl_LoadExtensions();
|
||||
void gl_PrintStartupLog();
|
||||
|
@ -312,8 +311,7 @@ void OpenGLFrameBuffer::PrecacheMaterial(FMaterial *mat, int translation)
|
|||
auto tex = mat->tex;
|
||||
if (tex->isSWCanvas()) return;
|
||||
|
||||
// Textures that are already scaled in the texture lump will not get replaced by hires textures.
|
||||
int flags = mat->isExpanded() ? CTF_Expand : (gl_texture_usehires && !tex->isScaled()) ? CTF_CheckHires : 0;
|
||||
int flags = mat->isExpanded() ? CTF_Expand : 0;
|
||||
int numLayers = mat->GetLayers();
|
||||
auto base = static_cast<FHardwareTexture*>(mat->GetLayer(0, translation));
|
||||
|
||||
|
|
|
@ -29,8 +29,6 @@
|
|||
#include "hw_ihwtexture.h"
|
||||
#include "hw_material.h"
|
||||
|
||||
EXTERN_CVAR(Bool, gl_texture_usehires)
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Quick'n dirty image rescaling.
|
||||
|
|
|
@ -80,11 +80,6 @@ CUSTOM_CVAR(Int, gl_texture_filter, 4, CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOINI
|
|||
screen->TextureFilterChanged();
|
||||
}
|
||||
|
||||
CUSTOM_CVAR(Bool, gl_texture_usehires, true, CVAR_ARCHIVE|CVAR_NOINITCALL)
|
||||
{
|
||||
TexMan.FlushAll();
|
||||
}
|
||||
|
||||
CVAR(Bool, gl_precache, false, CVAR_ARCHIVE)
|
||||
|
||||
//==========================================================================
|
||||
|
|
|
@ -10,7 +10,6 @@ EXTERN_CVAR(Bool, gl_texture)
|
|||
EXTERN_CVAR(Int, gl_texture_filter)
|
||||
EXTERN_CVAR(Float, gl_texture_filter_anisotropic)
|
||||
EXTERN_CVAR(Int, gl_texture_format)
|
||||
EXTERN_CVAR(Bool, gl_texture_usehires)
|
||||
EXTERN_CVAR(Bool, gl_usefb)
|
||||
|
||||
EXTERN_CVAR(Int, gl_weaponlight)
|
||||
|
|
|
@ -267,7 +267,8 @@ sector_t *PolyFrameBuffer::RenderView(player_t *player)
|
|||
NoInterpolateView = false;
|
||||
|
||||
// Shader start time does not need to be handled per level. Just use the one from the camera to render from.
|
||||
GetRenderState()->CheckTimer(player->camera->Level->ShaderStartTime);
|
||||
if (player->camera)
|
||||
GetRenderState()->CheckTimer(player->camera->Level->ShaderStartTime);
|
||||
// prepare all camera textures that have been used in the last frame.
|
||||
// This must be done for all levels, not just the primary one!
|
||||
for (auto Level : AllLevels())
|
||||
|
@ -537,8 +538,7 @@ void PolyFrameBuffer::PrecacheMaterial(FMaterial *mat, int translation)
|
|||
auto tex = mat->tex;
|
||||
if (tex->isSWCanvas()) return;
|
||||
|
||||
// Textures that are already scaled in the texture lump will not get replaced by hires textures.
|
||||
int flags = mat->isExpanded() ? CTF_Expand : (gl_texture_usehires && !tex->isScaled()) ? CTF_CheckHires : 0;
|
||||
int flags = mat->isExpanded() ? CTF_Expand : 0;
|
||||
auto base = static_cast<PolyHardwareTexture*>(mat->GetLayer(0, translation));
|
||||
|
||||
base->Precache(mat, translation, flags);
|
||||
|
|
|
@ -89,8 +89,7 @@ DCanvas *PolyHardwareTexture::GetImage(const FMaterialState &state)
|
|||
if (tex->isHardwareCanvas()) clampmode = CLAMP_CAMTEX;
|
||||
else if ((tex->isWarped() || tex->shaderindex >= FIRST_USER_SHADER) && clampmode <= CLAMP_XY) clampmode = CLAMP_NONE;
|
||||
|
||||
// Textures that are already scaled in the texture lump will not get replaced by hires textures.
|
||||
int flags = state.mMaterial->isExpanded() ? CTF_Expand : (gl_texture_usehires && !tex->isScaled() && clampmode <= CLAMP_XY) ? CTF_CheckHires : 0;
|
||||
int flags = state.mMaterial->isExpanded() ? CTF_Expand : 0;
|
||||
|
||||
return GetImage(tex, translation, flags);
|
||||
}
|
||||
|
|
|
@ -280,6 +280,11 @@ void PolyRenderState::Apply()
|
|||
mDrawCommands->SetShader(EFF_NONE, mTextureEnabled ? effectState : SHADER_NoTexture, mAlphaThreshold >= 0.f, false);
|
||||
}
|
||||
|
||||
if (mMaterial.mMaterial && mMaterial.mMaterial->tex)
|
||||
mStreamData.timer = static_cast<float>((double)(screen->FrameTime - firstFrame) * (double)mMaterial.mMaterial->tex->shaderspeed / 1000.);
|
||||
else
|
||||
mStreamData.timer = 0.0f;
|
||||
|
||||
PolyPushConstants constants;
|
||||
constants.uFogEnabled = fogset;
|
||||
constants.uTextureMode = mTextureMode == TM_NORMAL && mTempTM == TM_OPAQUE ? TM_OPAQUE : mTextureMode;
|
||||
|
|
|
@ -407,6 +407,60 @@ static void WriteVaryingWrap(float pos, float step, int x0, int x1, const float*
|
|||
}
|
||||
#endif
|
||||
|
||||
static void WriteVaryingWarp1(float posU, float posV, float stepU, float stepV, int x0, int x1, PolyTriangleThreadData* thread)
|
||||
{
|
||||
float pi2 = 3.14159265358979323846f * 2.0f;
|
||||
float timer = thread->mainVertexShader.Data.timer * 0.125f;
|
||||
|
||||
const float* w = thread->scanline.W;
|
||||
uint16_t* scanlineU = thread->scanline.U;
|
||||
uint16_t* scanlineV = thread->scanline.V;
|
||||
|
||||
for (int x = x0; x < x1; x++)
|
||||
{
|
||||
float u = posU * w[x];
|
||||
float v = posV * w[x];
|
||||
|
||||
v += g_sin(pi2 * (u + timer)) * 0.1f;
|
||||
u += g_sin(pi2 * (v + timer)) * 0.1f;
|
||||
|
||||
u = u - std::floor(u);
|
||||
v = v - std::floor(v);
|
||||
scanlineU[x] = static_cast<uint32_t>(static_cast<int32_t>(u * static_cast<float>(0x1000'0000)) << 4) >> 16;
|
||||
scanlineV[x] = static_cast<uint32_t>(static_cast<int32_t>(v * static_cast<float>(0x1000'0000)) << 4) >> 16;
|
||||
|
||||
posU += stepU;
|
||||
posV += stepV;
|
||||
}
|
||||
}
|
||||
|
||||
static void WriteVaryingWarp2(float posU, float posV, float stepU, float stepV, int x0, int x1, PolyTriangleThreadData* thread)
|
||||
{
|
||||
float pi2 = 3.14159265358979323846f * 2.0f;
|
||||
float timer = thread->mainVertexShader.Data.timer;
|
||||
|
||||
const float* w = thread->scanline.W;
|
||||
uint16_t* scanlineU = thread->scanline.U;
|
||||
uint16_t* scanlineV = thread->scanline.V;
|
||||
|
||||
for (int x = x0; x < x1; x++)
|
||||
{
|
||||
float u = posU * w[x];
|
||||
float v = posV * w[x];
|
||||
|
||||
v += (0.5f + g_sin(pi2 * (v + timer * 0.61f + 900.f/8192.f)) + g_sin(pi2 * (u * 2.0f + timer * 0.36f + 300.0f/8192.0f))) * 0.025f;
|
||||
u += (0.5f + g_sin(pi2 * (v + timer * 0.49f + 700.f/8192.f)) + g_sin(pi2 * (u * 2.0f + timer * 0.49f + 1200.0f/8192.0f))) * 0.025f;
|
||||
|
||||
u = u - std::floor(u);
|
||||
v = v - std::floor(v);
|
||||
scanlineU[x] = static_cast<uint32_t>(static_cast<int32_t>(u * static_cast<float>(0x1000'0000)) << 4) >> 16;
|
||||
scanlineV[x] = static_cast<uint32_t>(static_cast<int32_t>(v * static_cast<float>(0x1000'0000)) << 4) >> 16;
|
||||
|
||||
posU += stepU;
|
||||
posV += stepV;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef NO_SSE
|
||||
static void WriteVaryingColor(float pos, float step, int x0, int x1, const float* w, uint8_t* varying)
|
||||
{
|
||||
|
@ -448,8 +502,28 @@ void WriteVaryings(int y, int x0, int x1, const TriDrawTriangleArgs* args, PolyT
|
|||
float startX = x0 + (0.5f - args->v1->x);
|
||||
float startY = y + (0.5f - args->v1->y);
|
||||
|
||||
WriteVaryingWrap(args->v1->u * args->v1->w + args->gradientX.U * startX + args->gradientY.U * startY, args->gradientX.U, x0, x1, thread->scanline.W, thread->scanline.U);
|
||||
WriteVaryingWrap(args->v1->v * args->v1->w + args->gradientX.V * startX + args->gradientY.V * startY, args->gradientX.V, x0, x1, thread->scanline.W, thread->scanline.V);
|
||||
void (*useShader)(float posU, float posV, float stepU, float stepV, int x0, int x1, PolyTriangleThreadData* thread) = nullptr;
|
||||
|
||||
if (thread->EffectState == SHADER_Warp1)
|
||||
useShader = &WriteVaryingWarp1;
|
||||
else if (thread->EffectState == SHADER_Warp2)
|
||||
useShader = &WriteVaryingWarp2;
|
||||
|
||||
if (useShader)
|
||||
{
|
||||
useShader(
|
||||
args->v1->u * args->v1->w + args->gradientX.U * startX + args->gradientY.U * startY,
|
||||
args->v1->v * args->v1->w + args->gradientX.V * startX + args->gradientY.V * startY,
|
||||
args->gradientX.U,
|
||||
args->gradientX.V,
|
||||
x0, x1,
|
||||
thread);
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteVaryingWrap(args->v1->u * args->v1->w + args->gradientX.U * startX + args->gradientY.U * startY, args->gradientX.U, x0, x1, thread->scanline.W, thread->scanline.U);
|
||||
WriteVaryingWrap(args->v1->v * args->v1->w + args->gradientX.V * startX + args->gradientY.V * startY, args->gradientX.V, x0, x1, thread->scanline.W, thread->scanline.V);
|
||||
}
|
||||
WriteVarying(args->v1->worldX * args->v1->w + args->gradientX.WorldX * startX + args->gradientY.WorldX * startY, args->gradientX.WorldX, x0, x1, thread->scanline.W, thread->scanline.WorldX);
|
||||
WriteVarying(args->v1->worldY * args->v1->w + args->gradientX.WorldY * startX + args->gradientY.WorldY * startY, args->gradientX.WorldY, x0, x1, thread->scanline.W, thread->scanline.WorldY);
|
||||
WriteVarying(args->v1->worldZ * args->v1->w + args->gradientX.WorldZ * startX + args->gradientY.WorldZ * startY, args->gradientX.WorldZ, x0, x1, thread->scanline.W, thread->scanline.WorldZ);
|
||||
|
|
|
@ -39,8 +39,6 @@
|
|||
#include "m_alloc.h"
|
||||
#include "imagehelpers.h"
|
||||
|
||||
EXTERN_CVAR(Bool, gl_texture_usehires)
|
||||
|
||||
|
||||
FSoftwareTexture *FTexture::GetSoftwareTexture()
|
||||
{
|
||||
|
@ -64,7 +62,7 @@ FSoftwareTexture::FSoftwareTexture(FTexture *tex)
|
|||
mTexture = tex;
|
||||
mSource = tex;
|
||||
|
||||
mBufferFlags = (gl_texture_usehires && !tex->isScaled() && tex->GetImage() && !tex->isSprite() ) ? CTF_CheckHires|CTF_ProcessData : CTF_ProcessData;
|
||||
mBufferFlags = CTF_ProcessData;
|
||||
auto info = tex->CreateTexBuffer(0, CTF_CheckOnly| mBufferFlags);
|
||||
mPhysicalWidth = info.mWidth;
|
||||
mPhysicalHeight = info.mHeight;
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
|
||||
EXTERN_CVAR(Int, gl_texture_hqresizemult)
|
||||
EXTERN_CVAR(Int, gl_texture_hqresizemode)
|
||||
EXTERN_CVAR(Int, gl_texture_hqresize_targets)
|
||||
|
||||
FWarpTexture::FWarpTexture (FTexture *source, int warptype)
|
||||
: FSoftwareTexture (source)
|
||||
|
@ -63,7 +64,7 @@ const uint32_t *FWarpTexture::GetPixelsBgra()
|
|||
|
||||
if (time != GenTime[2])
|
||||
{
|
||||
if (gl_texture_hqresizemode == 0 || gl_texture_hqresizemult < 1)
|
||||
if (gl_texture_hqresizemode == 0 || gl_texture_hqresizemult < 1 || !(gl_texture_hqresize_targets & 1))
|
||||
resizeMult = 1;
|
||||
|
||||
auto otherpix = FSoftwareTexture::GetPixelsBgra();
|
||||
|
@ -84,7 +85,7 @@ const uint8_t *FWarpTexture::GetPixels(int index)
|
|||
|
||||
if (time != GenTime[index])
|
||||
{
|
||||
if (gl_texture_hqresizemode == 0 || gl_texture_hqresizemult < 1)
|
||||
if (gl_texture_hqresizemode == 0 || gl_texture_hqresizemult < 1 || !(gl_texture_hqresize_targets & 1))
|
||||
resizeMult = 1;
|
||||
|
||||
const uint8_t *otherpix = FSoftwareTexture::GetPixels(index);
|
||||
|
|
|
@ -136,11 +136,13 @@ namespace swrenderer
|
|||
if (thing->renderflags & RF_SPRITEFLIP)
|
||||
renderflags ^= RF_XFLIP;
|
||||
|
||||
double yscale;
|
||||
double yscale, origyscale;
|
||||
int resizeMult = gl_texture_hqresizemult;
|
||||
|
||||
origyscale = spriteScale.Y / tex->GetScale().Y;
|
||||
if (gl_texture_hqresizemode == 0 || gl_texture_hqresizemult < 1 || !(gl_texture_hqresize_targets & 2))
|
||||
yscale = spriteScale.Y / tex->GetScale().Y;
|
||||
else
|
||||
yscale = spriteScale.Y / tex->GetScale().Y / gl_texture_hqresizemult;
|
||||
resizeMult = 1;
|
||||
yscale = origyscale / resizeMult;
|
||||
|
||||
// store information in a vissprite
|
||||
RenderSprite *vis = thread->FrameMemory->NewObject<RenderSprite>();
|
||||
|
@ -150,8 +152,8 @@ namespace swrenderer
|
|||
vis->CurrentPortalUniq = renderportal->CurrentPortalUniq;
|
||||
vis->yscale = float(viewport->InvZtoScale * yscale / wallc.sz1);
|
||||
vis->idepth = float(1 / wallc.sz1);
|
||||
vis->floorclip = thing->Floorclip / yscale;
|
||||
vis->texturemid = tex->GetTopOffsetSW() - (viewport->viewpoint.Pos.Z - pos.Z + thing->Floorclip) / yscale;
|
||||
vis->floorclip = thing->Floorclip / origyscale;
|
||||
vis->texturemid = tex->GetTopOffsetSW() - (viewport->viewpoint.Pos.Z - pos.Z + thing->Floorclip / resizeMult) / yscale;
|
||||
vis->x1 = wallc.sx1 < renderportal->WindowLeft ? renderportal->WindowLeft : wallc.sx1;
|
||||
vis->x2 = wallc.sx2 > renderportal->WindowRight ? renderportal->WindowRight : wallc.sx2;
|
||||
vis->heightsec = heightsec;
|
||||
|
|
|
@ -404,7 +404,8 @@ sector_t *VulkanFrameBuffer::RenderView(player_t *player)
|
|||
NoInterpolateView = false;
|
||||
|
||||
// Shader start time does not need to be handled per level. Just use the one from the camera to render from.
|
||||
GetRenderState()->CheckTimer(player->camera->Level->ShaderStartTime);
|
||||
if (player->camera)
|
||||
GetRenderState()->CheckTimer(player->camera->Level->ShaderStartTime);
|
||||
// prepare all camera textures that have been used in the last frame.
|
||||
// This must be done for all levels, not just the primary one!
|
||||
for (auto Level : AllLevels())
|
||||
|
@ -651,7 +652,7 @@ void VulkanFrameBuffer::PrecacheMaterial(FMaterial *mat, int translation)
|
|||
if (tex->isSWCanvas()) return;
|
||||
|
||||
// Textures that are already scaled in the texture lump will not get replaced by hires textures.
|
||||
int flags = mat->isExpanded() ? CTF_Expand : (gl_texture_usehires && !tex->isScaled()) ? CTF_CheckHires : 0;
|
||||
int flags = mat->isExpanded() ? CTF_Expand : 0;
|
||||
auto base = static_cast<VkHardwareTexture*>(mat->GetLayer(0, translation));
|
||||
|
||||
base->Precache(mat, translation, flags);
|
||||
|
|
|
@ -132,7 +132,7 @@ VulkanDescriptorSet *VkHardwareTexture::GetDescriptorSet(const FMaterialState &s
|
|||
else if ((tex->isWarped() || tex->shaderindex >= FIRST_USER_SHADER) && clampmode <= CLAMP_XY) clampmode = CLAMP_NONE;
|
||||
|
||||
// Textures that are already scaled in the texture lump will not get replaced by hires textures.
|
||||
int flags = state.mMaterial->isExpanded() ? CTF_Expand : (gl_texture_usehires && !tex->isScaled() && clampmode <= CLAMP_XY) ? CTF_CheckHires : 0;
|
||||
int flags = state.mMaterial->isExpanded() ? CTF_Expand : 0;
|
||||
|
||||
if (tex->isHardwareCanvas()) static_cast<FCanvasTexture*>(tex)->NeedUpdate();
|
||||
|
||||
|
|
|
@ -1629,6 +1629,23 @@ DEFINE_ACTION_FUNCTION_NATIVE(AActor, A_NoBlocking, A_Unblock)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void CopyBloodColor(AActor* self, AActor* other)
|
||||
{
|
||||
if (self && other)
|
||||
{
|
||||
self->BloodColor = other->BloodColor;
|
||||
self->BloodTranslation = other->BloodTranslation;
|
||||
}
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION_NATIVE(AActor, CopyBloodColor, CopyBloodColor)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
PARAM_OBJECT(other, AActor);
|
||||
CopyBloodColor(self, other);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//=====================================================================================
|
||||
//
|
||||
// Inventory exports
|
||||
|
|
|
@ -36,10 +36,6 @@
|
|||
#include <chrono>
|
||||
#include <thread>
|
||||
#include "i_time.h"
|
||||
#include "doomdef.h"
|
||||
#include "c_cvars.h"
|
||||
#include "doomstat.h"
|
||||
#include "doomtype.h"
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
|
@ -50,27 +46,9 @@
|
|||
static uint64_t FirstFrameStartTime;
|
||||
static uint64_t CurrentFrameStartTime;
|
||||
static uint64_t FreezeTime;
|
||||
int GameTicRate;
|
||||
|
||||
static double TimeScale = 1.0;
|
||||
|
||||
CUSTOM_CVAR(Float, i_timescale, 1.0f, CVAR_NOINITCALL)
|
||||
{
|
||||
if (netgame)
|
||||
{
|
||||
Printf("Time scale cannot be changed in net games.\n");
|
||||
self = 1.0f;
|
||||
}
|
||||
else if (self >= 0.05f)
|
||||
{
|
||||
I_FreezeTime(true);
|
||||
TimeScale = self;
|
||||
I_FreezeTime(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
Printf("Time scale must be at least 0.05!\n");
|
||||
}
|
||||
}
|
||||
double TimeScale = 1.0;
|
||||
|
||||
static uint64_t GetClockTimeNS()
|
||||
{
|
||||
|
@ -90,12 +68,12 @@ static uint64_t NSToMS(uint64_t ns)
|
|||
|
||||
static int NSToTic(uint64_t ns)
|
||||
{
|
||||
return static_cast<int>(ns * TICRATE / 1'000'000'000);
|
||||
return static_cast<int>(ns * GameTicRate / 1'000'000'000);
|
||||
}
|
||||
|
||||
static uint64_t TicToNS(int tic)
|
||||
{
|
||||
return static_cast<uint64_t>(tic) * 1'000'000'000 / TICRATE;
|
||||
return static_cast<uint64_t>(tic) * 1'000'000'000 / GameTicRate;
|
||||
}
|
||||
|
||||
void I_SetFrameTime()
|
||||
|
|
|
@ -2,6 +2,9 @@
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
extern int GameTicRate;
|
||||
extern double TimeScale;
|
||||
|
||||
// Called by D_DoomLoop, sets the time for the current frame
|
||||
void I_SetFrameTime();
|
||||
|
||||
|
|
|
@ -78,6 +78,15 @@ public:
|
|||
protected:
|
||||
bool Grabbed;
|
||||
POINT UngrabbedPointerPos;
|
||||
|
||||
private:
|
||||
void RegisterRawInput();
|
||||
void UnregisterRawInput();
|
||||
void CheckDelayedUnregister(RAWINPUT* raw);
|
||||
void ReleaseLegacyInput();
|
||||
|
||||
bool mDelayUnregister = false;
|
||||
int mButtonsDown = 0;
|
||||
};
|
||||
|
||||
class FDInputMouse : public FMouse
|
||||
|
@ -569,22 +578,21 @@ void FRawMouse::Grab()
|
|||
{
|
||||
if (!Grabbed)
|
||||
{
|
||||
RAWINPUTDEVICE rid;
|
||||
|
||||
rid.usUsagePage = HID_GENERIC_DESKTOP_PAGE;
|
||||
rid.usUsage = HID_GDP_MOUSE;
|
||||
rid.dwFlags = RIDEV_CAPTUREMOUSE | RIDEV_NOLEGACY;
|
||||
rid.hwndTarget = Window;
|
||||
if (RegisterRawInputDevices(&rid, 1, sizeof(rid)))
|
||||
if (!mDelayUnregister)
|
||||
{
|
||||
GetCursorPos(&UngrabbedPointerPos);
|
||||
Grabbed = true;
|
||||
SetCursorState(false);
|
||||
// By setting the cursor position, we force the pointer image
|
||||
// to change right away instead of having it delayed until
|
||||
// some time in the future.
|
||||
CenterMouse(-1, -1, NULL, NULL);
|
||||
ReleaseLegacyInput();
|
||||
RegisterRawInput();
|
||||
mButtonsDown = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
mDelayUnregister = false;
|
||||
}
|
||||
|
||||
GetCursorPos(&UngrabbedPointerPos);
|
||||
while (ShowCursor(FALSE) >= 0);
|
||||
Grabbed = true;
|
||||
SetCursorState(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -598,19 +606,104 @@ void FRawMouse::Ungrab()
|
|||
{
|
||||
if (Grabbed)
|
||||
{
|
||||
RAWINPUTDEVICE rid;
|
||||
|
||||
rid.usUsagePage = HID_GENERIC_DESKTOP_PAGE;
|
||||
rid.usUsage = HID_GDP_MOUSE;
|
||||
rid.dwFlags = RIDEV_REMOVE;
|
||||
rid.hwndTarget = NULL;
|
||||
if (RegisterRawInputDevices(&rid, 1, sizeof(rid)))
|
||||
// This is to prevent WM_RBUTTONUP from falling through to the application under the cursor when we release capture.
|
||||
if (mButtonsDown == 0)
|
||||
{
|
||||
Grabbed = false;
|
||||
ClearButtonState();
|
||||
UnregisterRawInput();
|
||||
}
|
||||
else
|
||||
{
|
||||
mDelayUnregister = true;
|
||||
}
|
||||
|
||||
Grabbed = false;
|
||||
ClearButtonState();
|
||||
SetCursorState(true);
|
||||
SetCursorPos(UngrabbedPointerPos.x, UngrabbedPointerPos.y);
|
||||
while (ShowCursor(TRUE) < 0);
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FRawMouse :: RegisterRawInput
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FRawMouse::RegisterRawInput()
|
||||
{
|
||||
RAWINPUTDEVICE rid;
|
||||
rid.usUsagePage = HID_GENERIC_DESKTOP_PAGE;
|
||||
rid.usUsage = HID_GDP_MOUSE;
|
||||
rid.dwFlags = RIDEV_CAPTUREMOUSE | RIDEV_NOLEGACY | RIDEV_INPUTSINK;
|
||||
rid.hwndTarget = Window;
|
||||
RegisterRawInputDevices(&rid, 1, sizeof(rid));
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FRawMouse :: UnregisterRawInput
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FRawMouse::UnregisterRawInput()
|
||||
{
|
||||
RAWINPUTDEVICE rid;
|
||||
rid.usUsagePage = HID_GENERIC_DESKTOP_PAGE;
|
||||
rid.usUsage = HID_GDP_MOUSE;
|
||||
rid.dwFlags = RIDEV_REMOVE;
|
||||
rid.hwndTarget = NULL;
|
||||
RegisterRawInputDevices(&rid, 1, sizeof(rid));
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FRawMouse :: ReleaseLegacyMouseDown
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FRawMouse::ReleaseLegacyInput()
|
||||
{
|
||||
// Send release of all pressed mouse buttons to the Windows legacy input system.
|
||||
// If this isn't done the legacy input system may think the buttons are still down when we release the capture of input events.
|
||||
|
||||
const int vkeys[] = { VK_LBUTTON, VK_RBUTTON, VK_MBUTTON, VK_XBUTTON1, VK_XBUTTON2 };
|
||||
const DWORD keyflags[] = { MOUSEEVENTF_LEFTUP, MOUSEEVENTF_RIGHTUP, MOUSEEVENTF_MIDDLEUP, MOUSEEVENTF_XUP, MOUSEEVENTF_XUP };
|
||||
const DWORD mousedata[] = { 0, 0, 0, XBUTTON1, XBUTTON2 };
|
||||
std::vector<INPUT> inputs;
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
bool keydown = GetKeyState(vkeys[i]) < 0;
|
||||
if (keydown)
|
||||
{
|
||||
INPUT input = {};
|
||||
input.type = INPUT_MOUSE;
|
||||
input.mi.dwExtraInfo = GetMessageExtraInfo();
|
||||
input.mi.dwFlags = keyflags[i];
|
||||
input.mi.mouseData = mousedata[i];
|
||||
inputs.push_back(input);
|
||||
}
|
||||
}
|
||||
SendInput((UINT)inputs.size(), inputs.data(), sizeof(INPUT));
|
||||
}
|
||||
|
||||
void FRawMouse::CheckDelayedUnregister(RAWINPUT* raw)
|
||||
{
|
||||
// Track button state
|
||||
for (DWORD i = 0; i < 5; i++)
|
||||
{
|
||||
DWORD down = 1 << (i * 2);
|
||||
DWORD up = down << 1;
|
||||
if (raw->data.mouse.usButtonFlags & down)
|
||||
mButtonsDown |= (1 << i);
|
||||
else if (raw->data.mouse.usButtonFlags & up)
|
||||
mButtonsDown &= ~(1 << i);
|
||||
}
|
||||
|
||||
if (mDelayUnregister && mButtonsDown == 0)
|
||||
{
|
||||
UnregisterRawInput();
|
||||
mDelayUnregister = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -655,10 +748,7 @@ bool FRawMouse::ProcessRawInput(RAWINPUT *raw, int code)
|
|||
int x = m_noprescale ? raw->data.mouse.lLastX : raw->data.mouse.lLastX << 2;
|
||||
int y = -raw->data.mouse.lLastY;
|
||||
PostMouseMove(x, y);
|
||||
if (x | y)
|
||||
{
|
||||
CenterMouse(-1, -1, NULL, NULL);
|
||||
}
|
||||
CheckDelayedUnregister(raw);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -204,24 +204,7 @@ void I_DetectOS(void)
|
|||
{
|
||||
case VER_PLATFORM_WIN32_NT:
|
||||
osname = "NT";
|
||||
if (info.dwMajorVersion == 5)
|
||||
{
|
||||
if (info.dwMinorVersion == 0)
|
||||
{
|
||||
osname = "2000";
|
||||
}
|
||||
if (info.dwMinorVersion == 1)
|
||||
{
|
||||
osname = "XP";
|
||||
sys_ostype = 1; // legacy OS
|
||||
}
|
||||
else if (info.dwMinorVersion == 2)
|
||||
{
|
||||
osname = "Server 2003";
|
||||
sys_ostype = 1; // legacy OS
|
||||
}
|
||||
}
|
||||
else if (info.dwMajorVersion == 6)
|
||||
if (info.dwMajorVersion == 6)
|
||||
{
|
||||
if (info.dwMinorVersion == 0)
|
||||
{
|
||||
|
@ -248,12 +231,12 @@ void I_DetectOS(void)
|
|||
}
|
||||
else if (info.dwMinorVersion == 4)
|
||||
{
|
||||
osname = (info.wProductType == VER_NT_WORKSTATION) ? "10 (beta)" : "Server 10 (beta)";
|
||||
osname = (info.wProductType == VER_NT_WORKSTATION) ? "10 (beta)" : "Server 2016 (beta)";
|
||||
}
|
||||
}
|
||||
else if (info.dwMajorVersion == 10)
|
||||
{
|
||||
osname = (info.wProductType == VER_NT_WORKSTATION) ? "10 (or higher)" : "Server 10 (or higher)";
|
||||
osname = (info.wProductType == VER_NT_WORKSTATION) ? "10 (or higher)" : "Server 2016 (or higher)";
|
||||
sys_ostype = 3; // modern OS
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -162,11 +162,6 @@ AF40D0E49BD1B76D4B1AADD8212ADC46 // MAP01 (the wad that shall not be named =P)
|
|||
limitpain
|
||||
}
|
||||
|
||||
7C1913DEE396BA26CFF22A0E9369B7D2 // Nuke Mine, e1m2
|
||||
{
|
||||
pointonline
|
||||
}
|
||||
|
||||
920F8D876ECD96D8C2A978FF1AB2B401 // Darken2.wad map01 - Nodes go out of bounds/beyond normal sector boundaries
|
||||
CFEDB7FA89885E24856CAC9A2FB3CE58 // Darken2.wad map03 - GZDoomBuilder crashes when displaying Nodes
|
||||
8E961FA7029761D5FAB3932C40F10CD2 // Darken2.wad map04 - Nodes go out of bounds/beyond normal sector boundaries
|
||||
|
@ -198,6 +193,7 @@ EDA5CE7C462BD171BF8110AC56B67857 // pl2.wad map11
|
|||
A9A9A728E689266939C1B71655F320CA // pl2.wad map25
|
||||
62CA74092FC88C1E7FE2D0B1A8034E29 // pl2.wad map29
|
||||
19E1CFD717FC6BBA9371F0F529B4CDFF // ur_final.wad map27
|
||||
836E09559FF22A7A37C2587F7EAFF1EE // Requiem MAP29 - Incorrect sector lighting and vanishing items
|
||||
{
|
||||
rebuildnodes
|
||||
}
|
||||
|
@ -255,6 +251,7 @@ D7F6E9F08C39A17026349A04F8C0B0BE // Return to Hadron, e1m9
|
|||
19D03FFC875589E21EDBB7AB74EF4AEF // Return to Hadron, e1m9, 2016.01.03 update
|
||||
5BDA34DA60C0530794CC1EA2DA017976 // doom2.wad map14
|
||||
5B3F118B337BFBFB8D5C81E98AF7B71D // Ancient Aliens map23
|
||||
7C1913DEE396BA26CFF22A0E9369B7D2 // Nuke Mine, e1m2
|
||||
{
|
||||
pointonline
|
||||
}
|
||||
|
|
|
@ -2535,7 +2535,6 @@ OptionMenu "GLTextureGLOptions" protected
|
|||
Title "$GLTEXMNU_TITLE"
|
||||
Option "$GLTEXMNU_TEXFILTER", gl_texture_filter, "FilterModes"
|
||||
Option "$GLTEXMNU_ANISOTROPIC", gl_texture_filter_anisotropic, "Anisotropy"
|
||||
Option "$GLTEXMNU_ENABLEHIRES", gl_texture_usehires, "YesNo"
|
||||
|
||||
ifOption(MMX)
|
||||
{
|
||||
|
|
|
@ -1163,6 +1163,7 @@ class Actor : Thinker native
|
|||
native bool A_SetSize(double newradius = -1, double newheight = -1, bool testpos = false);
|
||||
native void A_SprayDecal(String name, double dist = 172);
|
||||
native void A_SetMugshotState(String name);
|
||||
native void CopyBloodColor(Actor other);
|
||||
|
||||
native void A_RearrangePointers(int newtarget, int newmaster = AAPTR_DEFAULT, int newtracer = AAPTR_DEFAULT, int flags=0);
|
||||
native void A_TransferPointer(int ptr_source, int ptr_recipient, int sourcefield, int recipientfield=AAPTR_DEFAULT, int flags=0);
|
||||
|
|
|
@ -1778,6 +1778,176 @@ class LevelCompatibility : LevelPostProcessor
|
|||
SetLineSpecial(11518, 9, 0, 0, 0, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'BA530202AF0BA0C6CBAE6A0C7076FB72': // Requiem MAP04
|
||||
{
|
||||
// Flag deathmatch berserk for 100% items in single-player
|
||||
SetThingFlags(284, 17);
|
||||
// Make Hell Knight trap switch repeatable to prevent softlock
|
||||
SetLineFlags(823, Line.ML_REPEAT_SPECIAL);
|
||||
break;
|
||||
}
|
||||
|
||||
case '104415DDEBCAFB9783CA60807C46B57D': // Requiem MAP05
|
||||
{
|
||||
// Raise spectre pit near soulsphere if player drops into it
|
||||
for(int i = 0; i < 4; i++)
|
||||
{
|
||||
SetLineSpecial(2130+i, Floor_LowerToHighest, 28, 8, 128);
|
||||
SetLineActivation(2130+i, SPAC_Cross);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case '1B0AF5286D4E914C5E903BC505E6A844': // Requiem MAP06
|
||||
{
|
||||
// Flag deathmatch berserks for 100% items in single-player
|
||||
SetThingFlags(103, 17);
|
||||
SetThingFlags(109, 17);
|
||||
// Shooting the cross before all Imps spawn in can make 100%
|
||||
// kills impossible, add line actions and change sector tag
|
||||
for(int i = 0; i < 7; i++)
|
||||
{
|
||||
SetLineSpecial(1788+i, Floor_RaiseToNearest, 100, 32);
|
||||
SetLineActivation(1788+i, SPAC_Cross);
|
||||
}
|
||||
SetLineSpecial(1796, Floor_RaiseToNearest, 100, 32);
|
||||
SetLineActivation(1796, SPAC_Cross);
|
||||
SetLineSpecial(1800, Floor_RaiseToNearest, 100, 32);
|
||||
SetLineActivation(1800, SPAC_Cross);
|
||||
SetLineSpecial(1802, Floor_RaiseToNearest, 100, 32);
|
||||
SetLineActivation(1802, SPAC_Cross);
|
||||
ClearSectorTags(412);
|
||||
AddSectorTag(412, 100);
|
||||
// Shootable cross at demon-faced floor changed to repeatable
|
||||
// action to prevent softlock if "spikes" are raised again
|
||||
SetLineFlags(2600, Line.ML_REPEAT_SPECIAL);
|
||||
break;
|
||||
}
|
||||
|
||||
case '3C10B1B017E902BE7CDBF2436DF56973': // Requiem MAP08
|
||||
{
|
||||
// Flag deathmatch soulsphere for 100% items in single-player
|
||||
SetThingFlags(48, 17);
|
||||
// Allow player to leave inescapable lift using the walls
|
||||
for(int i = 0; i < 3; i++)
|
||||
{
|
||||
SetLineSpecial(2485+i, Plat_DownWaitUpStayLip, 68, 64, 105, 0);
|
||||
SetLineActivation(2485+i, SPAC_Use);
|
||||
SetLineFlags(2485+i, Line.ML_REPEAT_SPECIAL);
|
||||
}
|
||||
SetLineSpecial(848, Plat_DownWaitUpStayLip, 68, 64, 105, 0);
|
||||
SetLineActivation(848, SPAC_UseBack);
|
||||
SetLineFlags(848, Line.ML_REPEAT_SPECIAL);
|
||||
SetLineSpecial(895, Plat_DownWaitUpStayLip, 68, 64, 105, 0);
|
||||
SetLineActivation(895, SPAC_UseBack);
|
||||
SetLineFlags(895, Line.ML_REPEAT_SPECIAL);
|
||||
break;
|
||||
}
|
||||
|
||||
case '14FE46ED0458979118007E1906A0C9BC': // Requiem MAP09
|
||||
{
|
||||
// Flag deathmatch items for 100% items in single-player
|
||||
for(int i = 0; i < 6; i++)
|
||||
SetThingFlags(371+i, 17);
|
||||
|
||||
for(int i = 0; i < 19; i++)
|
||||
SetThingFlags(402+i, 17);
|
||||
|
||||
SetThingFlags(359, 17);
|
||||
SetThingFlags(389, 17);
|
||||
SetThingFlags(390, 17);
|
||||
// Change sides of blue skull platform to be repeatable
|
||||
for(int i = 0; i < 4; i++)
|
||||
SetLineFlags(873+i, Line.ML_REPEAT_SPECIAL);
|
||||
// Make switch that raises bars near yellow skull repeatable
|
||||
SetLineFlags(2719, Line.ML_REPEAT_SPECIAL);
|
||||
break;
|
||||
}
|
||||
|
||||
case '53A6369C3C8DA4E7AC443A8F8684E38E': // Requiem MAP12
|
||||
{
|
||||
// Remove unreachable secrets
|
||||
SetSectorSpecial(352, 0);
|
||||
SetSectorSpecial(503, 0);
|
||||
// Change action of eastern switch at pool of water so that it
|
||||
// lowers the floor properly, making the secret accessible
|
||||
SetLineSpecial(4873, Floor_LowerToLowest, 62, 8);
|
||||
break;
|
||||
}
|
||||
|
||||
case '2DAB6E4B19B4F2763695267D39CD0275': // Requiem MAP13
|
||||
{
|
||||
// Fix missing nukage at starting bridge on hardware renderer
|
||||
for(int i = 0; i < 4; i++)
|
||||
SetLineSectorRef(2152+i, Line.back, 8);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'F55FB2A8DC68CFC75E4340EF4ED7A8BF': // Requiem MAP21
|
||||
{
|
||||
// Fix self-referencing floor hack
|
||||
for(int i = 0; i < 4; i++)
|
||||
SetLineSectorRef(3+i, Line.back, 219);
|
||||
|
||||
SetLineSpecial(8, Transfer_Heights, 80);
|
||||
// Fix south side of pit hack so textures don't bleed through
|
||||
// the fake floor on hardware renderer
|
||||
SetLineSectorRef(267, Line.back, 63);
|
||||
SetLineSectorRef(268, Line.back, 63);
|
||||
SetLineSectorRef(270, Line.back, 63);
|
||||
SetLineSectorRef(271, Line.back, 63);
|
||||
SetLineSectorRef(274, Line.back, 63);
|
||||
SetLineSectorRef(275, Line.back, 63);
|
||||
SetLineSectorRef(3989, Line.back, 63);
|
||||
SetLineSectorRef(3994, Line.back, 63);
|
||||
// Fix fake 3D bridge on hardware renderer
|
||||
SetLineSectorRef(506, Line.back, 841);
|
||||
SetLineSectorRef(507, Line.back, 841);
|
||||
SetLineSectorRef(536, Line.back, 841);
|
||||
SetLineSectorRef(537, Line.back, 841);
|
||||
SetLineSectorRef(541, Line.back, 841);
|
||||
SetLineSectorRef(547, Line.back, 841);
|
||||
AddSectorTag(90, 1000);
|
||||
AddSectorTag(91, 1000);
|
||||
SetSectorTexture(90, Sector.floor, "MFLR8_4");
|
||||
SetSectorTexture(91, Sector.floor, "MFLR8_4");
|
||||
|
||||
SetLineSectorRef(553, Line.back, 841);
|
||||
SetLineSectorRef(554, Line.back, 841);
|
||||
SetLineSectorRef(559, Line.back, 841);
|
||||
SetLineSectorRef(560, Line.back, 841);
|
||||
SetLineSectorRef(562, Line.back, 841);
|
||||
SetLineSectorRef(568, Line.back, 841);
|
||||
AddSectorTag(96, 1000);
|
||||
AddSectorTag(97, 1000);
|
||||
SetSectorTexture(96, Sector.floor, "MFLR8_4");
|
||||
SetSectorTexture(97, Sector.floor, "MFLR8_4");
|
||||
SetLineSpecial(505, Transfer_Heights, 1000);
|
||||
// Fix randomly appearing ceiling at deep water
|
||||
SetLineSectorRef(1219, Line.front, 233);
|
||||
SetLineSectorRef(1222, Line.front, 233);
|
||||
SetLineSectorRef(1223, Line.front, 233);
|
||||
SetLineSectorRef(1228, Line.front, 233);
|
||||
// Make switch in sky room repeatable so player does not get
|
||||
// trapped at red cross if returning a second time
|
||||
SetLineFlags(3870, Line.ML_REPEAT_SPECIAL);
|
||||
// Move unreachable item bonuses
|
||||
SetThingXY(412, -112, 6768);
|
||||
SetThingXY(413, -112, 6928);
|
||||
SetThingXY(414, -96, 6928);
|
||||
SetThingXY(415, -96, 6768);
|
||||
// Remove unreachable secret at exit megasphere
|
||||
SetSectorSpecial(123, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
case '2499CF9A9351BE9BC4E9C66FC9F291A7': // Requiem MAP23
|
||||
{
|
||||
// Remove secret at switch that can only be scored by crouching
|
||||
SetSectorSpecial(240, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue