Merge branch 'master' into whaven

# Conflicts:
#	source/build/include/buildtypes.h
#	source/core/console/c_notifybuffer.cpp
#	source/core/d_protocol.h
#	source/core/version.h
#	wadsrc/static/zscript.txt
This commit is contained in:
Christoph Oelckers 2021-05-16 13:03:17 +02:00
commit 671d200aa7
236 changed files with 7029 additions and 5557 deletions

View file

@ -43,10 +43,10 @@ jobs:
build_type: "RelWithDebInfo" build_type: "RelWithDebInfo"
} }
- { - {
name: "Linux GCC 10", name: "Linux GCC 11",
os: ubuntu-20.04, os: ubuntu-20.04,
extra_options: "-DCMAKE_C_COMPILER=gcc-10 -DCMAKE_CXX_COMPILER=g++-10", extra_options: "-DCMAKE_C_COMPILER=gcc-11 -DCMAKE_CXX_COMPILER=g++-11",
deps_cmdline: "sudo apt update && sudo apt install g++-10 libsdl2-dev libvpx-dev libgtk-3-dev", deps_cmdline: "sudo apt update && sudo apt install g++-11 libsdl2-dev libvpx-dev libgtk-3-dev",
build_type: "MinSizeRel" build_type: "MinSizeRel"
} }
- { - {
@ -54,7 +54,7 @@ jobs:
os: ubuntu-20.04, os: ubuntu-20.04,
extra_options: "-DCMAKE_C_COMPILER=clang-6.0 -DCMAKE_CXX_COMPILER=clang++-6.0 \ extra_options: "-DCMAKE_C_COMPILER=clang-6.0 -DCMAKE_CXX_COMPILER=clang++-6.0 \
-DDYN_FLUIDSYNTH=OFF -DDYN_OPENAL=OFF -DDYN_SNDFILE=OFF -DDYN_MPG123=OFF", -DDYN_FLUIDSYNTH=OFF -DDYN_OPENAL=OFF -DDYN_SNDFILE=OFF -DDYN_MPG123=OFF",
deps_cmdline: "sudo apt update && sudo apt install clang-6.0 libsdl2-dev libvpx-dev libopenal-dev libfluidsynth-dev libmpg123-dev libsndfile1-dev", deps_cmdline: "sudo apt update && sudo apt remove gcc-11 libgcc-11-dev g++-11 libstdc++-11-dev && sudo apt install clang-6.0 libstdc++-9-dev libsdl2-dev libvpx-dev libopenal-dev libfluidsynth-dev libmpg123-dev libsndfile1-dev",
build_type: "Debug" build_type: "Debug"
} }
- { - {

View file

@ -234,7 +234,7 @@ if( MSVC )
set( ALL_C_FLAGS "${ALL_C_FLAGS} /wd4996 /DUNICODE /D_UNICODE /D_WIN32_WINNT=0x0600" ) set( ALL_C_FLAGS "${ALL_C_FLAGS} /wd4996 /DUNICODE /D_UNICODE /D_WIN32_WINNT=0x0600" )
# These must be silenced because the code is full of them. Expect some of undefined behavior hidden in this mess. :( # These must be silenced because the code is full of them. Expect some of undefined behavior hidden in this mess. :(
set( ALL_C_FLAGS "${ALL_C_FLAGS} /wd4244 /wd4018 /wd4267" ) #set( ALL_C_FLAGS "${ALL_C_FLAGS} /wd4244 /wd4018 /wd4267" )
# Most of these need to be cleaned out. The source is currently infested with far too much conditional compilation which is a constant source of problems. # Most of these need to be cleaned out. The source is currently infested with far too much conditional compilation which is a constant source of problems.

View file

@ -828,8 +828,6 @@ set( NOT_COMPILED_SOURCE_FILES
games/duke/src/render.cpp games/duke/src/render.cpp
games/duke/src/savegame.cpp games/duke/src/savegame.cpp
games/duke/src/sbar.cpp games/duke/src/sbar.cpp
games/duke/src/sbar_d.cpp
games/duke/src/sbar_r.cpp
games/duke/src/sectors.cpp games/duke/src/sectors.cpp
games/duke/src/sectors_d.cpp games/duke/src/sectors_d.cpp
games/duke/src/sectors_r.cpp games/duke/src/sectors_r.cpp

View file

@ -392,7 +392,7 @@ void neartag(int32_t xs, int32_t ys, int32_t zs, int16_t sectnum, int16_t ange
int32_t (*blacklist_sprite_func)(int32_t) = nullptr) ATTRIBUTE((nonnull(6,7,8))); int32_t (*blacklist_sprite_func)(int32_t) = nullptr) ATTRIBUTE((nonnull(6,7,8)));
int32_t cansee(int32_t x1, int32_t y1, int32_t z1, int16_t sect1, int32_t cansee(int32_t x1, int32_t y1, int32_t z1, int16_t sect1,
int32_t x2, int32_t y2, int32_t z2, int16_t sect2); int32_t x2, int32_t y2, int32_t z2, int16_t sect2);
int32_t inside(int32_t x, int32_t y, int16_t sectnum); int32_t inside(int32_t x, int32_t y, int sectnum);
void dragpoint(int16_t pointhighlight, int32_t dax, int32_t day, uint8_t flags = 0); void dragpoint(int16_t pointhighlight, int32_t dax, int32_t day, uint8_t flags = 0);
int32_t try_facespr_intersect(uspriteptr_t const spr, vec3_t const in, int32_t try_facespr_intersect(uspriteptr_t const spr, vec3_t const in,
int32_t vx, int32_t vy, int32_t vz, int32_t vx, int32_t vy, int32_t vz,
@ -420,9 +420,9 @@ inline int32_t krand(void)
int32_t krand(void); int32_t krand(void);
#endif #endif
inline int32_t ksqrt(uint32_t num) inline int32_t ksqrt(uint64_t num)
{ {
return int(sqrt((float)num)); return int(sqrt(double(num)));
} }
int32_t getangle(int32_t xvect, int32_t yvect); int32_t getangle(int32_t xvect, int32_t yvect);
@ -461,36 +461,36 @@ void yax_getzsofslope(int sectNum, int playerX, int playerY, int32_t* pCeilZ, in
int32_t yax_getceilzofslope(int const sectnum, vec2_t const vect); int32_t yax_getceilzofslope(int const sectnum, vec2_t const vect);
int32_t yax_getflorzofslope(int const sectnum, vec2_t const vect); int32_t yax_getflorzofslope(int const sectnum, vec2_t const vect);
inline int32_t getceilzofslope(int16_t sectnum, int32_t dax, int32_t day) inline int32_t getceilzofslope(int sectnum, int32_t dax, int32_t day)
{ {
return getceilzofslopeptr((usectorptr_t)&sector[sectnum], dax, day); return getceilzofslopeptr((usectorptr_t)&sector[sectnum], dax, day);
} }
inline int32_t getflorzofslope(int16_t sectnum, int32_t dax, int32_t day) inline int32_t getflorzofslope(int sectnum, int32_t dax, int32_t day)
{ {
return getflorzofslopeptr((usectorptr_t)&sector[sectnum], dax, day); return getflorzofslopeptr((usectorptr_t)&sector[sectnum], dax, day);
} }
inline void getzsofslope(int16_t sectnum, int32_t dax, int32_t day, int32_t *ceilz, int32_t *florz) inline void getzsofslope(int sectnum, int32_t dax, int32_t day, int32_t *ceilz, int32_t *florz)
{ {
getzsofslopeptr((usectorptr_t)&sector[sectnum], dax, day, ceilz, florz); getzsofslopeptr((usectorptr_t)&sector[sectnum], dax, day, ceilz, florz);
} }
inline void getcorrectzsofslope(int16_t sectnum, int32_t dax, int32_t day, int32_t *ceilz, int32_t *florz) inline void getcorrectzsofslope(int sectnum, int32_t dax, int32_t day, int32_t *ceilz, int32_t *florz)
{ {
vec2_t closest = { dax, day }; vec2_t closest = { dax, day };
getsectordist(closest, sectnum, &closest); getsectordist(closest, sectnum, &closest);
getzsofslopeptr((usectorptr_t)&sector[sectnum], closest.x, closest.y, ceilz, florz); getzsofslopeptr((usectorptr_t)&sector[sectnum], closest.x, closest.y, ceilz, florz);
} }
inline int32_t getcorrectceilzofslope(int16_t sectnum, int32_t dax, int32_t day) inline int32_t getcorrectceilzofslope(int sectnum, int32_t dax, int32_t day)
{ {
vec2_t closest = { dax, day }; vec2_t closest = { dax, day };
getsectordist(closest, sectnum, &closest); getsectordist(closest, sectnum, &closest);
return getceilzofslopeptr((usectorptr_t)&sector[sectnum], closest.x, closest.y); return getceilzofslopeptr((usectorptr_t)&sector[sectnum], closest.x, closest.y);
} }
inline int32_t getcorrectflorzofslope(int16_t sectnum, int32_t dax, int32_t day) inline int32_t getcorrectflorzofslope(int sectnum, int32_t dax, int32_t day)
{ {
vec2_t closest = { dax, day }; vec2_t closest = { dax, day };
getsectordist(closest, sectnum, &closest); getsectordist(closest, sectnum, &closest);
@ -706,8 +706,8 @@ extern int32_t(*changespritestat_replace)(int16_t spritenum, int16_t newstatnum)
enum EHitBits enum EHitBits
{ {
kHitNone = 0, kHitNone = 0,
kHitTypeMask = 0xE000, kHitTypeMask = 0xC000,
kHitIndexMask = 0x1FFF, kHitIndexMask = 0x3FFF,
kHitSector = 0x4000, kHitSector = 0x4000,
kHitWall = 0x8000, kHitWall = 0x8000,
kHitSprite = 0xC000, kHitSprite = 0xC000,

View file

@ -79,14 +79,14 @@ struct sectortype
int ceilingypan() const { return int(ceilingypan_); } int ceilingypan() const { return int(ceilingypan_); }
int floorxpan() const { return int(floorxpan_); } int floorxpan() const { return int(floorxpan_); }
int floorypan() const { return int(floorypan_); } int floorypan() const { return int(floorypan_); }
void setfloorxpan(float val) { floorxpan_ = fmod(val + 512, 256); } // +512 is for handling negative offsets void setfloorxpan(float val) { floorxpan_ = fmodf(val + 512, 256); } // +512 is for handling negative offsets
void setfloorypan(float val) { floorypan_ = fmod(val + 512, 256); } // +512 is for handling negative offsets void setfloorypan(float val) { floorypan_ = fmodf(val + 512, 256); } // +512 is for handling negative offsets
void setceilingxpan(float val) { ceilingxpan_ = fmod(val + 512, 256); } // +512 is for handling negative offsets void setceilingxpan(float val) { ceilingxpan_ = fmodf(val + 512, 256); } // +512 is for handling negative offsets
void setceilingypan(float val) { ceilingypan_ = fmod(val + 512, 256); } // +512 is for handling negative offsets void setceilingypan(float val) { ceilingypan_ = fmodf(val + 512, 256); } // +512 is for handling negative offsets
void addfloorxpan(float add) { floorxpan_ = fmod(floorxpan_ + add + 512, 256); } // +512 is for handling negative offsets void addfloorxpan(float add) { floorxpan_ = fmodf(floorxpan_ + add + 512, 256); } // +512 is for handling negative offsets
void addfloorypan(float add) { floorypan_ = fmod(floorypan_ + add + 512, 256); } // +512 is for handling negative offsets void addfloorypan(float add) { floorypan_ = fmodf(floorypan_ + add + 512, 256); } // +512 is for handling negative offsets
void addceilingxpan(float add) { ceilingxpan_ = fmod(ceilingxpan_ + add + 512, 256); } // +512 is for handling negative offsets void addceilingxpan(float add) { ceilingxpan_ = fmodf(ceilingxpan_ + add + 512, 256); } // +512 is for handling negative offsets
void addceilingypan(float add) { ceilingypan_ = fmod(ceilingypan_ + add + 512, 256); } // +512 is for handling negative offsets void addceilingypan(float add) { ceilingypan_ = fmodf(ceilingypan_ + add + 512, 256); } // +512 is for handling negative offsets
}; };
//cstat: //cstat:
@ -130,10 +130,10 @@ struct walltype
int xpan() const { return int(xpan_); } int xpan() const { return int(xpan_); }
int ypan() const { return int(ypan_); } int ypan() const { return int(ypan_); }
void setxpan(float val) { xpan_ = fmod(val + 512, 256); } // +512 is for handling negative offsets void setxpan(float add) { xpan_ = fmodf(add + 512, 256); } // +512 is for handling negative offsets
void setypan(float val) { ypan_ = fmod(val + 512, 256); } // +512 is for handling negative offsets void setypan(float add) { ypan_ = fmodf(add + 512, 256); } // +512 is for handling negative offsets
void addxpan(float add) { xpan_ = fmod(xpan_ + add + 512, 256); } // +512 is for handling negative offsets void addxpan(float add) { xpan_ = fmodf(xpan_ + add + 512, 256); } // +512 is for handling negative offsets
void addypan(float add) { ypan_ = fmod(ypan_ + add + 512, 256); } // +512 is for handling negative offsets void addypan(float add) { ypan_ = fmodf(ypan_ + add + 512, 256); } // +512 is for handling negative offsets
#if 0 #if 0
// make sure we do not accidentally copy this // make sure we do not accidentally copy this

View file

@ -295,7 +295,7 @@ static inline int32_t cliptrace(vec2_t const pos, vec2_t * const goal)
{ {
int32_t hitwall = -1; int32_t hitwall = -1;
for (native_t z=clipnum-1; z>=0; z--) for (int z=clipnum-1; z>=0; z--)
{ {
vec2_t const p1 = { clipit[z].x1, clipit[z].y1 }; vec2_t const p1 = { clipit[z].x1, clipit[z].y1 };
vec2_t const p2 = { clipit[z].x2, clipit[z].y2 }; vec2_t const p2 = { clipit[z].x2, clipit[z].y2 };
@ -716,13 +716,13 @@ int32_t clipmove(vec3_t * const pos, int16_t * const sectnum, int32_t xvect, int
int32_t hitwalls[4], hitwall; int32_t hitwalls[4], hitwall;
int32_t clipReturn = 0; int32_t clipReturn = 0;
native_t cnt = clipmoveboxtracenum; int cnt = clipmoveboxtracenum;
do do
{ {
if (enginecompatibility_mode == ENGINECOMPATIBILITY_NONE && (xvect|yvect)) if (enginecompatibility_mode == ENGINECOMPATIBILITY_NONE && (xvect|yvect))
{ {
for (native_t i=clipnum-1;i>=0;--i) for (int i=clipnum-1;i>=0;--i)
{ {
if (!bitmap_test(clipignore, i) && clipinsideboxline(pos->x, pos->y, clipit[i].x1, clipit[i].y1, clipit[i].x2, clipit[i].y2, walldist)) if (!bitmap_test(clipignore, i) && clipinsideboxline(pos->x, pos->y, clipit[i].x1, clipit[i].y1, clipit[i].x2, clipit[i].y2, walldist))
{ {
@ -750,7 +750,7 @@ int32_t clipmove(vec3_t * const pos, int16_t * const sectnum, int32_t xvect, int
int32_t const templl2 int32_t const templl2
= (int32_t)clamp(compat_maybe_truncate_to_int32((int64_t)(goal.x - vec.x) * clipr.x + (int64_t)(goal.y - vec.y) * clipr.y), INT32_MIN, INT32_MAX); = (int32_t)clamp(compat_maybe_truncate_to_int32((int64_t)(goal.x - vec.x) * clipr.x + (int64_t)(goal.y - vec.y) * clipr.y), INT32_MIN, INT32_MAX);
int32_t const i = (enginecompatibility_mode == ENGINECOMPATIBILITY_19950829 || (abs(templl2)>>11) < templl) ? int32_t const i = (enginecompatibility_mode == ENGINECOMPATIBILITY_19950829 || (abs(templl2)>>11) < templl) ?
DivScaleL(templl2, templl, 20) : 0; (int)DivScaleL(templl2, templl, 20) : 0;
goal = { MulScale(clipr.x, i, 20)+vec.x, MulScale(clipr.y, i, 20)+vec.y }; goal = { MulScale(clipr.x, i, 20)+vec.x, MulScale(clipr.y, i, 20)+vec.y };
} }
@ -807,7 +807,7 @@ int32_t clipmove(vec3_t * const pos, int16_t * const sectnum, int32_t xvect, int
int32_t tempint2, tempint1 = INT32_MAX; int32_t tempint2, tempint1 = INT32_MAX;
*sectnum = -1; *sectnum = -1;
for (native_t j=numsectors-1; j>=0; j--) for (int j=numsectors-1; j>=0; j--)
if (inside(pos->x, pos->y, j) == 1) if (inside(pos->x, pos->y, j) == 1)
{ {
if (enginecompatibility_mode != ENGINECOMPATIBILITY_19950829 && (sector[j].ceilingstat&2)) if (enginecompatibility_mode != ENGINECOMPATIBILITY_19950829 && (sector[j].ceilingstat&2))
@ -819,7 +819,8 @@ int32_t clipmove(vec3_t * const pos, int16_t * const sectnum, int32_t xvect, int
{ {
if (tempint2 < tempint1) if (tempint2 < tempint1)
{ {
*sectnum = j; tempint1 = tempint2; *sectnum = (int16_t)j;
tempint1 = tempint2;
} }
} }
else else
@ -831,12 +832,13 @@ int32_t clipmove(vec3_t * const pos, int16_t * const sectnum, int32_t xvect, int
if (tempint2 <= 0) if (tempint2 <= 0)
{ {
*sectnum = j; *sectnum = (int16_t)j;
return clipReturn; return clipReturn;
} }
if (tempint2 < tempint1) if (tempint2 < tempint1)
{ {
*sectnum = j; tempint1 = tempint2; *sectnum = (int16_t)j;
tempint1 = tempint2;
} }
} }
} }
@ -1257,9 +1259,9 @@ static int32_t hitscan_trysector(const vec3_t *sv, usectorptr_t sec, hitdata_t *
{ {
if (tmp==NULL) if (tmp==NULL)
{ {
if (inside(x1,y1,sec-sector) == 1) if (inside(x1,y1,int(sec-sector)) == 1)
{ {
hit_set(hit, sec-sector, -1, -1, x1, y1, z1); hit_set(hit, int(sec-sector), -1, -1, x1, y1, z1);
hitscan_hitsectcf = (how+1)>>1; hitscan_hitsectcf = (how+1)>>1;
} }
} }
@ -1267,12 +1269,12 @@ static int32_t hitscan_trysector(const vec3_t *sv, usectorptr_t sec, hitdata_t *
{ {
const int32_t curidx=(int32_t)tmp[0]; const int32_t curidx=(int32_t)tmp[0];
auto const curspr=(spritetype *)tmp[1]; auto const curspr=(spritetype *)tmp[1];
const int32_t thislastsec = tmp[2]; const int32_t thislastsec = (int32_t)tmp[2];
if (!thislastsec) if (!thislastsec)
{ {
if (inside(x1,y1,sec-sector) == 1) if (inside(x1,y1,int(sec-sector)) == 1)
hit_set(hit, curspr->sectnum, -1, curspr-sprite, x1, y1, z1); hit_set(hit, int(curspr->sectnum), -1, int(curspr-sprite), x1, y1, z1);
} }
} }
} }

View file

@ -778,7 +778,7 @@ int32_t inside_old(int32_t x, int32_t y, int16_t sectnum)
return -1; return -1;
} }
int32_t inside(int32_t x, int32_t y, int16_t sectnum) int32_t inside(int32_t x, int32_t y, int sectnum)
{ {
switch (enginecompatibility_mode) switch (enginecompatibility_mode)
{ {

View file

@ -19,6 +19,12 @@
#include "hw_voxels.h" #include "hw_voxels.h"
#include "../../glbackend/glbackend.h" #include "../../glbackend/glbackend.h"
#ifdef _MSC_VER
// just make it shut up. Most of this file will go down the drain anyway soon.
#pragma warning(disable:4244)
#pragma warning(disable:4267)
#endif
static int32_t curextra=MAXTILES; static int32_t curextra=MAXTILES;
#define MIN_CACHETIME_PRINT 10 #define MIN_CACHETIME_PRINT 10

View file

@ -28,6 +28,10 @@ Ken Silverman's official web site: http://www.advsys.net/ken
#include "gamestruct.h" #include "gamestruct.h"
#include "hw_voxels.h" #include "hw_voxels.h"
#ifdef _MSC_VER
// just make it shut up. Most of this file will go down the drain anyway soon.
#pragma warning(disable:4244)
#endif
typedef struct { typedef struct {
union { double x; double d; }; union { double x; double d; };
@ -309,7 +313,7 @@ static void polymost_updaterotmat(void)
renderSetVisibility(g_visibility * fxdimen * (1.f / (65536.f)) / r_ambientlight); renderSetVisibility(g_visibility * fxdimen * (1.f / (65536.f)) / r_ambientlight);
} }
const vec2_16_t tileSize(size_t index) const vec2_16_t tileSize(int index)
{ {
vec2_16_t v = { (int16_t)tileWidth(index), (int16_t)tileHeight(index) }; vec2_16_t v = { (int16_t)tileWidth(index), (int16_t)tileHeight(index) };
return v; return v;

View file

@ -929,12 +929,7 @@ void SoundEngine::StopSound(int sourcetype, const void* actor, int channel, int
void SoundEngine::StopActorSounds(int sourcetype, const void* actor, int chanmin, int chanmax) void SoundEngine::StopActorSounds(int sourcetype, const void* actor, int chanmin, int chanmax)
{ {
const bool all = (chanmin == 0 && chanmax == 0); const bool all = (chanmin == 0 && chanmax == 0);
if (!all && chanmax > chanmin) if (chanmax < chanmin) std::swap(chanmin, chanmax);
{
const int temp = chanmax;
chanmax = chanmin;
chanmin = temp;
}
FSoundChan* chan = Channels; FSoundChan* chan = Channels;
while (chan != nullptr) while (chan != nullptr)

View file

@ -293,8 +293,8 @@ CCMD (md5sum)
} }
for (int i = 1; i < argv.argc(); ++i) for (int i = 1; i < argv.argc(); ++i)
{ {
FileReader fr = fileSystem.OpenFileReader(argv[i]); FileReader fr;
if (!fr.isOpen()) if (!fr.OpenFile(argv[i]))
{ {
Printf("%s: %s\n", argv[i], strerror(errno)); Printf("%s: %s\n", argv[i], strerror(errno));
} }

View file

@ -1108,3 +1108,4 @@ xy(menu_advance, "menu/advance")
xx(zoomsize) xx(zoomsize)
xx(ScreenJobRunner) xx(ScreenJobRunner)
xx(RazeStatusBar)

View file

@ -145,6 +145,12 @@ public:
return true; return true;
} }
bool GetFloat(float& var, bool evaluate = false)
{
if (!GetFloat(evaluate)) return false;
var = float(Float);
return true;
}
void MustGetFloat(bool evaluate = false); void MustGetFloat(bool evaluate = false);
bool CheckFloat(bool evaluate = false); bool CheckFloat(bool evaluate = false);

View file

@ -232,7 +232,6 @@ DEFINE_ACTION_FUNCTION(FSavegameManager, LoadSavegame)
void FSavegameManagerBase::DoSave(int Selected, const char *savegamestring) void FSavegameManagerBase::DoSave(int Selected, const char *savegamestring)
{ {
RemoveNewSaveNode();
if (Selected != 0) if (Selected != 0)
{ {
auto node = SaveGames[Selected]; auto node = SaveGames[Selected];

View file

@ -314,7 +314,7 @@ void DObject::Release()
// //
//========================================================================== //==========================================================================
void DObject:: Destroy () void DObject::Destroy ()
{ {
// We cannot call the VM during shutdown because all the needed data has been or is in the process of being deleted. // We cannot call the VM during shutdown because all the needed data has been or is in the process of being deleted.
if (PClass::bVMOperational) if (PClass::bVMOperational)

View file

@ -449,13 +449,14 @@ DFrameBuffer *SDLVideo::CreateFrameBuffer ()
device = new VulkanDevice(); device = new VulkanDevice();
fb = new VulkanFrameBuffer(nullptr, vid_fullscreen, device); fb = new VulkanFrameBuffer(nullptr, vid_fullscreen, device);
} }
catch (CVulkanError const&) catch (CVulkanError const &error)
{ {
if (Priv::window != nullptr) if (Priv::window != nullptr)
{ {
Priv::DestroyWindow(); Priv::DestroyWindow();
} }
Printf(TEXTCOLOR_RED "Initialization of Vulkan failed: %s\n", error.what());
Priv::vulkanEnabled = false; Priv::vulkanEnabled = false;
} }
} }

View file

@ -1006,6 +1006,22 @@ DEFINE_ACTION_FUNCTION_NATIVE(FDynArray_String, Push, ArrayPush<FDynArray_String
ACTION_RETURN_INT(self->Push(val)); ACTION_RETURN_INT(self->Push(val));
} }
DEFINE_ACTION_FUNCTION(FDynArray_String, PushV)
{
PARAM_SELF_STRUCT_PROLOGUE(FDynArray_String);
PARAM_VA_POINTER(va_reginfo); // Get the hidden type information array
VMVa_List args = { param + 1, 0, numparam - 2, va_reginfo + 1 };
while (args.curindex < args.numargs)
{
if (args.reginfo[args.curindex] == REGT_STRING)
{
self->Push(args.args[args.curindex++].s());
}
else ThrowAbortException(X_OTHER, "Invalid parameter in pushv, string expected");
}
ACTION_RETURN_INT(self->Size() - 1);
}
DEFINE_ACTION_FUNCTION_NATIVE(FDynArray_String, Pop, ArrayPop<FDynArray_String>) DEFINE_ACTION_FUNCTION_NATIVE(FDynArray_String, Pop, ArrayPop<FDynArray_String>)
{ {
PARAM_SELF_STRUCT_PROLOGUE(FDynArray_String); PARAM_SELF_STRUCT_PROLOGUE(FDynArray_String);

View file

@ -81,10 +81,10 @@ DEFINE_ACTION_FUNCTION_NATIVE(DStatusBarCore, StatusbarToRealCoords, StatusbarTo
return MIN(4, numret); return MIN(4, numret);
} }
void SBar_DrawTexture(DStatusBarCore* self, int texid, double x, double y, int flags, double alpha, double w, double h, double scaleX, double scaleY, int style) void SBar_DrawTexture(DStatusBarCore* self, int texid, double x, double y, int flags, double alpha, double w, double h, double scaleX, double scaleY, int style, int color, int translation, double clipwidth)
{ {
if (!twod->HasBegun2D()) ThrowAbortException(X_OTHER, "Attempt to draw to screen outside a draw function"); if (!twod->HasBegun2D()) ThrowAbortException(X_OTHER, "Attempt to draw to screen outside a draw function");
self->DrawGraphic(FSetTextureID(texid), x, y, flags, alpha, w, h, scaleX, scaleY, ERenderStyle(style)); self->DrawGraphic(FSetTextureID(texid), x, y, flags, alpha, w, h, scaleX, scaleY, ERenderStyle(style), color, translation, clipwidth);
} }
DEFINE_ACTION_FUNCTION_NATIVE(DStatusBarCore, DrawTexture, SBar_DrawTexture) DEFINE_ACTION_FUNCTION_NATIVE(DStatusBarCore, DrawTexture, SBar_DrawTexture)
@ -100,14 +100,17 @@ DEFINE_ACTION_FUNCTION_NATIVE(DStatusBarCore, DrawTexture, SBar_DrawTexture)
PARAM_FLOAT(scaleX); PARAM_FLOAT(scaleX);
PARAM_FLOAT(scaleY); PARAM_FLOAT(scaleY);
PARAM_INT(style); PARAM_INT(style);
SBar_DrawTexture(self, texid, x, y, flags, alpha, w, h, scaleX, scaleY, style); PARAM_INT(col);
PARAM_INT(trans);
PARAM_FLOAT(clipwidth);
SBar_DrawTexture(self, texid, x, y, flags, alpha, w, h, scaleX, scaleY, style, col, trans, clipwidth);
return 0; return 0;
} }
void SBar_DrawImage(DStatusBarCore* self, const FString& texid, double x, double y, int flags, double alpha, double w, double h, double scaleX, double scaleY, int style) void SBar_DrawImage(DStatusBarCore* self, const FString& texid, double x, double y, int flags, double alpha, double w, double h, double scaleX, double scaleY, int style, int color, int translation, double clipwidth)
{ {
if (!twod->HasBegun2D()) ThrowAbortException(X_OTHER, "Attempt to draw to screen outside a draw function"); if (!twod->HasBegun2D()) ThrowAbortException(X_OTHER, "Attempt to draw to screen outside a draw function");
self->DrawGraphic(TexMan.CheckForTexture(texid, ETextureType::Any), x, y, flags, alpha, w, h, scaleX, scaleY, ERenderStyle(style)); self->DrawGraphic(TexMan.CheckForTexture(texid, ETextureType::Any), x, y, flags, alpha, w, h, scaleX, scaleY, ERenderStyle(style), color, translation, clipwidth);
} }
DEFINE_ACTION_FUNCTION_NATIVE(DStatusBarCore, DrawImage, SBar_DrawImage) DEFINE_ACTION_FUNCTION_NATIVE(DStatusBarCore, DrawImage, SBar_DrawImage)
@ -123,10 +126,62 @@ DEFINE_ACTION_FUNCTION_NATIVE(DStatusBarCore, DrawImage, SBar_DrawImage)
PARAM_FLOAT(scaleX); PARAM_FLOAT(scaleX);
PARAM_FLOAT(scaleY); PARAM_FLOAT(scaleY);
PARAM_INT(style); PARAM_INT(style);
SBar_DrawImage(self, texid, x, y, flags, alpha, w, h, scaleX, scaleY, style); PARAM_INT(col);
PARAM_INT(trans);
PARAM_FLOAT(clipwidth);
SBar_DrawImage(self, texid, x, y, flags, alpha, w, h, scaleX, scaleY, style, col, trans, clipwidth);
return 0; return 0;
} }
void SBar_DrawImageRotated(DStatusBarCore* self, const FString& texid, double x, double y, int flags, double angle, double alpha, double scaleX, double scaleY, int style, int color, int translation)
{
if (!twod->HasBegun2D()) ThrowAbortException(X_OTHER, "Attempt to draw to screen outside a draw function");
self->DrawRotated(TexMan.CheckForTexture(texid, ETextureType::Any), x, y, flags, angle, alpha, scaleX, scaleY, color, translation, (ERenderStyle)style);
}
DEFINE_ACTION_FUNCTION_NATIVE(DStatusBarCore, DrawImageRotated, SBar_DrawImageRotated)
{
PARAM_SELF_PROLOGUE(DStatusBarCore);
PARAM_STRING(texid);
PARAM_FLOAT(x);
PARAM_FLOAT(y);
PARAM_INT(flags);
PARAM_FLOAT(angle);
PARAM_FLOAT(alpha);
PARAM_FLOAT(scaleX);
PARAM_FLOAT(scaleY);
PARAM_INT(style);
PARAM_INT(col);
PARAM_INT(trans);
SBar_DrawImageRotated(self, texid, x, y, flags, angle, alpha, scaleX, scaleY, style, col, trans);
return 0;
}
void SBar_DrawTextureRotated(DStatusBarCore* self, int texid, double x, double y, int flags, double angle, double alpha, double scaleX, double scaleY, int style, int color, int translation)
{
if (!twod->HasBegun2D()) ThrowAbortException(X_OTHER, "Attempt to draw to screen outside a draw function");
self->DrawRotated(FSetTextureID(texid), x, y, flags, alpha, scaleX, scaleY, color, translation, style);
}
DEFINE_ACTION_FUNCTION_NATIVE(DStatusBarCore, DrawTextureRotated, SBar_DrawTextureRotated)
{
PARAM_SELF_PROLOGUE(DStatusBarCore);
PARAM_INT(texid);
PARAM_FLOAT(x);
PARAM_FLOAT(y);
PARAM_INT(flags);
PARAM_FLOAT(angle);
PARAM_FLOAT(alpha);
PARAM_FLOAT(scaleX);
PARAM_FLOAT(scaleY);
PARAM_INT(style);
PARAM_INT(col);
PARAM_INT(trans);
SBar_DrawTextureRotated(self, texid, x, y, flags, angle, alpha, scaleX, scaleY, style, col, trans);
return 0;
}
void SBar_DrawString(DStatusBarCore* self, DHUDFont* font, const FString& string, double x, double y, int flags, int trans, double alpha, int wrapwidth, int linespacing, double scaleX, double scaleY, int translation, int style); void SBar_DrawString(DStatusBarCore* self, DHUDFont* font, const FString& string, double x, double y, int flags, int trans, double alpha, int wrapwidth, int linespacing, double scaleX, double scaleY, int translation, int style);
DEFINE_ACTION_FUNCTION_NATIVE(DStatusBarCore, DrawString, SBar_DrawString) DEFINE_ACTION_FUNCTION_NATIVE(DStatusBarCore, DrawString, SBar_DrawString)

View file

@ -51,7 +51,7 @@ FGameTexture* CrosshairImage;
static int CrosshairNum; static int CrosshairNum;
IMPLEMENT_CLASS(DStatusBarCore, true, false) IMPLEMENT_CLASS(DStatusBarCore, false, false)
IMPLEMENT_CLASS(DHUDFont, false, false); IMPLEMENT_CLASS(DHUDFont, false, false);
@ -458,7 +458,7 @@ void DStatusBarCore::DrawGraphic(FTextureID texture, double x, double y, int fla
return; return;
FGameTexture* tex = TexMan.GetGameTexture(texture, !(flags & DI_DONTANIMATE)); FGameTexture* tex = TexMan.GetGameTexture(texture, !(flags & DI_DONTANIMATE));
DrawGraphic(tex, x, y, flags, Alpha, boxwidth, boxheight, scaleX, scaleY, style, color, translation); DrawGraphic(tex, x, y, flags, Alpha, boxwidth, boxheight, scaleX, scaleY, style, color, translation, clipwidth);
} }
void DStatusBarCore::DrawGraphic(FGameTexture* tex, double x, double y, int flags, double Alpha, double boxwidth, double boxheight, double scaleX, double scaleY, ERenderStyle style, PalEntry color, int translation, double clipwidth) void DStatusBarCore::DrawGraphic(FGameTexture* tex, double x, double y, int flags, double Alpha, double boxwidth, double boxheight, double scaleX, double scaleY, ERenderStyle style, PalEntry color, int translation, double clipwidth)
@ -577,6 +577,10 @@ void DStatusBarCore::DrawGraphic(FGameTexture* tex, double x, double y, int flag
x += orgx; x += orgx;
y += orgy; y += orgy;
} }
if (clipwidth != -1)
{
int a = 0;
}
DrawTexture(twod, tex, x, y, DrawTexture(twod, tex, x, y,
DTA_TopOffset, 0, DTA_TopOffset, 0,
DTA_LeftOffset, 0, DTA_LeftOffset, 0,
@ -594,7 +598,7 @@ void DStatusBarCore::DrawGraphic(FGameTexture* tex, double x, double y, int flag
DTA_FillColor, (flags & DI_ALPHAMAPPED) ? 0 : -1, DTA_FillColor, (flags & DI_ALPHAMAPPED) ? 0 : -1,
DTA_FlipX, !!(flags & DI_MIRROR), DTA_FlipX, !!(flags & DI_MIRROR),
DTA_FlipY, !!(flags& DI_MIRRORY), DTA_FlipY, !!(flags& DI_MIRRORY),
DTA_LegacyRenderStyle, style, DTA_LegacyRenderStyle, (flags & DI_ALPHAMAPPED) ? STYLE_Shaded : style,
TAG_DONE); TAG_DONE);
} }

View file

@ -89,8 +89,8 @@ TArray<uint8_t> base64_encode(unsigned char const* bytes_to_encode, size_t in_le
while((i++ < 3)) while((i++ < 3))
reta.Push('='); reta.Push('=');
reta.Push(0);
} }
reta.Push(0);
return reta; return reta;

View file

@ -185,7 +185,7 @@ static void CalcMapBounds()
void AutomapControl() void AutomapControl()
{ {
static int nonsharedtimer; static int nonsharedtimer;
int ms = screen->FrameTime; int ms = (int)screen->FrameTime;
int interval; int interval;
int panvert = 0, panhorz = 0; int panvert = 0, panhorz = 0;
@ -197,7 +197,7 @@ void AutomapControl()
{ {
interval = 0; interval = 0;
} }
nonsharedtimer = screen->FrameTime; nonsharedtimer = ms;
if (System_WantGuiCapture()) if (System_WantGuiCapture())
return; return;

View file

@ -362,22 +362,37 @@ inline binangle bvectangbam(int32_t x, int32_t y)
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
inline int32_t interpolatedvalue(int32_t oval, int32_t val, double const smoothratio, int const scale = 16) inline constexpr int32_t interpolatedvalue(int32_t oval, int32_t val, double const smoothratio, int const scale = 16)
{
return oval + MulScale(val - oval, int(smoothratio), scale);
}
inline constexpr int32_t interpolatedvalue(int32_t oval, int32_t val, int const smoothratio, int const scale = 16)
{ {
return oval + MulScale(val - oval, smoothratio, scale); return oval + MulScale(val - oval, smoothratio, scale);
} }
inline double interpolatedvaluef(double oval, double val, double const smoothratio, int const scale = 16) inline constexpr double interpolatedvaluef(double oval, double val, double const smoothratio, int const scale = 16)
{ {
return oval + MulScaleF(val - oval, smoothratio, scale); return oval + MulScaleF(val - oval, smoothratio, scale);
} }
inline int32_t interpolatedangle(int32_t oang, int32_t ang, double const smoothratio, int const scale = 16) inline constexpr int32_t interpolatedangle(int32_t oang, int32_t ang, double const smoothratio, int const scale = 16)
{
return oang + MulScale(((ang + 1024 - oang) & 2047) - 1024, int(smoothratio), scale);
}
inline constexpr int32_t interpolatedangle(int32_t oang, int32_t ang, int const smoothratio, int const scale = 16)
{ {
return oang + MulScale(((ang + 1024 - oang) & 2047) - 1024, smoothratio, scale); return oang + MulScale(((ang + 1024 - oang) & 2047) - 1024, smoothratio, scale);
} }
inline binangle interpolatedangle(binangle oang, binangle ang, double const smoothratio, int const scale = 16) inline constexpr binangle interpolatedangle(binangle oang, binangle ang, double const smoothratio, int const scale = 16)
{
return bamang(oang.asbam() + MulScale(((ang.asbam() + 0x80000000 - oang.asbam()) & 0xFFFFFFFF) - 0x80000000, int(smoothratio), scale));
}
inline constexpr binangle interpolatedangle(binangle oang, binangle ang, int const smoothratio, int const scale = 16)
{ {
return bamang(oang.asbam() + MulScale(((ang.asbam() + 0x80000000 - oang.asbam()) & 0xFFFFFFFF) - 0x80000000, smoothratio, scale)); return bamang(oang.asbam() + MulScale(((ang.asbam() + 0x80000000 - oang.asbam()) & 0xFFFFFFFF) - 0x80000000, smoothratio, scale));
} }

View file

@ -196,7 +196,7 @@ CCMD(give)
if (!CheckCheatmode(true, true)) if (!CheckCheatmode(true, true))
{ {
Net_WriteByte(DEM_GIVE); Net_WriteByte(DEM_GIVE);
Net_WriteByte(found); Net_WriteByte((uint8_t)found);
} }
} }

View file

@ -9,3 +9,4 @@ EXTERN_CVAR(Bool, sv_cheats)
void genericCheat(int player, uint8_t** stream, bool skip); void genericCheat(int player, uint8_t** stream, bool skip);
void changeMap(int player, uint8_t** stream, bool skip); void changeMap(int player, uint8_t** stream, bool skip);
void endScreenJob(int player, uint8_t** stream, bool skip); void endScreenJob(int player, uint8_t** stream, bool skip);
void startSaveGame(int player, uint8_t** stream, bool skip);

View file

@ -116,10 +116,10 @@ void FNotifyBuffer::DrawNative()
FFont* font = isBlood() ? SmallFont2 : SmallFont; FFont* font = isBlood() ? SmallFont2 : SmallFont;
int line = isBlood() ? Top : (g_gameType & GAMEFLAG_SW) ? 40 : (g_gameType & GAMEFLAG_WHALL)? 18 : font->GetDisplacement(); double line = isBlood() ? Top : (g_gameType & GAMEFLAG_SW) ? 40 : (g_gameType & GAMEFLAG_WHALL)? 18 : font->GetDisplacement();
bool canskip = isBlood(); bool canskip = isBlood();
double scale = 1 / (NotifyFontScale * con_notifyscale); double scale = 1 / (NotifyFontScale * con_notifyscale);
int lineadv = font->GetHeight() / NotifyFontScale; double lineadv = font->GetHeight() / NotifyFontScale;
int textleft = (g_gameType & GAMEFLAG_WHALL) ? 18 : 0; int textleft = (g_gameType & GAMEFLAG_WHALL) ? 18 : 0;
for (unsigned i = topline; i < Text.Size(); ++i) for (unsigned i = topline; i < Text.Size(); ++i)
@ -193,8 +193,8 @@ void FNotifyBuffer::Draw()
double nfscale = (generic_ui? 0.7 : NotifyFontScale); double nfscale = (generic_ui? 0.7 : NotifyFontScale);
double scale = 1 / ( * con_notifyscale); double scale = 1 / ( * con_notifyscale);
int line = Top + font->GetDisplacement() / nfscale; double line = Top + font->GetDisplacement() / nfscale;
int lineadv = font->GetHeight () / nfscale; double lineadv = font->GetHeight () / nfscale;
for (unsigned i = 0; i < Text.Size(); ++ i) for (unsigned i = 0; i < Text.Size(); ++ i)
{ {

View file

@ -1674,6 +1674,7 @@ bool D_CheckNetGame (void)
Net_SetCommandHandler(DEM_GENERICCHEAT, genericCheat); Net_SetCommandHandler(DEM_GENERICCHEAT, genericCheat);
Net_SetCommandHandler(DEM_CHANGEMAP, changeMap); Net_SetCommandHandler(DEM_CHANGEMAP, changeMap);
Net_SetCommandHandler(DEM_ENDSCREENJOB, endScreenJob); Net_SetCommandHandler(DEM_ENDSCREENJOB, endScreenJob);
Net_SetCommandHandler(DEM_SAVEGAME, startSaveGame);
for (i = 0; i < MAXNETNODES; i++) for (i = 0; i < MAXNETNODES; i++)
{ {

View file

@ -90,6 +90,7 @@ enum EDemoCommand
DEM_GIVE, DEM_GIVE,
DEM_CHANGEMAP, DEM_CHANGEMAP,
DEM_ENDSCREENJOB, DEM_ENDSCREENJOB,
DEM_SAVEGAME,
DEM_SPELL, //Witchaven DEM_SPELL, //Witchaven
DEM_MAX DEM_MAX

View file

@ -135,7 +135,7 @@ static void parseTexturePaletteBlock(FScanner& sc, int tile)
int pal = -1, xsiz = 0, ysiz = 0; int pal = -1, xsiz = 0, ysiz = 0;
FString fn; FString fn;
double alphacut = -1.0, xscale = 1.0, yscale = 1.0, specpower = 1.0, specfactor = 1.0; float alphacut = -1.0, xscale = 1.0, yscale = 1.0, specpower = 1.0, specfactor = 1.0;
if (!sc.GetNumber(pal, true)) return; if (!sc.GetNumber(pal, true)) return;
@ -178,7 +178,7 @@ static void parseTextureSpecialBlock(FScanner& sc, int tile, int pal)
FScriptPosition pos = sc; FScriptPosition pos = sc;
FString fn; FString fn;
double xscale = 1.0, yscale = 1.0, specpower = 1.0, specfactor = 1.0; float xscale = 1.0, yscale = 1.0, specpower = 1.0, specfactor = 1.0;
if (sc.StartBraces(&blockend)) return; if (sc.StartBraces(&blockend)) return;
while (!sc.FoundEndBrace(blockend)) while (!sc.FoundEndBrace(blockend))
@ -653,6 +653,7 @@ void parseVoxel(FScanner& sc, FScriptPosition& pos)
FScanner::SavedPos blockend; FScanner::SavedPos blockend;
int tile0 = MAXTILES, tile1 = -1; int tile0 = MAXTILES, tile1 = -1;
FString fn; FString fn;
bool error = false;
if (!sc.GetString(fn)) return; if (!sc.GetString(fn)) return;
@ -661,17 +662,16 @@ void parseVoxel(FScanner& sc, FScriptPosition& pos)
if (nextvoxid == MAXVOXELS) if (nextvoxid == MAXVOXELS)
{ {
pos.Message(MSG_ERROR, "Maximum number of voxels (%d) already defined.", MAXVOXELS); pos.Message(MSG_ERROR, "Maximum number of voxels (%d) already defined.", MAXVOXELS);
return; error = true;
} }
else if (voxDefine(nextvoxid, fn))
if (voxDefine(nextvoxid, fn))
{ {
pos.Message(MSG_ERROR, "Unable to load voxel file \"%s\"", fn.GetChars()); pos.Message(MSG_ERROR, "Unable to load voxel file \"%s\"", fn.GetChars());
return; error = true;
} }
int lastvoxid = nextvoxid++; int lastvoxid = nextvoxid++;
if (sc.StartBraces(&blockend)) return; if (sc.StartBraces(&blockend)) return;
while (!sc.FoundEndBrace(blockend)) while (!sc.FoundEndBrace(blockend))
{ {
@ -679,13 +679,16 @@ void parseVoxel(FScanner& sc, FScriptPosition& pos)
if (sc.Compare("tile")) if (sc.Compare("tile"))
{ {
sc.GetNumber(true); sc.GetNumber(true);
if (ValidateTilenum("voxel", sc.Number, pos)) tiletovox[sc.Number] = lastvoxid; if (ValidateTilenum("voxel", sc.Number, pos))
{
if (!error) tiletovox[sc.Number] = lastvoxid;
}
} }
if (sc.Compare("tile0")) sc.GetNumber(tile0, true); if (sc.Compare("tile0")) sc.GetNumber(tile0, true);
if (sc.Compare("tile1")) if (sc.Compare("tile1"))
{ {
sc.GetNumber(tile1, true); sc.GetNumber(tile1, true);
if (ValidateTileRange("voxel", tile0, tile1, pos)) if (ValidateTileRange("voxel", tile0, tile1, pos) && !error)
{ {
for (int i = tile0; i <= tile1; i++) tiletovox[i] = lastvoxid; for (int i = tile0; i <= tile1; i++) tiletovox[i] = lastvoxid;
} }
@ -693,9 +696,9 @@ void parseVoxel(FScanner& sc, FScriptPosition& pos)
if (sc.Compare("scale")) if (sc.Compare("scale"))
{ {
sc.GetFloat(true); sc.GetFloat(true);
voxscale[lastvoxid] = (float)sc.Float; if (!error) voxscale[lastvoxid] = (float)sc.Float;
} }
if (sc.Compare("rotate")) voxrotate.Set(lastvoxid); if (sc.Compare("rotate") && !error) voxrotate.Set(lastvoxid);
} }
} }
@ -834,7 +837,7 @@ void parseMapinfo(FScanner& sc, FScriptPosition& pos)
for (int i = 0; i < 16; i++) for (int i = 0; i < 16; i++)
{ {
char smallbuf[3] = { sc.String[2 * i], sc.String[2 * i + 1], 0 }; char smallbuf[3] = { sc.String[2 * i], sc.String[2 * i + 1], 0 };
mhk.md4[i] = strtol(smallbuf, nullptr, 16); mhk.md4[i] = (uint8_t)strtol(smallbuf, nullptr, 16);
} }
} }
} }
@ -1772,7 +1775,7 @@ static bool parseModelFrameBlock(FScanner& sc, FixedBitArray<1024>& usedframes)
bool ok = true; bool ok = true;
int pal = -1; int pal = -1;
int starttile = -1, endtile = -1; int starttile = -1, endtile = -1;
double smoothduration = 0.1f; float smoothduration = 0.1f;
if (sc.StartBraces(&blockend)) return false; if (sc.StartBraces(&blockend)) return false;
while (!sc.FoundEndBrace(blockend)) while (!sc.FoundEndBrace(blockend))
@ -1855,7 +1858,7 @@ static bool parseModelSkinBlock(FScanner& sc, int pal)
FString filename; FString filename;
int surface = 0; int surface = 0;
double param = 1.0, specpower = 1.0, specfactor = 1.0; float param = 1.0, specpower = 1.0, specfactor = 1.0;
int flags = 0; int flags = 0;
if (sc.StartBraces(&blockend)) return false; if (sc.StartBraces(&blockend)) return false;
@ -1887,7 +1890,7 @@ static bool parseModelSkinBlock(FScanner& sc, int pal)
return false; return false;
} }
if (pal == DETAILPAL) param = 1. / param; if (pal == DETAILPAL) param = 1.f / param;
int res = md_defineskin(mdglobal.lastmodelid, filename, pal, max(0, mdglobal.modelskin), surface, param, specpower, specfactor, flags); int res = md_defineskin(mdglobal.lastmodelid, filename, pal, max(0, mdglobal.modelskin), surface, param, specpower, specfactor, flags);
if (res < 0) if (res < 0)
{ {

View file

@ -586,14 +586,14 @@ DEFINE_MAP_OPTION(ex_ramses_pup, false)
{ {
parse.ParseAssign(); parse.ParseAssign();
parse.sc.MustGetString(); parse.sc.MustGetString();
info->ex_ramses_pup = parse.sc.Number; info->ex_ramses_pup = parse.sc.String;
} }
DEFINE_MAP_OPTION(ex_ramses_text, false) DEFINE_MAP_OPTION(ex_ramses_text, false)
{ {
parse.ParseAssign(); parse.ParseAssign();
parse.sc.MustGetString(); parse.sc.MustGetString();
info->ex_ramses_text = parse.sc.Number; info->ex_ramses_text = parse.sc.String;
} }
int ex_ramses_horiz = 11; int ex_ramses_horiz = 11;
@ -925,7 +925,7 @@ MapRecord *FMapInfoParser::ParseMapHeader(MapRecord &defaultinfo)
if (map != &sink && map->name.IsEmpty()) sc.ScriptError("Missing level name"); if (map != &sink && map->name.IsEmpty()) sc.ScriptError("Missing level name");
sc.UnGet(); sc.UnGet();
} }
if (!map->levelNumber) map->levelNumber = GetDefaultLevelNum(map->labelName); if (map->levelNumber <= 0) map->levelNumber = GetDefaultLevelNum(map->labelName);
return map; return map;
} }
@ -1128,6 +1128,14 @@ void FMapInfoParser::ParseGameInfo()
sc.SetCMode(false); sc.SetCMode(false);
globalCutscenes.MPSummaryScreen = sc.String; globalCutscenes.MPSummaryScreen = sc.String;
} }
else if (sc.Compare("statusbarclass"))
{
ParseAssign();
sc.SetCMode(false);
sc.MustGetString();
sc.SetCMode(false);
globalCutscenes.StatusBarClass = sc.String;
}
else if (!ParseCloseBrace()) else if (!ParseCloseBrace())
{ {
// Unknown // Unknown

View file

@ -140,7 +140,7 @@ void PostLoadSetup();
void FontCharCreated(FGameTexture* base, FGameTexture* untranslated, FGameTexture* translated); void FontCharCreated(FGameTexture* base, FGameTexture* untranslated, FGameTexture* translated);
void LoadVoxelModels(); void LoadVoxelModels();
DBaseStatusBar* StatusBar; DStatusBarCore* StatusBar;
bool AppActive = true; bool AppActive = true;
@ -477,9 +477,6 @@ void CheckUserMap()
namespace Duke3d namespace Duke3d
{ {
::GameInterface* CreateInterface(); ::GameInterface* CreateInterface();
DBaseStatusBar* CreateDukeStatusBar();
DBaseStatusBar* CreateRedneckStatusBar();
} }
namespace Blood namespace Blood
{ {
@ -810,32 +807,15 @@ void InitLanguages()
void CreateStatusBar() void CreateStatusBar()
{ {
int flags = g_gameType; auto stbarclass = PClass::FindClass(globalCutscenes.StatusBarClass);
PClass* stbarclass = nullptr;
GC::AddMarkerFunc([]() { GC::Mark(StatusBar); });
if (flags & GAMEFLAG_BLOOD)
{
stbarclass = PClass::FindClass("BloodStatusBar");
}
else if (flags & GAMEFLAG_SW)
{
stbarclass = PClass::FindClass("SWStatusBar");
}
else if (flags & GAMEFLAG_PSEXHUMED)
{
stbarclass = PClass::FindClass("ExhumedStatusBar");
}
else
{
StatusBar = isRR() ? Duke3d::CreateRedneckStatusBar() : Duke3d::CreateDukeStatusBar();
return;
}
if (!stbarclass) if (!stbarclass)
{ {
I_FatalError("No status bar defined"); I_FatalError("No status bar defined");
} }
StatusBar = static_cast<DBaseStatusBar*>(stbarclass->CreateNew()); StatusBar = static_cast<DStatusBarCore*>(stbarclass->CreateNew());
StatusBar->SetSize(0, 320, 200);
InitStatusBar();
GC::AddMarkerFunc([]() { GC::Mark(StatusBar); });
} }
@ -1075,7 +1055,7 @@ int RunGame()
void updatePauseStatus() void updatePauseStatus()
{ {
// This must go through the network in multiplayer games. // This must go through the network in multiplayer games.
if (M_Active() || System_WantGuiCapture()) if (M_Active() || System_WantGuiCapture() || !AppActive)
{ {
paused = 1; paused = 1;
} }
@ -1224,10 +1204,10 @@ void S_SetSoundPaused(int state)
if (paused == 0) if (paused == 0)
{ {
S_ResumeSound(true); S_ResumeSound(true);
if (GSnd != nullptr) }
{ if (GSnd != nullptr)
GSnd->SetInactive(SoundRenderer::INACTIVE_Active); {
} GSnd->SetInactive(SoundRenderer::INACTIVE_Active);
} }
} }
else else
@ -1537,7 +1517,7 @@ DEFINE_ACTION_FUNCTION_NATIVE(_Raze, MusicEnabled, MusicEnabled)
DEFINE_ACTION_FUNCTION_NATIVE(_Raze, GetTimeFrac, I_GetTimeFrac) DEFINE_ACTION_FUNCTION_NATIVE(_Raze, GetTimeFrac, I_GetTimeFrac)
{ {
ACTION_RETURN_INT(I_GetTimeFrac()); ACTION_RETURN_FLOAT(I_GetTimeFrac());
} }
DEFINE_ACTION_FUNCTION(_Raze, PlayerName) DEFINE_ACTION_FUNCTION(_Raze, PlayerName)
@ -1563,6 +1543,25 @@ DEFINE_ACTION_FUNCTION_NATIVE(_Raze, bcos, bcos)
ACTION_RETURN_INT(bcos(v, shift)); ACTION_RETURN_INT(bcos(v, shift));
} }
DEFINE_ACTION_FUNCTION_NATIVE(_Raze, GetBuildTime, I_GetBuildTime)
{
ACTION_RETURN_INT(I_GetBuildTime());
}
bool PickTexture(FRenderState* state, FGameTexture* tex, int paletteid, TexturePick& pick);
DEFINE_ACTION_FUNCTION(_Raze, PickTexture)
{
PARAM_PROLOGUE;
PARAM_INT(texid);
TexturePick pick;
if (PickTexture(nullptr, TexMan.GetGameTexture(FSetTextureID(texid)), TRANSLATION(Translation_Remap, 0), pick))
{
ACTION_RETURN_INT(pick.texture->GetID().GetIndex());
}
ACTION_RETURN_INT(texid);
}
DEFINE_ACTION_FUNCTION(_MapRecord, GetCluster) DEFINE_ACTION_FUNCTION(_MapRecord, GetCluster)
{ {
PARAM_SELF_STRUCT_PROLOGUE(MapRecord); PARAM_SELF_STRUCT_PROLOGUE(MapRecord);
@ -1578,6 +1577,8 @@ DEFINE_GLOBAL(demoplayback)
DEFINE_GLOBAL(consoleplayer) DEFINE_GLOBAL(consoleplayer)
DEFINE_GLOBAL(currentLevel) DEFINE_GLOBAL(currentLevel)
DEFINE_GLOBAL(paused) DEFINE_GLOBAL(paused)
DEFINE_GLOBAL(automapMode)
DEFINE_GLOBAL(PlayClock)
DEFINE_FIELD_X(ClusterDef, ClusterDef, name) DEFINE_FIELD_X(ClusterDef, ClusterDef, name)
DEFINE_FIELD_X(ClusterDef, ClusterDef, InterBackground) DEFINE_FIELD_X(ClusterDef, ClusterDef, InterBackground)

View file

@ -12,6 +12,10 @@
#include "i_time.h" #include "i_time.h"
#include "palentry.h" #include "palentry.h"
extern bool sendsave;
extern FString savedescription;
extern FString savegamefile;
extern FString currentGame; extern FString currentGame;
extern FString LumpFilter; extern FString LumpFilter;
extern int PlayClock; extern int PlayClock;

View file

@ -146,7 +146,7 @@ CCMD(sizeup)
} }
else else
{ {
hud_scalefactor = hud_scalefactor + 0.04; hud_scalefactor = hud_scalefactor + 0.04f;
} }
} }
@ -162,7 +162,7 @@ CCMD(sizedown)
} }
else else
{ {
hud_scalefactor = hud_scalefactor - 0.04; hud_scalefactor = hud_scalefactor - 0.04f;
} }
} }

View file

@ -131,7 +131,7 @@ bool calcChaseCamPos(int* px, int* py, int* pz, spritetype* pspr, short *psectnu
*pz += MulScale(nz, cameradist, 16); *pz += MulScale(nz, cameradist, 16);
// Caculate clock using GameTicRate so it increases the same rate on all speed computers. // Caculate clock using GameTicRate so it increases the same rate on all speed computers.
int myclock = PlayClock + MulScale(120 / GameTicRate, smoothratio, 16); int myclock = PlayClock + MulScale(120 / GameTicRate, int(smoothratio), 16);
if (cameraclock == INT_MIN) if (cameraclock == INT_MIN)
{ {
// Third person view was just started. // Third person view was just started.
@ -154,7 +154,7 @@ bool calcChaseCamPos(int* px, int* py, int* pz, spritetype* pspr, short *psectnu
// //
//========================================================================== //==========================================================================
void PlanesAtPoint(const sectortype* sec, float dax, float day, float* pceilz, float* pflorz) void PlanesAtPoint(const sectortype* sec, int dax, int day, float* pceilz, float* pflorz)
{ {
float ceilz = float(sec->ceilingz); float ceilz = float(sec->ceilingz);
float florz = float(sec->floorz); float florz = float(sec->floorz);
@ -164,13 +164,13 @@ void PlanesAtPoint(const sectortype* sec, float dax, float day, float* pceilz, f
auto wal = &wall[sec->wallptr]; auto wal = &wall[sec->wallptr];
auto wal2 = &wall[wal->point2]; auto wal2 = &wall[wal->point2];
float dx = wal2->x - wal->x; float dx = float(wal2->x - wal->x);
float dy = wal2->y - wal->y; float dy = float(wal2->y - wal->y);
int i = (int)sqrt(dx * dx + dy * dy) << 5; // length of sector's first wall. int i = (int)sqrt(dx * dx + dy * dy) << 5; // length of sector's first wall.
if (i != 0) if (i != 0)
{ {
float const j = (dx * (day - wal->y) - dy * (dax - wal->x)) * (1.f / 8.f); float const j = (dx * (float(day - wal->y)) - dy * (float(dax - wal->x))) * (1.f / 8.f);
if (sec->ceilingstat & CSTAT_SECTOR_SLOPE) ceilz += (sec->ceilingheinum * j) / i; if (sec->ceilingstat & CSTAT_SECTOR_SLOPE) ceilz += (sec->ceilingheinum * j) / i;
if (sec->floorstat & CSTAT_SECTOR_SLOPE) florz += (sec->floorheinum * j) / i; if (sec->floorstat & CSTAT_SECTOR_SLOPE) florz += (sec->floorheinum * j) / i;
} }

View file

@ -9,7 +9,11 @@ extern int cameradist, cameraclock;
void loaddefinitionsfile(const char* fn, bool cumulative = false); void loaddefinitionsfile(const char* fn, bool cumulative = false);
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);
void PlanesAtPoint(const sectortype* sec, float dax, float day, float* ceilz, float* florz); void PlanesAtPoint(const sectortype* sec, int dax, int day, float* ceilz, float* florz);
inline void PlanesAtPoint(const sectortype* sec, float dax, float day, float* ceilz, float* florz) // this is just for warning evasion.
{
PlanesAtPoint(sec, int(dax), int(day), ceilz, 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);
void GetFlatSpritePosition(const spritetype* spr, vec2_t pos, vec2_t* out, bool render = false); void GetFlatSpritePosition(const spritetype* spr, vec2_t pos, vec2_t* out, bool render = false);

View file

@ -61,7 +61,7 @@ binangle getincanglebam(binangle a, binangle na)
if(cura > INT32_MAX) cura -= UINT32_MAX; if(cura > INT32_MAX) cura -= UINT32_MAX;
} }
return bamang(newa-cura); return bamang(uint32_t(newa-cura));
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -133,7 +133,7 @@ void processMovement(InputPacket* currInput, InputPacket* inputBuffer, ControlIn
if (buttonMap.ButtonDown(gamefunc_Strafe) && allowstrafe) if (buttonMap.ButtonDown(gamefunc_Strafe) && allowstrafe)
currInput->svel -= xs_CRoundToInt((hidInput->mousemovex * mousevelscale) + (scaleAdjust * hidInput->dyaw * keymove * cntrlvelscale)); currInput->svel -= xs_CRoundToInt((hidInput->mousemovex * mousevelscale) + (scaleAdjust * hidInput->dyaw * keymove * cntrlvelscale));
else else
currInput->avel += hidInput->mouseturnx + (scaleAdjust * hidInput->dyaw * hidspeed * turnscale); currInput->avel += float(hidInput->mouseturnx + (scaleAdjust * hidInput->dyaw * hidspeed * turnscale));
if (!(inputBuffer->actions & SB_AIMMODE)) if (!(inputBuffer->actions & SB_AIMMODE))
currInput->horz -= hidInput->mouseturny; currInput->horz -= hidInput->mouseturny;
@ -147,7 +147,7 @@ void processMovement(InputPacket* currInput, InputPacket* inputBuffer, ControlIn
currInput->avel = -currInput->avel; currInput->avel = -currInput->avel;
// process remaining controller input. // process remaining controller input.
currInput->horz -= scaleAdjust * hidInput->dpitch * hidspeed; currInput->horz -= float(scaleAdjust * hidInput->dpitch * hidspeed);
currInput->svel += xs_CRoundToInt(scaleAdjust * hidInput->dx * keymove * cntrlvelscale); currInput->svel += xs_CRoundToInt(scaleAdjust * hidInput->dx * keymove * cntrlvelscale);
currInput->fvel += xs_CRoundToInt(scaleAdjust * hidInput->dz * keymove * cntrlvelscale); currInput->fvel += xs_CRoundToInt(scaleAdjust * hidInput->dz * keymove * cntrlvelscale);
@ -177,12 +177,12 @@ void processMovement(InputPacket* currInput, InputPacket* inputBuffer, ControlIn
if (buttonMap.ButtonDown(gamefunc_Turn_Left) || (buttonMap.ButtonDown(gamefunc_Strafe_Left) && !allowstrafe)) if (buttonMap.ButtonDown(gamefunc_Turn_Left) || (buttonMap.ButtonDown(gamefunc_Strafe_Left) && !allowstrafe))
{ {
updateTurnHeldAmt(scaleAdjust); updateTurnHeldAmt(scaleAdjust);
currInput->avel -= scaleAdjust * (isTurboTurnTime() ? turnamount : preambleturn); currInput->avel -= float(scaleAdjust * (isTurboTurnTime() ? turnamount : preambleturn));
} }
else if (buttonMap.ButtonDown(gamefunc_Turn_Right) || (buttonMap.ButtonDown(gamefunc_Strafe_Right) && !allowstrafe)) else if (buttonMap.ButtonDown(gamefunc_Turn_Right) || (buttonMap.ButtonDown(gamefunc_Strafe_Right) && !allowstrafe))
{ {
updateTurnHeldAmt(scaleAdjust); updateTurnHeldAmt(scaleAdjust);
currInput->avel += scaleAdjust * (isTurboTurnTime() ? turnamount : preambleturn); currInput->avel += float(scaleAdjust * (isTurboTurnTime() ? turnamount : preambleturn));
} }
else else
{ {

View file

@ -263,7 +263,7 @@ static void DeleteStuff(FileSystem &fileSystem, const TArray<FString>& deletelum
str.Truncate(ndx); str.Truncate(ndx);
} }
for (uint32_t i = 0; i < fileSystem.GetNumEntries(); i++) for (int i = 0; i < fileSystem.GetNumEntries(); i++)
{ {
int cf = fileSystem.GetFileContainer(i); int cf = fileSystem.GetFileContainer(i);
auto fname = fileSystem.GetFileFullName(i, false); auto fname = fileSystem.GetFileFullName(i, false);
@ -343,8 +343,8 @@ void InitFileSystem(TArray<GrpEntry>& groups)
D_AddConfigFiles(Files, "Global.Autoload", "*.grp", GameConfig); D_AddConfigFiles(Files, "Global.Autoload", "*.grp", GameConfig);
long len; size_t len;
int lastpos = 0; size_t lastpos = 0;
while (lastpos < LumpFilter.Len() && (len = strcspn(LumpFilter.GetChars() + lastpos, ".")) > 0) while (lastpos < LumpFilter.Len() && (len = strcspn(LumpFilter.GetChars() + lastpos, ".")) > 0)
{ {

View file

@ -106,10 +106,14 @@ int oldentertics;
int gametic; int gametic;
int intermissiondelay; int intermissiondelay;
FString savename;
FString BackupSaveGame; FString BackupSaveGame;
void DoLoadGame(const char* name); void DoLoadGame(const char* name);
bool sendsave;
FString savedescription;
FString savegamefile;
//========================================================================== //==========================================================================
// //
@ -119,6 +123,14 @@ void DoLoadGame(const char* name);
void G_BuildTiccmd(ticcmd_t* cmd) void G_BuildTiccmd(ticcmd_t* cmd)
{ {
if (sendsave)
{
sendsave = false;
Net_WriteByte(DEM_SAVEGAME);
Net_WriteString(savegamefile);
Net_WriteString(savedescription);
savegamefile = "";
}
cmd->ucmd = {}; cmd->ucmd = {};
I_GetEvent(); I_GetEvent();
auto input = CONTROL_GetInput(); auto input = CONTROL_GetInput();
@ -138,6 +150,7 @@ void NewGame(MapRecord* map, int skill, bool ns = false)
newGameStarted = true; newGameStarted = true;
ShowIntermission(nullptr, map, nullptr, [=](bool) { ShowIntermission(nullptr, map, nullptr, [=](bool) {
gi->NewGame(map, skill, ns); gi->NewGame(map, skill, ns);
ResetStatusBar();
}); });
} }
@ -187,6 +200,7 @@ static void GameTicker()
gi->FreeLevelData(); gi->FreeLevelData();
gameaction = ga_level; gameaction = ga_level;
gi->NextLevel(g_nextmap, g_nextskill); gi->NextLevel(g_nextmap, g_nextskill);
ResetStatusBar();
} }
else else
{ {
@ -199,6 +213,7 @@ static void GameTicker()
gi->FreeLevelData(); gi->FreeLevelData();
gameaction = ga_level; gameaction = ga_level;
gi->NextLevel(g_nextmap, g_nextskill); gi->NextLevel(g_nextmap, g_nextskill);
ResetStatusBar();
break; break;
case ga_newgame: case ga_newgame:
@ -240,8 +255,16 @@ static void GameTicker()
break; break;
case ga_savegame: case ga_savegame:
// We only need this for multiplayer saves that need to go through the network. G_DoSaveGame(true, false, savegamefile, savedescription);
// gi->SaveGame(); gameaction = ga_nothing;
savegamefile = "";
savedescription = "";
break;
case ga_loadgame:
case ga_loadgamehidecon:
//case ga_autoloadgame:
G_DoLoadGame();
break; break;
case ga_autosave: case ga_autosave:
@ -340,6 +363,7 @@ static void GameTicker()
gameupdatetime.Reset(); gameupdatetime.Reset();
gameupdatetime.Clock(); gameupdatetime.Clock();
gi->Ticker(); gi->Ticker();
TickStatusBar();
levelTextTime--; levelTextTime--;
gameupdatetime.Unclock(); gameupdatetime.Unclock();
break; break;

View file

@ -168,7 +168,7 @@ MapRecord* FindNextSecretMap(MapRecord* thismap)
bool SetMusicForMap(const char* mapname, const char* music, bool namehack) bool SetMusicForMap(const char* mapname, const char* music, bool namehack)
{ {
static const char* specials[] = { "intro", "briefing", "loading" }; static const char* specials[] = { "intro", "briefing", "loading" };
for (int i = 0; i < 3; i++) for (unsigned i = 0; i < 3; i++)
{ {
if (!stricmp(mapname, specials[i])) if (!stricmp(mapname, specials[i]))
{ {

View file

@ -104,6 +104,7 @@ struct GlobalCutscenes
CutsceneDef LoadingScreen; CutsceneDef LoadingScreen;
FString MPSummaryScreen; FString MPSummaryScreen;
FString SummaryScreen; FString SummaryScreen;
FString StatusBarClass;
}; };
struct ClusterDef struct ClusterDef

View file

@ -208,7 +208,7 @@ static void SetWallPalV5()
static void ValidateSprite(spritetype& spr) static void ValidateSprite(spritetype& spr)
{ {
int index = &spr - sprite; int index = int(&spr - sprite);
bool bugged = false; bool bugged = false;
if ((unsigned)spr.statnum >= MAXSTATUS) if ((unsigned)spr.statnum >= MAXSTATUS)
{ {

View file

@ -114,12 +114,12 @@ void FSavegameManager::ReadSaveStrings()
void FSavegameManager::PerformLoadGame(const char *f, bool s) void FSavegameManager::PerformLoadGame(const char *f, bool s)
{ {
G_LoadGame(f); G_LoadGame(f, s);
} }
void FSavegameManager::PerformSaveGame(const char *f, const char *s) void FSavegameManager::PerformSaveGame(const char *f, const char *s)
{ {
G_SaveGame(f, s, true, false); G_SaveGame(f, s);
} }
FString FSavegameManager::BuildSaveName(const char* fn, int slot) FString FSavegameManager::BuildSaveName(const char* fn, int slot)

View file

@ -192,16 +192,10 @@ bool M_SetSpecialMenu(FName& menu, int param)
void M_StartControlPanel(bool makeSound, bool) void M_StartControlPanel(bool makeSound, bool)
{ {
static bool created = false;
// intro might call this repeatedly // intro might call this repeatedly
if (CurrentMenu != NULL) if (CurrentMenu != NULL)
return; return;
if (!created) // Cannot do this earlier.
{
created = true;
M_CreateMenus();
}
GSnd->SetSfxPaused(true, PAUSESFX_MENU); GSnd->SetSfxPaused(true, PAUSESFX_MENU);
gi->MenuOpened(); gi->MenuOpened();
if (makeSound && menu_sounds) gi->MenuSound(ActivateSound); if (makeSound && menu_sounds) gi->MenuSound(ActivateSound);
@ -309,7 +303,7 @@ CCMD(quicksave)
// [mxd]. Just save the game, no questions asked. // [mxd]. Just save the game, no questions asked.
if (!saveloadconfirmation) if (!saveloadconfirmation)
{ {
G_SaveGame(savegameManager.quickSaveSlot->Filename, savegameManager.quickSaveSlot->SaveTitle, true, true); G_SaveGame(savegameManager.quickSaveSlot->Filename, savegameManager.quickSaveSlot->SaveTitle);
return; return;
} }
@ -320,7 +314,7 @@ CCMD(quicksave)
DMenu* newmenu = CreateMessageBoxMenu(CurrentMenu, tempstring, 0, false, NAME_None, []() DMenu* newmenu = CreateMessageBoxMenu(CurrentMenu, tempstring, 0, false, NAME_None, []()
{ {
M_ClearMenus(); M_ClearMenus();
G_SaveGame(savegameManager.quickSaveSlot->Filename, savegameManager.quickSaveSlot->SaveTitle, true, true); G_SaveGame(savegameManager.quickSaveSlot->Filename, savegameManager.quickSaveSlot->SaveTitle);
}); });
M_ActivateMenu(newmenu); M_ActivateMenu(newmenu);
@ -416,7 +410,7 @@ static void BuildEpisodeMenu()
} }
ld->mSelectedItem = gDefaultVolume + ld->mItems.Size(); // account for pre-added items ld->mSelectedItem = gDefaultVolume + ld->mItems.Size(); // account for pre-added items
int y = ld->mYpos; double y = ld->mYpos;
// Volume definitions should be sorted by intended menu order. // Volume definitions should be sorted by intended menu order.
for (auto &vol : volumes) for (auto &vol : volumes)
@ -473,7 +467,7 @@ static void BuildEpisodeMenu()
} }
if (isBlood()) gDefaultSkill = 2; if (isBlood()) gDefaultSkill = 2;
ld->mSelectedItem = gDefaultSkill + ld->mItems.Size(); // account for pre-added items ld->mSelectedItem = gDefaultSkill + ld->mItems.Size(); // account for pre-added items
int y = ld->mYpos; double y = ld->mYpos;
for (int i = 0; i < MAXSKILLS; i++) for (int i = 0; i < MAXSKILLS; i++)
{ {

View file

@ -419,7 +419,7 @@ public:
{ {
if (soundtrack > 0) if (soundtrack > 0)
{ {
Mus_Play(nullptr, fileSystem.GetFileFullName(soundtrack, false), false); Mus_Play(fileSystem.GetFileFullName(soundtrack, false), false);
} }
animtex.SetSize(AnimTexture::YUV, width, height); animtex.SetSize(AnimTexture::YUV, width, height);
} }
@ -519,7 +519,6 @@ class SmkPlayer : public MoviePlayer
AnimTextures animtex; AnimTextures animtex;
TArray<uint8_t> pFrame; TArray<uint8_t> pFrame;
TArray<uint8_t> audioBuffer; TArray<uint8_t> audioBuffer;
int nFrameRate;
int nFrames; int nFrames;
bool fullscreenScale; bool fullscreenScale;
uint64_t nFrameNs; uint64_t nFrameNs;
@ -571,8 +570,8 @@ public:
flags = flags_; flags = flags_;
Smacker_GetFrameSize(hSMK, nWidth, nHeight); Smacker_GetFrameSize(hSMK, nWidth, nHeight);
pFrame.Resize(nWidth * nHeight + std::max(nWidth, nHeight)); pFrame.Resize(nWidth * nHeight + std::max(nWidth, nHeight));
nFrameRate = Smacker_GetFrameRate(hSMK); float frameRate = Smacker_GetFrameRate(hSMK);
nFrameNs = 1'000'000'000 / nFrameRate; nFrameNs = uint64_t(1'000'000'000 / frameRate);
nFrames = Smacker_GetNumFrames(hSMK); nFrames = Smacker_GetNumFrames(hSMK);
Smacker_GetPalette(hSMK, palette); Smacker_GetPalette(hSMK, palette);
@ -617,7 +616,7 @@ public:
bool Frame(uint64_t clock) override bool Frame(uint64_t clock) override
{ {
int frame = clock / nFrameNs; int frame = int(clock / nFrameNs);
twod->ClearScreen(); twod->ClearScreen();
if (frame > nFrame) if (frame > nFrame)
@ -698,7 +697,7 @@ MoviePlayer* OpenMovie(const char* filename, TArray<int>& ans, const int* framet
if (!fr.isOpen()) fr = fileSystem.OpenFileReader(filename); if (!fr.isOpen()) fr = fileSystem.OpenFileReader(filename);
if (!fr.isOpen()) if (!fr.isOpen())
{ {
int nLen = strlen(filename); size_t nLen = strlen(filename);
// Strip the drive letter and retry. // Strip the drive letter and retry.
if (nLen >= 3 && isalpha(filename[0]) && filename[1] == ':' && filename[2] == '/') if (nLen >= 3 && isalpha(filename[0]) && filename[1] == ':' && filename[2] == '/')
{ {

View file

@ -252,7 +252,7 @@ bool InterplayDecoder::RunFrame(uint64_t clock)
{ {
nTimerRate = fr.ReadUInt32(); nTimerRate = fr.ReadUInt32();
nTimerDiv = fr.ReadUInt16(); nTimerDiv = fr.ReadUInt16();
nFrameDuration = ((double)nTimerRate * nTimerDiv) * 1000; nFrameDuration = ((uint64_t)nTimerRate * nTimerDiv) * 1000;
break; break;
} }
@ -346,7 +346,7 @@ bool InterplayDecoder::RunFrame(uint64_t clock)
case OPCODE_AUDIO_FRAME: case OPCODE_AUDIO_FRAME:
{ {
int nStart = fr.Tell(); int nStart = (int)fr.Tell();
uint16_t seqIndex = fr.ReadUInt16(); uint16_t seqIndex = fr.ReadUInt16();
uint16_t streamMask = fr.ReadUInt16(); uint16_t streamMask = fr.ReadUInt16();
uint16_t nSamples = fr.ReadUInt16(); // number of samples this chunk uint16_t nSamples = fr.ReadUInt16(); // number of samples this chunk
@ -380,7 +380,7 @@ bool InterplayDecoder::RunFrame(uint64_t clock)
ch ^= audio.nChannels - 1; ch ^= audio.nChannels - 1;
} }
int nEnd = fr.Tell(); int nEnd = (int)fr.Tell();
int nRead = nEnd - nStart; int nRead = nEnd - nStart;
assert(opcodeSize == nRead); assert(opcodeSize == nRead);
break; break;
@ -449,14 +449,14 @@ bool InterplayDecoder::RunFrame(uint64_t clock)
} }
} }
int nRead = fr.Read(decodeMap.pData, opcodeSize); int nRead = (int)fr.Read(decodeMap.pData, opcodeSize);
assert(nRead == opcodeSize); assert(nRead == opcodeSize);
break; break;
} }
case OPCODE_VIDEO_DATA: case OPCODE_VIDEO_DATA:
{ {
int nStart = fr.Tell(); int nStart = (int)fr.Tell();
// need to skip 14 bytes // need to skip 14 bytes
fr.Seek(14, FileReader::SeekCur); fr.Seek(14, FileReader::SeekCur);
@ -536,7 +536,7 @@ bool InterplayDecoder::RunFrame(uint64_t clock)
} }
} }
int nEnd = fr.Tell(); int nEnd = (int)fr.Tell();
int nSkipBytes = opcodeSize - (nEnd - nStart); // we can end up with 1 byte left we need to skip int nSkipBytes = opcodeSize - (nEnd - nStart); // we can end up with 1 byte left we need to skip
assert(nSkipBytes <= 1); assert(nSkipBytes <= 1);

View file

@ -52,13 +52,11 @@ enum SICommands
SI_MusicVolume, SI_MusicVolume,
SI_MidiDevice, SI_MidiDevice,
SI_MusicAlias, SI_MusicAlias,
SI_LevelMusic,
}; };
// This specifies whether Timidity or Windows playback is preferred for a certain song (only useful for Windows.) // This specifies whether Timidity or Windows playback is preferred for a certain song (only useful for Windows.)
extern MusicAliasMap MusicAliases; extern MusicAliasMap MusicAliases;
extern MusicAliasMap LevelMusicAliases;
extern MidiDeviceMap MidiDevices; extern MidiDeviceMap MidiDevices;
extern MusicVolumeMap MusicVolumes; extern MusicVolumeMap MusicVolumes;
@ -80,7 +78,6 @@ static const char *SICommandStrings[] =
"$musicvolume", "$musicvolume",
"$mididevice", "$mididevice",
"$musicalias", "$musicalias",
"$levelmusic",
NULL NULL
}; };
@ -140,7 +137,7 @@ static void S_AddSNDINFO (int lump)
sc.MustGetString(); sc.MustGetString();
FName musname (sc.String); FName musname (sc.String);
sc.MustGetFloat(); sc.MustGetFloat();
MusicVolumes[musname] = sc.Float; MusicVolumes[musname] = (float)sc.Float;
} }
break; break;
@ -172,20 +169,6 @@ static void S_AddSNDINFO (int lump)
} }
break; break;
case SI_LevelMusic: {
sc.MustGetString();
FName alias = sc.String;
sc.MustGetString();
FName mapped = sc.String;
// only set the alias if the lump it maps to exists.
if (mapped == NAME_None || fileSystem.FindFile(sc.String) >= 0)
{
LevelMusicAliases[alias] = mapped;
}
}
break;
case SI_MidiDevice: { case SI_MidiDevice: {
sc.MustGetString(); sc.MustGetString();
FName nm = sc.String; FName nm = sc.String;

View file

@ -49,7 +49,6 @@ static FString lastStartedMusic;
TArray<FString> specialmusic; TArray<FString> specialmusic;
MusicAliasMap MusicAliases; MusicAliasMap MusicAliases;
MusicAliasMap LevelMusicAliases;
CVAR(Bool, printmusicinfo, false, 0) CVAR(Bool, printmusicinfo, false, 0)
CVAR(Bool, mus_extendedlookup, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CVAR(Bool, mus_extendedlookup, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
@ -191,31 +190,18 @@ static FString LookupMusicCB(const char* musicname, int& order)
} }
static FString lastMusicLevel, lastMusic; static FString lastMusic;
int Mus_Play(const char *mapname, const char *fn, bool loop) int Mus_Play(const char *fn, bool loop)
{ {
if (mus_blocked) return 1; // Caller should believe it succeeded. if (mus_blocked) return 1; // Caller should believe it succeeded.
if (*fn == '/') fn++; if (*fn == '/') fn++;
// Store the requested names for resuming. // Store the requested names for resuming.
lastMusicLevel = mapname;
lastMusic = fn; lastMusic = fn;
if (!MusicEnabled()) if (!MusicEnabled())
{ {
return 1; return 1;
} }
// Allow per level music substitution.
// For most cases using $musicalias would be sufficient, but that method only works if a level actually has some music defined at all.
// This way it can be done with an add-on definition lump even in cases like Redneck Rampage where no music definitions exist
// or where music gets reused for multiple levels but replacement is wanted individually.
if (mapname && *mapname)
{
if (*mapname == '/') mapname++;
FName *check = LevelMusicAliases.CheckKey(FName(mapname, true));
if (check) fn = check->GetChars();
}
return S_ChangeMusic(fn, 0, loop, true); return S_ChangeMusic(fn, 0, loop, true);
} }

View file

@ -11,7 +11,7 @@ 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();
void Mus_UpdateMusic(); void Mus_UpdateMusic();
int Mus_Play(const char *mapname, const char *fn, bool loop); int Mus_Play(const char *fn, bool loop);
void Mus_Stop(); void Mus_Stop();
bool Mus_IsPlaying(); bool Mus_IsPlaying();
void Mus_SetPaused(bool on); void Mus_SetPaused(bool on);

View file

@ -57,6 +57,7 @@ void BunchDrawer::Init(HWDrawInfo *_di, Clipper* c, vec2_t& view, binangle a1, b
{ {
ang1 = a1; ang1 = a1;
ang2 = a2; ang2 = a2;
angrange = ang2 - ang1;
di = _di; di = _di;
clipper = c; clipper = c;
viewx = view.x * (1/ 16.f); viewx = view.x * (1/ 16.f);
@ -108,10 +109,11 @@ bool BunchDrawer::StartBunch(int sectnum, int linenum, binangle startan, binangl
bunch->sectnum = sectnum; bunch->sectnum = sectnum;
bunch->startline = bunch->endline = linenum; bunch->startline = bunch->endline = linenum;
bunch->startangle = (startan.asbam() - ang1.asbam()) > ANGLE_180? ang1 :startan; bunch->startangle = startan;
bunch->endangle = (endan.asbam() - ang2.asbam()) < ANGLE_180 ? ang2 : endan; bunch->endangle = endan;
bunch->portal = portal; bunch->portal = portal;
return bunch->endangle != ang2; assert(bunch->endangle.asbam() > bunch->startangle.asbam());
return bunch->endangle != angrange;
} }
//========================================================================== //==========================================================================
@ -123,8 +125,10 @@ bool BunchDrawer::StartBunch(int sectnum, int linenum, binangle startan, binangl
bool BunchDrawer::AddLineToBunch(int line, binangle newan) bool BunchDrawer::AddLineToBunch(int line, binangle newan)
{ {
Bunches[LastBunch].endline++; Bunches[LastBunch].endline++;
Bunches[LastBunch].endangle = (newan.asbam() - ang2.asbam()) < ANGLE_180 ? ang2 : newan; assert(newan.asbam() > Bunches[LastBunch].endangle.asbam());
return Bunches[LastBunch].endangle != ang2; Bunches[LastBunch].endangle = newan;
assert(Bunches[LastBunch].endangle.asbam() > Bunches[LastBunch].startangle.asbam());
return Bunches[LastBunch].endangle != angrange;
} }
//========================================================================== //==========================================================================
@ -202,8 +206,8 @@ int BunchDrawer::ClipLine(int aline, bool portal)
int section = cline->section; int section = cline->section;
int line = cline->wall; int line = cline->wall;
auto startAngleBam = wall[cline->startpoint].clipangle; auto startAngleBam = ClipAngle(cline->startpoint);
auto endAngleBam = wall[cline->endpoint].clipangle; auto endAngleBam = ClipAngle(cline->endpoint);
// Back side, i.e. backface culling - read: endAngle <= startAngle! // Back side, i.e. backface culling - read: endAngle <= startAngle!
if (startAngleBam.asbam() - endAngleBam.asbam() < ANGLE_180) if (startAngleBam.asbam() - endAngleBam.asbam() < ANGLE_180)
@ -213,10 +217,10 @@ int BunchDrawer::ClipLine(int aline, bool portal)
if (line >= 0 && blockwall[line]) return CL_Draw; if (line >= 0 && blockwall[line]) return CL_Draw;
// convert to clipper coordinates and clamp to valid range. // convert to clipper coordinates and clamp to valid range.
int startAngle = startAngleBam.asbam() - ang1.asbam(); int startAngle = startAngleBam.asbam();
int endAngle = endAngleBam.asbam() - ang1.asbam(); int endAngle = endAngleBam.asbam();
if (startAngle < 0) startAngle = 0; if (startAngle < 0) startAngle = 0;
if (endAngle < 0) endAngle = INT_MAX; if (endAngle < 0 || endAngle > (int)angrange.asbam()) endAngle = angrange.asbam();
// since these values are derived from previous calls of this function they cannot be out of range. // since these values are derived from previous calls of this function they cannot be out of range.
int sectStartAngle = sectionstartang[section]; int sectStartAngle = sectionstartang[section];
@ -380,9 +384,6 @@ int BunchDrawer::WallInFront(int line1, int line2)
//========================================================================== //==========================================================================
// //
// This is a bit more complicated than it looks because angles can wrap
// around so we can only compare angle differences.
//
// Rules: // Rules:
// 1. Any bunch can span at most 180°. // 1. Any bunch can span at most 180°.
// 2. 2 bunches can never overlap at both ends // 2. 2 bunches can never overlap at both ends
@ -395,15 +396,15 @@ int BunchDrawer::BunchInFront(FBunch* b1, FBunch* b2)
{ {
binangle anglecheck, endang; binangle anglecheck, endang;
if (b2->startangle.asbam() - b1->startangle.asbam() < b1->endangle.asbam() - b1->startangle.asbam()) if (b2->startangle.asbam() >= b1->startangle.asbam() && b2->startangle.asbam() < b1->endangle.asbam())
{ {
// we have an overlap at b2->startangle // we have an overlap at b2->startangle
anglecheck = b2->startangle - b1->startangle; anglecheck = b2->startangle;
// Find the wall in b1 that overlaps b2->startangle // Find the wall in b1 that overlaps b2->startangle
for (int i = b1->startline; i <= b1->endline; i++) for (int i = b1->startline; i <= b1->endline; i++)
{ {
endang = wall[wall[i].point2].clipangle - b1->startangle; endang = ClipAngle(wall[i].point2);
if (endang.asbam() > anglecheck.asbam()) if (endang.asbam() > anglecheck.asbam())
{ {
// found a line // found a line
@ -412,15 +413,15 @@ int BunchDrawer::BunchInFront(FBunch* b1, FBunch* b2)
} }
} }
} }
else if (b1->startangle.asbam() - b2->startangle.asbam() < b2->endangle.asbam() - b2->startangle.asbam()) else if (b1->startangle.asbam() >= b2->startangle.asbam() && b1->startangle.asbam() < b2->endangle.asbam())
{ {
// we have an overlap at b1->startangle // we have an overlap at b1->startangle
anglecheck = b1->startangle - b2->startangle; anglecheck = b1->startangle;
// Find the wall in b2 that overlaps b1->startangle // Find the wall in b2 that overlaps b1->startangle
for (int i = b2->startline; i <= b2->endline; i++) for (int i = b2->startline; i <= b2->endline; i++)
{ {
endang = wall[wall[i].point2].clipangle - b2->startangle; endang = ClipAngle(wall[i].point2);
if (endang.asbam() > anglecheck.asbam()) if (endang.asbam() > anglecheck.asbam())
{ {
// found a line // found a line
@ -500,7 +501,6 @@ void BunchDrawer::ProcessSection(int sectionnum, bool portal)
gotsection2.Set(sectionnum); gotsection2.Set(sectionnum);
bool inbunch; bool inbunch;
binangle startangle;
SetupSprite.Clock(); SetupSprite.Clock();
@ -548,31 +548,29 @@ void BunchDrawer::ProcessSection(int sectionnum, bool portal)
{ {
auto thisline = &sectionLines[section->lines[i]]; auto thisline = &sectionLines[section->lines[i]];
#ifdef _DEBUG binangle walang1 = ClipAngle(thisline->startpoint);
// For displaying positions in debugger binangle walang2 = ClipAngle(thisline->endpoint);
//DVector2 start = { WallStartX(thiswall), WallStartY(thiswall) };
//DVector2 end = { WallStartX(thiswall->point2), WallStartY(thiswall->point2) };
#endif
binangle walang1 = wall[thisline->startpoint].clipangle;
binangle walang2 = wall[thisline->endpoint].clipangle;
// outside the visible area or seen from the backside. // outside the visible area or seen from the backside.
if ((walang1.asbam() - ang1.asbam() > ANGLE_180 && walang2.asbam() - ang1.asbam() > ANGLE_180) || if ((walang1.asbam() > angrange.asbam() && walang2.asbam() > angrange.asbam() && walang1.asbam() < walang2.asbam()) ||
(walang1.asbam() - ang2.asbam() < ANGLE_180 && walang2.asbam() - ang2.asbam() < ANGLE_180) ||
(walang1.asbam() - walang2.asbam() < ANGLE_180)) (walang1.asbam() - walang2.asbam() < ANGLE_180))
{ {
inbunch = false; inbunch = false;
} }
else if (!inbunch)
{
startangle = walang1;
//Printf("Starting bunch:\n\tWall %d\n", sect->wallptr + i);
inbunch = StartBunch(sectnum, section->lines[i], walang1, walang2, portal);
}
else else
{ {
//Printf("\tWall %d\n", sect->wallptr + i); if (walang1.asbam() >= angrange.asbam()) { walang1 = bamang(0); inbunch = false; }
inbunch = AddLineToBunch(section->lines[i], walang2); if (walang2.asbam() >= angrange.asbam()) walang2 = angrange;
if (!inbunch)
{
//Printf("Starting bunch:\n\tWall %d\n", section->lines[i]);
inbunch = StartBunch(sectnum, section->lines[i], walang1, walang2, portal);
}
else
{
//Printf("\tWall %d\n", section->lines[i]);
inbunch = AddLineToBunch(section->lines[i], walang2);
}
} }
if (thisline->endpoint != section->lines[i] + 1) inbunch = false; if (thisline->endpoint != section->lines[i] + 1) inbunch = false;
} }
@ -596,7 +594,7 @@ void BunchDrawer::RenderScene(const int* viewsectors, unsigned sectcount, bool p
for (auto j : sectionspersector[viewsectors[i]]) for (auto j : sectionspersector[viewsectors[i]])
{ {
sectionstartang[j] = 0; sectionstartang[j] = 0;
sectionendang[j] = int(ang2.asbam() - ang1.asbam()); sectionendang[j] = int(angrange.asbam());
} }
} }
for (unsigned i = 0; i < sectcount; i++) for (unsigned i = 0; i < sectcount; i++)
@ -626,10 +624,12 @@ void BunchDrawer::RenderScene(const int* viewsectors, unsigned sectcount, bool p
auto rotang = di->Viewpoint.RotAngle; auto rotang = di->Viewpoint.RotAngle;
ang1 = bamang(rotang - ANGLE_90); ang1 = bamang(rotang - ANGLE_90);
ang2 = bamang(rotang + ANGLE_90 - 1); ang2 = bamang(rotang + ANGLE_90 - 1);
angrange = ang2 - ang1;
process(); process();
gotsection2.Zero(); gotsection2.Zero();
ang1 = bamang(rotang + ANGLE_90); ang1 = bamang(rotang + ANGLE_90);
ang2 = bamang(rotang - ANGLE_90 - 1); ang2 = bamang(rotang - ANGLE_90 - 1);
angrange = ang2 - ang1;
process(); process();
} }
Bsp.Unclock(); Bsp.Unclock();

View file

@ -31,7 +31,7 @@ class BunchDrawer
FixedBitArray<MAXSECTORS*5/4> gotsection2; FixedBitArray<MAXSECTORS*5/4> gotsection2;
FixedBitArray<MAXWALLS> gotwall; FixedBitArray<MAXWALLS> gotwall;
FixedBitArray<MAXWALLS> blockwall; FixedBitArray<MAXWALLS> blockwall;
binangle ang1, ang2; binangle ang1, ang2, angrange;
int sectionstartang[MAXSECTORS*5/4], sectionendang[MAXSECTORS*5/4]; int sectionstartang[MAXSECTORS*5/4], sectionendang[MAXSECTORS*5/4];
@ -44,6 +44,7 @@ private:
CL_Pass = 2, CL_Pass = 2,
}; };
binangle ClipAngle(int wal) { return wall[wal].clipangle - ang1; }
void StartScene(); void StartScene();
bool StartBunch(int sectnum, int linenum, binangle startan, binangle endan, bool portal); bool StartBunch(int sectnum, int linenum, binangle startan, binangle endan, bool portal);
bool AddLineToBunch(int line, binangle newan); bool AddLineToBunch(int line, binangle newan);

View file

@ -15,9 +15,7 @@
#include "hw_renderstate.h" #include "hw_renderstate.h"
#include "hw_cvars.h" #include "hw_cvars.h"
#ifdef _MSC_VER #pragma warning(disable:4244) // this gets a bit annoying in the renderer...
#pragma warning(disable:4244)
#endif
struct HWHorizonInfo; struct HWHorizonInfo;
struct HWSkyInfo; struct HWSkyInfo;
@ -403,15 +401,12 @@ inline void SetSpriteTranslucency(const spritetype* sprite, float& alpha, FRende
extern PalEntry GlobalMapFog; extern PalEntry GlobalMapFog;
extern float GlobalFogDensity; extern float GlobalFogDensity;
__forceinline void SetLightAndFog(FRenderState& state, PalEntry fade, int palette, int shade, float visibility, float alpha, bool setcolor = true) __forceinline void SetLightAndFog(FRenderState& state, PalEntry fade, int palette, int shade, float visibility, float alpha)
{ {
// 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)); bool foggy = (GlobalMapFog || (fade & 0xffffff));
auto ShadeDiv = lookups.tables[palette].ShadeFactor; auto ShadeDiv = lookups.tables[palette].ShadeFactor;
bool shadow = shade >= numshades; if (shade == 127) state.SetObjectColor(0xff000000); // 127 is generally used for shadow objects that must be black, even in foggy areas.
if (shadow) state.SetObjectColor(0xff000000); // make sure that nothing lights this up again.
else state.SetObjectColor(0xffffffff);
// Disable brightmaps if non-black fog is used. // Disable brightmaps if non-black fog is used.
if (ShadeDiv >= 1 / 1000.f && foggy) if (ShadeDiv >= 1 / 1000.f && foggy)

View file

@ -191,7 +191,7 @@ void HWFlat::DrawFlat(HWDrawInfo *di, FRenderState &state, bool translucent)
if (translucent) state.SetRenderStyle(LegacyRenderStyles[STYLE_Translucent]); if (translucent) state.SetRenderStyle(LegacyRenderStyles[STYLE_Translucent]);
state.EnableBrightmap(true); state.EnableBrightmap(true);
//state.SetObjectColor(0xffffffff); state.SetObjectColor(0xffffffff);
//state.SetAddColor(0); //state.SetAddColor(0);
//state.ApplyTextureManipulation(nullptr); //state.ApplyTextureManipulation(nullptr);
} }
@ -244,7 +244,7 @@ void HWFlat::ProcessSector(HWDrawInfo *di, sectortype * frontsector, int section
const auto &vp = di->Viewpoint; const auto &vp = di->Viewpoint;
float florz, ceilz; float florz, ceilz;
PlanesAtPoint(frontsector, vp.Pos.X * 16.f, vp.Pos.Y * -16.f, &ceilz, &florz); PlanesAtPoint(frontsector, float(vp.Pos.X) * 16.f, float(vp.Pos.Y) * -16.f, &ceilz, &florz);
fade = lookups.getFade(frontsector->floorpal); // fog is per sector. fade = lookups.getFade(frontsector->floorpal); // fog is per sector.
visibility = sectorVisibility(frontsector); visibility = sectorVisibility(frontsector);

View file

@ -481,7 +481,7 @@ int HWLinePortal::ClipSeg(walltype *seg, const DVector3 &viewpos)
int HWLinePortal::ClipSector(sectortype *sub) int HWLinePortal::ClipSector(sectortype *sub)
{ {
// this seg is completely behind the mirror // this seg is completely behind the mirror
for (unsigned int i = 0; i<sub->wallnum; i++) for (int i = 0; i<sub->wallnum; i++)
{ {
if (PointOnLineSide(WallStart(&wall[sub->wallptr]), line) == 0) return PClip_Inside; if (PointOnLineSide(WallStart(&wall[sub->wallptr]), line) == 0) return PClip_Inside;
} }

View file

@ -109,7 +109,10 @@ void HWSprite::DrawSprite(HWDrawInfo* di, FRenderState& state, bool translucent)
else RenderStyle.BlendOp = STYLEOP_Fuzz; // subtractive with models is not going to work. else RenderStyle.BlendOp = STYLEOP_Fuzz; // subtractive with models is not going to work.
} }
SetLightAndFog(state, fade, palette, shade, visibility, alpha, this->shade <= numshades); SetLightAndFog(state, fade, palette, shade, visibility, alpha);
if (shade >= numshades) state.SetObjectColor(0xff000000); // make sure that nothing lights this up again.
if (modelframe == 0) if (modelframe == 0)
{ {
@ -161,6 +164,7 @@ void HWSprite::DrawSprite(HWDrawInfo* di, FRenderState& state, bool translucent)
{ {
//RenderModel(&renderer, x, y, z, modelframe, actor, di->Viewpoint.TicFrac); //RenderModel(&renderer, x, y, z, modelframe, actor, di->Viewpoint.TicFrac);
} }
state.SetObjectColor(0xffffffff);
state.SetVertexBuffer(screen->mVertexData); state.SetVertexBuffer(screen->mVertexData);
state.EnableModelMatrix(false); state.EnableModelMatrix(false);
} }

View file

@ -128,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, fade, palette, shade, visibility, alpha, false); SetLightAndFog(state, fade, palette, min<int>(shade, numshades), visibility, alpha);
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);
@ -173,8 +173,8 @@ void HWWall::RenderTexturedWall(HWDrawInfo *di, FRenderState &state, int rflags)
RenderWall(di, state, rflags); RenderWall(di, state, rflags);
state.SetNpotEmulation(0.f, 0.f); state.SetNpotEmulation(0.f, 0.f);
/* none of these functions is in use.
state.SetObjectColor(0xffffffff); state.SetObjectColor(0xffffffff);
/* none of these functions is in use.
state.SetObjectColor2(0); state.SetObjectColor2(0);
state.SetAddColor(0); state.SetAddColor(0);
state.SetTextureMode(tmode); state.SetTextureMode(tmode);
@ -1088,10 +1088,17 @@ void HWWall::ProcessWallSprite(HWDrawInfo* di, spritetype* spr, sectortype* sect
zbottom[0] = zbottom[1] = (sprz) * (1 / -256.); zbottom[0] = zbottom[1] = (sprz) * (1 / -256.);
ztop[0] = ztop[1] = (sprz - ((height * spr->yrepeat) << 2)) * (1 / -256.); ztop[0] = ztop[1] = (sprz - ((height * spr->yrepeat) << 2)) * (1 / -256.);
if (zbottom[0] > ztop[0])
{
// reorder coordinates to make the clipping code below behave.
auto zz = zbottom[0];
zbottom[0] = zbottom[1] = ztop[0];
ztop[0] = ztop[1] = zz;
}
// Clip sprites to ceilings/floors // Clip sprites to ceilings/floors
float origz = ztop[0]; float origz = zbottom[0];
float polyh = (zbottom[0] - origz); float polyh = (ztop[0] - origz);
if (!(sector->ceilingstat & CSTAT_SECTOR_SKY)) if (!(sector->ceilingstat & CSTAT_SECTOR_SKY))
{ {
float ceilingz = sector->ceilingz * (1 / -256.f); float ceilingz = sector->ceilingz * (1 / -256.f);

View file

@ -95,7 +95,7 @@ bool RTS_IsInitialized()
{ {
FileLump *li = (FileLump*)(RTSFile.Data() + LittleLong(wi->infotableofs)); FileLump *li = (FileLump*)(RTSFile.Data() + LittleLong(wi->infotableofs));
LumpInfo.Resize(numlumps); LumpInfo.Resize(numlumps);
for(unsigned i = 0; i < numlumps; i++, li++) for(int i = 0; i < numlumps; i++, li++)
{ {
LumpInfo[i] = { LittleLong(li->position), LittleLong(li->size), -1 }; LumpInfo[i] = { LittleLong(li->position), LittleLong(li->size), -1 };
if (unsigned(LumpInfo[i].position + LumpInfo[i].size) >= RTSFile.Size()) if (unsigned(LumpInfo[i].position + LumpInfo[i].size) >= RTSFile.Size())

View file

@ -68,7 +68,10 @@ walltype wallbackup[MAXWALLS];
void WriteSavePic(FileWriter* file, int width, int height); void WriteSavePic(FileWriter* file, int width, int height);
bool WriteZip(const char* filename, TArray<FString>& filenames, TArray<FCompressedBuffer>& content); bool WriteZip(const char* filename, TArray<FString>& filenames, TArray<FCompressedBuffer>& content);
extern FString savename;
extern FString BackupSaveGame; extern FString BackupSaveGame;
int SaveVersion;
void SerializeMap(FSerializer &arc); void SerializeMap(FSerializer &arc);
FixedBitArray<MAXSPRITES> activeSprites; FixedBitArray<MAXSPRITES> activeSprites;
@ -344,6 +347,7 @@ int G_ValidateSavegame(FileReader &fr, FString *savetitle, bool formenu)
// not our business. Leave it alone. // not our business. Leave it alone.
return 0; return 0;
} }
SaveVersion = savesig.currentsavever;
MapRecord *curLevel = FindMapByName(label); MapRecord *curLevel = FindMapByName(label);
@ -686,26 +690,103 @@ static int nextquicksave = -1;
} }
void G_LoadGame(const char *filename) void G_LoadGame(const char* name, bool hidecon)
{ {
inputState.ClearAllInput(); if (name != NULL)
gi->FreeLevelData(); {
DoLoadGame(filename); savename = name;
BackupSaveGame = filename; gameaction = !hidecon ? ga_loadgame : ga_loadgamehidecon;
}
} }
void G_SaveGame(const char *fn, const char *desc, bool ok4q, bool forceq) void G_DoLoadGame()
{
if (gameaction == ga_loadgamehidecon && gamestate == GS_FULLCONSOLE)
{
// does this even do anything anymore?
gamestate = GS_HIDECONSOLE;
}
inputState.ClearAllInput();
gi->FreeLevelData();
DoLoadGame(savename);
BackupSaveGame = savename;
}
extern bool sendsave;
extern FString savedescription;
extern FString savegamefile;
void G_SaveGame(const char* filename, const char* description)
{
if (sendsave || gameaction == ga_savegame)
{
Printf("%s\n", GStrings("TXT_SAVEPENDING"));
}
else if (gamestate != GS_LEVEL)
{
Printf("%s\n", GStrings("TXT_NOTINLEVEL"));
}
else if (!gi->CanSave())
{
Printf("%s\n", GStrings("TXT_SPPLAYERDEAD"));
}
else
{
savegamefile = filename;
savedescription = description;
sendsave = true;
}
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void startSaveGame(int player, uint8_t** stream, bool skip)
{
auto s = ReadString(stream);
savegamefile = s;
delete[] s;
s = ReadString(stream);
savedescription = s;
if (!skip && gi->CanSave())
{
if (player != consoleplayer)
{
// Paths sent over the network will be valid for the system that sent
// the save command. For other systems, the path needs to be changed.
savegamefile = G_BuildSaveName(ExtractFileBase(savegamefile, true));
}
gameaction = ga_savegame;
}
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void G_DoSaveGame(bool ok4q, bool forceq, const char* fn, const char* desc)
{ {
if (WriteSavegame(fn, desc)) if (WriteSavegame(fn, desc))
{ {
savegameManager.NotifyNewSave(fn, desc, ok4q, forceq); savegameManager.NotifyNewSave(fn, desc, ok4q, forceq);
Printf(PRINT_NOTIFY, "%s\n", GStrings("GAME SAVED")); Printf(PRINT_NOTIFY, "%s\n", GStrings("GGSAVED"));
BackupSaveGame = fn; BackupSaveGame = fn;
}
} }
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void M_Autosave()
void M_Autosave()
{ {
if (disableautosave) return; if (disableautosave) return;
if (!gi->CanSave()) return; if (!gi->CanSave()) return;
@ -728,7 +809,7 @@ void M_Autosave()
readableTime = myasctime(); readableTime = myasctime();
FStringf SaveTitle("Autosave %s", readableTime); FStringf SaveTitle("Autosave %s", readableTime);
nextautosave = (nextautosave + 1) % count; nextautosave = (nextautosave + 1) % count;
G_SaveGame(Filename, SaveTitle, false, false); G_DoSaveGame(false, false, Filename, SaveTitle);
} }
CCMD(autosave) CCMD(autosave)
@ -759,7 +840,51 @@ CCMD(rotatingquicksave)
readableTime = myasctime(); readableTime = myasctime();
FStringf SaveTitle("Quicksave %s", readableTime); FStringf SaveTitle("Quicksave %s", readableTime);
nextquicksave = (nextquicksave + 1) % count; nextquicksave = (nextquicksave + 1) % count;
G_SaveGame(Filename, SaveTitle, false, false); G_SaveGame(Filename, SaveTitle);
}
//==========================================================================
//
// CCMD load
//
// Load a saved game.
//
//==========================================================================
UNSAFE_CCMD(load)
{
if (argv.argc() != 2)
{
Printf("usage: load <filename>\n");
return;
}
if (netgame)
{
Printf("cannot load during a network game\n");
return;
}
FString fname = G_BuildSaveName(argv[1]);
G_LoadGame(fname);
}
//==========================================================================
//
// CCMD save
//
// Save the current game.
//
//==========================================================================
UNSAFE_CCMD(save)
{
if (argv.argc() < 2 || argv.argc() > 3)
{
Printf("usage: save <filename> [description]\n");
return;
}
FString fname = G_BuildSaveName(argv[1]);
G_SaveGame(fname, argv.argc() > 2 ? argv[2] : argv[1]);
} }

View file

@ -7,12 +7,15 @@ extern FixedBitArray<MAXSPRITES> activeSprites;
// Savegame utilities // Savegame utilities
class FileReader; class FileReader;
extern int SaveVersion;
FString G_BuildSaveName (const char *prefix); FString G_BuildSaveName (const char *prefix);
int G_ValidateSavegame(FileReader &fr, FString *savetitle, bool formenu); int G_ValidateSavegame(FileReader &fr, FString *savetitle, bool formenu);
void G_LoadGame(const char* filename); void G_LoadGame(const char* filename, bool hidecon = false);
void G_SaveGame(const char* fn, const char* desc, bool ok4q, bool forceq); void G_SaveGame(const char* fn, const char* desc);
void G_DoSaveGame(bool okForQuicksave, bool forceQuicksave, const char* filename, const char* description);
void G_DoLoadGame();
void M_Autosave(); void M_Autosave();

View file

@ -94,7 +94,7 @@ void Job_Init()
static VMFunction* LookupFunction(const char* qname, bool validate = true) static VMFunction* LookupFunction(const char* qname, bool validate = true)
{ {
int p = strcspn(qname, "."); size_t p = strcspn(qname, ".");
if (p == 0) I_Error("Call to undefined function %s", qname); if (p == 0) I_Error("Call to undefined function %s", qname);
FString clsname(qname, p); FString clsname(qname, p);
FString funcname = qname + p + 1; FString funcname = qname + p + 1;
@ -488,7 +488,11 @@ void ShowIntermission(MapRecord* fromMap, MapRecord* toMap, SummaryInfo* info, C
if (tocluster == nullptr || !tocluster->intro.Create(runner, toMap, !!fromMap)) if (tocluster == nullptr || !tocluster->intro.Create(runner, toMap, !!fromMap))
globalCutscenes.DefaultMapIntro.Create(runner, toMap, !!fromMap); globalCutscenes.DefaultMapIntro.Create(runner, toMap, !!fromMap);
} }
globalCutscenes.LoadingScreen.Create(runner, toMap, true); // Skip the load screen if the level is started from the console.
// In this case the load screen is not helpful as it blocks the actual level start,
// requiring closing and reopening the console first before entering any commands that need the level.
if (ConsoleState == c_up || ConsoleState == c_rising)
globalCutscenes.LoadingScreen.Create(runner, toMap, true);
} }
else if (isShareware()) else if (isShareware())
{ {

View file

@ -668,7 +668,7 @@ void GetCRC(FileEntry *entry, TArray<FileEntry> &CRCCache)
do do
{ {
b = f.Read(buffer.Data(), buffer.Size()); b = f.Read(buffer.Data(), buffer.Size());
if (b > 0) crcval = AddCRC32(crcval, buffer.Data(), b); if (b > 0) crcval = AddCRC32(crcval, buffer.Data(), unsigned(b));
} }
while (b == buffer.Size()); while (b == buffer.Size());
entry->CRCValue = crcval; entry->CRCValue = crcval;

View file

@ -139,8 +139,8 @@ public:
DVector2 dv = { double(ix2 - ix1), -double(iy2 - iy1) }; DVector2 dv = { double(ix2 - ix1), -double(iy2 - iy1) };
auto vang = dv.Angle() - 90.; auto vang = dv.Angle() - 90.;
cosalign = vang.Cos(); cosalign = float(vang.Cos());
sinalign = vang.Sin(); sinalign = float(vang.Sin());
int pow2width = 1 << sizeToBits((int)tx->GetDisplayWidth()); int pow2width = 1 << sizeToBits((int)tx->GetDisplayWidth());
if (pow2width < (int)tx->GetDisplayWidth()) pow2width *= 2; if (pow2width < (int)tx->GetDisplayWidth()) pow2width *= 2;
@ -247,9 +247,9 @@ bool SectorGeometry::MakeVertices(unsigned int secnum, int plane, const FVector2
{ {
auto sline = &sectionLines[sec->lines[start]]; auto sline = &sectionLines[sec->lines[start]];
auto wallp = &wall[sline->startpoint]; auto wallp = &wall[sline->startpoint];
float X = WallStartX(wallp); float X = float(WallStartX(wallp));
float Y = WallStartY(wallp); float Y = float(WallStartY(wallp));
if (fabs(X) > 32768. || fabs(Y) > 32768.) if (fabs(X) > 32768.f || fabs(Y) > 32768.f)
{ {
// If we get here there's some fuckery going around with the coordinates. Let's better abort and wait for things to realign. // If we get here there's some fuckery going around with the coordinates. Let's better abort and wait for things to realign.
// Do not try alternative methods if this happens. // Do not try alternative methods if this happens.
@ -277,7 +277,7 @@ bool SectorGeometry::MakeVertices(unsigned int secnum, int plane, const FVector2
{ {
minx = pt.first; minx = pt.first;
miny = pt.second; miny = pt.second;
outer = a; outer = int(a);
} }
} }
} }
@ -303,8 +303,8 @@ bool SectorGeometry::MakeVertices(unsigned int secnum, int plane, const FVector2
} }
auto& entry = data[secnum].planes[plane]; auto& entry = data[secnum].planes[plane];
entry.vertices.Resize(indices.size()); entry.vertices.Resize((unsigned)indices.size());
entry.texcoords.Resize(indices.size()); entry.texcoords.Resize((unsigned)indices.size());
entry.normal = CalcNormal(sectorp, plane); entry.normal = CalcNormal(sectorp, plane);
auto texture = tileGetTexture(plane ? sectorp->ceilingpicnum : sectorp->floorpicnum); auto texture = tileGetTexture(plane ? sectorp->ceilingpicnum : sectorp->floorpicnum);

View file

@ -70,63 +70,7 @@ enum
HUDMSGLayer_Default = HUDMSGLayer_OverHUD, HUDMSGLayer_Default = HUDMSGLayer_OverHUD,
}; };
struct FLevelStats extern DStatusBarCore *StatusBar;
{
int screenbottomspace;
int time; // in milliseconds
int frags;
int kills, maxkills; // set maxkills to -1 to ignore, or to -2 to only print kills
int secrets, maxsecrets, supersecrets; // set maxsecrets to -1 to ignore
int spacing; // uses fontheight if 0 or less.
EColorRange letterColor, standardColor, completeColor;
double fontscale;
FFont* font;
};
//============================================================================
//
// encapsulates all settings a HUD font may need
//
//============================================================================
class DBaseStatusBar : public DStatusBarCore
{
DECLARE_ABSTRACT_CLASS (DBaseStatusBar, DStatusBarCore)
public:
DBaseStatusBar ();
virtual ~DBaseStatusBar() = default;
// do not make this a DObject Serialize function because it's not used like one!
//void SerializeMessages(FSerializer &arc);
virtual void Tick ();
void PrintLevelStats(FLevelStats& stats);
void PrintAutomapInfo(FLevelStats& stats, bool forcetextfont = false);
int GetTopOfStatusbar() const
{
return SBarTop;
}
short CalcMagazineAmount(short ammo_remaining, short clip_capacity, bool reloading);
void Set43ClipRect();
virtual void UpdateStatusBar() = 0;
private:
DObject *AltHud = nullptr;
public:
bool Centering;
bool FixedOrigin;
private:
};
extern DBaseStatusBar *StatusBar;
// Status bar factories ----------------------------------------------------- // Status bar factories -----------------------------------------------------
@ -136,7 +80,6 @@ void ST_Clear();
extern FGameTexture *CrosshairImage; extern FGameTexture *CrosshairImage;
void SBar_DrawString(DStatusBarCore* self, DHUDFont* font, const FString& string, double x, double y, int flags, int trans, double alpha, int wrapwidth, int linespacing, double scaleX, double scaleY, int pt = 0, int style = STYLE_Translucent);
void setViewport(int viewSize); void setViewport(int viewSize);
struct MapRecord; struct MapRecord;
void setLevelStarted(MapRecord *); void setLevelStarted(MapRecord *);
@ -144,5 +87,10 @@ void drawMapTitle();
class FSerializer; class FSerializer;
void SerializeHud(FSerializer &arc); void SerializeHud(FSerializer &arc);
extern int levelTextTime; extern int levelTextTime;
struct SummaryInfo;
void UpdateStatusBar(SummaryInfo* info);
void TickStatusBar();
void ResetStatusBar();
void InitStatusBar();
#endif /* __SBAR_H__ */ #endif /* __SBAR_H__ */

View file

@ -64,12 +64,6 @@
#include "../version.h" #include "../version.h"
#define XHAIRSHRINKSIZE (1./18)
#define XHAIRPICKUPSIZE (2+XHAIRSHRINKSIZE)
#define POWERUPICONSIZE 32
//IMPLEMENT_CLASS(DHUDFont, true, false);
EXTERN_CVAR (Bool, am_showmonsters) EXTERN_CVAR (Bool, am_showmonsters)
EXTERN_CVAR (Bool, am_showsecrets) EXTERN_CVAR (Bool, am_showsecrets)
EXTERN_CVAR (Bool, am_showtime) EXTERN_CVAR (Bool, am_showtime)
@ -78,12 +72,10 @@ EXTERN_CVAR (Bool, noisedebug)
EXTERN_CVAR(Bool, vid_fps) EXTERN_CVAR(Bool, vid_fps)
EXTERN_CVAR(Bool, inter_subtitles) EXTERN_CVAR(Bool, inter_subtitles)
//extern DBaseStatusBar *StatusBar;
extern int setblocks; extern int setblocks;
IMPLEMENT_CLASS(DBaseStatusBar, true, false)
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
//
// ST_Clear // ST_Clear
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -99,198 +91,6 @@ void ST_Clear()
*/ */
} }
//---------------------------------------------------------------------------
//
// Constructor
//
//---------------------------------------------------------------------------
DBaseStatusBar::DBaseStatusBar ()
{
CompleteBorder = false;
Centering = false;
FixedOrigin = false;
SetSize(0);
}
//---------------------------------------------------------------------------
//
// PROC Tick
//
//---------------------------------------------------------------------------
void DBaseStatusBar::Tick ()
{
}
static DObject *InitObject(PClass *type, int paramnum, VM_ARGS)
{
auto obj = type->CreateNew();
// Todo: init
return obj;
}
//============================================================================
//
//
//
//============================================================================
void DBaseStatusBar::PrintLevelStats(FLevelStats &stats)
{
double y;
double scale = stats.fontscale * hud_statscale;
if (stats.spacing <= 0) stats.spacing = stats.font->GetHeight() * stats.fontscale;
double spacing = stats.spacing * hud_statscale;
if (stats.screenbottomspace < 0)
{
y = 200 - (RelTop - stats.screenbottomspace) * hud_scalefactor - spacing;
}
else
{
y = 200 - stats.screenbottomspace * hud_scalefactor - spacing;
}
double y1, y2, y3;
if (stats.maxsecrets > 0) // don't bother if there are no secrets.
{
y1 = y;
y -= spacing;
}
if (stats.frags >= 0 || stats.maxkills != -1)
{
y2 = y;
y -= spacing;
}
y3 = y;
FString text;
int black = 0x80000000;
text.Format(TEXTCOLOR_ESCAPESTR "%cT: " TEXTCOLOR_ESCAPESTR "%c%d:%02d", stats.letterColor + 'A', stats.standardColor + 'A', stats.time / 60000, (stats.time % 60000) / 1000);
DrawText(twod, stats.font, CR_UNTRANSLATED, 2 * hud_statscale + scale, y3 + scale, text, DTA_FullscreenScale, FSMode_ScaleToHeight, DTA_VirtualWidth, 320, DTA_VirtualHeight, 200,
DTA_KeepRatio, true, DTA_ScaleX, scale, DTA_ScaleY, scale, DTA_LegacyRenderStyle, STYLE_TranslucentStencil, DTA_Color, black, TAG_DONE);
DrawText(twod, stats.font, CR_UNTRANSLATED, 2 * hud_statscale, y3, text, DTA_FullscreenScale, FSMode_ScaleToHeight, DTA_VirtualWidth, 320, DTA_VirtualHeight, 200,
DTA_KeepRatio, true, DTA_ScaleX, scale, DTA_ScaleY, scale, TAG_DONE);
text = "";
if (stats.frags > -1) text.Format(TEXTCOLOR_ESCAPESTR "%cF: " TEXTCOLOR_ESCAPESTR "%c%d", stats.letterColor + 'A', stats.standardColor + 'A', stats.frags);
else if (stats.maxkills == -2) text.Format(TEXTCOLOR_ESCAPESTR "%cK: " TEXTCOLOR_ESCAPESTR "%c%d", stats.letterColor + 'A', stats.standardColor + 'A', stats.kills);
else if (stats.maxkills != -1) text.Format(TEXTCOLOR_ESCAPESTR "%cK: " TEXTCOLOR_ESCAPESTR "%c%d/%d",
stats.letterColor + 'A', stats.kills == stats.maxkills ? stats.completeColor + 'A' : stats.standardColor + 'A', stats.kills, stats.maxkills);
if (text.IsNotEmpty())
{
DrawText(twod, stats.font, CR_UNTRANSLATED, 2 * hud_statscale+scale, y2+scale, text, DTA_FullscreenScale, FSMode_ScaleToHeight, DTA_VirtualWidth, 320, DTA_VirtualHeight, 200,
DTA_KeepRatio, true, DTA_ScaleX, scale, DTA_ScaleY, scale, DTA_LegacyRenderStyle, STYLE_TranslucentStencil, DTA_Color, black, TAG_DONE);
DrawText(twod, stats.font, CR_UNTRANSLATED, 2 * hud_statscale, y2, text, DTA_FullscreenScale, FSMode_ScaleToHeight, DTA_VirtualWidth, 320, DTA_VirtualHeight, 200,
DTA_KeepRatio, true, DTA_ScaleX, scale, DTA_ScaleY, scale, TAG_DONE);
}
if (stats.maxsecrets > 0) // don't bother if there are no secrets.
{
if (stats.supersecrets <= 0)
text.Format(TEXTCOLOR_ESCAPESTR "%cS: " TEXTCOLOR_ESCAPESTR "%c%d/%d",
stats.letterColor + 'A', stats.secrets >= stats.maxsecrets ? stats.completeColor + 'A' : stats.standardColor + 'A', stats.secrets, stats.maxsecrets);
else
text.Format(TEXTCOLOR_ESCAPESTR "%cS: " TEXTCOLOR_ESCAPESTR "%c%d/%d+%d",
stats.letterColor + 'A', stats.secrets >= stats.maxsecrets ? stats.completeColor + 'A' : stats.standardColor + 'A', stats.secrets, stats.maxsecrets, stats.supersecrets);
DrawText(twod, stats.font, CR_UNTRANSLATED, 2 * hud_statscale + scale, y1 + scale, text, DTA_FullscreenScale, FSMode_ScaleToHeight, DTA_VirtualWidth, 320, DTA_VirtualHeight, 200,
DTA_KeepRatio, true, DTA_ScaleX, scale, DTA_ScaleY, scale, DTA_LegacyRenderStyle, STYLE_TranslucentStencil, DTA_Color, black, TAG_DONE);
DrawText(twod, stats.font, CR_UNTRANSLATED, 2 * hud_statscale, y1, text, DTA_FullscreenScale, FSMode_ScaleToHeight, DTA_VirtualWidth, 320, DTA_VirtualHeight, 200,
DTA_KeepRatio, true, DTA_ScaleX, scale, DTA_ScaleY, scale, TAG_DONE);
}
}
//============================================================================
//
//
//
//============================================================================
void DBaseStatusBar::PrintAutomapInfo(FLevelStats& stats, bool forcetextfont)
{
auto lev = currentLevel;
FString mapname;
if (am_showlabel)
mapname.Format(TEXTCOLOR_ESCAPESTR "%c%s: " TEXTCOLOR_ESCAPESTR "%c%s", stats.letterColor+'A', lev->LabelName(), stats.standardColor+'A', lev->DisplayName());
else
mapname = lev->DisplayName();
forcetextfont |= am_textfont;
double y;
double scale = stats.fontscale * (forcetextfont ? *hud_statscale : 1); // the tiny default font used by all games here cannot be scaled for readability purposes.
if (stats.spacing <= 0) stats.spacing = stats.font->GetHeight() * stats.fontscale;
double spacing = stats.spacing * (forcetextfont ? *hud_statscale : 1);
if (am_nameontop)
{
y = spacing + 1;
}
else if (stats.screenbottomspace < 0)
{
y = 200 - RelTop - spacing;
}
else
{
y = 200 - stats.screenbottomspace - spacing;
}
auto cluster = FindCluster(lev->cluster);
FString volname;
if (cluster) volname = cluster->name;
if (volname.IsEmpty() && am_nameontop) y = 1;
DrawText(twod, stats.font, stats.standardColor, 2 * hud_statscale, y, mapname, DTA_FullscreenScale, FSMode_ScaleToHeight, DTA_VirtualWidth, 320, DTA_VirtualHeight, 200,
DTA_ScaleX, scale, DTA_ScaleY, scale, DTA_KeepRatio, true, TAG_DONE);
y -= spacing;
if (!(lev->flags & MI_USERMAP) && !(g_gameType & GAMEFLAG_PSEXHUMED) && volname.IsNotEmpty())
DrawText(twod, stats.font, stats.standardColor, 2 * hud_statscale, y, GStrings.localize(volname),
DTA_FullscreenScale, FSMode_ScaleToHeight, DTA_VirtualWidth, 320, DTA_VirtualHeight, 200,
DTA_ScaleX, scale, DTA_ScaleY, scale, DTA_KeepRatio, true, TAG_DONE);
}
//============================================================================
//
//
//
//============================================================================
short DBaseStatusBar::CalcMagazineAmount(short ammo_remaining, short clip_capacity, bool reloading)
{
// Determine amount in clip.
short clip_amount = ammo_remaining % clip_capacity;
// Set current clip value to clip capacity if wrapped around to zero, otherwise use determined value.
short clip_current = ammo_remaining != 0 && clip_amount == 0 ? clip_capacity : clip_amount;
// Return current clip value if weapon has rounds or is not on a reload cycle.
return ammo_remaining == 0 || (reloading && clip_amount == 0) ? 0 : clip_current;
}
//============================================================================
//
//
//
//============================================================================
void DBaseStatusBar::Set43ClipRect()
{
auto GetWidth = [=]() { return twod->GetWidth(); };
auto GetHeight = [=]() {return twod->GetHeight(); };
auto screenratio = ActiveRatio(GetWidth(), GetHeight());
if (screenratio < 1.34) return;
int width = xs_CRoundToInt(GetWidth() * 1.333 / screenratio);
int left = (GetWidth() - width) / 2;
twod->SetClipRect(left, 0, width, GetHeight());
}
//============================================================================ //============================================================================
// //
// //
@ -379,5 +179,39 @@ void drawMapTitle()
} }
} }
void UpdateStatusBar(SummaryInfo* info)
{
IFVIRTUALPTRNAME(StatusBar, NAME_RazeStatusBar, UpdateStatusBar)
{
VMValue params[] = { StatusBar, info };
VMCall(func, params, 2, nullptr, 0);
}
}
void TickStatusBar()
{
IFVIRTUALPTRNAME(StatusBar, NAME_RazeStatusBar, Tick)
{
VMValue params[] = { StatusBar };
VMCall(func, params, 1, nullptr, 0);
}
}
void ResetStatusBar()
{
IFVIRTUALPTRNAME(StatusBar, NAME_RazeStatusBar, Reset)
{
VMValue params[] = { StatusBar };
VMCall(func, params, 1, nullptr, 0);
}
}
void InitStatusBar()
{
IFVIRTUALPTRNAME(StatusBar, NAME_RazeStatusBar, Init)
{
VMValue params[] = { StatusBar };
VMCall(func, params, 1, nullptr, 0);
}
}

View file

@ -274,7 +274,7 @@ void BuildTiles::MakeCanvas(int tilenum, int width, int height)
{ {
auto canvas = ValidateCustomTile(tilenum, ReplacementType::Canvas); auto canvas = ValidateCustomTile(tilenum, ReplacementType::Canvas);
canvas->SetSize(width*4, height*4); canvas->SetSize(width*4, height*4);
canvas->SetDisplaySize(width, height); canvas->SetDisplaySize((float)width, (float)height);
canvas->GetTexture()->SetSize(width * 4, height * 4); canvas->GetTexture()->SetSize(width * 4, height * 4);
static_cast<FCanvasTexture*>(canvas->GetTexture())->aspectRatio = (float)width / height; static_cast<FCanvasTexture*>(canvas->GetTexture())->aspectRatio = (float)width / height;
} }
@ -291,7 +291,7 @@ void BuildTiles::MakeCanvas(int tilenum, int width, int height)
int BuildTiles::LoadArtFile(const char *fn, const char *mapname, int firsttile) int BuildTiles::LoadArtFile(const char *fn, const char *mapname, int firsttile)
{ {
auto old = FindFile(fn); unsigned old = FindFile(fn);
if (old >= ArtFiles.Size()) // Do not process if already loaded. if (old >= ArtFiles.Size()) // Do not process if already loaded.
{ {
FileReader fr = fileSystem.OpenFileReader(fn); FileReader fr = fileSystem.OpenFileReader(fn);

View file

@ -440,7 +440,7 @@ bool PreBindTexture(FRenderState* state, FGameTexture*& tex, EUpscaleFlags& flag
flags |= (((pick.tintFlags & TINTF_BLENDMASK) >> 6) + 1) & TextureManipulation::BlendMask; flags |= (((pick.tintFlags & TINTF_BLENDMASK) >> 6) + 1) & TextureManipulation::BlendMask;
} }
} }
addcol.W = flags; addcol.W = (float)flags;
if ((pick.translation & 0x80000000) && hw_shadeinterpolate) addcol.W += 16384; // hijack a free bit in here. if ((pick.translation & 0x80000000) && hw_shadeinterpolate) addcol.W += 16384; // hijack a free bit in here.
state->SetTextureColors(&modcol.X, &addcol.X, &blendcol.X); state->SetTextureColors(&modcol.X, &addcol.X, &blendcol.X);
} }

View file

@ -70,16 +70,16 @@ const char *GetVersionString();
#define SAVESIG_PS GAMENAME ".Exhumed" #define SAVESIG_PS GAMENAME ".Exhumed"
#define SAVESIG_WH GAMENAME ".Witchaven" #define SAVESIG_WH GAMENAME ".Witchaven"
#define MINSAVEVER_DN3D 10 #define MINSAVEVER_DN3D 11
#define MINSAVEVER_BLD 11 #define MINSAVEVER_BLD 12
#define MINSAVEVER_SW 12 #define MINSAVEVER_SW 13
#define MINSAVEVER_PS 12 #define MINSAVEVER_PS 13
#define MINSAVEVER_WH 10 #define MINSAVEVER_WH 10
#define SAVEVER_DN3D 10 #define SAVEVER_DN3D 11
#define SAVEVER_BLD 11 #define SAVEVER_BLD 12
#define SAVEVER_SW 12 #define SAVEVER_SW 13
#define SAVEVER_PS 12 #define SAVEVER_PS 13
#define SAVEVER_WH 10 #define SAVEVER_WH 10
#define NETGAMEVERSION 1 #define NETGAMEVERSION 1

View file

@ -148,7 +148,7 @@ RORHACK:
for (int i = 0; i < 16; i++) for (int i = 0; i < 16; i++)
ror_status[i] = testgotpic(4080 + i); ror_status[i] = testgotpic(4080 + i);
fixed_t deliriumPitchI = interpolatedvalue(IntToFixed(deliriumPitchO), IntToFixed(deliriumPitch), gInterpolate); fixed_t deliriumPitchI = interpolatedvalue(IntToFixed(deliriumPitchO), IntToFixed(deliriumPitch), gInterpolate);
DrawMirrors(cX, cY, cZ, cA.asq16(), cH.asq16() + deliriumPitchI, gInterpolate, gViewIndex); DrawMirrors(cX, cY, cZ, cA.asq16(), cH.asq16() + deliriumPitchI, int(gInterpolate), gViewIndex);
int bakCstat = gView->pSprite->cstat; int bakCstat = gView->pSprite->cstat;
if (gViewPos == 0) if (gViewPos == 0)
{ {
@ -160,7 +160,7 @@ RORHACK:
} }
renderDrawRoomsQ16(cX, cY, cZ, cA.asq16(), cH.asq16() + deliriumPitchI, nSectnum); renderDrawRoomsQ16(cX, cY, cZ, cA.asq16(), cH.asq16() + deliriumPitchI, nSectnum);
viewProcessSprites(pm_tsprite, pm_spritesortcnt, cX, cY, cZ, cA.asbuild(), gInterpolate); viewProcessSprites(pm_tsprite, pm_spritesortcnt, cX, cY, cZ, cA.asbuild(), int(gInterpolate));
bool do_ror_hack = false; bool do_ror_hack = false;
for (int i = 0; i < 16; i++) for (int i = 0; i < 16; i++)
if (ror_status[i] != testgotpic(4080 + i)) if (ror_status[i] != testgotpic(4080 + i))
@ -176,7 +176,7 @@ RORHACK:
renderDrawMasks(); renderDrawMasks();
pm_spritesortcnt = nSpriteSortCnt; pm_spritesortcnt = nSpriteSortCnt;
setPortalFlags(0); setPortalFlags(0);
processSpritesOnOtherSideOfPortal(cX, cY, gInterpolate); processSpritesOnOtherSideOfPortal(cX, cY, int(gInterpolate));
renderDrawMasks(); renderDrawMasks();
gView->pSprite->cstat = bakCstat; gView->pSprite->cstat = bakCstat;

View file

@ -2926,7 +2926,7 @@ bool actHealDude(DBloodActor* actor, int add, int threshold)
auto pXDude = &actor->x(); auto pXDude = &actor->x();
add <<= 4; add <<= 4;
threshold <<= 4; threshold <<= 4;
if (pXDude->health < threshold) if (pXDude->health < (unsigned)threshold)
{ {
spritetype* pSprite = &actor->s(); spritetype* pSprite = &actor->s();
if (actor->IsPlayerActor()) sfxPlay3DSound(pSprite->x, pSprite->y, pSprite->z, 780, pSprite->sectnum); if (actor->IsPlayerActor()) sfxPlay3DSound(pSprite->x, pSprite->y, pSprite->z, 780, pSprite->sectnum);

View file

@ -1003,7 +1003,7 @@ int aiDamageSprite(DBloodActor* source, DBloodActor* actor, DAMAGE_TYPE nDmgType
GENDUDEEXTRA* pExtra = genDudeExtra(pSprite); GENDUDEEXTRA* pExtra = genDudeExtra(pSprite);
if (nDmgType == DAMAGE_TYPE_1) { if (nDmgType == DAMAGE_TYPE_1) {
if (pXSprite->health > pDudeInfo->fleeHealth) break; if (pXSprite->health > (unsigned)pDudeInfo->fleeHealth) break;
else if (pXSprite->txID <= 0 || getNextIncarnation(pXSprite) == NULL) { else if (pXSprite->txID <= 0 || getNextIncarnation(pXSprite) == NULL) {
removeDudeStuff(pSprite); removeDudeStuff(pSprite);

View file

@ -292,7 +292,7 @@ static void beastThinkChase(DBloodActor* actor)
else else
pXSector = NULL; pXSector = NULL;
int hit = HitScan(pSprite, pSprite->z, dx, dy, 0, CLIPMASK1, 0); int hit = HitScan(pSprite, pSprite->z, dx, dy, 0, CLIPMASK1, 0);
if (pXTarget->health > gPlayerTemplate[0].startHealth/2) if (pXTarget->health > (unsigned)gPlayerTemplate[0].startHealth/2)
{ {
switch (hit) switch (hit)
{ {

View file

@ -138,7 +138,7 @@ void AddCmdDefine(char *text, int value)
static void SplitPath(const char *pzPath, char *pzDirectory, char *pzFile, char *pzType) static void SplitPath(const char *pzPath, char *pzDirectory, char *pzFile, char *pzType)
{ {
int const nLength = strlen(pzPath); int const nLength = (int)strlen(pzPath);
const char *pDirectory = pzPath+nLength; const char *pDirectory = pzPath+nLength;
const char *pDot = NULL; const char *pDot = NULL;
for (int i = nLength-1; i >= 0; i--) for (int i = nLength-1; i >= 0; i--)
@ -217,7 +217,7 @@ int RFS::Open(int lumpnum)
return 1; return 1;
} }
int fileSize = hFile.GetLength(); int fileSize = (int)hFile.GetLength();
buffer.Resize(fileSize); buffer.Resize(fileSize);
_ptr = buffer.Data(); _ptr = buffer.Data();
if (_ptr == NULL) { if (_ptr == NULL) {
@ -890,7 +890,7 @@ void ParseScript(int lumpnum)
case kTagString: case kTagString:
{ {
memcpy(&buffer[nBytes], scriptBuffer, strlen(scriptBuffer) + 1); memcpy(&buffer[nBytes], scriptBuffer, strlen(scriptBuffer) + 1);
nBytes += strlen(scriptBuffer) + 1; nBytes += (int)strlen(scriptBuffer) + 1;
break; break;
} }
case kTagConstant: case kTagConstant:

View file

@ -487,7 +487,7 @@ void GameInterface::Render()
void sndPlaySpecialMusicOrNothing(int nMusic) void sndPlaySpecialMusicOrNothing(int nMusic)
{ {
if (!Mus_Play(nullptr, quoteMgr.GetQuote(nMusic), true)) if (!Mus_Play(quoteMgr.GetQuote(nMusic), true))
{ {
Mus_Stop(); Mus_Stop();
} }
@ -539,7 +539,7 @@ DEFINE_ACTION_FUNCTION(_Blood, OriginalLoadScreen)
DEFINE_ACTION_FUNCTION(_Blood, PlayIntroMusic) DEFINE_ACTION_FUNCTION(_Blood, PlayIntroMusic)
{ {
Mus_Play(nullptr, "PESTIS.MID", false); Mus_Play("PESTIS.MID", false);
return 0; return 0;
} }
@ -565,4 +565,37 @@ DEFINE_ACTION_FUNCTION(_Blood, sndStartSampleNamed)
return 0; return 0;
} }
DEFINE_ACTION_FUNCTION(_Blood, PowerupIcon)
{
PARAM_PROLOGUE;
PARAM_INT(pwup);
int tile = -1;
if (pwup >= 0 && pwup < (int)countof(gPowerUpInfo))
{
tile = gPowerUpInfo[pwup].picnum;
}
FGameTexture* tex = tileGetTexture(tile);
ACTION_RETURN_INT(tex ? tex->GetID().GetIndex() : -1);
}
DEFINE_ACTION_FUNCTION(_Blood, GetViewPlayer)
{
PARAM_PROLOGUE;
ACTION_RETURN_POINTER(gView);
}
DEFINE_ACTION_FUNCTION(_BloodPlayer, GetHealth)
{
PARAM_SELF_STRUCT_PROLOGUE(PLAYER);
XSPRITE* pXSprite = self->pXSprite;
ACTION_RETURN_INT(pXSprite->health);
}
DEFINE_ACTION_FUNCTION_NATIVE(_BloodPlayer, powerupCheck, powerupCheck)
{
PARAM_SELF_STRUCT_PROLOGUE(PLAYER);
PARAM_INT(pwup);
ACTION_RETURN_INT(powerupCheck(self, pwup));
}
END_BLD_NS END_BLD_NS

View file

@ -142,7 +142,7 @@ inline void actBurnSprite(DBloodActor* pSource, DBloodActor* pTarget, int nTime)
{ {
auto pXSprite = &pTarget->x(); auto pXSprite = &pTarget->x();
pXSprite->burnTime = ClipHigh(pXSprite->burnTime + nTime, sprite[pXSprite->reference].statnum == kStatDude ? 2400 : 1200); pXSprite->burnTime = ClipHigh(pXSprite->burnTime + nTime, sprite[pXSprite->reference].statnum == kStatDude ? 2400 : 1200);
pXSprite->burnSource = pSource->s().index; pXSprite->burnSource = pSource? pSource->s().index : -1;
} }
inline void GetActorExtents(DBloodActor* actor, int* top, int* bottom) inline void GetActorExtents(DBloodActor* actor, int* top, int* bottom)

View file

@ -712,7 +712,7 @@ void callbackCondition(int nSprite) {
if (pXSprite->isTriggered) return; if (pXSprite->isTriggered) return;
TRCONDITION* pCond = &gCondition[pXSprite->sysData1]; TRCONDITION* pCond = &gCondition[pXSprite->sysData1];
for (int i = 0; i < pCond->length; i++) { for (unsigned i = 0; i < pCond->length; i++) {
EVENT evn; evn.index = pCond->obj[i].index; evn.type = pCond->obj[i].type; EVENT evn; evn.index = pCond->obj[i].index; evn.type = pCond->obj[i].type;
evn.cmd = pCond->obj[i].cmd; evn.funcID = kCallbackCondition; evn.cmd = pCond->obj[i].cmd; evn.funcID = kCallbackCondition;
useCondition(&sprite[pXSprite->reference], pXSprite, evn); useCondition(&sprite[pXSprite->reference], pXSprite, evn);

View file

@ -200,18 +200,18 @@ static void SortRXBucket(int nCount)
vbx++; vbx++;
} }
RXBUCKET* v2c = pArray + nCount; RXBUCKET* v2c = pArray + nCount;
int vt = ClipHigh(vbx - first, first - pArray); int vt = int(min(vbx - first, first - pArray));
for (int i = 0; i < vt; i++) for (int i = 0; i < vt; i++)
{ {
SortSwap(&vbx[i - vt], &pArray[i]); SortSwap(&vbx[i - vt], &pArray[i]);
} }
vt = ClipHigh(last - v4, v2c - last - 1); vt = int(min(last - v4, v2c - last - 1));
for (int i = 0; i < vt; i++) for (int i = 0; i < vt; i++)
{ {
SortSwap(&v2c[i - vt], &vbx[i]); SortSwap(&v2c[i - vt], &vbx[i]);
} }
int vvsi = last - v4; int vvsi = int(last - v4);
int vvdi = vbx - first; int vvdi = int(vbx - first);
if (vvsi >= vvdi) if (vvsi >= vvdi)
{ {
vc4[v14] = vvsi; vc4[v14] = vvsi;

View file

@ -127,14 +127,14 @@ void hudDraw(PLAYER *gView, int nSectnum, double bobx, double boby, double zDelt
} }
#ifdef NOONE_EXTENSIONS #ifdef NOONE_EXTENSIONS
if (gView->sceneQav < 0) WeaponDraw(gView, nShade, cX, cY, nPalette, smoothratio); if (gView->sceneQav < 0) WeaponDraw(gView, nShade, cX, cY, nPalette, int(smoothratio));
else if (gView->pXSprite->health > 0) playerQavSceneDraw(gView, nShade, cX, cY, nPalette, smoothratio); else if (gView->pXSprite->health > 0) playerQavSceneDraw(gView, nShade, cX, cY, nPalette, int(smoothratio));
else { else {
gView->sceneQav = gView->weaponQav = -1; gView->sceneQav = gView->weaponQav = -1;
gView->weaponTimer = gView->curWeapon = 0; gView->weaponTimer = gView->curWeapon = 0;
} }
#else #else
WeaponDraw(gView, nShade, cX, cY, nPalette, smoothratio); WeaponDraw(gView, nShade, cX, cY, nPalette, int(smoothratio));
#endif #endif
} }
if (gViewPos == 0 && gView->pXSprite->burnTime > 60) if (gViewPos == 0 && gView->pXSprite->burnTime > 60)

View file

@ -171,7 +171,6 @@ void IniFile::Load()
auto fp = fileSystem.OpenFileReader(fileName); auto fp = fileSystem.OpenFileReader(fileName);
if (fp.isOpen()) if (fp.isOpen())
{ {
int nSize = fp.GetLength();
auto pBuffer = fp.Read(); auto pBuffer = fp.Read();
LoadRes(pBuffer.Data()); LoadRes(pBuffer.Data());
} }

View file

@ -246,12 +246,12 @@ void levelTryPlayMusic()
else else
{ {
buffer = currentLevel->music; buffer = currentLevel->music;
if (Mus_Play(currentLevel->labelName, buffer, true)) return; if (Mus_Play(buffer, true)) return;
if (buffer.IsNotEmpty()) DefaultExtension(buffer, ".mid"); if (buffer.IsNotEmpty()) DefaultExtension(buffer, ".mid");
} }
if (!Mus_Play(currentLevel->labelName, buffer, true)) if (!Mus_Play(buffer, true))
{ {
Mus_Play("", "", true); Mus_Play("", true);
} }
} }

View file

@ -18,3 +18,177 @@ x(SBarNumberInv, 9240)
x(SBarNumberArmor1, 9250) x(SBarNumberArmor1, 9250)
x(SBarNumberArmor2, 9260) x(SBarNumberArmor2, 9260)
x(SBarNumberArmor3, 9270) x(SBarNumberArmor3, 9270)
x(SBarSlash, 9280)
x(PackBG, 2568)
x(PackSelect, 2559)
x(PackIcon1, 2569)
x(PackIcon2, 2564)
x(PackIcon3, 2566)
x(PackIcon4, 2568)
x(PackIcon5, 2560)
x(Pack2Icon1, 519)
x(Pack2Icon2, 830)
x(Pack2Icon3, 760)
x(Pack2Icon4, 839)
x(Pack2Icon5, 827)
x(AmmoIcon1, 816)
x(AmmoIcon2, 619)
x(AmmoIcon3, 817)
x(AmmoIcon4, 801)
x(AmmoIcon5, 589)
x(AmmoIcon6, 618)
x(AmmoIcon7, 548)
x(AmmoIcon8, 820)
x(AmmoIcon9, 525)
x(AmmoIcon10, 811)
x(AmmoIcon11, 810)
x(SBPlayerSlot, 2229)
x(FlagHave, 3558)
x(FlagHaveNot, 3559)
x(FlagDropped, 2332)
x(FlagTaken, 4097)
x(Statusbar, 2200)
x(FullHUD, 2201)
x(Armor1Gauge, 2207)
x(Armor2Gauge, 2208)
x(Armor3Gauge, 2209)
x(KeyIcon1, 2220)
x(KeyIcon2, 2221)
x(KeyIcon3, 2222)
x(KeyIcon4, 2223)
x(KeyIcon5, 2224)
x(KeyIcon6, 2225)
x(HudKeyIcon1, 2552)
x(HudKeyIcon2, 2553)
x(HudKeyIcon3, 2554)
x(HudKeyIcon4, 2555)
x(HudKeyIcon5, 2556)
x(HudKeyIcon6, 2557)
x(HudKeyIcon7, 2558)
x(BlinkIcon, 2202)
x(ThrowGauge, 2260)
x(Armorbox, 2173)
x(Healthicon, 2169)
x(Armor1Icon, 2578)
x(Armor2Icon, 2602)
x(Armor3Icon, 2586)
x(SBarNumberHealth0, 9220)
x(SBarNumberHealth1, 9221)
x(SBarNumberHealth2, 9222)
x(SBarNumberHealth3, 9223)
x(SBarNumberHealth4, 9224)
x(SBarNumberHealth5, 9225)
x(SBarNumberHealth6, 9226)
x(SBarNumberHealth7, 9227)
x(SBarNumberHealth8, 9228)
x(SBarNumberHealth9, 9229)
x(SBarNumberAmmo0, 9230)
x(SBarNumberAmmo1, 9231)
x(SBarNumberAmmo2, 9232)
x(SBarNumberAmmo3, 9233)
x(SBarNumberAmmo4, 9234)
x(SBarNumberAmmo5, 9235)
x(SBarNumberAmmo6, 9236)
x(SBarNumberAmmo7, 9237)
x(SBarNumberAmmo8, 9238)
x(SBarNumberAmmo9, 9239)
x(SBarNumberInv0, 9240)
x(SBarNumberInv1, 9241)
x(SBarNumberInv2, 9242)
x(SBarNumberInv3, 9243)
x(SBarNumberInv4, 9244)
x(SBarNumberInv5, 9245)
x(SBarNumberInv6, 9246)
x(SBarNumberInv7, 9247)
x(SBarNumberInv8, 9248)
x(SBarNumberInv9, 9249)
x(SBarNumberArmor1_0, 9250)
x(SBarNumberArmor1_1, 9251)
x(SBarNumberArmor1_2, 9252)
x(SBarNumberArmor1_3, 9253)
x(SBarNumberArmor1_4, 9254)
x(SBarNumberArmor1_5, 9255)
x(SBarNumberArmor1_6, 9256)
x(SBarNumberArmor1_7, 9257)
x(SBarNumberArmor1_8, 9258)
x(SBarNumberArmor1_9, 9259)
x(SBarNumberArmor2_0, 9260)
x(SBarNumberArmor2_1, 9261)
x(SBarNumberArmor2_2, 9262)
x(SBarNumberArmor2_3, 9263)
x(SBarNumberArmor2_4, 9264)
x(SBarNumberArmor2_5, 9265)
x(SBarNumberArmor2_6, 9266)
x(SBarNumberArmor2_7, 9267)
x(SBarNumberArmor2_8, 9268)
x(SBarNumberArmor2_9, 9269)
x(SBarNumberArmor3_0, 9270)
x(SBarNumberArmor3_1, 9271)
x(SBarNumberArmor3_2, 9272)
x(SBarNumberArmor3_3, 9273)
x(SBarNumberArmor3_4, 9274)
x(SBarNumberArmor3_5, 9275)
x(SBarNumberArmor3_6, 9276)
x(SBarNumberArmor3_7, 9277)
x(SBarNumberArmor3_8, 9278)
x(SBarNumberArmor3_9, 9279)
x(SBarPackAmount0, 2250)
x(SBarPackAmount1, 2251)
x(SBarPackAmount2, 2252)
x(SBarPackAmount3, 2253)
x(SBarPackAmount4, 2254)
x(SBarPackAmount5, 2255)
x(SBarPackAmount6, 2256)
x(SBarPackAmount7, 2257)
x(SBarPackAmount8, 2258)
x(SBarPackAmount9, 2259)
x(SBarHealthAmount0, 2190)
x(SBarHealthAmount1, 2191)
x(SBarHealthAmount2, 2192)
x(SBarHealthAmount3, 2193)
x(SBarHealthAmount4, 2194)
x(SBarHealthAmount5, 2195)
x(SBarHealthAmount6, 2196)
x(SBarHealthAmount7, 2197)
x(SBarHealthAmount8, 2198)
x(SBarHealthAmount9, 2199)
x(SBarAmmoAmount0, 2230)
x(SBarAmmoAmount1, 2231)
x(SBarAmmoAmount2, 2232)
x(SBarAmmoAmount3, 2233)
x(SBarAmmoAmount4, 2234)
x(SBarAmmoAmount5, 2235)
x(SBarAmmoAmount6, 2236)
x(SBarAmmoAmount7, 2237)
x(SBarAmmoAmount8, 2238)
x(SBarAmmoAmount9, 2239)
x(SBarWaponNum0, 2240)
x(SBarWaponNum0, 2241)
x(SBarWaponNum0, 2242)
x(SBarWaponNum0, 2243)
x(SBarWaponNum0, 2244)
x(SBarWaponNum0, 2245)
x(SBarWaponNum0, 2246)
x(SBarWaponNum0, 2247)
x(SBarWaponNum0, 2248)
x(SBarWaponNum0, 2249)

View file

@ -229,7 +229,7 @@ void nnExtResetGlobals() {
if (gTrackingCondsCount > 0) { if (gTrackingCondsCount > 0) {
for (int i = 0; i < gTrackingCondsCount; i++) { for (int i = 0; i < gTrackingCondsCount; i++) {
TRCONDITION* pCond = &gCondition[i]; TRCONDITION* pCond = &gCondition[i];
for (int k = 0; k < pCond->length; k++) { for (unsigned k = 0; k < pCond->length; k++) {
pCond->obj[k].index = pCond->obj[k].cmd = 0; pCond->obj[k].index = pCond->obj[k].cmd = 0;
pCond->obj[k].type = -1; pCond->obj[k].type = -1;
} }
@ -716,7 +716,7 @@ spritetype* randomDropPickupObject(spritetype* pSource, short prevItem) {
pSprite2 = actDropObject(pSource, selected); pSprite2 = actDropObject(pSource, selected);
if (pSprite2 != NULL) { if (pSprite2 != NULL) {
pXSource->dropMsg = pSprite2->type; // store dropped item type in dropMsg pXSource->dropMsg = uint8_t(pSprite2->type); // store dropped item type in dropMsg
pSprite2->x = pSource->x; pSprite2->x = pSource->x;
pSprite2->y = pSource->y; pSprite2->y = pSource->y;
pSprite2->z = pSource->z; pSprite2->z = pSource->z;
@ -763,7 +763,7 @@ void nnExtProcessSuperSprites() {
if (pCond->length > 0 && !pXCond->locked && !pXCond->isTriggered && ++pXCond->busy >= pXCond->busyTime) { if (pCond->length > 0 && !pXCond->locked && !pXCond->isTriggered && ++pXCond->busy >= pXCond->busyTime) {
pXCond->busy = 0; pXCond->busy = 0;
for (int k = 0; k < pCond->length; k++) { for (unsigned k = 0; k < pCond->length; k++) {
EVENT evn; EVENT evn;
evn.index = pCond->obj[k].index; evn.cmd = pCond->obj[k].cmd; evn.index = pCond->obj[k].index; evn.cmd = pCond->obj[k].cmd;
@ -1400,7 +1400,7 @@ void trPlayerCtrlLink(XSPRITE* pXSource, PLAYER* pPlayer, bool checkCondition) {
continue; continue;
// search for player control sprite and replace it with actual player sprite // search for player control sprite and replace it with actual player sprite
for (int k = 0; k < pCond->length; k++) { for (unsigned k = 0; k < pCond->length; k++) {
if (pCond->obj[k].type != OBJ_SPRITE || pCond->obj[k].index != pXSource->reference) continue; if (pCond->obj[k].type != OBJ_SPRITE || pCond->obj[k].index != pXSource->reference) continue;
pCond->obj[k].index = pPlayer->nSprite; pCond->obj[k].index = pPlayer->nSprite;
pCond->obj[k].cmd = pPlayer->pXSprite->command; pCond->obj[k].cmd = pPlayer->pXSprite->command;
@ -1638,16 +1638,16 @@ void useObjResizer(XSPRITE* pXSource, short objType, int objIndex) {
// for sectors // for sectors
case 6: case 6:
if (valueIsBetween(pXSource->data1, -1, 32767)) if (valueIsBetween(pXSource->data1, -1, 32767))
sector[objIndex].floorxpan_ = ClipRange(pXSource->data1, 0, 255); sector[objIndex].floorxpan_ = (float)ClipRange(pXSource->data1, 0, 255);
if (valueIsBetween(pXSource->data2, -1, 32767)) if (valueIsBetween(pXSource->data2, -1, 32767))
sector[objIndex].floorypan_ = ClipRange(pXSource->data2, 0, 255); sector[objIndex].floorypan_ = (float)ClipRange(pXSource->data2, 0, 255);
if (valueIsBetween(pXSource->data3, -1, 32767)) if (valueIsBetween(pXSource->data3, -1, 32767))
sector[objIndex].ceilingxpan_ = ClipRange(pXSource->data3, 0, 255); sector[objIndex].ceilingxpan_ = (float)ClipRange(pXSource->data3, 0, 255);
if (valueIsBetween(pXSource->data4, -1, 65535)) if (valueIsBetween(pXSource->data4, -1, 65535))
sector[objIndex].ceilingypan_ = ClipRange(pXSource->data4, 0, 255); sector[objIndex].ceilingypan_ = (float)ClipRange(pXSource->data4, 0, 255);
break; break;
// for sprites // for sprites
case 3: case 3:
@ -1698,10 +1698,10 @@ void useObjResizer(XSPRITE* pXSource, short objType, int objIndex) {
wall[objIndex].yrepeat = ClipRange(pXSource->data2, 0, 255); wall[objIndex].yrepeat = ClipRange(pXSource->data2, 0, 255);
if (valueIsBetween(pXSource->data3, -1, 32767)) if (valueIsBetween(pXSource->data3, -1, 32767))
wall[objIndex].xpan_ = ClipRange(pXSource->data3, 0, 255); wall[objIndex].xpan_ = (float)ClipRange(pXSource->data3, 0, 255);
if (valueIsBetween(pXSource->data4, -1, 65535)) if (valueIsBetween(pXSource->data4, -1, 65535))
wall[objIndex].ypan_ = ClipRange(pXSource->data4, 0, 255); wall[objIndex].ypan_ = (float)ClipRange(pXSource->data4, 0, 255);
break; break;
} }
@ -2314,7 +2314,7 @@ void useSpriteDamager(XSPRITE* pXSource, spritetype* pSprite) {
} }
if (dmgType >= kDmgFall) { if (dmgType >= kDmgFall) {
if (dmg < pXSprite->health << 4) { if (dmg < (int)pXSprite->health << 4) {
if (nnExtIsImmune(pSprite, dmgType, 0)) { if (nnExtIsImmune(pSprite, dmgType, 0)) {
Printf(PRINT_HIGH, "Dude type %d is immune to damage type %d!", pSprite->type, dmgType); Printf(PRINT_HIGH, "Dude type %d is immune to damage type %d!", pSprite->type, dmgType);
return; return;
@ -3201,7 +3201,7 @@ void condUpdateObjectIndex(int objType, int oldIndex, int newIndex) {
for (int i = 0; i < gTrackingCondsCount; i++) { for (int i = 0; i < gTrackingCondsCount; i++) {
TRCONDITION* pCond = &gCondition[i]; TRCONDITION* pCond = &gCondition[i];
for (int k = 0; k < pCond->length; k++) { for (unsigned k = 0; k < pCond->length; k++) {
if (pCond->obj[k].type != objType || pCond->obj[k].index != oldIndex) continue; if (pCond->obj[k].type != objType || pCond->obj[k].index != oldIndex) continue;
pCond->obj[k].index = newIndex; pCond->obj[k].index = newIndex;
break; break;
@ -3851,7 +3851,7 @@ bool modernTypeOperateSprite(int nSprite, spritetype* pSprite, XSPRITE* pXSprite
else evPost(nSprite, 3, 0, kCmdOff); else evPost(nSprite, 3, 0, kCmdOff);
break; break;
} }
pXSprite->dropMsg = pXSprite->data4; pXSprite->dropMsg = uint8_t(pXSprite->data4);
return true; return true;
case kModernObjDataAccumulator: case kModernObjDataAccumulator:
switch (event.cmd) { switch (event.cmd) {
@ -4352,7 +4352,7 @@ void useSoundGen(spritetype* pSource, XSPRITE* pXSource) {
void useIncDecGen(XSPRITE* pXSource, short objType, int objIndex) { void useIncDecGen(XSPRITE* pXSource, short objType, int objIndex) {
char buffer[5]; int data = -65535; short tmp = 0; int dataIndex = 0; char buffer[5]; int data = -65535; short tmp = 0; int dataIndex = 0;
sprintf(buffer, "%d", abs(pXSource->data1)); int len = strlen(buffer); sprintf(buffer, "%d", abs(pXSource->data1)); int len = int(strlen(buffer));
for (int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
dataIndex = (buffer[i] - 52) + 4; dataIndex = (buffer[i] - 52) + 4;
@ -4449,7 +4449,7 @@ void useSectorLigthChanger(XSPRITE* pXSource, XSECTOR* pXSector) {
int oldAmplitude = pXSector->amplitude; int oldAmplitude = pXSector->amplitude;
if (valueIsBetween(pXSource->data2, -128, 128)) if (valueIsBetween(pXSource->data2, -128, 128))
pXSector->amplitude = pXSource->data2; pXSector->amplitude = uint8_t(pXSource->data2);
if (valueIsBetween(pXSource->data3, -1, 32767)) if (valueIsBetween(pXSource->data3, -1, 32767))
pXSector->freq = ClipHigh(pXSource->data3, 255); pXSector->freq = ClipHigh(pXSource->data3, 255);
@ -4521,7 +4521,7 @@ void useTargetChanger(XSPRITE* pXSource, spritetype* pSprite) {
// heal dude a bit in case of friendly fire // heal dude a bit in case of friendly fire
int startHp = (pXSprite->sysData2 > 0) ? ClipRange(pXSprite->sysData2 << 4, 1, 65535) : pDudeInfo->startHealth << 4; int startHp = (pXSprite->sysData2 > 0) ? ClipRange(pXSprite->sysData2 << 4, 1, 65535) : pDudeInfo->startHealth << 4;
if (pXSprite->health < startHp) actHealDude(pXSprite, receiveHp, startHp); if (pXSprite->health < (unsigned)startHp) actHealDude(pXSprite, receiveHp, startHp);
} else if (xsprite[pBurnSource->extra].health <= 0) { } else if (xsprite[pBurnSource->extra].health <= 0) {
pXSprite->burnTime = 0; pXSprite->burnTime = 0;
} }
@ -4581,11 +4581,11 @@ void useTargetChanger(XSPRITE* pXSource, spritetype* pSprite) {
// heal dude // heal dude
int startHp = (pXSprite->sysData2 > 0) ? ClipRange(pXSprite->sysData2 << 4, 1, 65535) : pDudeInfo->startHealth << 4; int startHp = (pXSprite->sysData2 > 0) ? ClipRange(pXSprite->sysData2 << 4, 1, 65535) : pDudeInfo->startHealth << 4;
if (pXSprite->health < startHp) actHealDude(pXSprite, receiveHp, startHp); if (pXSprite->health < (unsigned)startHp) actHealDude(pXSprite, receiveHp, startHp);
// heal mate // heal mate
startHp = (pXMate->sysData2 > 0) ? ClipRange(pXMate->sysData2 << 4, 1, 65535) : getDudeInfo(pMate->type)->startHealth << 4; startHp = (pXMate->sysData2 > 0) ? ClipRange(pXMate->sysData2 << 4, 1, 65535) : getDudeInfo(pMate->type)->startHealth << 4;
if (pXMate->health < startHp) actHealDude(pXMate, receiveHp, startHp); if (pXMate->health < (unsigned)startHp) actHealDude(pXMate, receiveHp, startHp);
if (pXMate->target > -1 && sprite[pXMate->target].extra >= 0) { if (pXMate->target > -1 && sprite[pXMate->target].extra >= 0) {
pTarget = &sprite[pXMate->target]; pTarget = &sprite[pXMate->target];
@ -4742,10 +4742,10 @@ void usePictureChanger(XSPRITE* pXSource, int objType, int objIndex) {
sector[objIndex].ceilingpicnum = pXSource->data2; sector[objIndex].ceilingpicnum = pXSource->data2;
if (valueIsBetween(pXSource->data3, -1, 32767)) if (valueIsBetween(pXSource->data3, -1, 32767))
sector[objIndex].floorpal = pXSource->data3; sector[objIndex].floorpal = uint8_t(pXSource->data3);
if (valueIsBetween(pXSource->data4, -1, 65535)) if (valueIsBetween(pXSource->data4, -1, 65535))
sector[objIndex].ceilingpal = pXSource->data4; sector[objIndex].ceilingpal = uint8_t(pXSource->data4);
break; break;
case OBJ_SPRITE: case OBJ_SPRITE:
if (valueIsBetween(pXSource->data1, -1, 32767)) if (valueIsBetween(pXSource->data1, -1, 32767))
@ -4755,7 +4755,7 @@ void usePictureChanger(XSPRITE* pXSource, int objType, int objIndex) {
else if (pXSource->data2 < -1) sprite[objIndex].shade = (pXSource->data2 < -127) ? -127 : pXSource->data2; else if (pXSource->data2 < -1) sprite[objIndex].shade = (pXSource->data2 < -127) ? -127 : pXSource->data2;
if (valueIsBetween(pXSource->data3, -1, 32767)) if (valueIsBetween(pXSource->data3, -1, 32767))
sprite[objIndex].pal = pXSource->data3; sprite[objIndex].pal = uint8_t(pXSource->data3);
break; break;
case OBJ_WALL: case OBJ_WALL:
if (valueIsBetween(pXSource->data1, -1, 32767)) if (valueIsBetween(pXSource->data1, -1, 32767))
@ -4765,7 +4765,7 @@ void usePictureChanger(XSPRITE* pXSource, int objType, int objIndex) {
wall[objIndex].overpicnum = pXSource->data2; wall[objIndex].overpicnum = pXSource->data2;
if (valueIsBetween(pXSource->data3, -1, 32767)) if (valueIsBetween(pXSource->data3, -1, 32767))
wall[objIndex].pal = pXSource->data3; wall[objIndex].pal = uint8_t(pXSource->data3);
break; break;
} }
} }
@ -5163,7 +5163,7 @@ XSPRITE* evrListRedirectors(int objType, int objXIndex, XSPRITE* pXRedir, int* t
bool incDecGoalValueIsReached(XSPRITE* pXSprite) { bool incDecGoalValueIsReached(XSPRITE* pXSprite) {
if (pXSprite->data3 != pXSprite->sysData1) return false; if (pXSprite->data3 != pXSprite->sysData1) return false;
char buffer[5]; sprintf(buffer, "%d", abs(pXSprite->data1)); int len = strlen(buffer); int rx = -1; char buffer[5]; sprintf(buffer, "%d", abs(pXSprite->data1)); int len = int(strlen(buffer)); int rx = -1;
for (int i = bucketHead[pXSprite->txID]; i < bucketHead[pXSprite->txID + 1]; i++) { for (int i = bucketHead[pXSprite->txID]; i < bucketHead[pXSprite->txID + 1]; i++) {
if (rxBucket[i].type == OBJ_SPRITE && evrIsRedirector(rxBucket[i].index)) continue; if (rxBucket[i].type == OBJ_SPRITE && evrIsRedirector(rxBucket[i].index)) continue;
for (int a = 0; a < len; a++) { for (int a = 0; a < len; a++) {

View file

@ -2328,4 +2328,79 @@ void SerializePlayers(FSerializer& arc)
DEFINE_FIELD_X(BloodPlayer, PLAYER, newWeapon)
DEFINE_FIELD_X(BloodPlayer, PLAYER, weaponQav)
DEFINE_FIELD_X(BloodPlayer, PLAYER, qavCallback)
DEFINE_FIELD_X(BloodPlayer, PLAYER, isRunning)
DEFINE_FIELD_X(BloodPlayer, PLAYER, posture) // stand, crouch, swim
DEFINE_FIELD_X(BloodPlayer, PLAYER, sceneQav) // by NoOne: used to keep qav id
DEFINE_FIELD_X(BloodPlayer, PLAYER, bobPhase)
DEFINE_FIELD_X(BloodPlayer, PLAYER, bobAmp)
DEFINE_FIELD_X(BloodPlayer, PLAYER, bobHeight)
DEFINE_FIELD_X(BloodPlayer, PLAYER, bobWidth)
DEFINE_FIELD_X(BloodPlayer, PLAYER, swayPhase)
DEFINE_FIELD_X(BloodPlayer, PLAYER, swayAmp)
DEFINE_FIELD_X(BloodPlayer, PLAYER, swayHeight)
DEFINE_FIELD_X(BloodPlayer, PLAYER, swayWidth)
DEFINE_FIELD_X(BloodPlayer, PLAYER, nPlayer) // Connect id
DEFINE_FIELD_X(BloodPlayer, PLAYER, nSprite)
DEFINE_FIELD_X(BloodPlayer, PLAYER, lifeMode)
DEFINE_FIELD_X(BloodPlayer, PLAYER, zView)
DEFINE_FIELD_X(BloodPlayer, PLAYER, zViewVel)
DEFINE_FIELD_X(BloodPlayer, PLAYER, zWeapon)
DEFINE_FIELD_X(BloodPlayer, PLAYER, zWeaponVel)
DEFINE_FIELD_X(BloodPlayer, PLAYER, slope)
DEFINE_FIELD_X(BloodPlayer, PLAYER, isUnderwater)
DEFINE_FIELD_X(BloodPlayer, PLAYER, hasKey)
DEFINE_FIELD_X(BloodPlayer, PLAYER, hasFlag)
DEFINE_FIELD_X(BloodPlayer, PLAYER, damageControl)
DEFINE_FIELD_X(BloodPlayer, PLAYER, curWeapon)
DEFINE_FIELD_X(BloodPlayer, PLAYER, nextWeapon)
DEFINE_FIELD_X(BloodPlayer, PLAYER, weaponTimer)
DEFINE_FIELD_X(BloodPlayer, PLAYER, weaponState)
DEFINE_FIELD_X(BloodPlayer, PLAYER, weaponAmmo) //rename
DEFINE_FIELD_X(BloodPlayer, PLAYER, hasWeapon)
DEFINE_FIELD_X(BloodPlayer, PLAYER, weaponMode)
DEFINE_FIELD_X(BloodPlayer, PLAYER, weaponOrder)
DEFINE_FIELD_X(BloodPlayer, PLAYER, ammoCount)
DEFINE_FIELD_X(BloodPlayer, PLAYER, qavLoop)
DEFINE_FIELD_X(BloodPlayer, PLAYER, fuseTime)
DEFINE_FIELD_X(BloodPlayer, PLAYER, throwTime)
DEFINE_FIELD_X(BloodPlayer, PLAYER, throwPower)
DEFINE_FIELD_X(BloodPlayer, PLAYER, aim) // world
DEFINE_FIELD_X(BloodPlayer, PLAYER, aimTarget) // aim target sprite
DEFINE_FIELD_X(BloodPlayer, PLAYER, aimTargetsCount)
DEFINE_FIELD_X(BloodPlayer, PLAYER, aimTargets)
DEFINE_FIELD_X(BloodPlayer, PLAYER, deathTime)
DEFINE_FIELD_X(BloodPlayer, PLAYER, pwUpTime)
DEFINE_FIELD_X(BloodPlayer, PLAYER, teamId)
DEFINE_FIELD_X(BloodPlayer, PLAYER, fragCount)
DEFINE_FIELD_X(BloodPlayer, PLAYER, fragInfo)
DEFINE_FIELD_X(BloodPlayer, PLAYER, underwaterTime)
DEFINE_FIELD_X(BloodPlayer, PLAYER, bubbleTime)
DEFINE_FIELD_X(BloodPlayer, PLAYER, restTime)
DEFINE_FIELD_X(BloodPlayer, PLAYER, kickPower)
DEFINE_FIELD_X(BloodPlayer, PLAYER, laughCount)
DEFINE_FIELD_X(BloodPlayer, PLAYER, godMode)
DEFINE_FIELD_X(BloodPlayer, PLAYER, fallScream)
DEFINE_FIELD_X(BloodPlayer, PLAYER, cantJump)
DEFINE_FIELD_X(BloodPlayer, PLAYER, packItemTime) // pack timer
DEFINE_FIELD_X(BloodPlayer, PLAYER, packItemId) // pack id 1: diving suit, 2: crystal ball, 3:
DEFINE_FIELD_X(BloodPlayer, PLAYER, packSlots) // at325 1]: diving suit, [2]: crystal ball,
DEFINE_FIELD_X(BloodPlayer, PLAYER, armor) // armor
DEFINE_FIELD_X(BloodPlayer, PLAYER, voodooTarget)
DEFINE_FIELD_X(BloodPlayer, PLAYER, flickerEffect)
DEFINE_FIELD_X(BloodPlayer, PLAYER, tiltEffect)
DEFINE_FIELD_X(BloodPlayer, PLAYER, visibility)
DEFINE_FIELD_X(BloodPlayer, PLAYER, painEffect)
DEFINE_FIELD_X(BloodPlayer, PLAYER, blindEffect)
DEFINE_FIELD_X(BloodPlayer, PLAYER, chokeEffect)
DEFINE_FIELD_X(BloodPlayer, PLAYER, handTime)
DEFINE_FIELD_X(BloodPlayer, PLAYER, hand) // if true, there is hand start choking the player
DEFINE_FIELD_X(BloodPlayer, PLAYER, pickupEffect)
DEFINE_FIELD_X(BloodPlayer, PLAYER, flashEffect) // if true, reduce pPlayer->visibility counter
DEFINE_FIELD_X(BloodPlayer, PLAYER, quakeEffect)
DEFINE_FIELD_X(BloodPlayer, PLAYER, player_par)
DEFINE_FIELD_X(BloodPlayer, PLAYER, nWaterPal)
END_BLD_NS END_BLD_NS

View file

@ -1,13 +1,13 @@
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
/* /*
Copyright (C) 2010-2019 EDuke32 developers and contributors Copyright (C) 2020-2021 Christoph Oelckers
Copyright (C) 2019 Nuke.YKT
This file is part of NBlood. This file is part of Raze.
NBlood is free software; you can redistribute it and/or This is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2 modify it under the terms of the GNU General Public License
as published by the Free Software Foundation. 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, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
@ -31,8 +31,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "blood.h" #include "blood.h"
#include "zstring.h" #include "zstring.h"
#include "razemenu.h"
#include "gstrings.h"
#include "v_2ddrawer.h" #include "v_2ddrawer.h"
#include "v_video.h" #include "v_video.h"
#include "v_font.h" #include "v_font.h"
@ -42,802 +40,10 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "gamecvars.h" #include "gamecvars.h"
CVARD(Bool, hud_powerupduration, true, CVAR_ARCHIVE/*|CVAR_FRONTEND_BLOOD*/, "enable/disable displaying the remaining seconds for power-ups") CVARD(Bool, hud_powerupduration, true, CVAR_ARCHIVE/*|CVAR_FRONTEND_BLOOD*/, "enable/disable displaying the remaining seconds for power-ups")
CVAR(Bool, hud_ctf_vanilla, false, CVAR_ARCHIVE)
BEGIN_BLD_NS BEGIN_BLD_NS
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
static int gPackIcons[5] = {
2569, 2564, 2566, 2568, 2560
};
struct PACKICON2 {
short nTile;
int nScale;
int nYOffs;
};
PACKICON2 gPackIcons2[] = {
{ 519, (int)(65536 * 0.5), 0 },
{ 830, (int)(65536 * 0.3), 0 },
{ 760, (int)(65536 * 0.6), 0 },
{ 839, (int)(65536 * 0.5), -4 },
{ 827, (int)(65536 * 0.4), 0 },
};
struct AMMOICON {
short nTile;
int nScale;
int nYOffs;
};
static AMMOICON gAmmoIcons[] = {
{ -1, 0, 0 },
{ 816, (int)(65536 * 0.5), 0 },
{ 619, (int)(65536 * 0.8), 0 },
{ 817, (int)(65536 * 0.7), 3 },
{ 801, (int)(65536 * 0.5), -6 },
{ 589, (int)(65536 * 0.7), 2 },
{ 618, (int)(65536 * 0.5), 4 },
{ 548, (int)(65536 * 0.3), -6 },
{ 820, (int)(65536 * 0.3), -6 },
{ 525, (int)(65536 * 0.6), -6 },
{ 811, (int)(65536 * 0.5), 2 },
{ 810, (int)(65536 * 0.45), 2 },
};
struct POWERUPDISPLAY
{
int nTile;
float nScaleRatio;
int yOffset;
int remainingDuration;
};
class DBloodStatusBar : public DBaseStatusBar
{
DECLARE_CLASS(DBloodStatusBar, DBaseStatusBar)
enum NewRSFlags
{
RS_CENTERBOTTOM = 16384,
};
TObjPtr<DHUDFont*> smallf, tinyf;
public:
DBloodStatusBar()
{
smallf = Create<DHUDFont>(SmallFont, 0, Off, 0, 0 );
tinyf = Create<DHUDFont>(gFont[4], 4, CellRight, 0, 0 );
}
private:
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void DrawStatSprite(int nTile, double x, double y, int nShade = 0, int nPalette = 0, unsigned int nStat = 0, int nScale = 65536, ERenderStyle style = STYLE_Normal, int align = DI_SCREEN_AUTO)
{
int flags = align | ((nStat & RS_CENTERBOTTOM)? DI_ITEM_CENTER_BOTTOM : (nStat & RS_TOPLEFT)? DI_ITEM_LEFT_TOP : DI_ITEM_RELCENTER);
double alpha = 1.;
double scale = nScale / 65536.;
DrawGraphic(tileGetTexture(nTile, true), x, y, flags, alpha, -1, -1, scale, scale, STYLE_Translucent, shadeToLight(nShade), TRANSLATION(Translation_Remap, nPalette), style);
}
void DrawStatMaskedSprite(int nTile, double x, double y, int nShade = 0, int nPalette = 0, unsigned int nStat = 0, int nScale = 65536, int align = DI_SCREEN_AUTO)
{
DrawStatSprite(nTile, x, y, nShade, nPalette, nStat, nScale, STYLE_Translucent, align);
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void DrawStatNumber(const char* pFormat, int nNumber, int nTile, double x, double y, int nShade, int nPalette, unsigned int nStat = 0, int nScale = 65536, int align = 0)
{
double width = (tileWidth(nTile) + 1) * (nScale / 65536.);
char tempbuf[80];
mysnprintf(tempbuf, 80, pFormat, nNumber);
x += 0.5;
y += 0.5; // This is needed because due to using floating point math, this code rounds slightly differently which for the numbers can be a problem.
for (unsigned int i = 0; tempbuf[i]; i++, x += width)
{
if (tempbuf[i] == ' ') continue;
DrawStatSprite(nTile + tempbuf[i] - '0', x, y, nShade, nPalette, nStat, nScale, STYLE_Translucent, align);
}
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void DrawCharArray(const char* string, int nTile, double x, double y, int nShade, int nPalette, unsigned int nStat = 0, int nScale = 65536, int align = 0)
{
double width = (tileWidth(nTile) + 1) * (nScale / 65536.);
x += 0.5;
y += 0.5; // This is needed because due to using floating point math, this code rounds slightly differently which for the numbers can be a problem.
for (unsigned int i = 0; string[i]; i++, x += width)
{
// Hackasaurus rex to give me a slash when drawing the weapon count of a reloadable gun.
if (string[i] == 47 && nTile == kSBarNumberAmmo)
{
DrawStatSprite(9280, x, y, nShade, nPalette, nStat, nScale, STYLE_Translucent, align);
}
else
{
DrawStatSprite(nTile + string[i] - '0', x, y, nShade, nPalette, nStat, nScale, STYLE_Translucent, align);
}
}
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void TileHGauge(int nTile, double x, double y, int nMult, int nDiv, int nStat = 0, int nScale = 65536)
{
int w = tileWidth(nTile);
int bx = scale(MulScale(w, nScale, 16), nMult, nDiv) + x;
double scale = double(bx - x) / w;
double sc = nScale / 65536.;
DrawGraphic(tileGetTexture(nTile, true), x, y, DI_ITEM_LEFT_TOP, 1., -1, -1, sc, sc, STYLE_Translucent, 0xffffffff, 0, scale);
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void PrintLevelStats(PLAYER* pPlayer, int bottomy)
{
FLevelStats stats{};
stats.fontscale = 1.;
stats.spacing = SmallFont->GetHeight() + 1;
stats.screenbottomspace = bottomy;
stats.font = SmallFont;
stats.letterColor = CR_DARKRED;
stats.standardColor = CR_DARKGRAY;
stats.time = gFrameCount / GameTicRate;
if (automapMode == am_full)
{
bool textfont = am_textfont;
if (!am_textfont)
{
// For non-English languages force use of the text font. The tiny one is simply too small to ever add localized characters to it.
auto p = GStrings["REQUIRED_CHARACTERS"];
if (p && *p) textfont = true;
}
if (!textfont)
{
stats.font = SmallFont2;
stats.spacing = 6;
}
if (hud_size <= Hud_StbarOverlay) stats.screenbottomspace = 56;
DBaseStatusBar::PrintAutomapInfo(stats, textfont);
}
if (automapMode == am_off && hud_stats)
{
stats.completeColor = CR_DARKGREEN;
stats.kills = gKillMgr.Kills;
stats.maxkills = gKillMgr.TotalKills;
stats.frags = gGameOptions.nGameType == 3? pPlayer->fragCount : -1;
stats.secrets = gSecretMgr.Founds;
stats.supersecrets = gSecretMgr.Super;
stats.maxsecrets = max(gSecretMgr.Founds, gSecretMgr.Total); // If we found more than there are, increase the total. Some levels have a bugged counter.
stats.time = Scale(PlayClock, 1000, 120);
DBaseStatusBar::PrintLevelStats(stats);
}
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
enum { nPowerUps = 11 };
void sortPowerUps(POWERUPDISPLAY* powerups) {
for (int i = 1; i < nPowerUps; i++)
{
for (int j = 0; j < nPowerUps - i; j++)
{
if (powerups[j].remainingDuration > powerups[j + 1].remainingDuration)
{
POWERUPDISPLAY temp = powerups[j];
powerups[j] = powerups[j + 1];
powerups[j + 1] = temp;
}
}
}
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void viewDrawPowerUps(PLAYER* pPlayer)
{
if (!hud_powerupduration)
return;
POWERUPDISPLAY powerups[nPowerUps];
powerups[0] = { gPowerUpInfo[kPwUpShadowCloak].picnum, 0.4f, 0, pPlayer->pwUpTime[kPwUpShadowCloak] }; // Invisibility
powerups[1] = { gPowerUpInfo[kPwUpReflectShots].picnum, 0.4f, 5, pPlayer->pwUpTime[kPwUpReflectShots] }; // Reflects enemy shots
powerups[2] = { gPowerUpInfo[kPwUpDeathMask].picnum, 0.3f, 9, pPlayer->pwUpTime[kPwUpDeathMask] }; // Invulnerability
powerups[3] = { gPowerUpInfo[kPwUpTwoGuns].picnum, 0.3f, 5, pPlayer->pwUpTime[kPwUpTwoGuns] }; // Guns Akimbo
powerups[4] = { gPowerUpInfo[kPwUpShadowCloakUseless].picnum, 0.4f, 9, pPlayer->pwUpTime[kPwUpShadowCloakUseless] }; // Does nothing, only appears at near the end of Cryptic Passage's Lost Monastery (CP04)
// Not in official maps, but custom maps can use them
powerups[5] = { gPowerUpInfo[kPwUpFeatherFall].picnum, 0.3f, 7, pPlayer->pwUpTime[kPwUpFeatherFall] }; // Makes player immune to fall damage
powerups[6] = { gPowerUpInfo[kPwUpGasMask].picnum, 0.4f, 4, pPlayer->pwUpTime[kPwUpGasMask] }; // Makes player immune to choke damage
powerups[7] = { gPowerUpInfo[kPwUpDoppleganger].picnum, 0.5f, 5, pPlayer->pwUpTime[kPwUpDoppleganger] }; // Works in multiplayer, it swaps player's team colors, so enemy team player thinks it's a team mate
powerups[8] = { gPowerUpInfo[kPwUpAsbestArmor].picnum, 0.3f, 9, pPlayer->pwUpTime[kPwUpAsbestArmor] }; // Makes player immune to fire damage and draws HUD
powerups[9] = { gPowerUpInfo[kPwUpGrowShroom].picnum, 0.4f, 4, pPlayer->pwUpTime[kPwUpGrowShroom] }; // Grows player size, works only if gModernMap == true
powerups[10] = { gPowerUpInfo[kPwUpShrinkShroom].picnum, 0.4f, 4, pPlayer->pwUpTime[kPwUpShrinkShroom] }; // Shrinks player size, works only if gModernMap == true
sortPowerUps(powerups);
const int warningTime = 5;
const int x = 15;
int y = -50;
for (int i = 0; i < nPowerUps; i++)
{
if (powerups[i].remainingDuration)
{
int remainingSeconds = powerups[i].remainingDuration / 100;
if (remainingSeconds > warningTime || (PlayClock & 32))
{
DrawStatMaskedSprite(powerups[i].nTile, x, y + powerups[i].yOffset, 0, 0, 256, (int)(65536 * powerups[i].nScaleRatio), DI_SCREEN_LEFT_CENTER);
}
DrawStatNumber("%d", remainingSeconds, kSBarNumberInv, x + 15, y, 0, remainingSeconds > warningTime ? 0 : 2, 256, 65536 * 0.5, DI_SCREEN_LEFT_CENTER);
y += 20;
}
}
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void drawInventory(PLAYER* pPlayer, int x, int y)
{
int packs[5];
if (pPlayer->packItemTime)
{
int nPacks = 0;
int width = 0;
for (int i = 0; i < 5; i++)
{
if (pPlayer->packSlots[i].curAmount)
{
packs[nPacks++] = i;
width += tileWidth(gPackIcons[i]) + 1;
}
}
width /= 2;
x -= width;
for (int i = 0; i < nPacks; i++)
{
int nPack = packs[i];
DrawStatSprite(2568, x + 1, y - 8);
DrawStatSprite(2568, x + 1, y - 6);
DrawStatSprite(gPackIcons[nPack], x + 1, y + 1);
if (nPack == pPlayer->packItemId)
DrawStatMaskedSprite(2559, x + 1, y + 1);
int nShade;
if (pPlayer->packSlots[nPack].isActive)
nShade = 4;
else
nShade = 24;
DrawStatNumber("%3d", pPlayer->packSlots[nPack].curAmount, 2250, x - 4, y - 13, nShade, 0);
x += tileWidth(gPackIcons[nPack]) + 1;
}
}
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void DrawPackItemInStatusBar(PLAYER* pPlayer, int x, int y, int x2, int y2)
{
auto id = pPlayer->packItemId;
//id = 0;
if (id < 0) return;
DrawStatSprite(gPackIcons[id], x, y, 0, 0);
DrawStatNumber("%3d", pPlayer->packSlots[id].curAmount, 2250, x2, y2, 0, 0);
}
void DrawPackItemInStatusBar2(PLAYER* pPlayer, int x, int y, int x2, int y2, int nStat, int nScale)
{
if (pPlayer->packItemId < 0) return;
DrawStatMaskedSprite(gPackIcons2[pPlayer->packItemId].nTile, x, y + gPackIcons2[pPlayer->packItemId].nYOffs, 0, 0, nStat, gPackIcons2[pPlayer->packItemId].nScale);
DrawStatNumber("%3d", pPlayer->packSlots[pPlayer->packItemId].curAmount, kSBarNumberInv, x2, y2, 0, 0, nStat, nScale);
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void viewDrawPlayerSlots(void)
{
for (int nRows = (gNetPlayers - 1) / 4; nRows >= 0; nRows--)
{
for (int nCol = 0; nCol < 4; nCol++)
{
DrawStatSprite(2229, -120 + nCol * 80, 4 + nRows * 9, 16, 0, 0, 65536, STYLE_Normal, DI_SCREEN_CENTER_TOP);
}
}
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void viewDrawPlayerFrags(void)
{
FString gTempStr;
viewDrawPlayerSlots();
for (int i = 0, p = connecthead; p >= 0; i++, p = connectpoint2[p])
{
int x = -160 + 80 * (i & 3);
int y = 9 * (i / 4);
int col = gPlayer[p].teamId & 3;
const char* name = PlayerName(p);
gTempStr.Format("%s", name);
int color = CR_UNDEFINED;// todo: remap the colors. (11+col)
SBar_DrawString(this, tinyf, gTempStr, x + 4, y, DI_SCREEN_CENTER_TOP, color, 1., -1, -1, 1, 1);
gTempStr.Format("%2d", gPlayer[p].fragCount);
SBar_DrawString(this, tinyf, gTempStr, x + 76, y, DI_SCREEN_CENTER_TOP, color, 1., -1, -1, 1, 1);
}
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void viewDrawPlayerFlags(void)
{
FString gTempStr;
viewDrawPlayerSlots();
for (int i = 0, p = connecthead; p >= 0; i++, p = connectpoint2[p])
{
int x = -160 + 80 * (i & 3);
int y = 9 * (i / 4);
int col = gPlayer[p].teamId & 3;
const char* name = PlayerName(p);
gTempStr.Format("%s", name);
gTempStr.ToUpper();
int color = CR_UNDEFINED;// todo: remap the colors.
SBar_DrawString(this, tinyf, gTempStr, x + 4, y, DI_SCREEN_CENTER_TOP, color, 1., -1, -1, 1, 1);
gTempStr = "F";
x += 76;
if (gPlayer[p].hasFlag & 2)
{
SBar_DrawString(this, tinyf, gTempStr, x, y, DI_SCREEN_CENTER_TOP, CR_GREEN/*12*/, 1., -1, -1, 1, 1);
x -= 6;
}
if (gPlayer[p].hasFlag & 1)
SBar_DrawString(this, tinyf, gTempStr, x, y, DI_SCREEN_CENTER_TOP, CR_RED/*11*/, 1., -1, -1, 1, 1);
}
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void viewDrawCtfHudVanilla()
{
FString gTempStr;
int x = 1, y = 1;
if (team_ticker[0] == 0 || (PlayClock & 8))
{
SBar_DrawString(this, smallf, GStrings("TXT_COLOR_BLUE"), x, y, 0, CR_LIGHTBLUE, 1., -1, -1, 1, 1);
gTempStr.Format("%-3d", team_score[0]);
SBar_DrawString(this, smallf, gTempStr, x, y + 10, 0, CR_LIGHTBLUE, 1., -1, -1, 1, 1);
}
x = -2;
if (team_ticker[1] == 0 || (PlayClock & 8))
{
SBar_DrawString(this, smallf, GStrings("TXT_COLOR_RED"), x, y, DI_TEXT_ALIGN_RIGHT, CR_BRICK, 1., -1, -1, 1, 1);
gTempStr.Format("%3d", team_score[1]);
SBar_DrawString(this, smallf, gTempStr, x, y + 10, DI_TEXT_ALIGN_RIGHT, CR_BRICK, 1., -1, -1, 1, 1);
}
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void flashTeamScore(int team, bool show)
{
assert(0 == team || 1 == team); // 0: blue, 1: red
if (team_ticker[team] == 0 || (PlayClock & 8))
{
if (show)
DrawStatNumber("%d", team_score[team], kSBarNumberInv, -30, team ? 25 : -10, 0, team ? 2 : 10, 512, 65536 * 0.75, DI_SCREEN_RIGHT_CENTER);
}
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void viewDrawCtfHud()
{
if (hud_size == Hud_Nothing)
{
flashTeamScore(0, false);
flashTeamScore(1, false);
return;
}
bool blueFlagTaken = false;
bool redFlagTaken = false;
int blueFlagCarrierColor = 0;
int redFlagCarrierColor = 0;
for (int i = 0, p = connecthead; p >= 0; i++, p = connectpoint2[p])
{
if ((gPlayer[p].hasFlag & 1) != 0)
{
blueFlagTaken = true;
blueFlagCarrierColor = gPlayer[p].teamId & 3;
}
if ((gPlayer[p].hasFlag & 2) != 0)
{
redFlagTaken = true;
redFlagCarrierColor = gPlayer[p].teamId & 3;
}
}
bool meHaveBlueFlag = gMe->hasFlag & 1;
DrawStatMaskedSprite(meHaveBlueFlag ? 3558 : 3559, 0, 75-100, 0, 10, 512, 65536 * 0.35, DI_SCREEN_RIGHT_CENTER);
if (gBlueFlagDropped)
DrawStatMaskedSprite(2332, 305-320, 83 - 100, 0, 10, 512, 65536, DI_SCREEN_RIGHT_CENTER);
else if (blueFlagTaken)
DrawStatMaskedSprite(4097, 307-320, 77 - 100, 0, blueFlagCarrierColor ? 2 : 10, 512, 65536, DI_SCREEN_RIGHT_CENTER);
flashTeamScore(0, true);
bool meHaveRedFlag = gMe->hasFlag & 2;
DrawStatMaskedSprite(meHaveRedFlag ? 3558 : 3559, 0, 10, 0, 2, 512, 65536 * 0.35, DI_SCREEN_RIGHT_CENTER);
if (gRedFlagDropped)
DrawStatMaskedSprite(2332, 305-320, 17, 0, 2, 512, 65536, DI_SCREEN_RIGHT_CENTER);
else if (redFlagTaken)
DrawStatMaskedSprite(4097, 307-320, 11, 0, redFlagCarrierColor ? 2 : 10, 512, 65536, DI_SCREEN_RIGHT_CENTER);
flashTeamScore(1, true);
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void DrawStatusBar(int nPalette)
{
BeginStatusBar(320, 200, tileHeight(2200));
PLAYER* pPlayer = gView;
XSPRITE* pXSprite = pPlayer->pXSprite;
DrawStatMaskedSprite(2200, 160, 200, 0, nPalette, RS_CENTERBOTTOM);
DrawPackItemInStatusBar(pPlayer, 265, 186, 260, 172);
if (pXSprite->health >= 16 || (PlayClock & 16) || pXSprite->health == 0)
{
DrawStatNumber("%3d", pXSprite->health >> 4, 2190, 86, 183, 0, 0);
}
if (pPlayer->curWeapon && pPlayer->weaponAmmo != -1)
{
int num = pPlayer->ammoCount[pPlayer->weaponAmmo];
if (pPlayer->weaponAmmo == 6)
num /= 10;
DrawStatNumber("%3d", num, 2240, 216, 183, 0, 0);
}
for (int i = 9; i >= 1; i--)
{
int x = 135 + ((i - 1) / 3) * 23;
int y = 182 + ((i - 1) % 3) * 6;
int num = pPlayer->ammoCount[i];
if (i == 6)
num /= 10;
DrawStatNumber("%3d", num, 2230, x, y, i == pPlayer->weaponAmmo? -128 : 32, 10);
}
DrawStatNumber("%2d", pPlayer->ammoCount[10], 2230, 291, 194, pPlayer->weaponAmmo == 10? -128 : 32, 10);
DrawStatNumber("%2d", pPlayer->ammoCount[11], 2230, 309, 194, pPlayer->weaponAmmo == 11? -128 : 32, 10);
if (pPlayer->armor[1])
{
TileHGauge(2207, 44, 174, pPlayer->armor[1], 3200);
DrawStatNumber("%3d", pPlayer->armor[1] >> 4, 2230, 50, 177, 0, 0);
}
if (pPlayer->armor[0])
{
TileHGauge(2209, 44, 182, pPlayer->armor[0], 3200);
DrawStatNumber("%3d", pPlayer->armor[0] >> 4, 2230, 50, 185, 0, 0);
}
if (pPlayer->armor[2])
{
TileHGauge(2208, 44, 190, pPlayer->armor[2], 3200);
DrawStatNumber("%3d", pPlayer->armor[2] >> 4, 2230, 50, 193, 0, 0);
}
for (int i = 0; i < 6; i++)
{
int nTile = 2220 + i;
double x = 73.5 + (i & 1) * 173;
double y = 171.5 + (i >> 1) * 11;
if (pPlayer->hasKey[i + 1])
DrawStatSprite(nTile, x, y);
else
DrawStatSprite(nTile, x, y, 40, 5);
}
DrawStatMaskedSprite(2202, 118.5, 185.5, /*pPlayer->isRunning ? 16 :*/ 40);
DrawStatMaskedSprite(2202, 201.5, 185.5, /*pPlayer->isRunning ? 16 :*/ 40);
if (pPlayer->throwPower)
{
TileHGauge(2260, 124, 175.5, pPlayer->throwPower, 65536);
}
drawInventory(pPlayer, 166, 200 - tileHeight(2200));
// Depending on the scale we can lower the stats display. This needs some tweaking but this catches the important default case already.
PrintLevelStats(pPlayer, (hud_statscale <= 0.501f || hud_scalefactor < 0.7) && double(twod->GetWidth())/twod->GetHeight() > 1.6? 28 : 56);
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void DrawHUD1(int nPalette)
{
PLAYER* pPlayer = gView;
XSPRITE* pXSprite = pPlayer->pXSprite;
BeginHUD(320, 200, 1);
DrawStatSprite(2201, 34, 187 - 200, 16, nPalette);
if (pXSprite->health >= 16 || (PlayClock & 16) || pXSprite->health == 0)
{
DrawStatNumber("%3d", pXSprite->health >> 4, 2190, 8, 183 - 200, 0, 0);
}
if (pPlayer->curWeapon && pPlayer->weaponAmmo != -1)
{
int num = pPlayer->ammoCount[pPlayer->weaponAmmo];
if (pPlayer->weaponAmmo == 6)
num /= 10;
DrawStatNumber("%3d", num, 2240, 42, 183 - 200, 0, 0);
}
DrawStatSprite(2173, 284-320, 187 - 200, 16, nPalette);
if (pPlayer->armor[1])
{
TileHGauge(2207, 250-320, 175 - 200, pPlayer->armor[1], 3200);
DrawStatNumber("%3d", pPlayer->armor[1] >> 4, 2230, 255-320, 178 - 200, 0, 0);
}
if (pPlayer->armor[0])
{
TileHGauge(2209, 250-320, 183 - 200, pPlayer->armor[0], 3200);
DrawStatNumber("%3d", pPlayer->armor[0] >> 4, 2230, 255-320, 186 - 200, 0, 0);
}
if (pPlayer->armor[2])
{
TileHGauge(2208, 250-320, 191 - 200, pPlayer->armor[2], 3200);
DrawStatNumber("%3d", pPlayer->armor[2] >> 4, 2230, 255-320, 194 - 200, 0, 0);
}
DrawPackItemInStatusBar(pPlayer, 286-320, 186 - 200, 302-320, 183 - 200);
for (int i = 0; i < 6; i++)
{
int nTile = 2220 + i;
int x;
int y = - 6;
if (i & 1)
{
x = - (78 + (i >> 1) * 10);
}
else
{
x = 73 + (i >> 1) * 10;
}
if (pPlayer->hasKey[i + 1])
DrawStatSprite(nTile, x, y, 0, 0);
}
PrintLevelStats(pPlayer, 28);
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void DrawHUD2()
{
PLAYER* pPlayer = gView;
XSPRITE* pXSprite = pPlayer->pXSprite;
BeginHUD(320, 200, 1);
DrawStatMaskedSprite(2169, 12, 195 - 200, 0, 0, 256, (int)(65536 * 0.56));
DrawStatNumber("%d", pXSprite->health >> 4, kSBarNumberHealth, 28, 187 - 200, 0, 0, 256);
if (pPlayer->armor[1])
{
DrawStatMaskedSprite(2578, 70, 186 - 200, 0, 0, 256, (int)(65536 * 0.5));
DrawStatNumber("%3d", pPlayer->armor[1] >> 4, kSBarNumberArmor2, 83, 187 - 200, 0, 0, 256, (int)(65536 * 0.65));
}
if (pPlayer->armor[0])
{
DrawStatMaskedSprite(2586, 112, 195 - 200, 0, 0, 256, (int)(65536 * 0.5));
DrawStatNumber("%3d", pPlayer->armor[0] >> 4, kSBarNumberArmor1, 125, 187 - 200, 0, 0, 256, (int)(65536 * 0.65));
}
if (pPlayer->armor[2])
{
DrawStatMaskedSprite(2602, 155, 196 - 200, 0, 0, 256, (int)(65536 * 0.5));
DrawStatNumber("%3d", pPlayer->armor[2] >> 4, kSBarNumberArmor3, 170, 187 - 200, 0, 0, 256, (int)(65536 * 0.65));
}
DrawPackItemInStatusBar2(pPlayer, 216 - 320, 194 - 200, 231 - 320, 187 - 200, 512, (int)(65536 * 0.7));
if (pPlayer->curWeapon && pPlayer->weaponAmmo != -1)
{
int num = pPlayer->ammoCount[pPlayer->weaponAmmo];
if (pPlayer->weaponAmmo == 6)
num /= 10;
if ((unsigned int)gAmmoIcons[pPlayer->weaponAmmo].nTile < kMaxTiles)
DrawStatMaskedSprite(gAmmoIcons[pPlayer->weaponAmmo].nTile, 304-320, -8 + gAmmoIcons[pPlayer->weaponAmmo].nYOffs,
0, 0, 512, gAmmoIcons[pPlayer->weaponAmmo].nScale);
bool reloadableWeapon = pPlayer->curWeapon == 3 && !powerupCheck(pPlayer, kPwUpTwoGuns);
if (!reloadableWeapon || (reloadableWeapon && !cl_showmagamt))
{
DrawStatNumber("%3d", num, kSBarNumberAmmo, 267-320, 187 - 200, 0, 0, 512);
}
else
{
FString format;
short clip = CalcMagazineAmount(num, 2, pPlayer->weaponState == 1);
short total = num - clip;
format.Format("%d/%d", clip, num - clip);
DrawCharArray(format.GetChars(), kSBarNumberAmmo, (total < 10 ? 267 : 258) - 320, 187 - 200, 0, 0, 512);
}
}
for (int i = 0; i < 6; i++)
{
if (pPlayer->hasKey[i + 1])
DrawStatMaskedSprite(2552 + i, -60 + 10 * i, 170 - 200, 0, 0, 0, (int)(65536 * 0.25));
}
BeginStatusBar(320, 200, 28);
if (pPlayer->throwPower)
TileHGauge(2260, 124, 175, pPlayer->throwPower, 65536);
else
drawInventory(pPlayer, 166, 200-tileHeight(2201) / 2 - 30);
PrintLevelStats(pPlayer, 28);
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
public:
void UpdateStatusBar()
{
PLAYER* pPlayer = gView;
XSPRITE* pXSprite = pPlayer->pXSprite;
int nPalette = 0;
if (gGameOptions.nGameType == 3)
{
if (pPlayer->teamId & 1)
nPalette = 7;
else
nPalette = 10;
}
if (hud_size == Hud_full)
{
DrawHUD2();
}
else if (hud_size > Hud_Stbar)
{
BeginStatusBar(320, 200, 28);
if (pPlayer->throwPower)
TileHGauge(2260, 124, 175, pPlayer->throwPower, 65536);
else if (hud_size > Hud_StbarOverlay)
drawInventory(pPlayer, 166, 200 - tileHeight(2201) / 2);
}
if (hud_size == Hud_Mini)
{
DrawHUD1(nPalette);
}
else if (hud_size <= Hud_StbarOverlay)
{
DrawStatusBar(nPalette);
}
// All remaining parts must be done with HUD alignment rules, even when showing a status bar.
BeginHUD(320, 200, 1);
viewDrawPowerUps(pPlayer);
if (gGameOptions.nGameType >= 1)
{
if (gGameOptions.nGameType == 3)
{
if (VanillaMode())
{
viewDrawCtfHudVanilla();
}
else
{
viewDrawCtfHud();
viewDrawPlayerFlags();
}
}
else
{
viewDrawPlayerFrags();
}
}
}
};
IMPLEMENT_CLASS(DBloodStatusBar, false, false)
static void UpdateFrame(void) static void UpdateFrame(void)
{ {
auto tex = tileGetTexture(kBackTile); auto tex = tileGetTexture(kBackTile);
@ -861,8 +67,22 @@ void UpdateStatusBar()
{ {
UpdateFrame(); UpdateFrame();
} }
SummaryInfo sum;
StatusBar->UpdateStatusBar(); if (gGameOptions.nGameType == 3)
{
sum.kills = gView ? gView->fragCount : 0;
sum.maxkills = -3;
}
else
{
sum.kills = gKillMgr.Kills;
sum.maxkills = gKillMgr.TotalKills;
}
sum.secrets = gSecretMgr.Founds;
sum.supersecrets = gSecretMgr.Super;
sum.maxsecrets = max(gSecretMgr.Founds, gSecretMgr.Total); // If we found more than there are, increase the total. Some levels have a bugged counter.
sum.time = Scale(PlayClock, 1000, 120);
UpdateStatusBar(&sum);
} }

View file

@ -281,8 +281,8 @@ void DoSectorPanning(void)
int px = MulScale(speed << 2, Cos(angle), 30) / xBits; int px = MulScale(speed << 2, Cos(angle), 30) / xBits;
int yBits = tileHeight(nTile) >> int((pSector->floorstat & 8) != 0); int yBits = tileHeight(nTile) >> int((pSector->floorstat & 8) != 0);
int py = MulScale(speed << 2, Sin(angle), 30) / yBits; int py = MulScale(speed << 2, Sin(angle), 30) / yBits;
pSector->addfloorxpan(px * (1. / 256)); pSector->addfloorxpan(px * (1.f / 256));
pSector->addfloorypan(-py * (1. / 256)); pSector->addfloorypan(-py * (1.f / 256));
} }
if (pXSector->panCeiling) // Ceiling if (pXSector->panCeiling) // Ceiling
{ {
@ -293,8 +293,8 @@ void DoSectorPanning(void)
int px = MulScale(speed << 2, Cos(angle), 30) / xBits; int px = MulScale(speed << 2, Cos(angle), 30) / xBits;
int yBits = tileHeight(nTile) >> int((pSector->ceilingstat & 8) != 0); int yBits = tileHeight(nTile) >> int((pSector->ceilingstat & 8) != 0);
int py = MulScale(speed << 2, Sin(angle), 30) / yBits; int py = MulScale(speed << 2, Sin(angle), 30) / yBits;
pSector->addceilingxpan(px * (1. / 256)); pSector->addceilingxpan(px * (1.f / 256));
pSector->addceilingypan(-py * (1. / 256)); pSector->addceilingypan(-py * (1.f / 256));
} }
} }
} }
@ -317,8 +317,8 @@ void DoSectorPanning(void)
int px = (psx << 2) / tileWidth(nTile); int px = (psx << 2) / tileWidth(nTile);
int py = (psy << 2) / tileHeight(nTile); int py = (psy << 2) / tileHeight(nTile);
wall[nWall].addxpan(px * (1. / 256)); wall[nWall].addxpan(px * (1.f / 256));
wall[nWall].addypan(py * (1. / 256)); wall[nWall].addypan(py * (1.f / 256));
} }
} }
} }

View file

@ -114,7 +114,7 @@ void GameInterface::UpdateSounds()
if (gMe->pSprite) if (gMe->pSprite)
{ {
listener.angle = -gMe->pSprite->ang * BAngRadian; // Build uses a period of 2048. listener.angle = -gMe->pSprite->ang * float(BAngRadian); // Build uses a period of 2048.
listener.velocity.Zero(); listener.velocity.Zero();
listener.position = GetSoundPos(&gMe->pSprite->pos); listener.position = GetSoundPos(&gMe->pSprite->pos);
listener.valid = true; listener.valid = true;

View file

@ -181,6 +181,7 @@ void sndStartSample(unsigned int nSound, int nVolume, int nChannel, bool bLoop,
else nVolume = 255; else nVolume = 255;
} }
if (bLoop) chanflags |= CHANF_LOOP; if (bLoop) chanflags |= CHANF_LOOP;
soundEngine->StopActorSounds(SOURCE_None, nullptr, nChannel + 1, nChannel + 1);
soundEngine->StartSound(SOURCE_None, nullptr, nullptr, (nChannel + 1), chanflags, snd, nVolume / 255.f, ATTN_NONE); soundEngine->StartSound(SOURCE_None, nullptr, nullptr, (nChannel + 1), chanflags, snd, nVolume / 255.f, ATTN_NONE);
} }
} }

View file

@ -270,9 +270,9 @@ void LifeLeechOperate(spritetype *pSprite, XSPRITE *pXSprite, EVENT event)
int nMissileType = kMissileLifeLeechAltNormal + (pXSprite->data3 ? 1 : 0); int nMissileType = kMissileLifeLeechAltNormal + (pXSprite->data3 ? 1 : 0);
int t2; int t2;
if (!pXSprite->data3) if (!pXSprite->data3)
t2 = 120 / 10.0; t2 = 120 / 10;
else else
t2 = (3*120) / 10.0; t2 = (3*120) / 10;
spritetype *pMissile = actFireMissile(pSprite, 0, z1, dx, dy, dz, nMissileType); spritetype *pMissile = actFireMissile(pSprite, 0, z1, dx, dy, dz, nMissileType);
if (pMissile) if (pMissile)
{ {

View file

@ -742,7 +742,7 @@ void viewDrawScreen(bool sceneonly)
} }
else else
{ {
renderSetRollAngle(rotscrnang.asbuildf()); renderSetRollAngle((float)rotscrnang.asbuildf());
render3DViewPolymost(nSectnum, cX, cY, cZ, cA, cH); render3DViewPolymost(nSectnum, cX, cY, cZ, cA, cH);
} }
bDeliriumOld = bDelirium && gDeliriumBlur; bDeliriumOld = bDelirium && gDeliriumBlur;
@ -785,12 +785,6 @@ void viewDrawScreen(bool sceneonly)
{ {
gChoke.animateChoke(160, zn, (int)gInterpolate); gChoke.animateChoke(160, zn, (int)gInterpolate);
} }
#if 0
if (drawtile_2048)
{
DrawStatSprite(2048, xdim-15, 20);
}
#endif
viewDrawAimedPlayerName(); viewDrawAimedPlayerName();
if (paused) if (paused)

View file

@ -194,7 +194,7 @@ static bool CheckAmmo(PLAYER *pPlayer, int ammotype, int count)
return 1; return 1;
if (pPlayer->curWeapon == 12 && pPlayer->weaponAmmo == 11 && pPlayer->weaponState == 11) if (pPlayer->curWeapon == 12 && pPlayer->weaponAmmo == 11 && pPlayer->weaponState == 11)
return 1; return 1;
if (pPlayer->curWeapon == 9 && pPlayer->pXSprite->health >= (count<<4)) if (pPlayer->curWeapon == 9 && pPlayer->pXSprite->health >= unsigned(count<<4))
return 1; return 1;
return pPlayer->ammoCount[ammotype] >= count; return pPlayer->ammoCount[ammotype] >= count;
} }
@ -1703,7 +1703,7 @@ void AltFireLifeLeech(int , PLAYER *pPlayer)
if (gGameOptions.nGameType <= 1) if (gGameOptions.nGameType <= 1)
{ {
int nAmmo = pPlayer->ammoCount[8]; int nAmmo = pPlayer->ammoCount[8];
if (nAmmo < 25 && pPlayer->pXSprite->health > ((25-nAmmo)<<4)) if (nAmmo < 25 && pPlayer->pXSprite->health > unsigned((25-nAmmo)<<4))
{ {
actDamageSprite(pPlayer->nSprite, pPlayer->pSprite, DAMAGE_TYPE_5, ((25-nAmmo)<<4)); actDamageSprite(pPlayer->nSprite, pPlayer->pSprite, DAMAGE_TYPE_5, ((25-nAmmo)<<4));
nAmmo = 25; nAmmo = 25;

View file

@ -6,7 +6,6 @@
#include "src/player_d.cpp" #include "src/player_d.cpp"
#include "src/player_w.cpp" #include "src/player_w.cpp"
#include "src/premap_d.cpp" #include "src/premap_d.cpp"
#include "src/sbar_d.cpp"
#include "src/sectors_d.cpp" #include "src/sectors_d.cpp"
#include "src/spawn_d.cpp" #include "src/spawn_d.cpp"

View file

@ -7,6 +7,5 @@
#include "src/hudweapon_r.cpp" #include "src/hudweapon_r.cpp"
#include "src/player_r.cpp" #include "src/player_r.cpp"
#include "src/premap_r.cpp" #include "src/premap_r.cpp"
#include "src/sbar_r.cpp"
#include "src/sectors_r.cpp" #include "src/sectors_r.cpp"
#include "src/spawn_r.cpp" #include "src/spawn_r.cpp"

View file

@ -112,9 +112,9 @@ void InitFonts_d()
fontdata.Clear(); fontdata.Clear();
// SBAR index font // SBAR index font
for (int i = 0; i < 10; i++) fontdata.Insert('0' + i, tileGetTexture(THREEBYFIVE + i)); for (int i = 0; i < 10; i++) fontdata.Insert('0' + i, tileGetTexture(THREEBYFIVE0 + i));
fontdata.Insert(':', tileGetTexture(THREEBYFIVE + 10)); fontdata.Insert(':', tileGetTexture(THREEBYFIVE0 + 10));
fontdata.Insert('/', tileGetTexture(THREEBYFIVE + 11)); fontdata.Insert('/', tileGetTexture(THREEBYFIVE0 + 11));
fontdata.Insert('%', tileGetTexture(MINIFONT + '%' - '!')); fontdata.Insert('%', tileGetTexture(MINIFONT + '%' - '!'));
fontdata.Insert(1, TexMan.FindGameTexture("TINYBLAK")); // this is only here to widen the color range of the font to produce a better translation. fontdata.Insert(1, TexMan.FindGameTexture("TINYBLAK")); // this is only here to widen the color range of the font to produce a better translation.
GlyphSet::Iterator iti(fontdata); GlyphSet::Iterator iti(fontdata);

View file

@ -316,19 +316,14 @@ void ms(DDukeActor* const actor)
void movecyclers(void) void movecyclers(void)
{ {
short q, j, x, t, s, * c; for (int q = numcyclers - 1; q >= 0; q--)
walltype* wal;
char cshade;
for (q = numcyclers - 1; q >= 0; q--)
{ {
short* c = &cyclers[q][0];
int s = c[0];
c = &cyclers[q][0]; int t = c[3];
s = c[0]; int j = t + bsin(c[1], -10);
int cshade = c[2];
t = c[3];
j = t + bsin(c[1], -10);
cshade = c[2];
if (j < cshade) j = cshade; if (j < cshade) j = cshade;
else if (j > t) j = t; else if (j > t) j = t;
@ -336,8 +331,8 @@ void movecyclers(void)
c[1] += sector[s].extra; c[1] += sector[s].extra;
if (c[5]) if (c[5])
{ {
wal = &wall[sector[s].wallptr]; auto wal = &wall[sector[s].wallptr];
for (x = sector[s].wallnum; x > 0; x--, wal++) for (int x = sector[s].wallnum; x > 0; x--, wal++)
if (wal->hitag != 1) if (wal->hitag != 1)
{ {
wal->shade = j; wal->shade = j;
@ -4466,7 +4461,7 @@ void handle_se27(DDukeActor* actor)
{ {
if (cansee(s->x, s->y, s->z, s->sectnum, ps[p].posx, ps[p].posy, ps[p].posz, ps[p].cursectnum)) if (cansee(s->x, s->y, s->z, s->sectnum, ps[p].posx, ps[p].posy, ps[p].posz, ps[p].cursectnum))
{ {
if (x < (unsigned)sh) if (x < sh)
{ {
ud.cameraactor = actor; ud.cameraactor = actor;
t[0] = 999; t[0] = 999;

View file

@ -220,9 +220,9 @@ void addweapon_d(struct player_struct *p, int weapon)
{ {
if ( p->gotweapon[weapon] == 0 ) if ( p->gotweapon[weapon] == 0 )
{ {
p->gotweapon.Set(weapon); p->gotweapon[weapon] = true;
if(weapon == SHRINKER_WEAPON) if (weapon == SHRINKER_WEAPON)
p->gotweapon.Set(GROW_WEAPON); p->gotweapon[GROW_WEAPON] = true;
} }
p->random_club_frame = 0; p->random_club_frame = 0;
@ -1578,7 +1578,7 @@ static bool movefireball(DDukeActor* actor)
spr->zvel = proj->zv; spr->zvel = proj->zv;
} }
} }
spr->yrepeat = spr->xrepeat = (short)(s->xrepeat * siz); spr->yrepeat = spr->xrepeat = (uint8_t)(s->xrepeat * siz);
spr->cstat = s->cstat; spr->cstat = s->cstat;
spr->extra = 0; spr->extra = 0;

View file

@ -557,7 +557,7 @@ void thunder(void)
struct player_struct* p; struct player_struct* p;
int r1, r2; int r1, r2;
short startwall, endwall, i, j; short startwall, endwall, i, j;
unsigned char shade; uint8_t shade;
p = &ps[screenpeek]; p = &ps[screenpeek];
@ -612,10 +612,10 @@ void thunder(void)
{ {
startwall = sector[lightninsector[i]].wallptr; startwall = sector[lightninsector[i]].wallptr;
endwall = startwall + sector[lightninsector[i]].wallnum; endwall = startwall + sector[lightninsector[i]].wallnum;
sector[lightninsector[i]].floorshade = lightninsectorshade[i]; sector[lightninsector[i]].floorshade = (int8_t)lightninsectorshade[i];
sector[lightninsector[i]].ceilingshade = lightninsectorshade[i]; sector[lightninsector[i]].ceilingshade = (int8_t)lightninsectorshade[i];
for (j = startwall; j < endwall; j++) for (j = startwall; j < endwall; j++)
wall[j].shade = lightninsectorshade[i]; wall[j].shade = (int8_t)lightninsectorshade[i];
} }
} }
} }

View file

@ -118,16 +118,16 @@ void addweapon_r(struct player_struct* p, int weapon)
short cw = p->curr_weapon; short cw = p->curr_weapon;
if (p->OnMotorcycle || p->OnBoat) if (p->OnMotorcycle || p->OnBoat)
{ {
p->gotweapon.Set(weapon); p->gotweapon[weapon] = true;;
if (weapon == THROWSAW_WEAPON) if (weapon == THROWSAW_WEAPON)
{ {
p->gotweapon.Set(BUZZSAW_WEAPON); p->gotweapon[BUZZSAW_WEAPON] = true;
p->ammo_amount[BUZZSAW_WEAPON] = 1; p->ammo_amount[BUZZSAW_WEAPON] = 1;
} }
else if (weapon == CROSSBOW_WEAPON) else if (weapon == CROSSBOW_WEAPON)
{ {
p->gotweapon.Set(CHICKEN_WEAPON); p->gotweapon[CHICKEN_WEAPON] = true;
p->gotweapon.Set(DYNAMITE_WEAPON); p->gotweapon[DYNAMITE_WEAPON] = true;
} }
else if (weapon == SLINGBLADE_WEAPON) else if (weapon == SLINGBLADE_WEAPON)
{ {
@ -138,17 +138,17 @@ void addweapon_r(struct player_struct* p, int weapon)
if (p->gotweapon[weapon] == 0) if (p->gotweapon[weapon] == 0)
{ {
p->gotweapon.Set(weapon); p->gotweapon[weapon] = true;;
if (weapon == THROWSAW_WEAPON) if (weapon == THROWSAW_WEAPON)
{ {
p->gotweapon.Set(BUZZSAW_WEAPON); p->gotweapon[BUZZSAW_WEAPON] = true;
p->ammo_amount[BUZZSAW_WEAPON] = 1; p->ammo_amount[BUZZSAW_WEAPON] = 1;
} }
if (isRRRA()) if (isRRRA())
{ {
if (weapon == CROSSBOW_WEAPON) if (weapon == CROSSBOW_WEAPON)
{ {
p->gotweapon.Set(CHICKEN_WEAPON); p->gotweapon[CHICKEN_WEAPON] = true;
} }
if (weapon == SLINGBLADE_WEAPON) if (weapon == SLINGBLADE_WEAPON)
{ {
@ -157,7 +157,7 @@ void addweapon_r(struct player_struct* p, int weapon)
} }
if (weapon == CROSSBOW_WEAPON) if (weapon == CROSSBOW_WEAPON)
{ {
p->gotweapon.Set(DYNAMITE_WEAPON); p->gotweapon[DYNAMITE_WEAPON] = true;
} }
if (weapon != DYNAMITE_WEAPON) if (weapon != DYNAMITE_WEAPON)

View file

@ -29,7 +29,6 @@ Modifications for JonoF's port by Jonathon Fowler (jf@jonof.id.au)
#include "ns.h" #include "ns.h"
#include "duke3d.h" #include "duke3d.h"
#include "sbar.h"
#include "mapinfo.h" #include "mapinfo.h"
#include "cheathandler.h" #include "cheathandler.h"
#include "c_dispatch.h" #include "c_dispatch.h"

View file

@ -194,7 +194,7 @@ const char* GameInterface::GenericCheat(int player, int cheat)
case CHT_RHETT: case CHT_RHETT:
ud.god = 0; ud.god = 0;
ps[player].gotweapon.Zero(); memset(ps[player].gotweapon, 0, MAX_WEAPONS);
ps[player].curr_weapon = KNEE_WEAPON; ps[player].curr_weapon = KNEE_WEAPON;
ps[player].nocheat = 1; ps[player].nocheat = 1;
ps[player].GetActor()->s->extra = 1; ps[player].GetActor()->s->extra = 1;
@ -231,7 +231,7 @@ static bool cheatWeapons(int player)
for (int weapon = PISTOL_WEAPON; weapon < weaponLimit; weapon++ ) for (int weapon = PISTOL_WEAPON; weapon < weaponLimit; weapon++ )
{ {
addammo( weapon, &ps[player], gs.max_ammo_amount[weapon] ); addammo( weapon, &ps[player], gs.max_ammo_amount[weapon] );
ps[player].gotweapon.Set(weapon); ps[player].gotweapon[weapon] = true;;
} }
if (isRRRA()) if (isRRRA())
ps[player].ammo_amount[SLINGBLADE_WEAPON] = 1; ps[player].ammo_amount[SLINGBLADE_WEAPON] = 1;

View file

@ -173,7 +173,7 @@ void initactorflags_r()
STEROIDS, STEROIDS,
HEATSENSOR, HEATSENSOR,
BOOTS, BOOTS,
JETPACK, COWPIE,
HOLODUKE, HOLODUKE,
AIRTANK }); AIRTANK });
@ -205,7 +205,7 @@ void initactorflags_r()
gs.weaponsandammosprites[2] = DEVISTATORAMMO; gs.weaponsandammosprites[2] = DEVISTATORAMMO;
gs.weaponsandammosprites[3] = RPGAMMO; gs.weaponsandammosprites[3] = RPGAMMO;
gs.weaponsandammosprites[4] = RPGAMMO; gs.weaponsandammosprites[4] = RPGAMMO;
gs.weaponsandammosprites[5] = JETPACK; gs.weaponsandammosprites[5] = COWPIE;
gs.weaponsandammosprites[6] = SHIELD; gs.weaponsandammosprites[6] = SHIELD;
gs.weaponsandammosprites[7] = FIRSTAID; gs.weaponsandammosprites[7] = FIRSTAID;
gs.weaponsandammosprites[8] = STEROIDS; gs.weaponsandammosprites[8] = STEROIDS;

View file

@ -227,6 +227,7 @@ void PlayerColorChanged(void);
bool movementBlocked(player_struct *p); bool movementBlocked(player_struct *p);
void loadcons(); void loadcons();
void recordoldspritepos(); void recordoldspritepos();
void DrawStatusBar();
int* animateptr(int i); int* animateptr(int i);

View file

@ -40,7 +40,6 @@ Modifications for JonoF's port by Jonathon Fowler (jf@jonof.id.au)
#include "st_start.h" #include "st_start.h"
#include "i_interface.h" #include "i_interface.h"
#include "prediction.h" #include "prediction.h"
#include "sbar.h"
#include "gamestate.h" #include "gamestate.h"
#include "dukeactor.h" #include "dukeactor.h"
#include "interpolate.h" #include "interpolate.h"
@ -232,7 +231,7 @@ void drawoverlays(double smoothratio)
// loogies courtesy of being snotted on // loogies courtesy of being snotted on
if (pp->loogcnt > 0 && !isRR()) if (pp->loogcnt > 0 && !isRR())
{ {
V_AddBlend(0, 63, 0, (pp->loogcnt >> 1), blend); V_AddBlend(0, 63, 0, float(pp->loogcnt >> 1), blend);
} }
if (blend[3]) if (blend[3])
{ {
@ -291,9 +290,7 @@ void drawoverlays(double smoothratio)
} }
} }
DrawBorder(); DrawStatusBar();
StatusBar->UpdateStatusBar();
if (ps[myconnectindex].newOwner == nullptr && ud.cameraactor == nullptr) if (ps[myconnectindex].newOwner == nullptr && ud.cameraactor == nullptr)
{ {

View file

@ -300,7 +300,7 @@ int ConCompiler::getkeyword(const char* text)
while (min <= max) while (min <= max)
{ {
int mid = (min + max) >> 1; auto mid = (min + max) >> 1;
const int comp = strcmp(text, cmdList[mid].cmd); const int comp = strcmp(text, cmdList[mid].cmd);
if (comp == 0) if (comp == 0)

Some files were not shown because too many files have changed in this diff Show more