mirror of
https://git.do.srb2.org/KartKrew/Kart-Public.git
synced 2024-11-10 15:22:20 +00:00
Merge branch 'uncapped-next' into 'next'
Uncapped See merge request KartKrew/Kart-Public!276
This commit is contained in:
commit
d0addde847
69 changed files with 3034 additions and 711 deletions
|
@ -81,6 +81,7 @@ set(SRB2_CORE_HEADERS
|
|||
i_sound.h
|
||||
i_system.h
|
||||
i_tcp.h
|
||||
i_time.h
|
||||
i_video.h
|
||||
info.h
|
||||
keys.h
|
||||
|
@ -118,6 +119,7 @@ set(SRB2_CORE_RENDER_SOURCES
|
|||
r_bsp.c
|
||||
r_data.c
|
||||
r_draw.c
|
||||
r_fps.c
|
||||
r_main.c
|
||||
r_plane.c
|
||||
r_segs.c
|
||||
|
@ -129,6 +131,7 @@ set(SRB2_CORE_RENDER_SOURCES
|
|||
r_data.h
|
||||
r_defs.h
|
||||
r_draw.h
|
||||
r_fps.h
|
||||
r_local.h
|
||||
r_main.h
|
||||
r_plane.h
|
||||
|
@ -158,6 +161,7 @@ set(SRB2_CORE_GAME_SOURCES
|
|||
p_tick.c
|
||||
p_user.c
|
||||
k_kart.c
|
||||
i_time.c
|
||||
|
||||
p_local.h
|
||||
p_maputl.h
|
||||
|
@ -248,6 +252,7 @@ if(${SRB2_CONFIG_HAVE_BLUA})
|
|||
lua_consolelib.c
|
||||
lua_hooklib.c
|
||||
lua_hudlib.c
|
||||
lua_hudlib_drawlist.c
|
||||
lua_infolib.c
|
||||
lua_maplib.c
|
||||
lua_mathlib.c
|
||||
|
@ -260,6 +265,7 @@ if(${SRB2_CONFIG_HAVE_BLUA})
|
|||
set(SRB2_LUA_HEADERS
|
||||
lua_hook.h
|
||||
lua_hud.h
|
||||
lua_hudlib_drawlist.h
|
||||
lua_libs.h
|
||||
lua_script.h
|
||||
)
|
||||
|
|
|
@ -587,6 +587,7 @@ OBJS:=$(i_main_o) \
|
|||
$(OBJDIR)/r_bsp.o \
|
||||
$(OBJDIR)/r_data.o \
|
||||
$(OBJDIR)/r_draw.o \
|
||||
$(OBJDIR)/r_fps.o \
|
||||
$(OBJDIR)/r_main.o \
|
||||
$(OBJDIR)/r_plane.o \
|
||||
$(OBJDIR)/r_segs.o \
|
||||
|
@ -602,6 +603,7 @@ OBJS:=$(i_main_o) \
|
|||
$(OBJDIR)/mserv.o \
|
||||
$(OBJDIR)/http-mserv.o\
|
||||
$(OBJDIR)/i_tcp.o \
|
||||
$(OBJDIR)/i_time.o \
|
||||
$(OBJDIR)/lzf.o \
|
||||
$(OBJDIR)/vid_copy.o \
|
||||
$(OBJDIR)/b_bot.o \
|
||||
|
|
|
@ -82,13 +82,17 @@ INT64 current_time_in_ps() {
|
|||
return (t.tv_sec * (INT64)1000000) + t.tv_usec;
|
||||
}
|
||||
|
||||
tic_t I_GetTime(void)
|
||||
void I_Sleep(UINT32 ms){}
|
||||
|
||||
precise_t I_GetPreciseTime(void)
|
||||
{
|
||||
INT64 since_start = current_time_in_ps() - start_time;
|
||||
return (since_start*TICRATE)/1000000;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void I_Sleep(void){}
|
||||
UINT64 I_GetPrecisePrecision(void)
|
||||
{
|
||||
return 1000000;
|
||||
}
|
||||
|
||||
void I_GetEvent(void){}
|
||||
|
||||
|
|
|
@ -270,8 +270,8 @@ void B_RespawnBot(INT32 playernum)
|
|||
player->powers[pw_gravityboots] = sonic->player->powers[pw_gravityboots];
|
||||
player->powers[pw_nocontrol] = sonic->player->powers[pw_nocontrol];
|
||||
|
||||
P_TeleportMove(tails, x, y, z);
|
||||
P_SetOrigin(tails, x, y, z);
|
||||
P_SetPlayerMobjState(tails, S_KART_STND1); // SRB2kart - was S_PLAY_FALL1
|
||||
P_SetScale(tails, sonic->scale);
|
||||
tails->destscale = sonic->destscale;
|
||||
tails->destscale = tails->old_scale = sonic->destscale;
|
||||
}
|
||||
|
|
|
@ -50,4 +50,5 @@ OBJS:=$(OBJS) \
|
|||
$(OBJDIR)/lua_skinlib.o \
|
||||
$(OBJDIR)/lua_thinkerlib.o \
|
||||
$(OBJDIR)/lua_maplib.o \
|
||||
$(OBJDIR)/lua_hudlib.o
|
||||
$(OBJDIR)/lua_hudlib.o \
|
||||
$(OBJDIR)/lua_hudlib_drawlist.o
|
||||
|
|
|
@ -1231,7 +1231,7 @@ static void Setvalue(consvar_t *var, const char *valstr, boolean stealth)
|
|||
|
||||
// search for other
|
||||
for (i = MAXVAL+1; var->PossibleValue[i].strvalue; i++)
|
||||
if (!stricmp(var->PossibleValue[i].strvalue, valstr))
|
||||
if (v == var->PossibleValue[i].value || !stricmp(var->PossibleValue[i].strvalue, valstr))
|
||||
{
|
||||
var->value = var->PossibleValue[i].value;
|
||||
var->string = var->PossibleValue[i].strvalue;
|
||||
|
@ -1616,6 +1616,9 @@ void CV_AddValue(consvar_t *var, INT32 increment)
|
|||
{
|
||||
INT32 newvalue, max;
|
||||
|
||||
if (!increment)
|
||||
return;
|
||||
|
||||
// count pointlimit better
|
||||
/*if (var == &cv_pointlimit && (gametype == GT_MATCH))
|
||||
increment *= 50;*/
|
||||
|
@ -1628,7 +1631,6 @@ void CV_AddValue(consvar_t *var, INT32 increment)
|
|||
// Special case for the nextmap variable, used only directly from the menu
|
||||
INT32 oldvalue = var->value - 1, gt;
|
||||
gt = cv_newgametype.value;
|
||||
if (increment != 0) // Going up!
|
||||
{
|
||||
newvalue = var->value - 1;
|
||||
do
|
||||
|
@ -1670,21 +1672,35 @@ void CV_AddValue(consvar_t *var, INT32 increment)
|
|||
{
|
||||
INT32 currentindice = -1, newindice;
|
||||
for (max = MAXVAL+1; var->PossibleValue[max].strvalue; max++)
|
||||
if (var->PossibleValue[max].value == var->value)
|
||||
currentindice = max;
|
||||
|
||||
if (currentindice == -1 && max != MAXVAL+1)
|
||||
newindice = ((increment > 0) ? MAXVAL : max) + increment;
|
||||
else
|
||||
newindice = currentindice + increment;
|
||||
|
||||
if (newindice >= max || newindice <= MAXVAL)
|
||||
{
|
||||
newvalue = var->PossibleValue[((increment > 0) ? MINVAL : MAXVAL)].value;
|
||||
CV_SetValue(var, newvalue);
|
||||
if (var->PossibleValue[max].value == newvalue)
|
||||
{
|
||||
increment = 0;
|
||||
currentindice = max;
|
||||
break; // The value we definitely want, stop here.
|
||||
}
|
||||
else if (var->PossibleValue[max].value == var->value)
|
||||
currentindice = max; // The value we maybe want.
|
||||
}
|
||||
|
||||
if (increment)
|
||||
{
|
||||
increment = (increment > 0) ? 1 : -1;
|
||||
if (currentindice == -1 && max != MAXVAL+1)
|
||||
newindice = ((increment > 0) ? MAXVAL : max) + increment;
|
||||
else
|
||||
newindice = currentindice + increment;
|
||||
|
||||
if (newindice >= max || newindice <= MAXVAL)
|
||||
{
|
||||
newvalue = var->PossibleValue[((increment > 0) ? MINVAL : MAXVAL)].value;
|
||||
CV_SetValue(var, newvalue);
|
||||
}
|
||||
else
|
||||
CV_Set(var, var->PossibleValue[newindice].strvalue);
|
||||
}
|
||||
else
|
||||
CV_Set(var, var->PossibleValue[newindice].strvalue);
|
||||
CV_Set(var, var->PossibleValue[currentindice].strvalue);
|
||||
}
|
||||
else
|
||||
CV_SetValue(var, newvalue);
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include <unistd.h> //for unlink
|
||||
#endif
|
||||
|
||||
#include "i_time.h"
|
||||
#include "i_net.h"
|
||||
#include "i_system.h"
|
||||
#include "i_video.h"
|
||||
|
@ -2502,7 +2503,10 @@ static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic
|
|||
#endif
|
||||
}
|
||||
else
|
||||
I_Sleep();
|
||||
{
|
||||
I_Sleep(cv_sleep.value);
|
||||
I_UpdateTime(cv_timescale.value);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -4014,10 +4018,6 @@ boolean SV_SpawnServer(void)
|
|||
if (netgame && I_NetOpenSocket)
|
||||
{
|
||||
I_NetOpenSocket();
|
||||
#ifdef MASTERSERVER
|
||||
if (cv_advertise.value)
|
||||
RegisterServer();
|
||||
#endif
|
||||
}
|
||||
|
||||
// non dedicated server just connect to itself
|
||||
|
@ -5540,8 +5540,10 @@ static void SV_Maketic(void)
|
|||
maketic++;
|
||||
}
|
||||
|
||||
void TryRunTics(tic_t realtics)
|
||||
boolean TryRunTics(tic_t realtics)
|
||||
{
|
||||
boolean ticking;
|
||||
|
||||
// the machine has lagged but it is not so bad
|
||||
if (realtics > TICRATE/7) // FIXME: consistency failure!!
|
||||
{
|
||||
|
@ -5593,10 +5595,12 @@ void TryRunTics(tic_t realtics)
|
|||
if (player_joining)
|
||||
{
|
||||
hu_stopped = true;
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (neededtic > gametic)
|
||||
ticking = neededtic > gametic;
|
||||
|
||||
if (ticking)
|
||||
{
|
||||
if (advancedemo)
|
||||
D_StartTitle();
|
||||
|
@ -5620,6 +5624,8 @@ void TryRunTics(tic_t realtics)
|
|||
{
|
||||
hu_stopped = true;
|
||||
}
|
||||
|
||||
return ticking;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -595,7 +595,7 @@ boolean Playing(void);
|
|||
void D_QuitNetGame(void);
|
||||
|
||||
//? How many ticks to run?
|
||||
void TryRunTics(tic_t realtic);
|
||||
boolean TryRunTics(tic_t realtic);
|
||||
|
||||
// extra data for lmps
|
||||
// these functions scare me. they contain magic.
|
||||
|
|
135
src/d_main.c
135
src/d_main.c
|
@ -50,6 +50,7 @@ int snprintf(char *str, size_t n, const char *fmt, ...);
|
|||
#include "hu_stuff.h"
|
||||
#include "i_sound.h"
|
||||
#include "i_system.h"
|
||||
#include "i_time.h"
|
||||
#include "i_threads.h"
|
||||
#include "i_video.h"
|
||||
#include "m_argv.h"
|
||||
|
@ -73,6 +74,7 @@ int snprintf(char *str, size_t n, const char *fmt, ...);
|
|||
#include "dehacked.h" // Dehacked list test
|
||||
#include "m_cond.h" // condition initialization
|
||||
#include "fastcmp.h"
|
||||
#include "r_fps.h" // Frame interpolation/uncapped
|
||||
#include "keys.h"
|
||||
#include "filesrch.h" // refreshdirmenu
|
||||
|
||||
|
@ -430,6 +432,8 @@ static void D_Display(void)
|
|||
// draw the view directly
|
||||
if (cv_renderview.value && !automapactive)
|
||||
{
|
||||
R_ApplyLevelInterpolators(R_UsingFrameInterpolation() ? rendertimefrac : FRACUNIT);
|
||||
|
||||
for (i = 0; i <= splitscreen; i++)
|
||||
{
|
||||
if (players[displayplayers[i]].mo || players[displayplayers[i]].playerstate == PST_DEAD)
|
||||
|
@ -502,6 +506,8 @@ static void D_Display(void)
|
|||
V_DoPostProcessor(i, postimgtype[i], postimgparam[i]);
|
||||
}
|
||||
}
|
||||
|
||||
R_RestoreLevelInterpolators();
|
||||
}
|
||||
|
||||
if (lastdraw)
|
||||
|
@ -619,7 +625,12 @@ tic_t rendergametic;
|
|||
|
||||
void D_SRB2Loop(void)
|
||||
{
|
||||
tic_t oldentertics = 0, entertic = 0, realtics = 0, rendertimeout = INFTICS;
|
||||
tic_t entertic = 0, oldentertics = 0, realtics = 0, rendertimeout = INFTICS;
|
||||
double deltatics = 0.0;
|
||||
double deltasecs = 0.0;
|
||||
|
||||
boolean interp = false;
|
||||
boolean doDisplay = false;
|
||||
|
||||
if (dedicated)
|
||||
server = true;
|
||||
|
@ -631,6 +642,7 @@ void D_SRB2Loop(void)
|
|||
I_DoStartupMouse();
|
||||
#endif
|
||||
|
||||
I_UpdateTime(cv_timescale.value);
|
||||
oldentertics = I_GetTime();
|
||||
|
||||
// end of loading screen: CONS_Printf() will no more call FinishUpdate()
|
||||
|
@ -657,6 +669,19 @@ void D_SRB2Loop(void)
|
|||
|
||||
for (;;)
|
||||
{
|
||||
// capbudget is the minimum precise_t duration of a single loop iteration
|
||||
precise_t capbudget;
|
||||
precise_t enterprecise = I_GetPreciseTime();
|
||||
precise_t finishprecise = enterprecise;
|
||||
|
||||
{
|
||||
// Casting the return value of a function is bad practice (apparently)
|
||||
double budget = round((1.0 / R_GetFramerateCap()) * I_GetPrecisePrecision());
|
||||
capbudget = (precise_t) budget;
|
||||
}
|
||||
|
||||
I_UpdateTime(cv_timescale.value);
|
||||
|
||||
if (lastwipetic)
|
||||
{
|
||||
oldentertics = lastwipetic;
|
||||
|
@ -668,7 +693,11 @@ void D_SRB2Loop(void)
|
|||
realtics = entertic - oldentertics;
|
||||
oldentertics = entertic;
|
||||
|
||||
refreshdirmenu = 0; // not sure where to put this, here as good as any?
|
||||
if (demo.playback && gamestate == GS_LEVEL)
|
||||
{
|
||||
// Nicer place to put this.
|
||||
realtics = realtics * cv_playbackspeed.value;
|
||||
}
|
||||
|
||||
#ifdef DEBUGFILE
|
||||
if (!realtics)
|
||||
|
@ -676,47 +705,74 @@ void D_SRB2Loop(void)
|
|||
debugload--;
|
||||
#endif
|
||||
|
||||
if (!realtics && !singletics)
|
||||
{
|
||||
I_Sleep();
|
||||
continue;
|
||||
}
|
||||
interp = R_UsingFrameInterpolation() && !dedicated;
|
||||
doDisplay = false;
|
||||
|
||||
#ifdef HW3SOUND
|
||||
HW3S_BeginFrameUpdate();
|
||||
#endif
|
||||
|
||||
// don't skip more than 10 frames at a time
|
||||
// (fadein / fadeout cause massive frame skip!)
|
||||
if (realtics > 8)
|
||||
realtics = 1;
|
||||
refreshdirmenu = 0; // not sure where to put this, here as good as any?
|
||||
|
||||
// process tics (but maybe not if realtic == 0)
|
||||
TryRunTics(realtics);
|
||||
|
||||
if (lastdraw || singletics || gametic > rendergametic)
|
||||
if (realtics > 0 || singletics)
|
||||
{
|
||||
rendergametic = gametic;
|
||||
rendertimeout = entertic+TICRATE/17;
|
||||
// don't skip more than 10 frames at a time
|
||||
// (fadein / fadeout cause massive frame skip!)
|
||||
if (realtics > 8)
|
||||
realtics = 1;
|
||||
|
||||
// Update display, next frame, with current state.
|
||||
D_Display();
|
||||
// process tics (but maybe not if realtic == 0)
|
||||
TryRunTics(realtics);
|
||||
|
||||
if (moviemode)
|
||||
M_SaveFrame();
|
||||
if (takescreenshot) // Only take screenshots after drawing.
|
||||
M_DoScreenShot();
|
||||
if (lastdraw || singletics || gametic > rendergametic)
|
||||
{
|
||||
rendergametic = gametic;
|
||||
rendertimeout = entertic + TICRATE/17;
|
||||
|
||||
doDisplay = true;
|
||||
}
|
||||
else if (rendertimeout < entertic) // in case the server hang or netsplit
|
||||
{
|
||||
doDisplay = true;
|
||||
}
|
||||
|
||||
renderisnewtic = true;
|
||||
}
|
||||
else if (rendertimeout < entertic) // in case the server hang or netsplit
|
||||
else
|
||||
{
|
||||
renderisnewtic = false;
|
||||
}
|
||||
|
||||
if (interp)
|
||||
{
|
||||
renderdeltatics = FLOAT_TO_FIXED(deltatics);
|
||||
|
||||
if (!(paused || P_AutoPause()) && !hu_stopped)
|
||||
{
|
||||
rendertimefrac = g_time.timefrac;
|
||||
}
|
||||
else
|
||||
{
|
||||
rendertimefrac = FRACUNIT;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
renderdeltatics = realtics * FRACUNIT;
|
||||
rendertimefrac = FRACUNIT;
|
||||
}
|
||||
|
||||
if (interp || doDisplay)
|
||||
{
|
||||
D_Display();
|
||||
|
||||
if (moviemode)
|
||||
M_SaveFrame();
|
||||
if (takescreenshot) // Only take screenshots after drawing.
|
||||
M_DoScreenShot();
|
||||
}
|
||||
|
||||
// Only take screenshots after drawing.
|
||||
if (moviemode)
|
||||
M_SaveFrame();
|
||||
if (takescreenshot)
|
||||
M_DoScreenShot();
|
||||
|
||||
// consoleplayer -> displayplayers (hear sounds from viewpoint)
|
||||
S_UpdateSounds(); // move positional sounds
|
||||
|
||||
|
@ -737,6 +793,21 @@ void D_SRB2Loop(void)
|
|||
Discord_RunCallbacks();
|
||||
}
|
||||
#endif
|
||||
|
||||
// Fully completed frame made.
|
||||
finishprecise = I_GetPreciseTime();
|
||||
if (!singletics)
|
||||
{
|
||||
INT64 elapsed = (INT64)(finishprecise - enterprecise);
|
||||
if (elapsed > 0 && (INT64)capbudget > elapsed)
|
||||
{
|
||||
I_SleepDuration(capbudget - (finishprecise - enterprecise));
|
||||
}
|
||||
}
|
||||
// Capture the time once more to get the real delta time.
|
||||
finishprecise = I_GetPreciseTime();
|
||||
deltasecs = (double)((INT64)(finishprecise - enterprecise)) / I_GetPrecisePrecision();
|
||||
deltatics = deltasecs * NEWTICRATE;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1189,8 +1260,8 @@ void D_SRB2Main(void)
|
|||
//---------------------------------------------------- READY TIME
|
||||
// we need to check for dedicated before initialization of some subsystems
|
||||
|
||||
CONS_Printf("I_StartupTimer()...\n");
|
||||
I_StartupTimer();
|
||||
CONS_Printf("I_InitializeTime()...\n");
|
||||
I_InitializeTime();
|
||||
|
||||
// Make backups of some SOCcable tables.
|
||||
P_BackupTables();
|
||||
|
@ -1520,6 +1591,8 @@ void D_SRB2Main(void)
|
|||
// as having been modified for the first game.
|
||||
M_PushSpecialParameters(); // push all "+" parameter at the command buffer
|
||||
|
||||
COM_BufExecute(); // ensure the command buffer gets executed before the map starts (+skin)
|
||||
|
||||
strncpy(connectedservername, cv_servername.string, MAXSERVERNAME);
|
||||
|
||||
if (M_CheckParm("-gametype") && M_IsNextParm())
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
#include "doomdef.h"
|
||||
#include "g_game.h"
|
||||
#include "i_time.h"
|
||||
#include "i_net.h"
|
||||
#include "i_system.h"
|
||||
#include "m_argv.h"
|
||||
|
@ -614,7 +615,10 @@ void Net_WaitAllAckReceived(UINT32 timeout)
|
|||
while (timeout > I_GetTime() && !Net_AllAcksReceived())
|
||||
{
|
||||
while (tictac == I_GetTime())
|
||||
I_Sleep();
|
||||
{
|
||||
I_Sleep(cv_sleep.value);
|
||||
I_UpdateTime(cv_timescale.value);
|
||||
}
|
||||
tictac = I_GetTime();
|
||||
HGetPacket();
|
||||
Net_AckTicker();
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
#include "console.h"
|
||||
#include "command.h"
|
||||
#include "i_time.h"
|
||||
#include "i_system.h"
|
||||
#include "g_game.h"
|
||||
#include "hu_stuff.h"
|
||||
|
@ -2445,7 +2446,6 @@ void D_PickVote(void)
|
|||
SINT8 templevels[MAXPLAYERS];
|
||||
SINT8 votecompare = -1;
|
||||
UINT8 numvotes = 0, key = 0;
|
||||
boolean force = true;
|
||||
INT32 i;
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
|
@ -2459,8 +2459,6 @@ void D_PickVote(void)
|
|||
numvotes++;
|
||||
if (votecompare == -1)
|
||||
votecompare = votes[i];
|
||||
else if (votes[i] != votecompare)
|
||||
force = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -50,6 +50,7 @@
|
|||
#include "doomstat.h"
|
||||
#include "d_main.h"
|
||||
#include "g_game.h"
|
||||
#include "i_time.h"
|
||||
#include "i_net.h"
|
||||
#include "i_system.h"
|
||||
#include "m_argv.h"
|
||||
|
|
|
@ -388,6 +388,7 @@ typedef struct player_s
|
|||
// SRB2kart stuff
|
||||
INT32 kartstuff[NUMKARTSTUFF];
|
||||
angle_t frameangle; // for the player add the ability to have the sprite only face other angles
|
||||
angle_t old_frameangle, old_frameangle2;
|
||||
INT16 lturn_max[MAXPREDICTTICS]; // What's the expected turn value for full-left for a number of frames back (to account for netgame latency)?
|
||||
INT16 rturn_max[MAXPREDICTTICS]; // Ditto but for full-right
|
||||
|
||||
|
|
|
@ -405,4 +405,6 @@ typedef UINT32 tic_t;
|
|||
#define UINT2RGBA(a) (UINT32)((a&0xff)<<24)|((a&0xff00)<<8)|((a&0xff0000)>>8)|(((UINT32)a&0xff000000)>>24)
|
||||
#endif
|
||||
|
||||
typedef UINT64 precise_t;
|
||||
|
||||
#endif //__DOOMTYPE__
|
||||
|
|
|
@ -11,12 +11,15 @@ UINT32 I_GetFreeMem(UINT32 *total)
|
|||
return 0;
|
||||
}
|
||||
|
||||
tic_t I_GetTime(void)
|
||||
{
|
||||
void I_Sleep(UINT32 ms){}
|
||||
|
||||
precise_t I_GetPreciseTime(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void I_Sleep(void){}
|
||||
UINT64 I_GetPrecisePrecision(void) {
|
||||
return 1000000;
|
||||
}
|
||||
|
||||
void I_GetEvent(void){}
|
||||
|
||||
|
|
116
src/f_finale.c
116
src/f_finale.c
|
@ -19,6 +19,7 @@
|
|||
#include "hu_stuff.h"
|
||||
#include "r_local.h"
|
||||
#include "s_sound.h"
|
||||
#include "i_time.h"
|
||||
#include "i_video.h"
|
||||
#include "v_video.h"
|
||||
#include "w_wad.h"
|
||||
|
@ -77,7 +78,6 @@ static INT32 cutscene_textcount = 0;
|
|||
static INT32 cutscene_textspeed = 0;
|
||||
static UINT8 cutscene_boostspeed = 0;
|
||||
static tic_t cutscene_lasttextwrite = 0;
|
||||
|
||||
//
|
||||
// This alters the text string cutscene_disptext.
|
||||
// Use the typical string drawing functions to display it.
|
||||
|
@ -249,9 +249,9 @@ void F_StartIntro(void)
|
|||
}
|
||||
|
||||
//
|
||||
// F_IntroDrawScene
|
||||
// F_IntroDrawer
|
||||
//
|
||||
static void F_IntroDrawScene(void)
|
||||
void F_IntroDrawer(void)
|
||||
{
|
||||
boolean highres = false;
|
||||
INT32 cx = 8, cy = 128;
|
||||
|
@ -261,16 +261,6 @@ static void F_IntroDrawScene(void)
|
|||
// DRAW A FULL PIC INSTEAD OF FLAT!
|
||||
if (intro_scenenum == 0)
|
||||
{
|
||||
if (finalecount == 8)
|
||||
S_StartSound(NULL, sfx_vroom);
|
||||
else if (finalecount == 47)
|
||||
{
|
||||
// Need to use M_Random otherwise it always uses the same sound
|
||||
INT32 rskin = M_RandomKey(numskins);
|
||||
UINT8 rtaunt = M_RandomKey(2);
|
||||
sfxenum_t rsound = skins[rskin].soundsid[SKSKBST1+rtaunt];
|
||||
S_StartSound(NULL, rsound);
|
||||
}
|
||||
background = W_CachePatchName("KARTKREW", PU_CACHE);
|
||||
highres = true;
|
||||
}
|
||||
|
@ -293,64 +283,6 @@ static void F_IntroDrawScene(void)
|
|||
V_DrawString(cx, cy, 0, cutscene_disptext);
|
||||
}
|
||||
|
||||
//
|
||||
// F_IntroDrawer
|
||||
//
|
||||
void F_IntroDrawer(void)
|
||||
{
|
||||
if (timetonext <= 0)
|
||||
{
|
||||
if (intro_scenenum == 0)
|
||||
{
|
||||
if (rendermode != render_none)
|
||||
{
|
||||
F_WipeStartScreen();
|
||||
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31);
|
||||
F_WipeEndScreen();
|
||||
F_RunWipe(99,true);
|
||||
}
|
||||
|
||||
// Stay on black for a bit. =)
|
||||
{
|
||||
tic_t quittime;
|
||||
quittime = I_GetTime() + NEWTICRATE*2; // Shortened the quit time, used to be 2 seconds
|
||||
while (quittime > I_GetTime())
|
||||
{
|
||||
I_OsPolling();
|
||||
I_UpdateNoBlit();
|
||||
#ifdef HAVE_THREADS
|
||||
I_lock_mutex(&m_menu_mutex);
|
||||
#endif
|
||||
M_Drawer(); // menu is drawn even on top of wipes
|
||||
#ifdef HAVE_THREADS
|
||||
I_unlock_mutex(m_menu_mutex);
|
||||
#endif
|
||||
I_FinishUpdate(); // Update the screen with the image Tails 06-19-2001
|
||||
}
|
||||
}
|
||||
|
||||
D_StartTitle();
|
||||
// Yes, this is a weird hack, we need to force a wipe for this because the game state has changed in the middle of where it would normally wipe
|
||||
// Need to set the wipe start and then draw the first frame of the title screen to get it working
|
||||
F_WipeStartScreen();
|
||||
F_TitleScreenDrawer();
|
||||
wipegamestate = -1; // force a wipe
|
||||
return;
|
||||
}
|
||||
|
||||
F_NewCutscene(introtext[++intro_scenenum]);
|
||||
timetonext = introscenetime[intro_scenenum];
|
||||
|
||||
F_WipeStartScreen();
|
||||
wipegamestate = -1;
|
||||
animtimer = stoptimer = 0;
|
||||
}
|
||||
|
||||
intro_curtime = introscenetime[intro_scenenum] - timetonext;
|
||||
|
||||
F_IntroDrawScene();
|
||||
}
|
||||
|
||||
//
|
||||
// F_IntroTicker
|
||||
//
|
||||
|
@ -364,6 +296,20 @@ void F_IntroTicker(void)
|
|||
|
||||
timetonext--;
|
||||
|
||||
if (intro_scenenum == 0)
|
||||
{
|
||||
if (finalecount == 8)
|
||||
S_StartSound(NULL, sfx_vroom);
|
||||
else if (finalecount == 47)
|
||||
{
|
||||
// Need to use M_Random otherwise it always uses the same sound
|
||||
INT32 rskin = M_RandomKey(numskins);
|
||||
UINT8 rtaunt = M_RandomKey(2);
|
||||
sfxenum_t rsound = skins[rskin].soundsid[SKSKBST1+rtaunt];
|
||||
S_StartSound(NULL, rsound);
|
||||
}
|
||||
}
|
||||
|
||||
F_WriteText();
|
||||
|
||||
// check for skipping
|
||||
|
@ -1318,6 +1264,22 @@ static boolean runningprecutscene = false, precutresetplayer = false;
|
|||
|
||||
static void F_AdvanceToNextScene(void)
|
||||
{
|
||||
if (rendermode != render_none)
|
||||
{
|
||||
F_WipeStartScreen();
|
||||
|
||||
// Fade to any palette color you want.
|
||||
if (cutscenes[cutnum]->scene[scenenum].fadecolor)
|
||||
{
|
||||
V_DrawFill(0,0,BASEVIDWIDTH,BASEVIDHEIGHT,cutscenes[cutnum]->scene[scenenum].fadecolor);
|
||||
|
||||
F_WipeEndScreen();
|
||||
F_RunWipe(cutscenes[cutnum]->scene[scenenum].fadeinid, true);
|
||||
|
||||
F_WipeStartScreen();
|
||||
}
|
||||
}
|
||||
|
||||
// Don't increment until after endcutscene check
|
||||
// (possible overflow / bad patch names from the one tic drawn before the fade)
|
||||
if (scenenum+1 >= cutscenes[cutnum]->numscenes)
|
||||
|
@ -1325,6 +1287,7 @@ static void F_AdvanceToNextScene(void)
|
|||
F_EndCutScene();
|
||||
return;
|
||||
}
|
||||
|
||||
++scenenum;
|
||||
|
||||
timetonext = 0;
|
||||
|
@ -1340,7 +1303,6 @@ static void F_AdvanceToNextScene(void)
|
|||
cutscenes[cutnum]->scene[scenenum].musswitchposition, 0, 0);
|
||||
|
||||
// Fade to the next
|
||||
dofadenow = true;
|
||||
F_NewCutscene(cutscenes[cutnum]->scene[scenenum].text);
|
||||
|
||||
picnum = 0;
|
||||
|
@ -1350,6 +1312,14 @@ static void F_AdvanceToNextScene(void)
|
|||
textypos = cutscenes[cutnum]->scene[scenenum].textypos;
|
||||
|
||||
animtimer = pictime = cutscenes[cutnum]->scene[scenenum].picduration[picnum];
|
||||
|
||||
if (rendermode != render_none)
|
||||
{
|
||||
F_CutsceneDrawer();
|
||||
|
||||
F_WipeEndScreen();
|
||||
F_RunWipe(cutscenes[cutnum]->scene[scenenum].fadeoutid, true);
|
||||
}
|
||||
}
|
||||
|
||||
void F_EndCutScene(void)
|
||||
|
@ -1468,8 +1438,6 @@ void F_CutsceneTicker(void)
|
|||
finalecount++;
|
||||
cutscene_boostspeed = 0;
|
||||
|
||||
dofadenow = false;
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (netgame && i != serverplayer && !IsPlayerAdmin(i))
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "w_wad.h"
|
||||
#include "z_zone.h"
|
||||
|
||||
#include "i_time.h"
|
||||
#include "i_system.h"
|
||||
#include "i_threads.h"
|
||||
#include "m_menu.h"
|
||||
|
@ -365,7 +366,10 @@ void F_RunWipe(UINT8 wipetype, boolean drawMenu)
|
|||
|
||||
// wait loop
|
||||
while (!((nowtime = I_GetTime()) - lastwipetic))
|
||||
I_Sleep();
|
||||
{
|
||||
I_Sleep(cv_sleep.value);
|
||||
I_UpdateTime(cv_timescale.value);
|
||||
}
|
||||
lastwipetic = nowtime;
|
||||
|
||||
#ifdef HWRENDER
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "filesrch.h" // for refreshdirmenu
|
||||
#include "p_setup.h"
|
||||
#include "p_saveg.h"
|
||||
#include "i_time.h"
|
||||
#include "i_system.h"
|
||||
#include "am_map.h"
|
||||
#include "m_random.h"
|
||||
|
@ -50,6 +51,7 @@
|
|||
#include "m_cond.h" // condition sets
|
||||
#include "md5.h" // demo checksums
|
||||
#include "k_kart.h" // SRB2kart
|
||||
#include "r_fps.h" // frame interpolation/uncapped
|
||||
|
||||
#ifdef HAVE_DISCORDRPC
|
||||
#include "discord.h"
|
||||
|
@ -6131,7 +6133,7 @@ void G_ReadMetalTic(mobj_t *metal)
|
|||
// Read changes from the tic
|
||||
if (ziptic & GZT_XYZ)
|
||||
{
|
||||
P_TeleportMove(metal, READFIXED(metal_p), READFIXED(metal_p), READFIXED(metal_p));
|
||||
P_MoveOrigin(metal, READFIXED(metal_p), READFIXED(metal_p), READFIXED(metal_p));
|
||||
oldmetal.x = metal->x;
|
||||
oldmetal.y = metal->y;
|
||||
oldmetal.z = metal->z;
|
||||
|
|
|
@ -46,7 +46,7 @@ EXPORT void HWRAPI(ClearMipMapCache) (void);
|
|||
EXPORT void HWRAPI(SetSpecialState) (hwdspecialstate_t IdState, INT32 Value);
|
||||
|
||||
//Hurdler: added for new development
|
||||
EXPORT void HWRAPI(DrawModel) (model_t *model, INT32 frameIndex, INT32 duration, INT32 tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, FSurfaceInfo *Surface);
|
||||
EXPORT void HWRAPI(DrawModel) (model_t *model, INT32 frameIndex, float duration, float tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, FSurfaceInfo *Surface);
|
||||
EXPORT void HWRAPI(CreateModelVBOs) (model_t *model);
|
||||
EXPORT void HWRAPI(SetTransform) (FTransform *stransform);
|
||||
EXPORT INT32 HWRAPI(GetTextureUsed) (void);
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "../v_video.h"
|
||||
#include "../p_local.h"
|
||||
#include "../p_setup.h"
|
||||
#include "../r_fps.h"
|
||||
#include "../r_local.h"
|
||||
#include "../r_bsp.h" // R_NoEncore
|
||||
#include "../r_main.h" // cv_fov
|
||||
|
@ -2389,6 +2390,7 @@ void HWR_Subsector(size_t num)
|
|||
INT32 light = 0;
|
||||
extracolormap_t *floorcolormap;
|
||||
extracolormap_t *ceilingcolormap;
|
||||
ffloor_t *rover;
|
||||
|
||||
#ifdef PARANOIA //no risk while developing, enough debugging nights!
|
||||
if (num >= addsubsector)
|
||||
|
@ -2525,7 +2527,6 @@ void HWR_Subsector(size_t num)
|
|||
if (gr_frontsector->ffloors)
|
||||
{
|
||||
/// \todo fix light, xoffs, yoffs, extracolormap ?
|
||||
ffloor_t * rover;
|
||||
for (rover = gr_frontsector->ffloors;
|
||||
rover; rover = rover->next)
|
||||
{
|
||||
|
@ -4139,14 +4140,26 @@ void HWR_ProjectSprite(mobj_t *thing)
|
|||
const boolean papersprite = (thing->frame & FF_PAPERSPRITE);
|
||||
INT32 heightsec, phs;
|
||||
|
||||
// uncapped/interpolation
|
||||
interpmobjstate_t interp = {0};
|
||||
|
||||
if (!thing)
|
||||
return;
|
||||
|
||||
if (R_UsingFrameInterpolation() && !paused)
|
||||
{
|
||||
R_InterpolateMobjState(thing, rendertimefrac, &interp);
|
||||
}
|
||||
else
|
||||
this_scale = FIXED_TO_FLOAT(thing->scale);
|
||||
{
|
||||
R_InterpolateMobjState(thing, FRACUNIT, &interp);
|
||||
}
|
||||
|
||||
this_scale = FIXED_TO_FLOAT(interp.scale);
|
||||
|
||||
// transform the origin point
|
||||
tr_x = FIXED_TO_FLOAT(thing->x) - gr_viewx;
|
||||
tr_y = FIXED_TO_FLOAT(thing->y) - gr_viewy;
|
||||
tr_x = FIXED_TO_FLOAT(interp.x) - gr_viewx;
|
||||
tr_y = FIXED_TO_FLOAT(interp.y) - gr_viewy;
|
||||
|
||||
// rotation around vertical axis
|
||||
tz = (tr_x * gr_viewcos) + (tr_y * gr_viewsin);
|
||||
|
@ -4156,8 +4169,8 @@ void HWR_ProjectSprite(mobj_t *thing)
|
|||
return;
|
||||
|
||||
// The above can stay as it works for cutting sprites that are too close
|
||||
tr_x = FIXED_TO_FLOAT(thing->x);
|
||||
tr_y = FIXED_TO_FLOAT(thing->y);
|
||||
tr_x = FIXED_TO_FLOAT(interp.x);
|
||||
tr_y = FIXED_TO_FLOAT(interp.y);
|
||||
|
||||
// decide which patch to use for sprite relative to player
|
||||
#ifdef RANGECHECK
|
||||
|
@ -4192,10 +4205,7 @@ void HWR_ProjectSprite(mobj_t *thing)
|
|||
I_Error("sprframes NULL for sprite %d\n", thing->sprite);
|
||||
#endif
|
||||
|
||||
if (thing->player)
|
||||
ang = R_PointToAngle (thing->x, thing->y) - thing->player->frameangle;
|
||||
else
|
||||
ang = R_PointToAngle (thing->x, thing->y) - thing->angle;
|
||||
ang = R_PointToAngle (interp.x, interp.y) - interp.angle;
|
||||
|
||||
if (sprframe->rotate == SRF_SINGLE)
|
||||
{
|
||||
|
@ -4240,8 +4250,8 @@ void HWR_ProjectSprite(mobj_t *thing)
|
|||
|
||||
if (papersprite)
|
||||
{
|
||||
rightsin = FIXED_TO_FLOAT(FINESINE((thing->angle)>>ANGLETOFINESHIFT));
|
||||
rightcos = FIXED_TO_FLOAT(FINECOSINE((thing->angle)>>ANGLETOFINESHIFT));
|
||||
rightsin = FIXED_TO_FLOAT(FINESINE(interp.angle >> ANGLETOFINESHIFT));
|
||||
rightcos = FIXED_TO_FLOAT(FINECOSINE(interp.angle >> ANGLETOFINESHIFT));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -4268,12 +4278,12 @@ void HWR_ProjectSprite(mobj_t *thing)
|
|||
|
||||
if (thing->eflags & MFE_VERTICALFLIP)
|
||||
{
|
||||
gz = FIXED_TO_FLOAT(thing->z+thing->height) - FIXED_TO_FLOAT(spritecachedinfo[lumpoff].topoffset) * this_scale;
|
||||
gz = FIXED_TO_FLOAT(interp.z + thing->height) - FIXED_TO_FLOAT(spritecachedinfo[lumpoff].topoffset) * this_scale;
|
||||
gzt = gz + FIXED_TO_FLOAT(spritecachedinfo[lumpoff].height) * this_scale;
|
||||
}
|
||||
else
|
||||
{
|
||||
gzt = FIXED_TO_FLOAT(thing->z) + FIXED_TO_FLOAT(spritecachedinfo[lumpoff].topoffset) * this_scale;
|
||||
gzt = FIXED_TO_FLOAT(interp.z) + FIXED_TO_FLOAT(spritecachedinfo[lumpoff].topoffset) * this_scale;
|
||||
gz = gzt - FIXED_TO_FLOAT(spritecachedinfo[lumpoff].height) * this_scale;
|
||||
}
|
||||
|
||||
|
@ -4292,12 +4302,12 @@ void HWR_ProjectSprite(mobj_t *thing)
|
|||
if (heightsec != -1 && phs != -1) // only clip things which are in special sectors
|
||||
{
|
||||
if (gr_viewz < FIXED_TO_FLOAT(sectors[phs].floorheight) ?
|
||||
FIXED_TO_FLOAT(thing->z) >= FIXED_TO_FLOAT(sectors[heightsec].floorheight) :
|
||||
FIXED_TO_FLOAT(interp.z) >= FIXED_TO_FLOAT(sectors[heightsec].floorheight) :
|
||||
gzt < FIXED_TO_FLOAT(sectors[heightsec].floorheight))
|
||||
return;
|
||||
if (gr_viewz > FIXED_TO_FLOAT(sectors[phs].ceilingheight) ?
|
||||
gzt < FIXED_TO_FLOAT(sectors[heightsec].ceilingheight) && gr_viewz >= FIXED_TO_FLOAT(sectors[heightsec].ceilingheight) :
|
||||
FIXED_TO_FLOAT(thing->z) >= FIXED_TO_FLOAT(sectors[heightsec].ceilingheight))
|
||||
FIXED_TO_FLOAT(interp.z) >= FIXED_TO_FLOAT(sectors[heightsec].ceilingheight))
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -4375,9 +4385,25 @@ void HWR_ProjectPrecipitationSprite(precipmobj_t *thing)
|
|||
unsigned rot = 0;
|
||||
UINT8 flip;
|
||||
|
||||
// uncapped/interpolation
|
||||
interpmobjstate_t interp = {0};
|
||||
|
||||
if (!thing)
|
||||
return;
|
||||
|
||||
// do interpolation
|
||||
if (R_UsingFrameInterpolation() && !paused)
|
||||
{
|
||||
R_InterpolatePrecipMobjState(thing, rendertimefrac, &interp);
|
||||
}
|
||||
else
|
||||
{
|
||||
R_InterpolatePrecipMobjState(thing, FRACUNIT, &interp);
|
||||
}
|
||||
|
||||
// transform the origin point
|
||||
tr_x = FIXED_TO_FLOAT(thing->x) - gr_viewx;
|
||||
tr_y = FIXED_TO_FLOAT(thing->y) - gr_viewy;
|
||||
tr_x = FIXED_TO_FLOAT(interp.x) - gr_viewx;
|
||||
tr_y = FIXED_TO_FLOAT(interp.y) - gr_viewy;
|
||||
|
||||
// rotation around vertical axis
|
||||
tz = (tr_x * gr_viewcos) + (tr_y * gr_viewsin);
|
||||
|
@ -4386,8 +4412,8 @@ void HWR_ProjectPrecipitationSprite(precipmobj_t *thing)
|
|||
if (tz < ZCLIP_PLANE)
|
||||
return;
|
||||
|
||||
tr_x = FIXED_TO_FLOAT(thing->x);
|
||||
tr_y = FIXED_TO_FLOAT(thing->y);
|
||||
tr_x = FIXED_TO_FLOAT(interp.x);
|
||||
tr_y = FIXED_TO_FLOAT(interp.y);
|
||||
|
||||
// decide which patch to use for sprite relative to player
|
||||
if ((unsigned)thing->sprite >= numsprites)
|
||||
|
@ -4912,7 +4938,8 @@ void HWR_DoPostProcessor(player_t *player)
|
|||
{
|
||||
// 10 by 10 grid. 2 coordinates (xy)
|
||||
float v[SCREENVERTS][SCREENVERTS][2];
|
||||
double disStart = leveltime;
|
||||
static double disStart = 0;
|
||||
|
||||
UINT8 x, y;
|
||||
INT32 WAVELENGTH;
|
||||
INT32 AMPLITUDE;
|
||||
|
@ -4921,15 +4948,15 @@ void HWR_DoPostProcessor(player_t *player)
|
|||
// Modifies the wave.
|
||||
if (*type == postimg_water)
|
||||
{
|
||||
WAVELENGTH = 20; // Lower is longer
|
||||
AMPLITUDE = 20; // Lower is bigger
|
||||
FREQUENCY = 16; // Lower is faster
|
||||
WAVELENGTH = 5;
|
||||
AMPLITUDE = 20;
|
||||
FREQUENCY = 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
WAVELENGTH = 10; // Lower is longer
|
||||
AMPLITUDE = 30; // Lower is bigger
|
||||
FREQUENCY = 4; // Lower is faster
|
||||
WAVELENGTH = 10;
|
||||
AMPLITUDE = 60;
|
||||
FREQUENCY = 4;
|
||||
}
|
||||
|
||||
for (x = 0; x < SCREENVERTS; x++)
|
||||
|
@ -4942,6 +4969,8 @@ void HWR_DoPostProcessor(player_t *player)
|
|||
}
|
||||
}
|
||||
HWD.pfnPostImgRedraw(v);
|
||||
if (!(paused || P_AutoPause()))
|
||||
disStart += FIXED_TO_FLOAT(renderdeltatics);
|
||||
|
||||
// Capture the screen again for screen waving on the intermission
|
||||
if(gamestate != GS_INTERMISSION)
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "hw_md2.h"
|
||||
#include "../d_main.h"
|
||||
#include "../r_bsp.h"
|
||||
#include "../r_fps.h"
|
||||
#include "../r_main.h"
|
||||
#include "../m_misc.h"
|
||||
#include "../w_wad.h"
|
||||
|
@ -1128,6 +1129,16 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
|
|||
spritedef_t *sprdef;
|
||||
spriteframe_t *sprframe;
|
||||
float finalscale;
|
||||
interpmobjstate_t interp;
|
||||
|
||||
if (R_UsingFrameInterpolation() && !paused)
|
||||
{
|
||||
R_InterpolateMobjState(spr->mobj, rendertimefrac, &interp);
|
||||
}
|
||||
else
|
||||
{
|
||||
R_InterpolateMobjState(spr->mobj, FRACUNIT, &interp);
|
||||
}
|
||||
|
||||
// Apparently people don't like jump frames like that, so back it goes
|
||||
//if (tics > durs)
|
||||
|
@ -1233,14 +1244,17 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
|
|||
if (spr->mobj->frame & FF_ANIMATE)
|
||||
{
|
||||
// set duration and tics to be the correct values for FF_ANIMATE states
|
||||
durs = spr->mobj->state->var2;
|
||||
tics = spr->mobj->anim_duration;
|
||||
durs = (float)spr->mobj->state->var2;
|
||||
tics = (float)spr->mobj->anim_duration;
|
||||
}
|
||||
|
||||
//FIXME: this is not yet correct
|
||||
frame = (spr->mobj->frame & FF_FRAMEMASK) % md2->model->meshes[0].numFrames;
|
||||
|
||||
#ifdef USE_MODEL_NEXTFRAME
|
||||
// Interpolate the model interpolation. (lol)
|
||||
tics -= FixedToFloat(rendertimefrac);
|
||||
|
||||
if (cv_grmdls.value == 1 && tics <= durs)
|
||||
{
|
||||
// frames are handled differently for states with FF_ANIMATE, so get the next frame differently for the interpolation
|
||||
|
@ -1265,13 +1279,13 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
|
|||
#endif
|
||||
|
||||
//Hurdler: it seems there is still a small problem with mobj angle
|
||||
p.x = FIXED_TO_FLOAT(spr->mobj->x);
|
||||
p.y = FIXED_TO_FLOAT(spr->mobj->y)+md2->offset;
|
||||
p.x = FIXED_TO_FLOAT(interp.x);
|
||||
p.y = FIXED_TO_FLOAT(interp.y)+md2->offset;
|
||||
|
||||
if (spr->mobj->eflags & MFE_VERTICALFLIP)
|
||||
p.z = FIXED_TO_FLOAT(spr->mobj->z + spr->mobj->height);
|
||||
p.z = FIXED_TO_FLOAT(interp.z + spr->mobj->height);
|
||||
else
|
||||
p.z = FIXED_TO_FLOAT(spr->mobj->z);
|
||||
p.z = FIXED_TO_FLOAT(interp.z);
|
||||
|
||||
if (spr->mobj->skin && spr->mobj->sprite == SPR_PLAY)
|
||||
sprdef = &((skin_t *)spr->mobj->skin)->spritedef;
|
||||
|
@ -1282,16 +1296,13 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
|
|||
|
||||
if (sprframe->rotate)
|
||||
{
|
||||
fixed_t anglef;
|
||||
if (spr->mobj->player)
|
||||
anglef = AngleFixed(spr->mobj->player->frameangle);
|
||||
else
|
||||
anglef = AngleFixed(spr->mobj->angle);
|
||||
fixed_t anglef = AngleFixed(interp.angle);
|
||||
|
||||
p.angley = FIXED_TO_FLOAT(anglef);
|
||||
}
|
||||
else
|
||||
{
|
||||
const fixed_t anglef = AngleFixed((R_PointToAngle(spr->mobj->x, spr->mobj->y))-ANGLE_180);
|
||||
const fixed_t anglef = AngleFixed((R_PointToAngle(interp.x, interp.y))-ANGLE_180);
|
||||
p.angley = FIXED_TO_FLOAT(anglef);
|
||||
}
|
||||
p.anglex = 0.0f;
|
||||
|
@ -1311,7 +1322,7 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
|
|||
#endif
|
||||
|
||||
// SRB2CBTODO: MD2 scaling support
|
||||
finalscale *= FIXED_TO_FLOAT(spr->mobj->scale);
|
||||
finalscale *= FIXED_TO_FLOAT(interp.scale);
|
||||
|
||||
p.flip = atransform.flip;
|
||||
#ifdef USE_FTRANSFORM_MIRROR
|
||||
|
|
|
@ -2865,7 +2865,7 @@ EXPORT void HWRAPI(CreateModelVBOs) (model_t *model)
|
|||
|
||||
#define BUFFER_OFFSET(i) ((char*)(i))
|
||||
|
||||
static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, FSurfaceInfo *Surface)
|
||||
static void DrawModelEx(model_t *model, INT32 frameIndex, float duration, float tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, FSurfaceInfo *Surface)
|
||||
{
|
||||
static GLRGBAFloat poly = {0,0,0,0};
|
||||
static GLRGBAFloat tint = {0,0,0,0};
|
||||
|
@ -2884,11 +2884,11 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32
|
|||
scaley = scale;
|
||||
scalez = scale;
|
||||
|
||||
if (duration != 0 && duration != -1 && tics != -1) // don't interpolate if instantaneous or infinite in length
|
||||
if (duration > 0.0 && tics >= 0.0) // don't interpolate if instantaneous or infinite in length
|
||||
{
|
||||
UINT32 newtime = (duration - tics); // + 1;
|
||||
float newtime = (duration - tics); // + 1;
|
||||
|
||||
pol = (newtime)/(float)duration;
|
||||
pol = newtime / duration;
|
||||
|
||||
if (pol > 1.0f)
|
||||
pol = 1.0f;
|
||||
|
@ -3063,7 +3063,7 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32
|
|||
// -----------------+
|
||||
// HWRAPI DrawModel : Draw a model
|
||||
// -----------------+
|
||||
EXPORT void HWRAPI(DrawModel) (model_t *model, INT32 frameIndex, INT32 duration, INT32 tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, FSurfaceInfo *Surface)
|
||||
EXPORT void HWRAPI(DrawModel) (model_t *model, INT32 frameIndex, float duration, float tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, FSurfaceInfo *Surface)
|
||||
{
|
||||
DrawModelEx(model, frameIndex, duration, tics, nextFrameIndex, pos, scale, flipped, Surface);
|
||||
}
|
||||
|
|
137
src/hu_stuff.c
137
src/hu_stuff.c
|
@ -48,6 +48,7 @@
|
|||
|
||||
#ifdef HAVE_BLUA
|
||||
#include "lua_hud.h"
|
||||
#include "lua_hudlib_drawlist.h"
|
||||
#include "lua_hook.h"
|
||||
#endif
|
||||
|
||||
|
@ -90,6 +91,10 @@ static boolean headsupactive = false;
|
|||
boolean hu_showscores; // draw rankings
|
||||
static char hu_tick;
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
static huddrawlist_h luahuddrawlist_scores;
|
||||
#endif
|
||||
|
||||
patch_t *rflagico;
|
||||
patch_t *bflagico;
|
||||
patch_t *rmatcico;
|
||||
|
@ -176,6 +181,8 @@ static INT32 cechoflags = 0;
|
|||
// HEADS UP INIT
|
||||
//======================================================================
|
||||
|
||||
static tic_t resynch_ticker = 0;
|
||||
|
||||
#ifndef NONET
|
||||
// just after
|
||||
static void Command_Say_f(void);
|
||||
|
@ -334,6 +341,10 @@ void HU_Init(void)
|
|||
// set shift translation table
|
||||
shiftxform = english_shiftxform;
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
luahuddrawlist_scores = LUA_HUD_CreateDrawList();
|
||||
#endif
|
||||
|
||||
HU_LoadGraphics();
|
||||
}
|
||||
|
||||
|
@ -385,12 +396,12 @@ static INT16 addy = 0; // use this to make the messages scroll smoothly when one
|
|||
|
||||
static void HU_removeChatText_Mini(void)
|
||||
{
|
||||
// MPC: Don't create new arrays, just iterate through an existing one
|
||||
// MPC: Don't create new arrays, just iterate through an existing one
|
||||
size_t i;
|
||||
for(i=0;i<chat_nummsg_min-1;i++) {
|
||||
strcpy(chat_mini[i], chat_mini[i+1]);
|
||||
chat_timers[i] = chat_timers[i+1];
|
||||
}
|
||||
for(i=0;i<chat_nummsg_min-1;i++) {
|
||||
strcpy(chat_mini[i], chat_mini[i+1]);
|
||||
chat_timers[i] = chat_timers[i+1];
|
||||
}
|
||||
chat_nummsg_min--; // lost 1 msg.
|
||||
|
||||
// use addy and make shit slide smoothly af.
|
||||
|
@ -403,10 +414,10 @@ static void HU_removeChatText_Log(void)
|
|||
{
|
||||
// MPC: Don't create new arrays, just iterate through an existing one
|
||||
size_t i;
|
||||
for(i=0;i<chat_nummsg_log-1;i++) {
|
||||
strcpy(chat_log[i], chat_log[i+1]);
|
||||
}
|
||||
chat_nummsg_log--; // lost 1 msg.
|
||||
for(i=0;i<chat_nummsg_log-1;i++) {
|
||||
strcpy(chat_log[i], chat_log[i+1]);
|
||||
}
|
||||
chat_nummsg_log--; // lost 1 msg.
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -1071,6 +1082,38 @@ void HU_Ticker(void)
|
|||
hu_showscores = !chat_on;
|
||||
else
|
||||
hu_showscores = false;
|
||||
|
||||
if (chat_on)
|
||||
{
|
||||
// count down the scroll timer.
|
||||
if (chat_scrolltime > 0)
|
||||
chat_scrolltime--;
|
||||
}
|
||||
|
||||
if (netgame) // would handle that in hu_drawminichat, but it's actually kinda awkward when you're typing a lot of messages. (only handle that in netgames duh)
|
||||
{
|
||||
size_t i = 0;
|
||||
|
||||
// handle spam while we're at it:
|
||||
for(; (i<MAXPLAYERS); i++)
|
||||
{
|
||||
if (stop_spamming[i] > 0)
|
||||
stop_spamming[i]--;
|
||||
}
|
||||
|
||||
// handle chat timers
|
||||
for (i=0; (i<chat_nummsg_min); i++)
|
||||
{
|
||||
if (chat_timers[i] > 0)
|
||||
chat_timers[i]--;
|
||||
else
|
||||
HU_removeChatText_Mini();
|
||||
}
|
||||
}
|
||||
|
||||
if (cechotimer > 0) --cechotimer;
|
||||
|
||||
HU_TickSongCredits();
|
||||
}
|
||||
|
||||
#ifndef NONET
|
||||
|
@ -2204,8 +2247,6 @@ static void HU_DrawCEcho(void)
|
|||
echoptr = line;
|
||||
echoptr++;
|
||||
}
|
||||
|
||||
--cechotimer;
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -2252,10 +2293,27 @@ static void HU_DrawDemoInfo(void)
|
|||
//
|
||||
// Song credits
|
||||
//
|
||||
void HU_TickSongCredits(void)
|
||||
{
|
||||
if (cursongcredit.anim)
|
||||
{
|
||||
if (cursongcredit.trans > 0)
|
||||
cursongcredit.trans--;
|
||||
|
||||
cursongcredit.anim--;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cursongcredit.trans < NUMTRANSMAPS)
|
||||
cursongcredit.trans++;
|
||||
}
|
||||
}
|
||||
|
||||
void HU_DrawSongCredits(void)
|
||||
{
|
||||
char *str;
|
||||
INT32 len, destx;
|
||||
INT32 len;
|
||||
fixed_t destx;
|
||||
INT32 y = (splitscreen ? (BASEVIDHEIGHT/2)-4 : 32);
|
||||
INT32 bgt;
|
||||
|
||||
|
@ -2264,33 +2322,31 @@ void HU_DrawSongCredits(void)
|
|||
|
||||
str = va("\x1F"" %s", cursongcredit.def->source);
|
||||
len = V_ThinStringWidth(str, V_ALLOWLOWERCASE|V_6WIDTHSPACE);
|
||||
destx = (len+7);
|
||||
destx = (len + 7) * FRACUNIT;
|
||||
|
||||
if (cursongcredit.anim)
|
||||
{
|
||||
if (cursongcredit.trans > 0)
|
||||
cursongcredit.trans--;
|
||||
if (cursongcredit.x < destx)
|
||||
cursongcredit.x += (destx - cursongcredit.x) / 2;
|
||||
cursongcredit.x += FixedMul((destx - cursongcredit.x) / 2, renderdeltatics);
|
||||
if (cursongcredit.x > destx)
|
||||
cursongcredit.x = destx;
|
||||
cursongcredit.anim--;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cursongcredit.trans < NUMTRANSMAPS)
|
||||
cursongcredit.trans++;
|
||||
if (cursongcredit.x > 0)
|
||||
cursongcredit.x /= 2;
|
||||
cursongcredit.x -= FixedMul(cursongcredit.x / 2, renderdeltatics);
|
||||
if (cursongcredit.x < 0)
|
||||
cursongcredit.x = 0;
|
||||
}
|
||||
|
||||
bgt = (NUMTRANSMAPS/2)+(cursongcredit.trans/2);
|
||||
bgt = (NUMTRANSMAPS/2) + (cursongcredit.trans/2);
|
||||
|
||||
// v1 does not have v2's font revamp, so there is no function for thin string at fixed_t
|
||||
// sooo I'm just killing the precision.
|
||||
if (bgt < NUMTRANSMAPS)
|
||||
V_DrawScaledPatch(cursongcredit.x, y-2, V_SNAPTOLEFT|(bgt<<V_ALPHASHIFT), songcreditbg);
|
||||
V_DrawScaledPatch(cursongcredit.x / FRACUNIT, y-2, V_SNAPTOLEFT|(bgt<<V_ALPHASHIFT), songcreditbg);
|
||||
if (cursongcredit.trans < NUMTRANSMAPS)
|
||||
V_DrawRightAlignedThinString(cursongcredit.x, y, V_ALLOWLOWERCASE|V_6WIDTHSPACE|V_SNAPTOLEFT|(cursongcredit.trans<<V_ALPHASHIFT), str);
|
||||
V_DrawRightAlignedThinString(cursongcredit.x / FRACUNIT, y, V_ALLOWLOWERCASE|V_6WIDTHSPACE|V_SNAPTOLEFT|(cursongcredit.trans<<V_ALPHASHIFT), str);
|
||||
}
|
||||
|
||||
|
||||
|
@ -2305,9 +2361,6 @@ void HU_Drawer(void)
|
|||
// draw chat string plus cursor
|
||||
if (chat_on)
|
||||
{
|
||||
// count down the scroll timer.
|
||||
if (chat_scrolltime > 0)
|
||||
chat_scrolltime--;
|
||||
if (!OLDCHAT)
|
||||
HU_DrawChat();
|
||||
else
|
||||
|
@ -2317,30 +2370,10 @@ void HU_Drawer(void)
|
|||
{
|
||||
typelines = 1;
|
||||
chat_scrolltime = 0;
|
||||
|
||||
if (!OLDCHAT && cv_consolechat.value < 2 && netgame) // Don't display minimized chat if you set the mode to Window (Hidden)
|
||||
HU_drawMiniChat(); // draw messages in a cool fashion.
|
||||
}
|
||||
|
||||
if (netgame) // would handle that in hu_drawminichat, but it's actually kinda awkward when you're typing a lot of messages. (only handle that in netgames duh)
|
||||
{
|
||||
size_t i = 0;
|
||||
|
||||
// handle spam while we're at it:
|
||||
for(; (i<MAXPLAYERS); i++)
|
||||
{
|
||||
if (stop_spamming[i] > 0)
|
||||
stop_spamming[i]--;
|
||||
}
|
||||
|
||||
// handle chat timers
|
||||
for (i=0; (i<chat_nummsg_min); i++)
|
||||
{
|
||||
if (chat_timers[i] > 0)
|
||||
chat_timers[i]--;
|
||||
else
|
||||
HU_removeChatText_Mini();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (cechotimer)
|
||||
|
@ -2363,7 +2396,12 @@ void HU_Drawer(void)
|
|||
#endif
|
||||
HU_DrawRankings();
|
||||
#ifdef HAVE_BLUA
|
||||
LUAh_ScoresHUD();
|
||||
if (renderisnewtic)
|
||||
{
|
||||
LUA_HUD_ClearDrawList(luahuddrawlist_scores);
|
||||
LUAh_ScoresHUD(luahuddrawlist_scores);
|
||||
}
|
||||
LUA_HUD_DrawList(luahuddrawlist_scores);
|
||||
#endif
|
||||
}
|
||||
if (demo.playback)
|
||||
|
@ -2398,12 +2436,9 @@ void HU_Drawer(void)
|
|||
// draw desynch text
|
||||
if (hu_resynching)
|
||||
{
|
||||
static UINT32 resynch_ticker = 0;
|
||||
char resynch_text[14];
|
||||
UINT32 i;
|
||||
|
||||
// Animate the dots
|
||||
resynch_ticker++;
|
||||
strcpy(resynch_text, "Resynching");
|
||||
for (i = 0; i < (resynch_ticker / 16) % 4; i++)
|
||||
strcat(resynch_text, ".");
|
||||
|
|
|
@ -109,6 +109,7 @@ void HU_Start(void);
|
|||
|
||||
boolean HU_Responder(event_t *ev);
|
||||
void HU_Ticker(void);
|
||||
void HU_TickSongCredits(void);
|
||||
void HU_DrawSongCredits(void);
|
||||
void HU_Drawer(void);
|
||||
char HU_dequeueChatChar(void);
|
||||
|
|
|
@ -42,15 +42,32 @@ extern UINT8 keyboard_started;
|
|||
*/
|
||||
UINT32 I_GetFreeMem(UINT32 *total);
|
||||
|
||||
/** \brief Called by D_SRB2Loop, returns current time in tics.
|
||||
*/
|
||||
tic_t I_GetTime(void);
|
||||
/** \brief Returns precise time value for performance measurement. The precise
|
||||
time should be a monotonically increasing counter, and will wrap.
|
||||
precise_t is internally represented as an unsigned integer and
|
||||
integer arithmetic may be used directly between values of precise_t.
|
||||
*/
|
||||
precise_t I_GetPreciseTime(void);
|
||||
|
||||
/** \brief The I_Sleep function
|
||||
/** \brief Get the precision of precise_t in units per second. Invocations of
|
||||
this function for the program's duration MUST return the same value.
|
||||
*/
|
||||
UINT64 I_GetPrecisePrecision(void);
|
||||
|
||||
/** \brief Get the current time in rendering tics, including fractions.
|
||||
*/
|
||||
double I_GetFrameTime(void);
|
||||
|
||||
/** \brief Sleeps for the given duration in milliseconds. Depending on the
|
||||
operating system's scheduler, the calling thread may give up its
|
||||
time slice for a longer duration. The implementation should give a
|
||||
best effort to sleep for the given duration, without spin-locking.
|
||||
Calling code should check the current precise time after sleeping
|
||||
and not assume the thread has slept for the expected duration.
|
||||
|
||||
\return void
|
||||
*/
|
||||
void I_Sleep(void);
|
||||
void I_Sleep(UINT32 ms);
|
||||
|
||||
/** \brief Get events
|
||||
|
||||
|
|
123
src/i_time.c
Normal file
123
src/i_time.c
Normal file
|
@ -0,0 +1,123 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2022 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file i_time.c
|
||||
/// \brief Timing for the system layer.
|
||||
|
||||
#include "i_time.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "command.h"
|
||||
#include "doomtype.h"
|
||||
#include "d_netcmd.h"
|
||||
#include "m_fixed.h"
|
||||
#include "i_system.h"
|
||||
|
||||
timestate_t g_time;
|
||||
|
||||
static CV_PossibleValue_t timescale_cons_t[] = {{FRACUNIT/20, "MIN"}, {20*FRACUNIT, "MAX"}, {0, NULL}};
|
||||
consvar_t cv_timescale = {"timescale", "1.0", CV_NETVAR|CV_CHEAT|CV_FLOAT, timescale_cons_t, NULL, FRACUNIT, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
static precise_t enterprecise, oldenterprecise;
|
||||
static fixed_t entertic, oldentertics;
|
||||
static double tictimer;
|
||||
|
||||
// A little more than the minimum sleep duration on Windows.
|
||||
// May be incorrect for other platforms, but we don't currently have a way to
|
||||
// query the scheduler granularity. SDL will do what's needed to make this as
|
||||
// low as possible though.
|
||||
#define MIN_SLEEP_DURATION_MS 2.1
|
||||
|
||||
tic_t I_GetTime(void)
|
||||
{
|
||||
return g_time.time;
|
||||
}
|
||||
|
||||
void I_InitializeTime(void)
|
||||
{
|
||||
g_time.time = 0;
|
||||
g_time.timefrac = 0;
|
||||
|
||||
enterprecise = 0;
|
||||
oldenterprecise = 0;
|
||||
tictimer = 0.0;
|
||||
|
||||
CV_RegisterVar(&cv_timescale);
|
||||
|
||||
// I_StartupTimer is preserved for potential subsystems that need to setup
|
||||
// timing information for I_GetPreciseTime and sleeping
|
||||
I_StartupTimer();
|
||||
}
|
||||
|
||||
void I_UpdateTime(fixed_t timescale)
|
||||
{
|
||||
double ticratescaled;
|
||||
double elapsedseconds;
|
||||
tic_t realtics;
|
||||
|
||||
// get real tics
|
||||
ticratescaled = (double)TICRATE * FIXED_TO_FLOAT(timescale);
|
||||
|
||||
enterprecise = I_GetPreciseTime();
|
||||
elapsedseconds = (double)(enterprecise - oldenterprecise) / I_GetPrecisePrecision();
|
||||
tictimer += elapsedseconds;
|
||||
while (tictimer > 1.0/ticratescaled)
|
||||
{
|
||||
entertic += 1;
|
||||
tictimer -= 1.0/ticratescaled;
|
||||
}
|
||||
realtics = entertic - oldentertics;
|
||||
oldentertics = entertic;
|
||||
oldenterprecise = enterprecise;
|
||||
|
||||
// Update global time state
|
||||
g_time.time += realtics;
|
||||
{
|
||||
double fractional, integral;
|
||||
fractional = modf(tictimer * ticratescaled, &integral);
|
||||
g_time.timefrac = FLOAT_TO_FIXED(fractional);
|
||||
}
|
||||
}
|
||||
|
||||
void I_SleepDuration(precise_t duration)
|
||||
{
|
||||
UINT64 precision = I_GetPrecisePrecision();
|
||||
INT32 sleepvalue = cv_sleep.value;
|
||||
UINT64 delaygranularity;
|
||||
precise_t cur;
|
||||
precise_t dest;
|
||||
|
||||
{
|
||||
double gran = round(((double)(precision / 1000) * sleepvalue * MIN_SLEEP_DURATION_MS));
|
||||
delaygranularity = (UINT64)gran;
|
||||
}
|
||||
|
||||
cur = I_GetPreciseTime();
|
||||
dest = cur + duration;
|
||||
|
||||
// the reason this is not dest > cur is because the precise counter may wrap
|
||||
// two's complement arithmetic is our friend here, though!
|
||||
// e.g. cur 0xFFFFFFFFFFFFFFFE = -2, dest 0x0000000000000001 = 1
|
||||
// 0x0000000000000001 - 0xFFFFFFFFFFFFFFFE = 3
|
||||
while ((INT64)(dest - cur) > 0)
|
||||
{
|
||||
// If our cv_sleep value exceeds the remaining sleep duration, use the
|
||||
// hard sleep function.
|
||||
if (sleepvalue > 0 && (dest - cur) > delaygranularity)
|
||||
{
|
||||
I_Sleep(sleepvalue);
|
||||
}
|
||||
|
||||
// Otherwise, this is a spinloop.
|
||||
|
||||
cur = I_GetPreciseTime();
|
||||
}
|
||||
}
|
54
src/i_time.h
Normal file
54
src/i_time.h
Normal file
|
@ -0,0 +1,54 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2022 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file i_time.h
|
||||
/// \brief Timing for the system layer.
|
||||
|
||||
#ifndef __I_TIME_H__
|
||||
#define __I_TIME_H__
|
||||
|
||||
#include "command.h"
|
||||
#include "doomtype.h"
|
||||
#include "m_fixed.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct timestate_s {
|
||||
tic_t time;
|
||||
fixed_t timefrac;
|
||||
} timestate_t;
|
||||
|
||||
extern timestate_t g_time;
|
||||
extern consvar_t cv_timescale;
|
||||
|
||||
/** \brief Called by D_SRB2Loop, returns current time in game tics.
|
||||
*/
|
||||
tic_t I_GetTime(void);
|
||||
|
||||
/** \brief Initializes timing system.
|
||||
*/
|
||||
void I_InitializeTime(void);
|
||||
|
||||
void I_UpdateTime(fixed_t timescale);
|
||||
|
||||
/** \brief Block for at minimum the duration specified. This function makes a
|
||||
best effort not to oversleep, and will spinloop if sleeping would
|
||||
take too long. However, callers should still check the current time
|
||||
after this returns.
|
||||
*/
|
||||
void I_SleepDuration(precise_t duration);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // __I_TIME_H__
|
|
@ -135,4 +135,6 @@ void I_BeginRead(void);
|
|||
*/
|
||||
void I_EndRead(void);
|
||||
|
||||
UINT32 I_GetRefreshRate(void);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -182,10 +182,10 @@ state_t states[NUMSTATES] =
|
|||
|
||||
// 1-Up Box Sprites (uses player sprite)
|
||||
// Kart: hide for now, fix for R2
|
||||
{SPR_NULL, 0, 2, {NULL}, 0, 16, S_PLAY_BOX2}, // S_PLAY_BOX1
|
||||
{SPR_NULL, 0, 1, {NULL}, 0, 0, S_PLAY_BOX1}, // S_PLAY_BOX2
|
||||
{SPR_NULL, 0, 2, {NULL}, 0, 18, S_PLAY_BOX2}, // S_PLAY_BOX1
|
||||
{SPR_NULL, 0, 1, {NULL}, 0, 18, S_PLAY_BOX1}, // S_PLAY_BOX2
|
||||
{SPR_NULL, 0, 4, {NULL}, 0, 4, S_PLAY_ICON2}, // S_PLAY_ICON1
|
||||
{SPR_NULL, 0, 12, {NULL}, 0, 0, S_PLAY_ICON3}, // S_PLAY_ICON2
|
||||
{SPR_NULL, 0, 12, {NULL}, 0, 4, S_PLAY_ICON3}, // S_PLAY_ICON2
|
||||
{SPR_NULL, 0, 18, {NULL}, 0, 4, S_NULL}, // S_PLAY_ICON3
|
||||
|
||||
// Level end sign (uses player sprite)
|
||||
|
|
23
src/k_kart.c
23
src/k_kart.c
|
@ -2027,9 +2027,15 @@ void K_DoInstashield(player_t *player)
|
|||
S_StartSound(player->mo, sfx_cdpcm9);
|
||||
|
||||
layera = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_INSTASHIELDA);
|
||||
layera->old_x = player->mo->old_x;
|
||||
layera->old_y = player->mo->old_y;
|
||||
layera->old_z = player->mo->old_z;
|
||||
P_SetTarget(&layera->target, player->mo);
|
||||
|
||||
layerb = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_INSTASHIELDB);
|
||||
layerb->old_x = player->mo->old_x;
|
||||
layerb->old_y = player->mo->old_y;
|
||||
layerb->old_z = player->mo->old_z;
|
||||
P_SetTarget(&layerb->target, player->mo);
|
||||
}
|
||||
|
||||
|
@ -2731,7 +2737,7 @@ static mobj_t *K_SpawnKartMissile(mobj_t *source, mobjtype_t type, angle_t an, I
|
|||
{
|
||||
// floorz and ceilingz aren't properly set to account for FOFs and Polyobjects on spawn
|
||||
// This should set it for FOFs
|
||||
P_TeleportMove(th, th->x, th->y, th->z);
|
||||
P_SetOrigin(th, th->x, th->y, th->z);
|
||||
// spawn on the ground if the player is on the ground
|
||||
if (P_MobjFlip(source) < 0)
|
||||
{
|
||||
|
@ -3314,7 +3320,7 @@ static mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t map
|
|||
{
|
||||
// floorz and ceilingz aren't properly set to account for FOFs and Polyobjects on spawn
|
||||
// This should set it for FOFs
|
||||
P_TeleportMove(mo, mo->x, mo->y, mo->z); // however, THIS can fuck up your day. just absolutely ruin you.
|
||||
P_SetOrigin(mo, mo->x, mo->y, mo->z); // however, THIS can fuck up your day. just absolutely ruin you.
|
||||
if (P_MobjWasRemoved(mo))
|
||||
return NULL;
|
||||
|
||||
|
@ -3827,7 +3833,7 @@ void K_DropHnextList(player_t *player)
|
|||
{
|
||||
// floorz and ceilingz aren't properly set to account for FOFs and Polyobjects on spawn
|
||||
// This should set it for FOFs
|
||||
//P_TeleportMove(dropwork, dropwork->x, dropwork->y, dropwork->z); -- handled better by above floorz/ceilingz passing
|
||||
//P_SetOrigin(dropwork, dropwork->x, dropwork->y, dropwork->z); -- handled better by above floorz/ceilingz passing
|
||||
|
||||
if (flip == 1)
|
||||
{
|
||||
|
@ -4101,7 +4107,7 @@ static void K_MoveHeldObjects(player_t *player)
|
|||
z = player->mo->z + player->mo->height - cur->height;
|
||||
|
||||
cur->flags |= MF_NOCLIPTHING; // temporarily make them noclip other objects so they can't hit anyone while in the player
|
||||
P_TeleportMove(cur, player->mo->x, player->mo->y, z);
|
||||
P_MoveOrigin(cur, player->mo->x, player->mo->y, z);
|
||||
cur->momx = FixedMul(FINECOSINE(cur->angle>>ANGLETOFINESHIFT), cur->extravalue1);
|
||||
cur->momy = FixedMul(FINESINE(cur->angle>>ANGLETOFINESHIFT), cur->extravalue1);
|
||||
cur->flags &= ~MF_NOCLIPTHING;
|
||||
|
@ -4203,7 +4209,7 @@ static void K_MoveHeldObjects(player_t *player)
|
|||
P_SetObjectMomZ(cur, FixedMul(targz - cur->z, 7*FRACUNIT/8) - gravity, false);
|
||||
|
||||
if (R_PointToDist2(cur->x, cur->y, targx, targy) > 768*FRACUNIT)
|
||||
P_TeleportMove(cur, targx, targy, cur->z);
|
||||
P_MoveOrigin(cur, targx, targy, cur->z);
|
||||
|
||||
cur = cur->hnext;
|
||||
}
|
||||
|
@ -4287,12 +4293,12 @@ static void K_MoveHeldObjects(player_t *player)
|
|||
diffy = targy - cur->y;
|
||||
diffz = targz - cur->z;
|
||||
|
||||
P_TeleportMove(cur->tracer, cur->tracer->x + diffx + P_ReturnThrustX(cur, cur->angle + angoffset, 6*cur->scale),
|
||||
P_MoveOrigin(cur->tracer, cur->tracer->x + diffx + P_ReturnThrustX(cur, cur->angle + angoffset, 6*cur->scale),
|
||||
cur->tracer->y + diffy + P_ReturnThrustY(cur, cur->angle + angoffset, 6*cur->scale), cur->tracer->z + diffz);
|
||||
P_SetScale(cur->tracer, (cur->tracer->destscale = 3*cur->scale/4));
|
||||
}
|
||||
|
||||
P_TeleportMove(cur, targx, targy, targz);
|
||||
P_MoveOrigin(cur, targx, targy, targz);
|
||||
K_FlipFromObject(cur, player->mo); // Update graviflip in real time thanks.
|
||||
num = (num+1) % 2;
|
||||
cur = cur->hnext;
|
||||
|
@ -4951,6 +4957,9 @@ void K_KartPlayerAfterThink(player_t *player)
|
|||
}
|
||||
|
||||
ret = P_SpawnMobj(targ->mo->x, targ->mo->y, targ->mo->z, MT_PLAYERRETICULE);
|
||||
ret->old_x = targ->mo->old_x;
|
||||
ret->old_y = targ->mo->old_y;
|
||||
ret->old_z = targ->mo->old_z;
|
||||
P_SetTarget(&ret->target, targ->mo);
|
||||
ret->frame |= ((leveltime % 10) / 2);
|
||||
ret->tics = 1;
|
||||
|
|
|
@ -1026,7 +1026,40 @@ static int lib_pTeleportMove(lua_State *L)
|
|||
NOHUD
|
||||
if (!thing)
|
||||
return LUA_ErrInvalid(L, "mobj_t");
|
||||
lua_pushboolean(L, P_TeleportMove(thing, x, y, z));
|
||||
LUA_Deprecated(L, "P_TeleportMove", "P_SetOrigin\" or \"P_MoveOrigin");
|
||||
lua_pushboolean(L, P_MoveOrigin(thing, x, y, z));
|
||||
LUA_PushUserdata(L, tmthing, META_MOBJ);
|
||||
P_SetTarget(&tmthing, ptmthing);
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int lib_pSetOrigin(lua_State *L)
|
||||
{
|
||||
mobj_t *ptmthing = tmthing;
|
||||
mobj_t *thing = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
|
||||
fixed_t x = luaL_checkfixed(L, 2);
|
||||
fixed_t y = luaL_checkfixed(L, 3);
|
||||
fixed_t z = luaL_checkfixed(L, 4);
|
||||
NOHUD
|
||||
if (!thing)
|
||||
return LUA_ErrInvalid(L, "mobj_t");
|
||||
lua_pushboolean(L, P_SetOrigin(thing, x, y, z));
|
||||
LUA_PushUserdata(L, tmthing, META_MOBJ);
|
||||
P_SetTarget(&tmthing, ptmthing);
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int lib_pMoveOrigin(lua_State *L)
|
||||
{
|
||||
mobj_t *ptmthing = tmthing;
|
||||
mobj_t *thing = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
|
||||
fixed_t x = luaL_checkfixed(L, 2);
|
||||
fixed_t y = luaL_checkfixed(L, 3);
|
||||
fixed_t z = luaL_checkfixed(L, 4);
|
||||
NOHUD
|
||||
if (!thing)
|
||||
return LUA_ErrInvalid(L, "mobj_t");
|
||||
lua_pushboolean(L, P_MoveOrigin(thing, x, y, z));
|
||||
LUA_PushUserdata(L, tmthing, META_MOBJ);
|
||||
P_SetTarget(&tmthing, ptmthing);
|
||||
return 2;
|
||||
|
@ -3038,6 +3071,8 @@ static luaL_Reg lib[] = {
|
|||
{"P_TryMove",lib_pTryMove},
|
||||
{"P_Move",lib_pMove},
|
||||
{"P_TeleportMove",lib_pTeleportMove},
|
||||
{"P_SetOrigin",lib_pSetOrigin},
|
||||
{"P_MoveOrigin",lib_pMoveOrigin},
|
||||
{"P_SlideMove",lib_pSlideMove},
|
||||
{"P_BounceMove",lib_pBounceMove},
|
||||
{"P_CheckSight", lib_pCheckSight},
|
||||
|
|
|
@ -10,6 +10,11 @@
|
|||
/// \file lua_hud.h
|
||||
/// \brief HUD enable/disable flags for Lua scripting
|
||||
|
||||
#ifndef __LUA_HUD_H__
|
||||
#define __LUA_HUD_H__
|
||||
|
||||
#include "lua_hudlib_drawlist.h"
|
||||
|
||||
enum hud {
|
||||
hud_stagetitle = 0,
|
||||
hud_textspectator,
|
||||
|
@ -36,5 +41,7 @@ extern boolean hud_running;
|
|||
|
||||
boolean LUA_HudEnabled(enum hud option);
|
||||
|
||||
void LUAh_GameHUD(player_t *stplyr);
|
||||
void LUAh_ScoresHUD(void);
|
||||
void LUAh_GameHUD(player_t *stplyr, huddrawlist_h list);
|
||||
void LUAh_ScoresHUD(huddrawlist_h list);
|
||||
|
||||
#endif // __LUA_HUD_H__
|
||||
|
|
151
src/lua_hudlib.c
151
src/lua_hudlib.c
|
@ -344,7 +344,8 @@ static int libd_draw(lua_State *L)
|
|||
{
|
||||
INT32 x, y, flags;
|
||||
patch_t *patch;
|
||||
const UINT8 *colormap = NULL;
|
||||
UINT8 *colormap = NULL;
|
||||
huddrawlist_h list;
|
||||
|
||||
HUDONLY
|
||||
x = luaL_checkinteger(L, 1);
|
||||
|
@ -356,7 +357,14 @@ static int libd_draw(lua_State *L)
|
|||
|
||||
flags &= ~V_PARAMMASK; // Don't let crashes happen.
|
||||
|
||||
V_DrawFixedPatch(x<<FRACBITS, y<<FRACBITS, FRACUNIT, flags, patch, colormap);
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, "HUD_DRAW_LIST");
|
||||
list = (huddrawlist_h) lua_touserdata(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
if (LUA_HUD_IsDrawListValid(list))
|
||||
LUA_HUD_AddDraw(list, x, y, patch, flags, colormap);
|
||||
else
|
||||
V_DrawFixedPatch(x<<FRACBITS, y<<FRACBITS, FRACUNIT, flags, patch, colormap);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -365,7 +373,8 @@ static int libd_drawScaled(lua_State *L)
|
|||
fixed_t x, y, scale;
|
||||
INT32 flags;
|
||||
patch_t *patch;
|
||||
const UINT8 *colormap = NULL;
|
||||
UINT8 *colormap = NULL;
|
||||
huddrawlist_h list;
|
||||
|
||||
HUDONLY
|
||||
x = luaL_checkinteger(L, 1);
|
||||
|
@ -380,7 +389,14 @@ static int libd_drawScaled(lua_State *L)
|
|||
|
||||
flags &= ~V_PARAMMASK; // Don't let crashes happen.
|
||||
|
||||
V_DrawFixedPatch(x, y, scale, flags, patch, colormap);
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, "HUD_DRAW_LIST");
|
||||
list = (huddrawlist_h) lua_touserdata(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
if (LUA_HUD_IsDrawListValid(list))
|
||||
LUA_HUD_AddDrawScaled(list, x, y, scale, patch, flags, colormap);
|
||||
else
|
||||
V_DrawFixedPatch(x, y, scale, flags, patch, colormap);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -389,8 +405,9 @@ static int libd_drawOnMinimap(lua_State *L)
|
|||
{
|
||||
fixed_t x, y, scale; // coordinates of the object
|
||||
patch_t *patch; // patch we want to draw
|
||||
const UINT8 *colormap = NULL; // do we want to colormap this patch?
|
||||
UINT8 *colormap = NULL; // do we want to colormap this patch?
|
||||
boolean centered; // the patch is centered and doesn't need readjusting on x/y coordinates.
|
||||
huddrawlist_h list;
|
||||
|
||||
// variables used to replicate k_kart's mmap drawer:
|
||||
INT32 lumpnum;
|
||||
|
@ -553,13 +570,24 @@ static int libd_drawOnMinimap(lua_State *L)
|
|||
amypos = amnumypos + ((my + AutomapPic->height/2)<<FRACBITS) - patchh;
|
||||
|
||||
// and NOW we can FINALLY DRAW OUR GOD DAMN PATCH :V
|
||||
V_DrawFixedPatch(amxpos, amypos, scale, splitflags, patch, colormap);
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, "HUD_DRAW_LIST");
|
||||
list = (huddrawlist_h) lua_touserdata(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
if (LUA_HUD_IsDrawListValid(list))
|
||||
LUA_HUD_AddDrawScaled(list, amxpos, amypos, scale, patch, splitflags, colormap);
|
||||
else
|
||||
V_DrawFixedPatch(amxpos, amypos, scale, splitflags, patch, colormap);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int libd_drawNum(lua_State *L)
|
||||
{
|
||||
INT32 x, y, flags, num;
|
||||
huddrawlist_h list;
|
||||
|
||||
HUDONLY
|
||||
x = luaL_checkinteger(L, 1);
|
||||
y = luaL_checkinteger(L, 2);
|
||||
|
@ -567,13 +595,22 @@ static int libd_drawNum(lua_State *L)
|
|||
flags = luaL_optinteger(L, 4, 0);
|
||||
flags &= ~V_PARAMMASK; // Don't let crashes happen.
|
||||
|
||||
V_DrawTallNum(x, y, flags, num);
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, "HUD_DRAW_LIST");
|
||||
list = (huddrawlist_h) lua_touserdata(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
if (LUA_HUD_IsDrawListValid(list))
|
||||
LUA_HUD_AddDrawNum(list, x, y, num, flags);
|
||||
else
|
||||
V_DrawTallNum(x, y, flags, num);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int libd_drawPaddedNum(lua_State *L)
|
||||
{
|
||||
INT32 x, y, flags, num, digits;
|
||||
huddrawlist_h list;
|
||||
|
||||
HUDONLY
|
||||
x = luaL_checkinteger(L, 1);
|
||||
y = luaL_checkinteger(L, 2);
|
||||
|
@ -582,7 +619,14 @@ static int libd_drawPaddedNum(lua_State *L)
|
|||
flags = luaL_optinteger(L, 5, 0);
|
||||
flags &= ~V_PARAMMASK; // Don't let crashes happen.
|
||||
|
||||
V_DrawPaddedTallNum(x, y, flags, num, digits);
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, "HUD_DRAW_LIST");
|
||||
list = (huddrawlist_h) lua_touserdata(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
if (LUA_HUD_IsDrawListValid(list))
|
||||
LUA_HUD_AddDrawPaddedNum(list, x, y, num, digits, flags);
|
||||
else
|
||||
V_DrawPaddedTallNum(x, y, flags, num, digits);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -606,6 +650,7 @@ static int libd_drawPingNum(lua_State *L)
|
|||
|
||||
static int libd_drawFill(lua_State *L)
|
||||
{
|
||||
huddrawlist_h list;
|
||||
INT32 x = luaL_optinteger(L, 1, 0);
|
||||
INT32 y = luaL_optinteger(L, 2, 0);
|
||||
INT32 w = luaL_optinteger(L, 3, BASEVIDWIDTH);
|
||||
|
@ -613,36 +658,58 @@ static int libd_drawFill(lua_State *L)
|
|||
INT32 c = luaL_optinteger(L, 5, 31);
|
||||
|
||||
HUDONLY
|
||||
V_DrawFill(x, y, w, h, c);
|
||||
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, "HUD_DRAW_LIST");
|
||||
list = (huddrawlist_h) lua_touserdata(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
if (LUA_HUD_IsDrawListValid(list))
|
||||
LUA_HUD_AddDrawFill(list, x, y, w, h, c);
|
||||
else
|
||||
V_DrawFill(x, y, w, h, c);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int libd_fadeScreen(lua_State *L)
|
||||
{
|
||||
UINT16 color = luaL_checkinteger(L, 1);
|
||||
UINT8 strength = luaL_checkinteger(L, 2);
|
||||
const UINT8 maxstrength = ((color & 0xFF00) ? 32 : 10);
|
||||
UINT16 color = luaL_checkinteger(L, 1);
|
||||
UINT8 strength = luaL_checkinteger(L, 2);
|
||||
const UINT8 maxstrength = ((color & 0xFF00) ? 32 : 10);
|
||||
huddrawlist_h list;
|
||||
|
||||
HUDONLY
|
||||
HUDONLY
|
||||
|
||||
if (!strength)
|
||||
return 0;
|
||||
if (!strength)
|
||||
return 0;
|
||||
|
||||
if (strength > maxstrength)
|
||||
return luaL_error(L, "%s fade strength %d out of range (0 - %d)", ((color & 0xFF00) ? "COLORMAP" : "TRANSMAP"), strength, maxstrength);
|
||||
if (strength > maxstrength)
|
||||
return luaL_error(L, "%s fade strength %d out of range (0 - %d)", ((color & 0xFF00) ? "COLORMAP" : "TRANSMAP"), strength, maxstrength);
|
||||
|
||||
if (strength == maxstrength) // Allow as a shortcut for drawfill...
|
||||
{
|
||||
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, ((color & 0xFF00) ? 31 : color));
|
||||
return 0;
|
||||
}
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, "HUD_DRAW_LIST");
|
||||
list = (huddrawlist_h) lua_touserdata(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
V_DrawFadeScreen(color, strength);
|
||||
return 0;
|
||||
if (strength == maxstrength) // Allow as a shortcut for drawfill...
|
||||
{
|
||||
if (LUA_HUD_IsDrawListValid(list))
|
||||
LUA_HUD_AddDrawFill(list, 0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, ((color & 0xFF00) ? 31 : color));
|
||||
else
|
||||
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, ((color & 0xFF00) ? 31 : color));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (LUA_HUD_IsDrawListValid(list))
|
||||
LUA_HUD_AddFadeScreen(list, color, strength);
|
||||
else
|
||||
V_DrawFadeScreen(color, strength);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int libd_drawString(lua_State *L)
|
||||
{
|
||||
huddrawlist_h list;
|
||||
fixed_t x = luaL_checkinteger(L, 1);
|
||||
fixed_t y = luaL_checkinteger(L, 2);
|
||||
const char *str = luaL_checkstring(L, 3);
|
||||
|
@ -652,6 +719,15 @@ static int libd_drawString(lua_State *L)
|
|||
flags &= ~V_PARAMMASK; // Don't let crashes happen.
|
||||
|
||||
HUDONLY
|
||||
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, "HUD_DRAW_LIST");
|
||||
list = (huddrawlist_h) lua_touserdata(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
// okay, sorry, this is kind of ugly
|
||||
if (LUA_HUD_IsDrawListValid(list))
|
||||
LUA_HUD_AddDrawString(list, x, y, str, flags, align);
|
||||
else
|
||||
switch(align)
|
||||
{
|
||||
// hu_font
|
||||
|
@ -691,11 +767,20 @@ static int libd_drawKartString(lua_State *L)
|
|||
fixed_t y = luaL_checkinteger(L, 2);
|
||||
const char *str = luaL_checkstring(L, 3);
|
||||
INT32 flags = luaL_optinteger(L, 4, V_ALLOWLOWERCASE);
|
||||
huddrawlist_h list;
|
||||
|
||||
flags &= ~V_PARAMMASK; // Don't let crashes happen.
|
||||
|
||||
HUDONLY
|
||||
V_DrawKartString(x, y, flags, str);
|
||||
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, "HUD_DRAW_LIST");
|
||||
list = (huddrawlist_h) lua_touserdata(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
if (LUA_HUD_IsDrawListValid(list))
|
||||
LUA_HUD_AddDrawKartString(list, x, y, str, flags);
|
||||
else
|
||||
V_DrawKartString(x, y, flags, str);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -956,10 +1041,13 @@ boolean LUA_HudEnabled(enum hud option)
|
|||
}
|
||||
|
||||
// Hook for HUD rendering
|
||||
void LUAh_GameHUD(player_t *stplayr)
|
||||
void LUAh_GameHUD(player_t *stplayr, huddrawlist_h list)
|
||||
{
|
||||
if (!gL || !(hudAvailable & (1<<hudhook_game)))
|
||||
return;
|
||||
|
||||
lua_pushlightuserdata(gL, list);
|
||||
lua_setfield(gL, LUA_REGISTRYINDEX, "HUD_DRAW_LIST");
|
||||
|
||||
hud_running = true;
|
||||
lua_pop(gL, -1);
|
||||
|
@ -1004,12 +1092,18 @@ void LUAh_GameHUD(player_t *stplayr)
|
|||
}
|
||||
lua_pop(gL, -1);
|
||||
hud_running = false;
|
||||
|
||||
lua_pushlightuserdata(gL, NULL);
|
||||
lua_setfield(gL, LUA_REGISTRYINDEX, "HUD_DRAW_LIST");
|
||||
}
|
||||
|
||||
void LUAh_ScoresHUD(void)
|
||||
void LUAh_ScoresHUD(huddrawlist_h list)
|
||||
{
|
||||
if (!gL || !(hudAvailable & (1<<hudhook_scores)))
|
||||
return;
|
||||
|
||||
lua_pushlightuserdata(gL, list);
|
||||
lua_setfield(gL, LUA_REGISTRYINDEX, "HUD_DRAW_LIST");
|
||||
|
||||
hud_running = true;
|
||||
lua_pop(gL, -1);
|
||||
|
@ -1029,6 +1123,9 @@ void LUAh_ScoresHUD(void)
|
|||
}
|
||||
lua_pop(gL, -1);
|
||||
hud_running = false;
|
||||
|
||||
lua_pushlightuserdata(gL, NULL);
|
||||
lua_setfield(gL, LUA_REGISTRYINDEX, "HUD_DRAW_LIST");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
410
src/lua_hudlib_drawlist.c
Normal file
410
src/lua_hudlib_drawlist.c
Normal file
|
@ -0,0 +1,410 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2014-2016 by John "JTE" Muniz.
|
||||
// Copyright (C) 2014-2022 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file lua_hudlib_drawlist.c
|
||||
/// \brief a data structure for managing cached drawlists for the Lua hud lib
|
||||
|
||||
#include "lua_hudlib_drawlist.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "v_video.h"
|
||||
#include "z_zone.h"
|
||||
|
||||
enum drawitem_e {
|
||||
DI_Draw = 0,
|
||||
DI_DrawScaled,
|
||||
DI_DrawNum,
|
||||
DI_DrawPaddedNum,
|
||||
DI_DrawFill,
|
||||
DI_DrawString,
|
||||
DI_DrawKartString,
|
||||
DI_DrawLevelTitle,
|
||||
DI_FadeScreen,
|
||||
DI_MAX,
|
||||
};
|
||||
|
||||
// A single draw item with all possible arguments needed for a draw call.
|
||||
typedef struct drawitem_s {
|
||||
enum drawitem_e type;
|
||||
fixed_t x;
|
||||
fixed_t y;
|
||||
fixed_t w;
|
||||
fixed_t h;
|
||||
INT32 c;
|
||||
fixed_t scale;
|
||||
fixed_t hscale;
|
||||
fixed_t vscale;
|
||||
patch_t *patch;
|
||||
INT32 flags;
|
||||
UINT16 basecolor;
|
||||
UINT16 outlinecolor;
|
||||
UINT8 *colormap;
|
||||
UINT8 *basecolormap;
|
||||
UINT8 *outlinecolormap;
|
||||
fixed_t sx;
|
||||
fixed_t sy;
|
||||
INT32 num;
|
||||
INT32 digits;
|
||||
const char *str;
|
||||
UINT16 color;
|
||||
UINT8 strength;
|
||||
INT32 align;
|
||||
} drawitem_t;
|
||||
|
||||
// The internal structure of a drawlist.
|
||||
struct huddrawlist_s {
|
||||
drawitem_t *items;
|
||||
size_t items_capacity;
|
||||
size_t items_len;
|
||||
char *strbuf;
|
||||
size_t strbuf_capacity;
|
||||
size_t strbuf_len;
|
||||
};
|
||||
|
||||
// alignment types for v.drawString
|
||||
enum align {
|
||||
align_left = 0,
|
||||
align_center,
|
||||
align_right,
|
||||
align_fixed,
|
||||
align_small,
|
||||
align_smallright,
|
||||
align_thin,
|
||||
align_thinright
|
||||
};
|
||||
|
||||
huddrawlist_h LUA_HUD_CreateDrawList(void)
|
||||
{
|
||||
huddrawlist_h drawlist;
|
||||
|
||||
drawlist = (huddrawlist_h) Z_CallocAlign(sizeof(struct huddrawlist_s), PU_STATIC, NULL, 64);
|
||||
drawlist->items = NULL;
|
||||
drawlist->items_capacity = 0;
|
||||
drawlist->items_len = 0;
|
||||
drawlist->strbuf = NULL;
|
||||
drawlist->strbuf_capacity = 0;
|
||||
drawlist->strbuf_len = 0;
|
||||
|
||||
return drawlist;
|
||||
}
|
||||
|
||||
void LUA_HUD_ClearDrawList(huddrawlist_h list)
|
||||
{
|
||||
// rather than deallocate, we'll just save the existing allocation and empty
|
||||
// it out for reuse
|
||||
|
||||
// this memset probably isn't necessary
|
||||
if (list->items)
|
||||
{
|
||||
memset(list->items, 0, sizeof(drawitem_t) * list->items_capacity);
|
||||
}
|
||||
|
||||
list->items_len = 0;
|
||||
|
||||
if (list->strbuf)
|
||||
{
|
||||
list->strbuf[0] = 0;
|
||||
}
|
||||
list->strbuf_len = 0;
|
||||
}
|
||||
|
||||
void LUA_HUD_DestroyDrawList(huddrawlist_h list)
|
||||
{
|
||||
if (list == NULL) return;
|
||||
|
||||
if (list->items)
|
||||
{
|
||||
Z_Free(list->items);
|
||||
}
|
||||
Z_Free(list);
|
||||
}
|
||||
|
||||
boolean LUA_HUD_IsDrawListValid(huddrawlist_h list)
|
||||
{
|
||||
if (!list) return false;
|
||||
|
||||
// that's all we can really do to check the validity of the handle right now
|
||||
return true;
|
||||
}
|
||||
|
||||
static size_t AllocateDrawItem(huddrawlist_h list)
|
||||
{
|
||||
if (!list) I_Error("can't allocate draw item: invalid list");
|
||||
if (list->items_capacity <= list->items_len + 1)
|
||||
{
|
||||
if (list->items_capacity == 0) list->items_capacity = 128;
|
||||
else list->items_capacity *= 2;
|
||||
list->items = (drawitem_t *) Z_ReallocAlign(list->items, sizeof(struct drawitem_s) * list->items_capacity, PU_STATIC, NULL, 64);
|
||||
}
|
||||
|
||||
return list->items_len++;
|
||||
}
|
||||
|
||||
// copy string to list's internal string buffer
|
||||
// lua can deallocate the string before we get to use it, so it's important to
|
||||
// keep our own copy
|
||||
static const char *CopyString(huddrawlist_h list, const char* str)
|
||||
{
|
||||
size_t lenstr;
|
||||
|
||||
if (!list) I_Error("can't allocate string; invalid list");
|
||||
lenstr = strlen(str);
|
||||
if (list->strbuf_capacity <= list->strbuf_len + lenstr + 1)
|
||||
{
|
||||
if (list->strbuf_capacity == 0) list->strbuf_capacity = 256;
|
||||
else list->strbuf_capacity *= 2;
|
||||
list->strbuf = (char*) Z_ReallocAlign(list->strbuf, sizeof(char) * list->strbuf_capacity, PU_STATIC, NULL, 8);
|
||||
}
|
||||
|
||||
{
|
||||
const char *result = (const char *) &list->strbuf[list->strbuf_len];
|
||||
strncpy(&list->strbuf[list->strbuf_len], str, lenstr + 1);
|
||||
list->strbuf_len += lenstr + 1;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
void LUA_HUD_AddDraw(
|
||||
huddrawlist_h list,
|
||||
INT32 x,
|
||||
INT32 y,
|
||||
patch_t *patch,
|
||||
INT32 flags,
|
||||
UINT8 *colormap
|
||||
)
|
||||
{
|
||||
size_t i = AllocateDrawItem(list);
|
||||
drawitem_t *item = &list->items[i];
|
||||
item->type = DI_Draw;
|
||||
item->x = x;
|
||||
item->y = y;
|
||||
item->patch = patch;
|
||||
item->flags = flags;
|
||||
item->colormap = colormap;
|
||||
}
|
||||
|
||||
void LUA_HUD_AddDrawScaled(
|
||||
huddrawlist_h list,
|
||||
fixed_t x,
|
||||
fixed_t y,
|
||||
fixed_t scale,
|
||||
patch_t *patch,
|
||||
INT32 flags,
|
||||
UINT8 *colormap
|
||||
)
|
||||
{
|
||||
size_t i = AllocateDrawItem(list);
|
||||
drawitem_t *item = &list->items[i];
|
||||
item->type = DI_DrawScaled;
|
||||
item->x = x;
|
||||
item->y = y;
|
||||
item->scale = scale;
|
||||
item->patch = patch;
|
||||
item->flags = flags;
|
||||
item->colormap = colormap;
|
||||
}
|
||||
|
||||
void LUA_HUD_AddDrawNum(
|
||||
huddrawlist_h list,
|
||||
INT32 x,
|
||||
INT32 y,
|
||||
INT32 num,
|
||||
INT32 flags
|
||||
)
|
||||
{
|
||||
size_t i = AllocateDrawItem(list);
|
||||
drawitem_t *item = &list->items[i];
|
||||
item->type = DI_DrawNum;
|
||||
item->x = x;
|
||||
item->y = y;
|
||||
item->num = num;
|
||||
item->flags = flags;
|
||||
}
|
||||
|
||||
void LUA_HUD_AddDrawPaddedNum(
|
||||
huddrawlist_h list,
|
||||
INT32 x,
|
||||
INT32 y,
|
||||
INT32 num,
|
||||
INT32 digits,
|
||||
INT32 flags
|
||||
)
|
||||
{
|
||||
size_t i = AllocateDrawItem(list);
|
||||
drawitem_t *item = &list->items[i];
|
||||
item->type = DI_DrawPaddedNum;
|
||||
item->x = x;
|
||||
item->y = y;
|
||||
item->num = num;
|
||||
item->digits = digits;
|
||||
item->flags = flags;
|
||||
}
|
||||
|
||||
void LUA_HUD_AddDrawFill(
|
||||
huddrawlist_h list,
|
||||
INT32 x,
|
||||
INT32 y,
|
||||
INT32 w,
|
||||
INT32 h,
|
||||
INT32 c
|
||||
)
|
||||
{
|
||||
size_t i = AllocateDrawItem(list);
|
||||
drawitem_t *item = &list->items[i];
|
||||
item->type = DI_DrawFill;
|
||||
item->x = x;
|
||||
item->y = y;
|
||||
item->w = w;
|
||||
item->h = h;
|
||||
item->c = c;
|
||||
}
|
||||
|
||||
void LUA_HUD_AddDrawString(
|
||||
huddrawlist_h list,
|
||||
fixed_t x,
|
||||
fixed_t y,
|
||||
const char *str,
|
||||
INT32 flags,
|
||||
INT32 align
|
||||
)
|
||||
{
|
||||
size_t i = AllocateDrawItem(list);
|
||||
drawitem_t *item = &list->items[i];
|
||||
item->type = DI_DrawString;
|
||||
item->x = x;
|
||||
item->y = y;
|
||||
item->str = CopyString(list, str);
|
||||
item->flags = flags;
|
||||
item->align = align;
|
||||
}
|
||||
|
||||
void LUA_HUD_AddDrawKartString(
|
||||
huddrawlist_h list,
|
||||
fixed_t x,
|
||||
fixed_t y,
|
||||
const char *str,
|
||||
INT32 flags
|
||||
)
|
||||
{
|
||||
size_t i = AllocateDrawItem(list);
|
||||
drawitem_t *item = &list->items[i];
|
||||
item->type = DI_DrawKartString;
|
||||
item->x = x;
|
||||
item->y = y;
|
||||
item->str = CopyString(list, str);
|
||||
item->flags = flags;
|
||||
}
|
||||
|
||||
void LUA_HUD_AddDrawLevelTitle(
|
||||
huddrawlist_h list,
|
||||
INT32 x,
|
||||
INT32 y,
|
||||
const char *str,
|
||||
INT32 flags
|
||||
)
|
||||
{
|
||||
size_t i = AllocateDrawItem(list);
|
||||
drawitem_t *item = &list->items[i];
|
||||
item->type = DI_DrawLevelTitle;
|
||||
item->x = x;
|
||||
item->y = y;
|
||||
item->str = CopyString(list, str);
|
||||
item->flags = flags;
|
||||
}
|
||||
|
||||
void LUA_HUD_AddFadeScreen(
|
||||
huddrawlist_h list,
|
||||
UINT16 color,
|
||||
UINT8 strength
|
||||
)
|
||||
{
|
||||
size_t i = AllocateDrawItem(list);
|
||||
drawitem_t *item = &list->items[i];
|
||||
item->type = DI_FadeScreen;
|
||||
item->color = color;
|
||||
item->strength = strength;
|
||||
}
|
||||
|
||||
void LUA_HUD_DrawList(huddrawlist_h list)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (!list) I_Error("HUD drawlist invalid");
|
||||
if (list->items_len <= 0) return;
|
||||
if (!list->items) I_Error("HUD drawlist->items invalid");
|
||||
|
||||
for (i = 0; i < list->items_len; i++)
|
||||
{
|
||||
drawitem_t *item = &list->items[i];
|
||||
|
||||
switch (item->type)
|
||||
{
|
||||
case DI_Draw:
|
||||
V_DrawFixedPatch(item->x<<FRACBITS, item->y<<FRACBITS, FRACUNIT, item->flags, item->patch, item->colormap);
|
||||
break;
|
||||
case DI_DrawScaled:
|
||||
V_DrawFixedPatch(item->x, item->y, item->scale, item->flags, item->patch, item->colormap);
|
||||
break;
|
||||
case DI_DrawNum:
|
||||
V_DrawTallNum(item->x, item->y, item->flags, item->num);
|
||||
break;
|
||||
case DI_DrawPaddedNum:
|
||||
V_DrawPaddedTallNum(item->x, item->y, item->flags, item->num, item->digits);
|
||||
break;
|
||||
case DI_DrawFill:
|
||||
V_DrawFill(item->x, item->y, item->w, item->h, item->c);
|
||||
break;
|
||||
case DI_DrawString:
|
||||
switch(item->align)
|
||||
{
|
||||
// hu_font
|
||||
case align_left:
|
||||
V_DrawString(item->x, item->y, item->flags, item->str);
|
||||
break;
|
||||
case align_center:
|
||||
V_DrawCenteredString(item->x, item->y, item->flags, item->str);
|
||||
break;
|
||||
case align_right:
|
||||
V_DrawRightAlignedString(item->x, item->y, item->flags, item->str);
|
||||
break;
|
||||
case align_fixed:
|
||||
V_DrawStringAtFixed(item->x, item->y, item->flags, item->str);
|
||||
break;
|
||||
// hu_font, 0.5x scale
|
||||
case align_small:
|
||||
V_DrawSmallString(item->x, item->y, item->flags, item->str);
|
||||
break;
|
||||
case align_smallright:
|
||||
V_DrawRightAlignedSmallString(item->x, item->y, item->flags, item->str);
|
||||
break;
|
||||
// tny_font
|
||||
case align_thin:
|
||||
V_DrawThinString(item->x, item->y, item->flags, item->str);
|
||||
break;
|
||||
case align_thinright:
|
||||
V_DrawRightAlignedThinString(item->x, item->y, item->flags, item->str);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case DI_DrawKartString:
|
||||
V_DrawKartString(item->x, item->y, item->flags, item->str);
|
||||
break;
|
||||
case DI_DrawLevelTitle:
|
||||
V_DrawLevelTitle(item->x, item->y, item->flags, item->str);
|
||||
break;
|
||||
case DI_FadeScreen:
|
||||
V_DrawFadeScreen(item->color, item->strength);
|
||||
break;
|
||||
default:
|
||||
I_Error("can't draw draw list item: invalid draw list item type");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
112
src/lua_hudlib_drawlist.h
Normal file
112
src/lua_hudlib_drawlist.h
Normal file
|
@ -0,0 +1,112 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2022-2022 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file lua_hudlib_drawlist.h
|
||||
/// \brief a data structure for managing cached drawlists for the Lua hud lib
|
||||
|
||||
// The idea behinds this module is to cache drawcall information into an ordered
|
||||
// list to repeat the same draw operations in later frames. It's used to ensure
|
||||
// that the HUD hooks from Lua are called at precisely 35hz to avoid problems
|
||||
// with variable framerates in existing Lua addons.
|
||||
|
||||
#ifndef __LUA_HUDLIB_DRAWLIST__
|
||||
#define __LUA_HUDLIB_DRAWLIST__
|
||||
|
||||
#include "doomtype.h"
|
||||
#include "r_defs.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct huddrawlist_s *huddrawlist_h;
|
||||
|
||||
// Create a new drawlist. Returns a handle to it.
|
||||
huddrawlist_h LUA_HUD_CreateDrawList(void);
|
||||
// Clears the draw list.
|
||||
void LUA_HUD_ClearDrawList(huddrawlist_h list);
|
||||
// Destroys the drawlist, invalidating the given handle
|
||||
void LUA_HUD_DestroyDrawList(huddrawlist_h list);
|
||||
boolean LUA_HUD_IsDrawListValid(huddrawlist_h list);
|
||||
|
||||
void LUA_HUD_AddDraw(
|
||||
huddrawlist_h list,
|
||||
INT32 x,
|
||||
INT32 y,
|
||||
patch_t *patch,
|
||||
INT32 flags,
|
||||
UINT8 *colormap
|
||||
);
|
||||
void LUA_HUD_AddDrawScaled(
|
||||
huddrawlist_h list,
|
||||
fixed_t x,
|
||||
fixed_t y,
|
||||
fixed_t scale,
|
||||
patch_t *patch,
|
||||
INT32 flags,
|
||||
UINT8 *colormap
|
||||
);
|
||||
void LUA_HUD_AddDrawNum(
|
||||
huddrawlist_h list,
|
||||
INT32 x,
|
||||
INT32 y,
|
||||
INT32 num,
|
||||
INT32 flags
|
||||
);
|
||||
void LUA_HUD_AddDrawPaddedNum(
|
||||
huddrawlist_h list,
|
||||
INT32 x,
|
||||
INT32 y,
|
||||
INT32 num,
|
||||
INT32 digits,
|
||||
INT32 flags
|
||||
);
|
||||
void LUA_HUD_AddDrawFill(
|
||||
huddrawlist_h list,
|
||||
INT32 x,
|
||||
INT32 y,
|
||||
INT32 w,
|
||||
INT32 h,
|
||||
INT32 c
|
||||
);
|
||||
void LUA_HUD_AddDrawString(
|
||||
huddrawlist_h list,
|
||||
fixed_t x,
|
||||
fixed_t y,
|
||||
const char *str,
|
||||
INT32 flags,
|
||||
INT32 align
|
||||
);
|
||||
void LUA_HUD_AddDrawKartString(
|
||||
huddrawlist_h list,
|
||||
fixed_t x,
|
||||
fixed_t y,
|
||||
const char *str,
|
||||
INT32 flags
|
||||
);
|
||||
void LUA_HUD_AddDrawLevelTitle(
|
||||
huddrawlist_h list,
|
||||
INT32 x,
|
||||
INT32 y,
|
||||
const char *str,
|
||||
INT32 flags
|
||||
);
|
||||
void LUA_HUD_AddFadeScreen(
|
||||
huddrawlist_h list,
|
||||
UINT16 color,
|
||||
UINT8 strength
|
||||
);
|
||||
|
||||
// Draws the given draw list
|
||||
void LUA_HUD_DrawList(huddrawlist_h list);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // __LUA_HUDLIB_DRAWLIST__
|
|
@ -373,7 +373,7 @@ static int mobj_get(lua_State *L)
|
|||
}
|
||||
|
||||
#define NOSET luaL_error(L, LUA_QL("mobj_t") " field " LUA_QS " should not be set directly.", mobj_opt[field])
|
||||
#define NOSETPOS luaL_error(L, LUA_QL("mobj_t") " field " LUA_QS " should not be set directly. Use " LUA_QL("P_Move") ", " LUA_QL("P_TryMove") ", or " LUA_QL("P_TeleportMove") " instead.", mobj_opt[field])
|
||||
#define NOSETPOS luaL_error(L, LUA_QL("mobj_t") " field " LUA_QS " should not be set directly. Use " LUA_QL("P_Move") ", " LUA_QL("P_TryMove") ", or " LUA_QL("P_SetOrigin") ", or " LUA_QL("P_MoveOrigin") " instead.", mobj_opt[field])
|
||||
static int mobj_set(lua_State *L)
|
||||
{
|
||||
mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
|
||||
|
@ -639,6 +639,7 @@ static int mobj_set(lua_State *L)
|
|||
scale = FRACUNIT/100;
|
||||
mo->destscale = scale;
|
||||
P_SetScale(mo, scale);
|
||||
mo->old_scale = scale;
|
||||
break;
|
||||
}
|
||||
case mobj_destscale:
|
||||
|
|
|
@ -495,7 +495,7 @@ void Command_RTeleport_f(void)
|
|||
CONS_Printf(M_GetText("Teleporting by %d, %d, %d...\n"), intx, inty, FixedInt((intz-p->mo->z)));
|
||||
|
||||
P_MapStart();
|
||||
if (!P_TeleportMove(p->mo, p->mo->x+intx*FRACUNIT, p->mo->y+inty*FRACUNIT, intz))
|
||||
if (!P_SetOrigin(p->mo, p->mo->x+intx*FRACUNIT, p->mo->y+inty*FRACUNIT, intz))
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Unable to teleport to that spot!\n"));
|
||||
else
|
||||
S_StartSound(p->mo, sfx_mixup);
|
||||
|
@ -562,7 +562,7 @@ void Command_Teleport_f(void)
|
|||
CONS_Printf(M_GetText("Teleporting to %d, %d, %d...\n"), intx, inty, FixedInt(intz));
|
||||
|
||||
P_MapStart();
|
||||
if (!P_TeleportMove(p->mo, intx*FRACUNIT, inty*FRACUNIT, intz))
|
||||
if (!P_SetOrigin(p->mo, intx*FRACUNIT, inty*FRACUNIT, intz))
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Unable to teleport to that spot!\n"));
|
||||
else
|
||||
S_StartSound(p->mo, sfx_mixup);
|
||||
|
@ -1107,13 +1107,13 @@ void OP_ObjectplaceMovement(player_t *player)
|
|||
if (cmd->forwardmove != 0)
|
||||
{
|
||||
P_Thrust(player->mo, player->mo->angle, (cmd->forwardmove*FRACUNIT/MAXPLMOVE)*cv_speed.value);
|
||||
P_TeleportMove(player->mo, player->mo->x+player->mo->momx, player->mo->y+player->mo->momy, player->mo->z);
|
||||
P_MoveOrigin(player->mo, player->mo->x+player->mo->momx, player->mo->y+player->mo->momy, player->mo->z);
|
||||
player->mo->momx = player->mo->momy = 0;
|
||||
}
|
||||
/*if (cmd->sidemove != 0) -- was disabled in practice anyways, since sidemove was suppressed
|
||||
{
|
||||
P_Thrust(player->mo, player->mo->angle-ANGLE_90, (cmd->sidemove*FRACUNIT/MAXPLMOVE)*cv_speed.value);
|
||||
P_TeleportMove(player->mo, player->mo->x+player->mo->momx, player->mo->y+player->mo->momy, player->mo->z);
|
||||
P_MoveOrigin(player->mo, player->mo->x+player->mo->momx, player->mo->y+player->mo->momy, player->mo->z);
|
||||
player->mo->momx = player->mo->momy = 0;
|
||||
}*/
|
||||
|
||||
|
|
48
src/m_menu.c
48
src/m_menu.c
|
@ -22,6 +22,7 @@
|
|||
#include "d_main.h"
|
||||
#include "d_netcmd.h"
|
||||
#include "console.h"
|
||||
#include "r_fps.h"
|
||||
#include "r_local.h"
|
||||
#include "hu_stuff.h"
|
||||
#include "g_game.h"
|
||||
|
@ -31,6 +32,7 @@
|
|||
// Data.
|
||||
#include "sounds.h"
|
||||
#include "s_sound.h"
|
||||
#include "i_time.h"
|
||||
#include "i_system.h"
|
||||
#include "i_threads.h"
|
||||
|
||||
|
@ -1255,9 +1257,10 @@ static menuitem_t OP_VideoOptionsMenu[] =
|
|||
|
||||
{IT_STRING | IT_CVAR, NULL, "Show FPS", &cv_ticrate, 90},
|
||||
{IT_STRING | IT_CVAR, NULL, "Vertical Sync", &cv_vidwait, 100},
|
||||
{IT_STRING | IT_CVAR, NULL, "FPS Cap", &cv_fpscap, 110},
|
||||
|
||||
#ifdef HWRENDER
|
||||
{IT_SUBMENU|IT_STRING, NULL, "OpenGL Options...", &OP_OpenGLOptionsDef, 120},
|
||||
{IT_SUBMENU|IT_STRING, NULL, "OpenGL Options...", &OP_OpenGLOptionsDef, 130},
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -6912,6 +6915,7 @@ static void M_DrawLoad(void)
|
|||
INT32 ymod = 0, offset = 0;
|
||||
|
||||
M_DrawMenuTitle();
|
||||
fixed_t scrollfrac = FixedDiv(2, 3);
|
||||
|
||||
if (menumovedir != 0) //movement illusion
|
||||
{
|
||||
|
@ -9137,12 +9141,12 @@ Update the maxplayers label...
|
|||
|
||||
if (itemOn == 2 && i == setupm_pselect)
|
||||
{
|
||||
static UINT8 cursorframe = 0;
|
||||
if (skullAnimCounter % 4 == 0)
|
||||
cursorframe++;
|
||||
if (cursorframe > 7)
|
||||
cursorframe = 0;
|
||||
V_DrawFixedPatch(x<<FRACBITS, y<<FRACBITS, FRACUNIT, 0, W_CachePatchName(va("K_BHILI%d", cursorframe+1), PU_CACHE), NULL);
|
||||
static fixed_t cursorframe = 0;
|
||||
|
||||
cursorframe += renderdeltatics / 4;
|
||||
for (; cursorframe > 7 * FRACUNIT; cursorframe -= 7 * FRACUNIT) {}
|
||||
|
||||
V_DrawFixedPatch(x<<FRACBITS, y<<FRACBITS, FRACUNIT, 0, W_CachePatchName(va("K_BHILI%d", (cursorframe >> FRACBITS) + 1), PU_CACHE), NULL);
|
||||
}
|
||||
|
||||
x += incrwidth;
|
||||
|
@ -9337,7 +9341,7 @@ static void M_HandleConnectIP(INT32 choice)
|
|||
// ========================
|
||||
// Tails 03-02-2002
|
||||
|
||||
static INT32 multi_tics;
|
||||
static fixed_t multi_tics;
|
||||
static state_t *multi_state;
|
||||
|
||||
// this is set before entering the MultiPlayer setup menu,
|
||||
|
@ -9483,16 +9487,14 @@ static void M_DrawSetupMultiPlayerMenu(void)
|
|||
fixed_t scale = FRACUNIT/2;
|
||||
INT32 offx = 8, offy = 8;
|
||||
patch_t *cursor;
|
||||
static UINT8 cursorframe = 0;
|
||||
static fixed_t cursorframe = 0;
|
||||
patch_t *face;
|
||||
UINT8 *colmap;
|
||||
|
||||
if (skullAnimCounter % 4 == 0)
|
||||
cursorframe++;
|
||||
if (cursorframe > 7)
|
||||
cursorframe = 0;
|
||||
cursorframe += renderdeltatics / 4;
|
||||
for (; cursorframe > 7 * FRACUNIT; cursorframe -= 7 * FRACUNIT) {}
|
||||
|
||||
cursor = W_CachePatchName(va("K_BHILI%d", cursorframe+1), PU_CACHE);
|
||||
cursor = W_CachePatchName(va("K_BHILI%d", (cursorframe >> FRACBITS) + 1), PU_CACHE);
|
||||
|
||||
if (col < 0)
|
||||
col += numskins;
|
||||
|
@ -9524,14 +9526,17 @@ static void M_DrawSetupMultiPlayerMenu(void)
|
|||
#undef iconwidth
|
||||
|
||||
// anim the player in the box
|
||||
if (--multi_tics <= 0)
|
||||
multi_tics -= renderdeltatics;
|
||||
while (multi_tics <= 0)
|
||||
{
|
||||
st = multi_state->nextstate;
|
||||
if (st != S_NULL)
|
||||
multi_state = &states[st];
|
||||
multi_tics = multi_state->tics;
|
||||
if (multi_tics == -1)
|
||||
multi_tics = 15;
|
||||
|
||||
if (multi_state->tics <= -1)
|
||||
multi_tics += 15*FRACUNIT;
|
||||
else
|
||||
multi_tics += multi_state->tics * FRACUNIT;
|
||||
}
|
||||
|
||||
// skin 0 is default player sprite
|
||||
|
@ -9692,7 +9697,7 @@ static void M_SetupMultiPlayer(INT32 choice)
|
|||
(void)choice;
|
||||
|
||||
multi_state = &states[mobjinfo[MT_PLAYER].seestate];
|
||||
multi_tics = multi_state->tics;
|
||||
multi_tics = multi_state->tics*FRACUNIT;
|
||||
strcpy(setupm_name, cv_playername.string);
|
||||
|
||||
// set for player 1
|
||||
|
@ -9723,7 +9728,7 @@ static void M_SetupMultiPlayer2(INT32 choice)
|
|||
(void)choice;
|
||||
|
||||
multi_state = &states[mobjinfo[MT_PLAYER].seestate];
|
||||
multi_tics = multi_state->tics;
|
||||
multi_tics = multi_state->tics*FRACUNIT;
|
||||
strcpy (setupm_name, cv_playername2.string);
|
||||
|
||||
// set for splitscreen secondary player
|
||||
|
@ -11226,7 +11231,8 @@ void M_QuitResponse(INT32 ch)
|
|||
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31);
|
||||
V_DrawSmallScaledPatch(0, 0, 0, W_CachePatchName("GAMEQUIT", PU_CACHE)); // Demo 3 Quit Screen Tails 06-16-2001
|
||||
I_FinishUpdate(); // Update the screen with the image Tails 06-19-2001
|
||||
I_Sleep();
|
||||
I_Sleep(cv_sleep.value);
|
||||
I_UpdateTime(cv_timescale.value);
|
||||
}
|
||||
}
|
||||
I_Quit();
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include "v_video.h"
|
||||
#include "z_zone.h"
|
||||
#include "g_input.h"
|
||||
#include "i_time.h"
|
||||
#include "i_video.h"
|
||||
#include "d_main.h"
|
||||
#include "m_argv.h"
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
|
||||
#include "doomdef.h"
|
||||
#include "p_local.h"
|
||||
#include "r_fps.h"
|
||||
#include "r_main.h"
|
||||
#include "s_sound.h"
|
||||
#include "z_zone.h"
|
||||
|
@ -600,6 +601,9 @@ INT32 EV_DoCeiling(line_t *line, ceiling_e type)
|
|||
ceiling->tag = sec->tag;
|
||||
ceiling->type = type;
|
||||
firstone = 0;
|
||||
|
||||
// interpolation
|
||||
R_CreateInterpolator_SectorPlane(&ceiling->thinker, sec, true);
|
||||
}
|
||||
return rtn;
|
||||
}
|
||||
|
@ -676,6 +680,10 @@ INT32 EV_DoCrush(line_t *line, ceiling_e type)
|
|||
|
||||
ceiling->tag = sec->tag;
|
||||
ceiling->type = type;
|
||||
|
||||
// interpolation
|
||||
R_CreateInterpolator_SectorPlane(&ceiling->thinker, sec, false);
|
||||
R_CreateInterpolator_SectorPlane(&ceiling->thinker, sec, true);
|
||||
}
|
||||
return rtn;
|
||||
}
|
||||
|
|
|
@ -8282,6 +8282,9 @@ void A_JawzChase(mobj_t *actor)
|
|||
|
||||
ret = P_SpawnMobj(actor->tracer->x, actor->tracer->y, actor->tracer->z, MT_PLAYERRETICULE);
|
||||
P_SetTarget(&ret->target, actor->tracer);
|
||||
ret->old_x = actor->tracer->old_x;
|
||||
ret->old_y = actor->tracer->old_y;
|
||||
ret->old_z = actor->tracer->old_z;
|
||||
ret->frame |= ((leveltime % 10) / 2) + 5;
|
||||
ret->color = actor->cvmem;
|
||||
|
||||
|
@ -8660,10 +8663,10 @@ void A_LightningFollowPlayer(mobj_t *actor)
|
|||
{
|
||||
sx = actor->target->x + FixedMul((actor->target->scale*actor->extravalue1), FINECOSINE((actor->angle)>>ANGLETOFINESHIFT));
|
||||
sy = actor->target->y + FixedMul((actor->target->scale*actor->extravalue1), FINESINE((actor->angle)>>ANGLETOFINESHIFT));
|
||||
P_TeleportMove(actor, sx, sy, actor->target->z);
|
||||
P_MoveOrigin(actor, sx, sy, actor->target->z);
|
||||
}
|
||||
else // else just teleport to player directly
|
||||
P_TeleportMove(actor, actor->target->x, actor->target->y, actor->target->z);
|
||||
P_MoveOrigin(actor, actor->target->x, actor->target->y, actor->target->z);
|
||||
|
||||
K_MatchGenericExtraFlags(actor, actor->target); // copy our target for graviflip
|
||||
actor->momx = actor->target->momx;
|
||||
|
@ -10731,7 +10734,7 @@ void A_VileAttack(mobj_t *actor)
|
|||
// move the fire between the vile and the player
|
||||
//fire->x = actor->target->x - FixedMul (24*FRACUNIT, finecosine[an]);
|
||||
//fire->y = actor->target->y - FixedMul (24*FRACUNIT, finesine[an]);
|
||||
P_TeleportMove(fire,
|
||||
P_MoveOrigin(fire,
|
||||
actor->target->x - P_ReturnThrustX(fire, actor->angle, FixedMul(24*FRACUNIT, fire->scale)),
|
||||
actor->target->y - P_ReturnThrustY(fire, actor->angle, FixedMul(24*FRACUNIT, fire->scale)),
|
||||
fire->z);
|
||||
|
@ -10776,7 +10779,7 @@ void A_VileAttack(mobj_t *actor)
|
|||
// move the fire between the vile and the player
|
||||
//fire->x = actor->target->x - FixedMul (24*FRACUNIT, finecosine[an]);
|
||||
//fire->y = actor->target->y - FixedMul (24*FRACUNIT, finesine[an]);
|
||||
P_TeleportMove(fire,
|
||||
P_MoveOrigin(fire,
|
||||
actor->target->x - P_ReturnThrustX(fire, actor->angle, FixedMul(24*FRACUNIT, fire->scale)),
|
||||
actor->target->y - P_ReturnThrustY(fire, actor->angle, FixedMul(24*FRACUNIT, fire->scale)),
|
||||
fire->z);
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "doomdef.h"
|
||||
#include "doomstat.h"
|
||||
#include "p_local.h"
|
||||
#include "r_fps.h"
|
||||
#include "r_state.h"
|
||||
#include "s_sound.h"
|
||||
#include "z_zone.h"
|
||||
|
@ -705,6 +706,7 @@ void T_ContinuousFalling(levelspecthink_t *faller)
|
|||
{
|
||||
faller->sector->ceilingheight = faller->ceilingwasheight;
|
||||
faller->sector->floorheight = faller->floorwasheight;
|
||||
R_ClearLevelInterpolatorState(&faller->thinker);
|
||||
}
|
||||
}
|
||||
else // Up
|
||||
|
@ -713,6 +715,7 @@ void T_ContinuousFalling(levelspecthink_t *faller)
|
|||
{
|
||||
faller->sector->ceilingheight = faller->ceilingwasheight;
|
||||
faller->sector->floorheight = faller->floorwasheight;
|
||||
R_ClearLevelInterpolatorState(&faller->thinker);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2862,6 +2865,9 @@ INT32 EV_DoFloor(line_t *line, floor_e floortype)
|
|||
}
|
||||
|
||||
firstone = 0;
|
||||
|
||||
// interpolation
|
||||
R_CreateInterpolator_SectorPlane(&dofloor->thinker, sec, false);
|
||||
}
|
||||
|
||||
return rtn;
|
||||
|
@ -2995,6 +3001,10 @@ INT32 EV_DoElevator(line_t *line, elevator_e elevtype, boolean customspeed)
|
|||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// interpolation
|
||||
R_CreateInterpolator_SectorPlane(&elevator->thinker, sec, false);
|
||||
R_CreateInterpolator_SectorPlane(&elevator->thinker, sec, true);
|
||||
}
|
||||
return rtn;
|
||||
}
|
||||
|
@ -3089,6 +3099,10 @@ INT32 EV_BounceSector(sector_t *sec, fixed_t momz, line_t *sourceline)
|
|||
bouncer->distance = FRACUNIT;
|
||||
bouncer->low = 1;
|
||||
|
||||
// interpolation
|
||||
R_CreateInterpolator_SectorPlane(&bouncer->thinker, sec, false);
|
||||
R_CreateInterpolator_SectorPlane(&bouncer->thinker, sec, true);
|
||||
|
||||
return 1;
|
||||
#undef speed
|
||||
#undef distance
|
||||
|
@ -3135,6 +3149,10 @@ INT32 EV_DoContinuousFall(sector_t *sec, sector_t *backsector, fixed_t spd, bool
|
|||
faller->direction = -1;
|
||||
}
|
||||
|
||||
// interpolation
|
||||
R_CreateInterpolator_SectorPlane(&faller->thinker, sec, false);
|
||||
R_CreateInterpolator_SectorPlane(&faller->thinker, sec, true);
|
||||
|
||||
return 1;
|
||||
#undef speed
|
||||
#undef direction
|
||||
|
@ -3210,6 +3228,10 @@ INT32 EV_StartCrumble(sector_t *sec, ffloor_t *rover, boolean floating,
|
|||
P_SpawnMobj(foundsec->soundorg.x, foundsec->soundorg.y, elevator->direction == 1 ? elevator->sector->floorheight : elevator->sector->ceilingheight, MT_CRUMBLEOBJ);
|
||||
}
|
||||
|
||||
// interpolation
|
||||
R_CreateInterpolator_SectorPlane(&elevator->thinker, sec, false);
|
||||
R_CreateInterpolator_SectorPlane(&elevator->thinker, sec, true);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -3250,6 +3272,10 @@ INT32 EV_MarioBlock(sector_t *sec, sector_t *roversector, fixed_t topheight, mob
|
|||
block->vars[5] = FRACUNIT; // distance
|
||||
block->vars[6] = 1; // low
|
||||
|
||||
// interpolation
|
||||
R_CreateInterpolator_SectorPlane(&block->thinker, roversector, false);
|
||||
R_CreateInterpolator_SectorPlane(&block->thinker, roversector, true);
|
||||
|
||||
if (itsamonitor)
|
||||
{
|
||||
oldx = thing->x;
|
||||
|
@ -3258,9 +3284,9 @@ INT32 EV_MarioBlock(sector_t *sec, sector_t *roversector, fixed_t topheight, mob
|
|||
}
|
||||
|
||||
P_UnsetThingPosition(thing);
|
||||
thing->x = roversector->soundorg.x;
|
||||
thing->y = roversector->soundorg.y;
|
||||
thing->z = topheight;
|
||||
thing->x = thing->old_x = roversector->soundorg.x;
|
||||
thing->y = thing->old_y = roversector->soundorg.y;
|
||||
thing->z = thing->old_z = topheight;
|
||||
thing->momz = FixedMul(6*FRACUNIT, thing->scale);
|
||||
P_SetThingPosition(thing);
|
||||
if (thing->flags & MF_SHOOTABLE)
|
||||
|
@ -3289,9 +3315,9 @@ INT32 EV_MarioBlock(sector_t *sec, sector_t *roversector, fixed_t topheight, mob
|
|||
if (itsamonitor)
|
||||
{
|
||||
P_UnsetThingPosition(tmthing);
|
||||
tmthing->x = oldx;
|
||||
tmthing->y = oldy;
|
||||
tmthing->z = oldz;
|
||||
tmthing->x = thing->old_x = oldx;
|
||||
tmthing->y = thing->old_y = oldy;
|
||||
tmthing->z = thing->old_z = oldz;
|
||||
tmthing->momx = 1;
|
||||
tmthing->momy = 1;
|
||||
P_SetThingPosition(tmthing);
|
||||
|
|
|
@ -348,7 +348,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
if (!special->target)
|
||||
return; // foolproof crash prevention check!!!!!
|
||||
|
||||
P_TeleportMove(player->mo, special->target->x, special->target->y, special->target->z + (48<<FRACBITS));
|
||||
P_SetOrigin(player->mo, special->target->x, special->target->y, special->target->z + (48<<FRACBITS));
|
||||
player->mo->angle = special->target->angle;
|
||||
P_SetObjectMomZ(player->mo, 12<<FRACBITS, false);
|
||||
P_InstaThrust(player->mo, player->mo->angle, 20<<FRACBITS);
|
||||
|
|
|
@ -348,7 +348,8 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y);
|
|||
boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam);
|
||||
boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff);
|
||||
boolean P_Move(mobj_t *actor, fixed_t speed);
|
||||
boolean P_TeleportMove(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z);
|
||||
boolean P_SetOrigin(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z);
|
||||
boolean P_MoveOrigin(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z);
|
||||
void P_SlideMove(mobj_t *mo, boolean forceslide);
|
||||
void P_BouncePlayerMove(mobj_t *mo);
|
||||
void P_BounceMove(mobj_t *mo);
|
||||
|
|
32
src/p_map.c
32
src/p_map.c
|
@ -19,6 +19,7 @@
|
|||
#include "m_random.h"
|
||||
#include "p_local.h"
|
||||
#include "p_setup.h" // NiGHTS stuff
|
||||
#include "r_fps.h"
|
||||
#include "r_state.h"
|
||||
#include "r_main.h"
|
||||
#include "r_sky.h"
|
||||
|
@ -75,7 +76,7 @@ camera_t *mapcampointer;
|
|||
//
|
||||
// P_TeleportMove
|
||||
//
|
||||
boolean P_TeleportMove(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z)
|
||||
static boolean P_TeleportMove(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z)
|
||||
{
|
||||
// the move is ok,
|
||||
// so link the thing into its new position
|
||||
|
@ -105,6 +106,30 @@ boolean P_TeleportMove(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z)
|
|||
return true;
|
||||
}
|
||||
|
||||
// P_SetOrigin - P_TeleportMove which RESETS interpolation values.
|
||||
//
|
||||
boolean P_SetOrigin(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z)
|
||||
{
|
||||
boolean result = P_TeleportMove(thing, x, y, z);
|
||||
|
||||
if (result == true)
|
||||
{
|
||||
thing->old_x = thing->x;
|
||||
thing->old_y = thing->y;
|
||||
thing->old_z = thing->z;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// P_MoveOrigin - P_TeleportMove which KEEPS interpolation values.
|
||||
//
|
||||
boolean P_MoveOrigin(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z)
|
||||
{
|
||||
return P_TeleportMove(thing, x, y, z);
|
||||
}
|
||||
|
||||
// =========================================================================
|
||||
// MOVEMENT ITERATOR FUNCTIONS
|
||||
// =========================================================================
|
||||
|
@ -599,9 +624,9 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
|||
return true; // underneath
|
||||
|
||||
if (tmthing->eflags & MFE_VERTICALFLIP)
|
||||
thing->z = tmthing->z - thing->height - FixedMul(FRACUNIT, tmthing->scale);
|
||||
thing->z = thing->old_z = tmthing->z - thing->height - FixedMul(FRACUNIT, tmthing->scale);
|
||||
else
|
||||
thing->z = tmthing->z + tmthing->height + FixedMul(FRACUNIT, tmthing->scale);
|
||||
thing->z = thing->old_z = tmthing->z + tmthing->height + FixedMul(FRACUNIT, tmthing->scale);
|
||||
if (thing->flags & MF_SHOOTABLE)
|
||||
P_DamageMobj(thing, tmthing, tmthing, 1);
|
||||
return true;
|
||||
|
@ -1904,7 +1929,6 @@ if (tmthing->flags & MF_PAPERCOLLISION) // Caution! Turning whilst up against a
|
|||
if (P_PointOnLineSide(tmx - cosradius, tmy - sinradius, ld)
|
||||
== P_PointOnLineSide(tmx + cosradius, tmy + sinradius, ld))
|
||||
return true; // the line doesn't cross between collider's start or end
|
||||
|
||||
}
|
||||
|
||||
// A line has been hit
|
||||
|
|
63
src/p_mobj.c
63
src/p_mobj.c
|
@ -18,6 +18,7 @@
|
|||
#include "hu_stuff.h"
|
||||
#include "p_local.h"
|
||||
#include "p_setup.h"
|
||||
#include "r_fps.h"
|
||||
#include "r_main.h"
|
||||
#include "r_things.h"
|
||||
#include "r_sky.h"
|
||||
|
@ -3795,15 +3796,22 @@ void P_NullPrecipThinker(precipmobj_t *mobj)
|
|||
|
||||
void P_SnowThinker(precipmobj_t *mobj)
|
||||
{
|
||||
R_ResetPrecipitationMobjInterpolationState(mobj);
|
||||
|
||||
P_CycleStateAnimation((mobj_t *)mobj);
|
||||
|
||||
// adjust height
|
||||
if ((mobj->z += mobj->momz) <= mobj->floorz)
|
||||
{
|
||||
mobj->z = mobj->ceilingz;
|
||||
R_ResetPrecipitationMobjInterpolationState(mobj);
|
||||
}
|
||||
}
|
||||
|
||||
void P_RainThinker(precipmobj_t *mobj)
|
||||
{
|
||||
R_ResetPrecipitationMobjInterpolationState(mobj);
|
||||
|
||||
P_CycleStateAnimation((mobj_t *)mobj);
|
||||
|
||||
if (mobj->state != &states[S_RAIN1])
|
||||
|
@ -3823,6 +3831,7 @@ void P_RainThinker(precipmobj_t *mobj)
|
|||
return;
|
||||
|
||||
mobj->z = mobj->ceilingz;
|
||||
R_ResetPrecipitationMobjInterpolationState(mobj);
|
||||
P_SetPrecipMobjState(mobj, S_RAIN1);
|
||||
|
||||
return;
|
||||
|
@ -4405,7 +4414,7 @@ static void P_Boss4MoveSpikeballs(mobj_t *mobj, angle_t angle, fixed_t fz)
|
|||
while ((base = base->tracer))
|
||||
{
|
||||
for (seg = base, dist = 172*FRACUNIT, s = 9; seg; seg = seg->hnext, dist += 124*FRACUNIT, --s)
|
||||
P_TeleportMove(seg, mobj->x + P_ReturnThrustX(mobj, angle, dist), mobj->y + P_ReturnThrustY(mobj, angle, dist), bz + FixedMul(fz, FixedDiv(s<<FRACBITS, 9<<FRACBITS)));
|
||||
P_MoveOrigin(seg, mobj->x + P_ReturnThrustX(mobj, angle, dist), mobj->y + P_ReturnThrustY(mobj, angle, dist), bz + FixedMul(fz, FixedDiv(s<<FRACBITS, 9<<FRACBITS)));
|
||||
angle += ANGLE_MAX/3;
|
||||
}
|
||||
}
|
||||
|
@ -5151,7 +5160,7 @@ static void P_Boss9Thinker(mobj_t *mobj)
|
|||
if (mobj->health > 3) {
|
||||
mobj->tracer->destscale = FRACUNIT + (4*TICRATE - mobj->fuse)*(FRACUNIT/2)/TICRATE + FixedMul(FINECOSINE(angle>>ANGLETOFINESHIFT),FRACUNIT/2);
|
||||
P_SetScale(mobj->tracer, mobj->tracer->destscale);
|
||||
P_TeleportMove(mobj->tracer, mobj->x, mobj->y, mobj->z + mobj->height/2 - mobj->tracer->height/2);
|
||||
P_SetOrigin(mobj->tracer, mobj->x, mobj->y, mobj->z + mobj->height/2 - mobj->tracer->height/2);
|
||||
mobj->tracer->momx = mobj->momx;
|
||||
mobj->tracer->momy = mobj->momy;
|
||||
mobj->tracer->momz = mobj->momz;
|
||||
|
@ -5821,9 +5830,9 @@ void P_Attract(mobj_t *source, mobj_t *dest, boolean nightsgrab) // Home in on y
|
|||
// place us on top of them then.
|
||||
source->momx = source->momy = source->momz = 0;
|
||||
P_UnsetThingPosition(source);
|
||||
source->x = tx;
|
||||
source->y = ty;
|
||||
source->z = tz;
|
||||
source->x = source->old_x = tx;
|
||||
source->y = source->old_y = ty;
|
||||
source->z = source->old_z = tz;
|
||||
P_SetThingPosition(source);
|
||||
}
|
||||
}
|
||||
|
@ -6101,7 +6110,7 @@ void P_RunShadows(void)
|
|||
if (dest->type == MT_THUNDERSHIELD)
|
||||
dest = dest->target;
|
||||
|
||||
P_TeleportMove(mobj, dest->x, dest->y, mobj->target->z);
|
||||
P_MoveOrigin(mobj, dest->x, dest->y, mobj->target->z);
|
||||
|
||||
if (((mobj->eflags & MFE_VERTICALFLIP) && (mobj->ceilingz > mobj->z+mobj->height))
|
||||
|| (!(mobj->eflags & MFE_VERTICALFLIP) && (floorz < mobj->z)))
|
||||
|
@ -6119,7 +6128,7 @@ void P_RunShadows(void)
|
|||
P_SetScale(mobj, FixedDiv(mobj->scale, max(FRACUNIT, ((mobj->target->z-mobj->z)/200)+FRACUNIT)));
|
||||
|
||||
// Check new position to see if you should still be on that ledge
|
||||
P_TeleportMove(mobj, dest->x, dest->y, mobj->z);
|
||||
P_MoveOrigin(mobj, dest->x, dest->y, mobj->z);
|
||||
|
||||
mobj->z = (mobj->eflags & MFE_VERTICALFLIP ? mobj->ceilingz : floorz);
|
||||
|
||||
|
@ -7000,7 +7009,7 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
if (mobj->target->eflags & MFE_VERTICALFLIP)
|
||||
z += mobj->target->height - FixedMul(mobj->target->scale, mobj->height);
|
||||
|
||||
P_TeleportMove(mobj, x, y, z);
|
||||
P_MoveOrigin(mobj, x, y, z);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@ -7400,7 +7409,7 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
P_RemoveMobj(mobj);
|
||||
return;
|
||||
}
|
||||
P_TeleportMove(mobj, mobj->target->x, mobj->target->y, mobj->target->z - mobj->height);
|
||||
P_MoveOrigin(mobj, mobj->target->x, mobj->target->y, mobj->target->z - mobj->height);
|
||||
break;
|
||||
case MT_HAMMER:
|
||||
if (mobj->z <= mobj->floorz)
|
||||
|
@ -8027,7 +8036,7 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
}
|
||||
|
||||
mobj->angle = mobj->target->angle;
|
||||
P_TeleportMove(mobj, mobj->target->x + P_ReturnThrustX(mobj, mobj->angle+ANGLE_180, mobj->target->radius),
|
||||
P_MoveOrigin(mobj, mobj->target->x + P_ReturnThrustX(mobj, mobj->angle+ANGLE_180, mobj->target->radius),
|
||||
mobj->target->y + P_ReturnThrustY(mobj, mobj->angle+ANGLE_180, mobj->target->radius), mobj->target->z);
|
||||
P_SetScale(mobj, mobj->target->scale);
|
||||
|
||||
|
@ -8076,7 +8085,7 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
P_RemoveMobj(mobj);
|
||||
return;
|
||||
}
|
||||
P_TeleportMove(mobj, mobj->target->x, mobj->target->y, mobj->target->z);
|
||||
P_SetOrigin(mobj, mobj->target->x, mobj->target->y, mobj->target->z);
|
||||
break;
|
||||
case MT_BRAKEDRIFT:
|
||||
if ((!mobj->target || !mobj->target->health || !mobj->target->player || !P_IsObjectOnGround(mobj->target))
|
||||
|
@ -8096,7 +8105,7 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
|
||||
newx = mobj->target->x + P_ReturnThrustX(mobj->target, travelangle+ANGLE_180, 24*mobj->target->scale);
|
||||
newy = mobj->target->y + P_ReturnThrustY(mobj->target, travelangle+ANGLE_180, 24*mobj->target->scale);
|
||||
P_TeleportMove(mobj, newx, newy, mobj->target->z);
|
||||
P_MoveOrigin(mobj, newx, newy, mobj->target->z);
|
||||
|
||||
mobj->angle = travelangle - ((ANGLE_90/5)*mobj->target->player->kartstuff[k_drift]);
|
||||
P_SetScale(mobj, (mobj->destscale = mobj->target->scale));
|
||||
|
@ -8124,7 +8133,7 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
P_RemoveMobj(mobj);
|
||||
return;
|
||||
}
|
||||
P_TeleportMove(mobj, mobj->target->x, mobj->target->y, mobj->target->z);
|
||||
P_MoveOrigin(mobj, mobj->target->x, mobj->target->y, mobj->target->z);
|
||||
break;
|
||||
case MT_INSTASHIELDB:
|
||||
mobj->flags2 ^= MF2_DONTDRAW;
|
||||
|
@ -8137,7 +8146,7 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
}
|
||||
|
||||
K_MatchGenericExtraFlags(mobj, mobj->target);
|
||||
P_TeleportMove(mobj, mobj->target->x, mobj->target->y, mobj->target->z);
|
||||
P_MoveOrigin(mobj, mobj->target->x, mobj->target->y, mobj->target->z);
|
||||
break;
|
||||
case MT_BATTLEPOINT:
|
||||
if (!mobj->target || P_MobjWasRemoved(mobj->target))
|
||||
|
@ -8159,7 +8168,7 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
mobj->movefactor = mobj->target->height;
|
||||
}
|
||||
K_MatchGenericExtraFlags(mobj, mobj->target);
|
||||
P_TeleportMove(mobj, mobj->target->x, mobj->target->y, mobj->target->z + (mobj->target->height/2) + mobj->movefactor);
|
||||
P_MoveOrigin(mobj, mobj->target->x, mobj->target->y, mobj->target->z + (mobj->target->height/2) + mobj->movefactor);
|
||||
break;
|
||||
case MT_THUNDERSHIELD:
|
||||
{
|
||||
|
@ -8194,7 +8203,7 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
desty = mobj->target->y;
|
||||
}
|
||||
|
||||
P_TeleportMove(mobj, destx, desty, mobj->target->z);
|
||||
P_MoveOrigin(mobj, destx, desty, mobj->target->z);
|
||||
break;
|
||||
}
|
||||
case MT_ROCKETSNEAKER:
|
||||
|
@ -8230,7 +8239,7 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
return;
|
||||
}
|
||||
|
||||
P_TeleportMove(mobj, mobj->target->x, mobj->target->y, mobj->target->z);
|
||||
P_MoveOrigin(mobj, mobj->target->x, mobj->target->y, mobj->target->z);
|
||||
mobj->angle = mobj->target->angle;
|
||||
mobj->scalespeed = mobj->target->scalespeed;
|
||||
mobj->destscale = mobj->target->destscale;
|
||||
|
@ -8291,7 +8300,7 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
if (cur->lastlook == 2 || cur->lastlook == 3)
|
||||
offy *= -1;
|
||||
|
||||
P_TeleportMove(cur, mobj->x + offx, mobj->y + offy, mobj->z);
|
||||
P_MoveOrigin(cur, mobj->x + offx, mobj->y + offy, mobj->z);
|
||||
cur->scalespeed = mobj->target->scalespeed;
|
||||
cur->destscale = mobj->target->destscale;
|
||||
P_SetScale(cur, mobj->target->scale);
|
||||
|
@ -8416,7 +8425,7 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
while (cur && !P_MobjWasRemoved(cur))
|
||||
{
|
||||
cur->angle += FixedAngle(mobj->info->speed);
|
||||
P_TeleportMove(cur, mobj->x + FINECOSINE((cur->angle*8)>>ANGLETOFINESHIFT),
|
||||
P_MoveOrigin(cur, mobj->x + FINECOSINE((cur->angle*8)>>ANGLETOFINESHIFT),
|
||||
mobj->y + FINESINE((cur->angle*8)>>ANGLETOFINESHIFT), mobj->z);
|
||||
//P_SpawnGhostMobj(cur)->tics = 2;
|
||||
|
||||
|
@ -8549,7 +8558,7 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
fixed_t wz = mobj->tracer->z + (joint * ((mobj->z + (mobj->height/2)) - mobj->tracer->z) / (numjoints+1));
|
||||
|
||||
if (cur && !P_MobjWasRemoved(cur))
|
||||
P_TeleportMove(cur, wx, wy, wz);
|
||||
P_MoveOrigin(cur, wx, wy, wz);
|
||||
else
|
||||
cur = P_SpawnMobj(wx, wy, wz, MT_FROGTONGUE_JOINT);
|
||||
|
||||
|
@ -8660,7 +8669,7 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
continue;
|
||||
}
|
||||
else // Move into place
|
||||
P_TeleportMove(cur, mobj->x, mobj->y, segz);
|
||||
P_MoveOrigin(cur, mobj->x, mobj->y, segz);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -8734,7 +8743,7 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
mobj->extravalue1 = 1;
|
||||
player->kartstuff[k_offroad] += 2<<FRACBITS;
|
||||
|
||||
P_TeleportMove(mobj,
|
||||
P_MoveOrigin(mobj,
|
||||
player->mo->x + P_ReturnThrustX(NULL, player->mo->angle, player->mo->radius)
|
||||
+ P_ReturnThrustX(NULL, player->mo->angle+ANGLE_90, (mobj->threshold)<<FRACBITS),
|
||||
player->mo->y + P_ReturnThrustY(NULL, player->mo->angle, player->mo->radius)
|
||||
|
@ -9855,7 +9864,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
|
|||
cur = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_SMK_ICEBLOCK_SIDE);
|
||||
P_SetTarget(&cur->target, mobj);
|
||||
cur->threshold = i;
|
||||
P_TeleportMove(cur, cur->x + ((cur->radius>>FRACBITS) * FINECOSINE((FixedAngle((90*cur->threshold)<<FRACBITS)>>ANGLETOFINESHIFT) & FINEMASK)),
|
||||
P_MoveOrigin(cur, cur->x + ((cur->radius>>FRACBITS) * FINECOSINE((FixedAngle((90*cur->threshold)<<FRACBITS)>>ANGLETOFINESHIFT) & FINEMASK)),
|
||||
cur->y + ((cur->radius>>FRACBITS) * FINESINE((FixedAngle((90*cur->threshold)<<FRACBITS)>>ANGLETOFINESHIFT) & FINEMASK)), cur->z);
|
||||
cur->angle = ANGLE_90*(cur->threshold+1);
|
||||
|
||||
|
@ -9925,6 +9934,8 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
|
|||
if (CheckForReverseGravity && !(mobj->flags & MF_NOBLOCKMAP))
|
||||
P_CheckGravity(mobj, false);
|
||||
|
||||
R_AddMobjInterpolator(mobj);
|
||||
|
||||
return mobj;
|
||||
}
|
||||
|
||||
|
@ -10038,6 +10049,8 @@ mobj_t *P_SpawnShadowMobj(mobj_t * caster)
|
|||
|
||||
P_SetTarget(&mobj->target, caster); // set the shadow's caster as the target
|
||||
|
||||
R_AddMobjInterpolator(mobj);
|
||||
|
||||
return mobj;
|
||||
}
|
||||
|
||||
|
@ -10086,6 +10099,8 @@ static precipmobj_t *P_SpawnPrecipMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype
|
|||
|| mobj->subsector->sector->floorpic == skyflatnum)
|
||||
mobj->precipflags |= PCF_PIT;
|
||||
|
||||
R_ResetPrecipitationMobjInterpolationState(mobj);
|
||||
|
||||
return mobj;
|
||||
}
|
||||
|
||||
|
@ -10237,6 +10252,8 @@ void P_RemoveMobj(mobj_t *mobj)
|
|||
#endif
|
||||
P_RemoveThinker((thinker_t *)mobj);
|
||||
}
|
||||
|
||||
R_RemoveMobjInterpolator(mobj);
|
||||
}
|
||||
|
||||
// This does not need to be added to Lua.
|
||||
|
|
11
src/p_mobj.h
11
src/p_mobj.h
|
@ -274,6 +274,8 @@ typedef struct mobj_s
|
|||
|
||||
// Info for drawing: position.
|
||||
fixed_t x, y, z;
|
||||
fixed_t old_x, old_y, old_z; // position interpolation
|
||||
fixed_t old_x2, old_y2, old_z2;
|
||||
|
||||
// More list: links in sector (if needed)
|
||||
struct mobj_s *snext;
|
||||
|
@ -281,6 +283,8 @@ typedef struct mobj_s
|
|||
|
||||
// More drawing info: to determine current sprite.
|
||||
angle_t angle; // orientation
|
||||
angle_t old_angle; // orientation interpolation
|
||||
angle_t old_angle2;
|
||||
spritenum_t sprite; // used to find patch_t and flip value
|
||||
UINT32 frame; // frame number, plus bits see p_pspr.h
|
||||
UINT16 anim_duration; // for FF_ANIMATE states
|
||||
|
@ -356,6 +360,8 @@ typedef struct mobj_s
|
|||
UINT32 mobjnum; // A unique number for this mobj. Used for restoring pointers on save games.
|
||||
|
||||
fixed_t scale;
|
||||
fixed_t old_scale; // interpolation
|
||||
fixed_t old_scale2;
|
||||
fixed_t destscale;
|
||||
fixed_t scalespeed;
|
||||
|
||||
|
@ -370,6 +376,7 @@ typedef struct mobj_s
|
|||
|
||||
struct pslope_s *standingslope; // The slope that the object is standing on (shouldn't need synced in savegames, right?)
|
||||
|
||||
boolean resetinterp; // if true, some fields should not be interpolated (see R_InterpolateMobjState implementation)
|
||||
boolean colorized; // Whether the mobj uses the rainbow colormap
|
||||
|
||||
// WARNING: New fields must be added separately to savegame and Lua.
|
||||
|
@ -389,6 +396,8 @@ typedef struct precipmobj_s
|
|||
|
||||
// Info for drawing: position.
|
||||
fixed_t x, y, z;
|
||||
fixed_t old_x, old_y, old_z; // position interpolation
|
||||
fixed_t old_x2, old_y2, old_z2;
|
||||
|
||||
// More list: links in sector (if needed)
|
||||
struct precipmobj_s *snext;
|
||||
|
@ -396,6 +405,8 @@ typedef struct precipmobj_s
|
|||
|
||||
// More drawing info: to determine current sprite.
|
||||
angle_t angle; // orientation
|
||||
angle_t old_angle; // orientation interpolation
|
||||
angle_t old_angle2;
|
||||
spritenum_t sprite; // used to find patch_t and flip value
|
||||
UINT32 frame; // frame number, plus bits see p_pspr.h
|
||||
UINT16 anim_duration; // for FF_ANIMATE states
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "p_tick.h"
|
||||
#include "p_local.h"
|
||||
#include "p_polyobj.h"
|
||||
#include "r_fps.h"
|
||||
#include "r_main.h"
|
||||
#include "r_state.h"
|
||||
#include "r_defs.h"
|
||||
|
@ -2367,6 +2368,9 @@ INT32 EV_DoPolyObjRotate(polyrotdata_t *prdata)
|
|||
|
||||
oldpo = po;
|
||||
|
||||
// interpolation
|
||||
R_CreateInterpolator_Polyobj(&th->thinker, po);
|
||||
|
||||
th->turnobjs = prdata->turnobjs;
|
||||
|
||||
// apply action to mirroring polyobjects as well
|
||||
|
@ -2428,6 +2432,9 @@ INT32 EV_DoPolyObjMove(polymovedata_t *pmdata)
|
|||
|
||||
oldpo = po;
|
||||
|
||||
// interpolation
|
||||
R_CreateInterpolator_Polyobj(&th->thinker, po);
|
||||
|
||||
// apply action to mirroring polyobjects as well
|
||||
start = 0;
|
||||
while ((po = Polyobj_GetChild(oldpo, &start)))
|
||||
|
@ -2443,12 +2450,14 @@ INT32 EV_DoPolyObjMove(polymovedata_t *pmdata)
|
|||
INT32 EV_DoPolyObjWaypoint(polywaypointdata_t *pwdata)
|
||||
{
|
||||
polyobj_t *po;
|
||||
polyobj_t *oldpo;
|
||||
polywaypoint_t *th;
|
||||
mobj_t *mo2;
|
||||
mobj_t *first = NULL;
|
||||
mobj_t *last = NULL;
|
||||
mobj_t *target = NULL;
|
||||
thinker_t *wp;
|
||||
INT32 start;
|
||||
|
||||
if (!(po = Polyobj_GetForNum(pwdata->polyObjNum)))
|
||||
{
|
||||
|
@ -2594,6 +2603,26 @@ INT32 EV_DoPolyObjWaypoint(polywaypointdata_t *pwdata)
|
|||
return 0;
|
||||
}
|
||||
|
||||
// interpolation
|
||||
R_CreateInterpolator_Polyobj(&th->thinker, po);
|
||||
// T_PolyObjWaypoint is the only polyobject movement
|
||||
// that can adjust z, so we add these ones too.
|
||||
R_CreateInterpolator_SectorPlane(&th->thinker, po->lines[0]->backsector, false);
|
||||
R_CreateInterpolator_SectorPlane(&th->thinker, po->lines[0]->backsector, true);
|
||||
|
||||
// Most other polyobject functions handle children by recursively
|
||||
// giving each child another thinker. T_PolyObjWaypoint handles
|
||||
// it manually though, which means we need to manually give them
|
||||
// interpolation here instead.
|
||||
start = 0;
|
||||
oldpo = po;
|
||||
while ((po = Polyobj_GetChild(oldpo, &start)))
|
||||
{
|
||||
R_CreateInterpolator_Polyobj(&th->thinker, po);
|
||||
R_CreateInterpolator_SectorPlane(&th->thinker, po->lines[0]->backsector, false);
|
||||
R_CreateInterpolator_SectorPlane(&th->thinker, po->lines[0]->backsector, true);
|
||||
}
|
||||
|
||||
// Set pointnum
|
||||
th->pointnum = target->health;
|
||||
|
||||
|
@ -2645,6 +2674,9 @@ static void Polyobj_doSlideDoor(polyobj_t *po, polydoordata_t *doordata)
|
|||
|
||||
oldpo = po;
|
||||
|
||||
// interpolation
|
||||
R_CreateInterpolator_Polyobj(&th->thinker, po);
|
||||
|
||||
// start action on mirroring polyobjects as well
|
||||
start = 0;
|
||||
while ((po = Polyobj_GetChild(oldpo, &start)))
|
||||
|
@ -2685,6 +2717,9 @@ static void Polyobj_doSwingDoor(polyobj_t *po, polydoordata_t *doordata)
|
|||
|
||||
oldpo = po;
|
||||
|
||||
// interpolation
|
||||
R_CreateInterpolator_Polyobj(&th->thinker, po);
|
||||
|
||||
// start action on mirroring polyobjects as well
|
||||
start = 0;
|
||||
while ((po = Polyobj_GetChild(oldpo, &start)))
|
||||
|
@ -2756,6 +2791,9 @@ INT32 EV_DoPolyObjDisplace(polydisplacedata_t *prdata)
|
|||
|
||||
oldpo = po;
|
||||
|
||||
// interpolation
|
||||
R_CreateInterpolator_Polyobj(&th->thinker, po);
|
||||
|
||||
// apply action to mirroring polyobjects as well
|
||||
start = 0;
|
||||
while ((po = Polyobj_GetChild(oldpo, &start)))
|
||||
|
@ -2859,6 +2897,9 @@ INT32 EV_DoPolyObjFlag(line_t *pfdata)
|
|||
|
||||
oldpo = po;
|
||||
|
||||
// interpolation
|
||||
R_CreateInterpolator_Polyobj(&th->thinker, po);
|
||||
|
||||
// apply action to mirroring polyobjects as well
|
||||
start = 0;
|
||||
while ((po = Polyobj_GetChild(oldpo, &start)))
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "p_local.h"
|
||||
#include "p_setup.h"
|
||||
#include "p_saveg.h"
|
||||
#include "r_fps.h"
|
||||
#include "r_things.h"
|
||||
#include "r_state.h"
|
||||
#include "w_wad.h"
|
||||
|
@ -2163,6 +2164,8 @@ static void LoadMobjThinker(actionf_p1 thinker)
|
|||
P_SetTarget(&waypointcap, mobj);
|
||||
|
||||
mobj->info = (mobjinfo_t *)next; // temporarily, set when leave this function
|
||||
|
||||
R_AddMobjInterpolator(mobj);
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "p_spec.h"
|
||||
#include "p_saveg.h"
|
||||
|
||||
#include "i_time.h"
|
||||
#include "i_sound.h" // for I_PlayCD()..
|
||||
#include "i_video.h" // for I_FinishUpdate()..
|
||||
#include "r_sky.h"
|
||||
|
@ -30,6 +31,7 @@
|
|||
#include "r_things.h"
|
||||
#include "r_sky.h"
|
||||
#include "r_draw.h"
|
||||
#include "r_fps.h" // R_ResetViewInterpolation in level load
|
||||
|
||||
#include "s_sound.h"
|
||||
#include "st_stuff.h"
|
||||
|
@ -2909,7 +2911,10 @@ boolean P_SetupLevel(boolean skipprecip)
|
|||
{
|
||||
// wait loop
|
||||
while (!((nowtime = I_GetTime()) - lastwipetic))
|
||||
I_Sleep();
|
||||
{
|
||||
I_Sleep(cv_sleep.value);
|
||||
I_UpdateTime(cv_timescale.value);
|
||||
}
|
||||
lastwipetic = nowtime;
|
||||
if (moviemode) // make sure we save frames for the white hold too
|
||||
M_SaveFrame();
|
||||
|
@ -2988,7 +2993,10 @@ boolean P_SetupLevel(boolean skipprecip)
|
|||
R_ClearLevelSplats();
|
||||
#endif
|
||||
|
||||
R_InitializeLevelInterpolators();
|
||||
|
||||
P_InitThinkers();
|
||||
R_InitMobjInterpolators();
|
||||
P_InitCachedActions();
|
||||
|
||||
/// \note for not spawning precipitation, etc. when loading netgame snapshots
|
||||
|
|
43
src/p_spec.c
43
src/p_spec.c
|
@ -20,6 +20,7 @@
|
|||
#include "p_local.h"
|
||||
#include "p_setup.h" // levelflats for flat animation
|
||||
#include "r_data.h"
|
||||
#include "r_fps.h"
|
||||
#include "m_random.h"
|
||||
#include "p_mobj.h"
|
||||
#include "i_system.h"
|
||||
|
@ -2384,7 +2385,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
|
|||
UINT8 i;
|
||||
|
||||
if (bot) // This might put poor Tails in a wall if he's too far behind! D: But okay, whatever! >:3
|
||||
P_TeleportMove(bot, bot->x + x, bot->y + y, bot->z + z);
|
||||
P_SetOrigin(bot, bot->x + x, bot->y + y, bot->z + z);
|
||||
|
||||
for (i = 0; i <= splitscreen; i++)
|
||||
{
|
||||
|
@ -2846,7 +2847,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
|
|||
// Reset bot too.
|
||||
if (bot) {
|
||||
if (line->flags & ML_NOCLIMB)
|
||||
P_TeleportMove(bot, mo->x, mo->y, mo->z);
|
||||
P_SetOrigin(bot, mo->x, mo->y, mo->z);
|
||||
bot->momx = bot->momy = bot->momz = 1;
|
||||
bot->pmomz = 0;
|
||||
bot->player->rmomx = bot->player->rmomy = 1;
|
||||
|
@ -2890,7 +2891,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
|
|||
// (Teleport them to you so they don't break it.)
|
||||
if (bot && (bot->flags2 & MF2_TWOD) != (mo->flags2 & MF2_TWOD)) {
|
||||
bot->flags2 = (bot->flags2 & ~MF2_TWOD) | (mo->flags2 & MF2_TWOD);
|
||||
P_TeleportMove(bot, mo->x, mo->y, mo->z);
|
||||
P_SetOrigin(bot, mo->x, mo->y, mo->z);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -5277,6 +5278,10 @@ static void P_AddFloatThinker(sector_t *sec, INT32 tag, line_t *sourceline)
|
|||
floater->sector = sec;
|
||||
floater->vars[0] = tag;
|
||||
floater->sourceline = sourceline;
|
||||
|
||||
// interpolation
|
||||
R_CreateInterpolator_SectorPlane(&floater->thinker, sec, false);
|
||||
R_CreateInterpolator_SectorPlane(&floater->thinker, sec, true);
|
||||
}
|
||||
|
||||
/** Adds a bridge thinker.
|
||||
|
@ -5309,6 +5314,9 @@ static inline void P_AddBridgeThinker(line_t *sourceline, sector_t *sec)
|
|||
// Control sector tags should be End_Tag + (End_Tag - Start_Tag)
|
||||
bridge->vars[4] = sourceline->tag; // Start tag
|
||||
bridge->vars[5] = (sides[sourceline->sidenum[0]].textureoffset>>FRACBITS); // End tag
|
||||
|
||||
// interpolation
|
||||
R_CreateInterpolator_SectorPlane(&bridge->thinker, §ors[affectee], false);
|
||||
}
|
||||
*/
|
||||
|
||||
|
@ -5388,6 +5396,10 @@ static void P_AddRaiseThinker(sector_t *sec, line_t *sourceline)
|
|||
- (sec->ceilingheight - sec->floorheight);
|
||||
|
||||
raise->sourceline = sourceline;
|
||||
|
||||
// interpolation
|
||||
R_CreateInterpolator_SectorPlane(&raise->thinker, sec, false);
|
||||
R_CreateInterpolator_SectorPlane(&raise->thinker, sec, true);
|
||||
}
|
||||
|
||||
// Function to maintain backwards compatibility
|
||||
|
@ -5430,6 +5442,10 @@ static void P_AddOldAirbob(sector_t *sec, line_t *sourceline, boolean noadjust)
|
|||
- (sec->ceilingheight - sec->floorheight);
|
||||
|
||||
airbob->sourceline = sourceline;
|
||||
|
||||
// interpolation
|
||||
R_CreateInterpolator_SectorPlane(&airbob->thinker, sec, false);
|
||||
R_CreateInterpolator_SectorPlane(&airbob->thinker, sec, true);
|
||||
}
|
||||
|
||||
/** Adds a thwomp thinker.
|
||||
|
@ -5471,6 +5487,11 @@ static inline void P_AddThwompThinker(sector_t *sec, sector_t *actionsector, lin
|
|||
thwomp->sourceline = sourceline;
|
||||
thwomp->sector->floordata = thwomp;
|
||||
thwomp->sector->ceilingdata = thwomp;
|
||||
|
||||
// interpolation
|
||||
R_CreateInterpolator_SectorPlane(&thwomp->thinker, sec, false);
|
||||
R_CreateInterpolator_SectorPlane(&thwomp->thinker, sec, true);
|
||||
|
||||
return;
|
||||
#undef speed
|
||||
#undef direction
|
||||
|
@ -7036,6 +7057,22 @@ static void Add_Scroller(INT32 type, fixed_t dx, fixed_t dy, INT32 control, INT3
|
|||
s->last_height = sectors[control].floorheight + sectors[control].ceilingheight;
|
||||
s->affectee = affectee;
|
||||
P_AddThinker(&s->thinker);
|
||||
|
||||
// interpolation
|
||||
switch (type)
|
||||
{
|
||||
case sc_side:
|
||||
R_CreateInterpolator_SideScroll(&s->thinker, &sides[affectee]);
|
||||
break;
|
||||
case sc_floor:
|
||||
R_CreateInterpolator_SectorScroll(&s->thinker, §ors[affectee], false);
|
||||
break;
|
||||
case sc_ceiling:
|
||||
R_CreateInterpolator_SectorScroll(&s->thinker, §ors[affectee], true);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/** Adds a wall scroller.
|
||||
|
|
|
@ -128,7 +128,7 @@ boolean P_Teleport(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle
|
|||
{
|
||||
UINT8 i;
|
||||
|
||||
if (!P_TeleportMove(thing, x, y, z))
|
||||
if (!P_SetOrigin(thing, x, y, z))
|
||||
return false;
|
||||
|
||||
thing->angle = angle;
|
||||
|
|
17
src/p_tick.c
17
src/p_tick.c
|
@ -23,6 +23,7 @@
|
|||
#include "lua_script.h"
|
||||
#include "lua_hook.h"
|
||||
#include "k_kart.h"
|
||||
#include "r_fps.h"
|
||||
|
||||
// Object place
|
||||
#include "m_cheat.h"
|
||||
|
@ -582,8 +583,10 @@ void P_Ticker(boolean run)
|
|||
if (OP_FreezeObjectplace())
|
||||
{
|
||||
P_MapStart();
|
||||
R_UpdateMobjInterpolators();
|
||||
OP_ObjectplaceMovement(&players[0]);
|
||||
P_MoveChaseCamera(&players[0], &camera[0], false);
|
||||
R_UpdateViewInterpolation();
|
||||
P_MapEnd();
|
||||
return;
|
||||
}
|
||||
|
@ -610,6 +613,8 @@ void P_Ticker(boolean run)
|
|||
|
||||
if (run)
|
||||
{
|
||||
R_UpdateMobjInterpolators();
|
||||
|
||||
if (demo.recording)
|
||||
{
|
||||
G_WriteDemoExtraData();
|
||||
|
@ -796,6 +801,12 @@ void P_Ticker(boolean run)
|
|||
P_MoveChaseCamera(&players[displayplayers[i]], &camera[i], false);
|
||||
}
|
||||
|
||||
if (run)
|
||||
{
|
||||
R_UpdateLevelInterpolators();
|
||||
R_UpdateViewInterpolation();
|
||||
}
|
||||
|
||||
P_MapEnd();
|
||||
|
||||
if (demo.playback)
|
||||
|
@ -819,6 +830,8 @@ void P_PreTicker(INT32 frames)
|
|||
{
|
||||
P_MapStart();
|
||||
|
||||
R_UpdateMobjInterpolators();
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
LUAh_PreThinkFrame();
|
||||
#endif
|
||||
|
@ -861,6 +874,10 @@ void P_PreTicker(INT32 frames)
|
|||
LUAh_PostThinkFrame();
|
||||
#endif
|
||||
|
||||
R_UpdateLevelInterpolators();
|
||||
R_UpdateViewInterpolation();
|
||||
R_ResetViewInterpolation(0);
|
||||
|
||||
P_MapEnd();
|
||||
|
||||
hook_defrosting--;
|
||||
|
|
13
src/p_user.c
13
src/p_user.c
|
@ -20,6 +20,7 @@
|
|||
#include "d_net.h"
|
||||
#include "g_game.h"
|
||||
#include "p_local.h"
|
||||
#include "r_fps.h"
|
||||
#include "r_main.h"
|
||||
#include "s_sound.h"
|
||||
#include "r_things.h"
|
||||
|
@ -1683,6 +1684,12 @@ mobj_t *P_SpawnGhostMobj(mobj_t *mobj)
|
|||
if (!(mobj->flags & MF_DONTENCOREMAP))
|
||||
mobj->flags &= ~MF_DONTENCOREMAP;
|
||||
|
||||
// Copy interpolation data :)
|
||||
ghost->old_x = mobj->old_x2;
|
||||
ghost->old_y = mobj->old_y2;
|
||||
ghost->old_z = mobj->old_z2;
|
||||
ghost->old_angle = (mobj->player ? mobj->player->old_frameangle2 : mobj->old_angle2);
|
||||
|
||||
return ghost;
|
||||
}
|
||||
|
||||
|
@ -7985,7 +7992,11 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
|||
}
|
||||
|
||||
if (lookbackdown)
|
||||
{
|
||||
P_MoveChaseCamera(player, thiscam, false);
|
||||
R_ResetViewInterpolation(num + 1);
|
||||
R_ResetViewInterpolation(num + 1);
|
||||
}
|
||||
|
||||
return (x == thiscam->x && y == thiscam->y && z == thiscam->z && angle == thiscam->aiming);
|
||||
}
|
||||
|
@ -9102,7 +9113,7 @@ void P_PlayerAfterThink(player_t *player)
|
|||
player->mo->momx = (player->mo->tracer->x - player->mo->x)*2;
|
||||
player->mo->momy = (player->mo->tracer->y - player->mo->y)*2;
|
||||
player->mo->momz = (player->mo->tracer->z - (player->mo->height-player->mo->tracer->height/2) - player->mo->z)*2;
|
||||
P_TeleportMove(player->mo, player->mo->tracer->x, player->mo->tracer->y, player->mo->tracer->z - (player->mo->height-player->mo->tracer->height/2));
|
||||
P_MoveOrigin(player->mo, player->mo->tracer->x, player->mo->tracer->y, player->mo->tracer->z - (player->mo->height-player->mo->tracer->height/2));
|
||||
player->pflags |= PF_JUMPED;
|
||||
player->secondjump = 0;
|
||||
player->pflags &= ~PF_THOKKED;
|
||||
|
|
20
src/r_bsp.c
20
src/r_bsp.c
|
@ -831,6 +831,7 @@ static void R_Subsector(size_t num)
|
|||
extracolormap_t *floorcolormap;
|
||||
extracolormap_t *ceilingcolormap;
|
||||
fixed_t floorcenterz, ceilingcenterz;
|
||||
ffloor_t *rover;
|
||||
|
||||
#ifdef RANGECHECK
|
||||
if (num >= numsubsectors)
|
||||
|
@ -862,7 +863,23 @@ static void R_Subsector(size_t num)
|
|||
// Check and prep all 3D floors. Set the sector floor/ceiling light levels and colormaps.
|
||||
if (frontsector->ffloors)
|
||||
{
|
||||
if (frontsector->moved)
|
||||
boolean anyMoved = frontsector->moved;
|
||||
|
||||
if (anyMoved == false)
|
||||
{
|
||||
for (rover = frontsector->ffloors; rover; rover = rover->next)
|
||||
{
|
||||
sector_t *controlSec = §ors[rover->secnum];
|
||||
|
||||
if (controlSec->moved == true)
|
||||
{
|
||||
anyMoved = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (anyMoved == true)
|
||||
{
|
||||
frontsector->numlights = sub->sector->numlights = 0;
|
||||
R_Prep3DFloors(frontsector);
|
||||
|
@ -919,7 +936,6 @@ static void R_Subsector(size_t num)
|
|||
ffloor[numffloors].polyobj = NULL;
|
||||
if (frontsector->ffloors)
|
||||
{
|
||||
ffloor_t *rover;
|
||||
fixed_t heightcheck, planecenterz;
|
||||
|
||||
for (rover = frontsector->ffloors; rover && numffloors < MAXFFLOORS; rover = rover->next)
|
||||
|
|
762
src/r_fps.c
Normal file
762
src/r_fps.c
Normal file
|
@ -0,0 +1,762 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2000 by Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze, Andrey Budko (prboom)
|
||||
// Copyright (C) 1999-2019 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file r_fps.h
|
||||
/// \brief Uncapped framerate stuff.
|
||||
|
||||
#include "r_fps.h"
|
||||
|
||||
#include "r_main.h"
|
||||
#include "g_game.h"
|
||||
#include "i_video.h"
|
||||
#include "r_plane.h"
|
||||
#include "p_spec.h"
|
||||
#include "r_state.h"
|
||||
#include "z_zone.h"
|
||||
#include "console.h" // con_startup_loadprogress
|
||||
|
||||
static CV_PossibleValue_t fpscap_cons_t[] = {
|
||||
#ifdef DEVELOP
|
||||
// Lower values are actually pretty useful for debugging interp problems!
|
||||
{1, "MIN"},
|
||||
#else
|
||||
{TICRATE, "MIN"},
|
||||
#endif
|
||||
{300, "MAX"},
|
||||
{-1, "Unlimited"},
|
||||
{0, "Match refresh rate"},
|
||||
{0, NULL}
|
||||
};
|
||||
consvar_t cv_fpscap = {"fpscap", "Match refresh rate", CV_SAVE, fpscap_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
UINT32 R_GetFramerateCap(void)
|
||||
{
|
||||
if (rendermode == render_none)
|
||||
{
|
||||
// If we're not rendering (dedicated server),
|
||||
// we shouldn't be using any interpolation.
|
||||
return TICRATE;
|
||||
}
|
||||
|
||||
if (cv_fpscap.value == 0)
|
||||
{
|
||||
// 0: Match refresh rate
|
||||
return I_GetRefreshRate();
|
||||
}
|
||||
|
||||
if (cv_fpscap.value < 0)
|
||||
{
|
||||
// -1: Unlimited
|
||||
return 0;
|
||||
}
|
||||
|
||||
return cv_fpscap.value;
|
||||
}
|
||||
|
||||
boolean R_UsingFrameInterpolation(void)
|
||||
{
|
||||
return (R_GetFramerateCap() != TICRATE || cv_timescale.value < FRACUNIT);
|
||||
}
|
||||
|
||||
static viewvars_t pview_old[MAXSPLITSCREENPLAYERS];
|
||||
static viewvars_t pview_new[MAXSPLITSCREENPLAYERS];
|
||||
static viewvars_t skyview_old[MAXSPLITSCREENPLAYERS];
|
||||
static viewvars_t skyview_new[MAXSPLITSCREENPLAYERS];
|
||||
|
||||
static viewvars_t *oldview = &pview_old[0];
|
||||
static int oldview_invalid[MAXSPLITSCREENPLAYERS] = {0, 0, 0, 0};
|
||||
viewvars_t *newview = &pview_new[0];
|
||||
|
||||
|
||||
enum viewcontext_e viewcontext = VIEWCONTEXT_PLAYER1;
|
||||
|
||||
static levelinterpolator_t **levelinterpolators;
|
||||
static size_t levelinterpolators_len;
|
||||
static size_t levelinterpolators_size;
|
||||
|
||||
|
||||
static fixed_t R_LerpFixed(fixed_t from, fixed_t to, fixed_t frac)
|
||||
{
|
||||
return from + FixedMul(frac, to - from);
|
||||
}
|
||||
|
||||
static angle_t R_LerpAngle(angle_t from, angle_t to, fixed_t frac)
|
||||
{
|
||||
return from + FixedMul(frac, to - from);
|
||||
}
|
||||
|
||||
static vector2_t *R_LerpVector2(const vector2_t *from, const vector2_t *to, fixed_t frac, vector2_t *out)
|
||||
{
|
||||
FV2_SubEx(to, from, out);
|
||||
FV2_MulEx(out, frac, out);
|
||||
FV2_AddEx(from, out, out);
|
||||
return out;
|
||||
}
|
||||
|
||||
static vector3_t *R_LerpVector3(const vector3_t *from, const vector3_t *to, fixed_t frac, vector3_t *out)
|
||||
{
|
||||
FV3_SubEx(to, from, out);
|
||||
FV3_MulEx(out, frac, out);
|
||||
FV3_AddEx(from, out, out);
|
||||
return out;
|
||||
}
|
||||
|
||||
// recalc necessary stuff for mouseaiming
|
||||
// slopes are already calculated for the full possible view (which is 4*viewheight).
|
||||
// 18/08/18: (No it's actually 16*viewheight, thanks Jimita for finding this out)
|
||||
static void R_SetupFreelook(player_t *player, boolean skybox)
|
||||
{
|
||||
(void)player;
|
||||
(void)skybox;
|
||||
|
||||
// clip it in the case we are looking a hardware 90 degrees full aiming
|
||||
// (lmps, network and use F12...)
|
||||
if (rendermode == render_soft)
|
||||
{
|
||||
G_SoftwareClipAimingPitch((INT32 *)&aimingangle);
|
||||
}
|
||||
|
||||
centeryfrac = (viewheight/2)<<FRACBITS;
|
||||
|
||||
if (rendermode == render_soft)
|
||||
centeryfrac += FixedMul(AIMINGTODY(aimingangle), FixedDiv(viewwidth<<FRACBITS, BASEVIDWIDTH<<FRACBITS));
|
||||
|
||||
centery = FixedInt(FixedRound(centeryfrac));
|
||||
|
||||
if (rendermode == render_soft)
|
||||
yslope = &yslopetab[viewheight*8 - centery];
|
||||
}
|
||||
|
||||
#undef AIMINGTODY
|
||||
|
||||
void R_InterpolateView(fixed_t frac)
|
||||
{
|
||||
viewvars_t* prevview = oldview;
|
||||
boolean skybox = 0;
|
||||
UINT8 i;
|
||||
|
||||
if (FIXED_TO_FLOAT(frac) < 0)
|
||||
frac = 0;
|
||||
if (frac > FRACUNIT)
|
||||
frac = FRACUNIT;
|
||||
|
||||
if (viewcontext >= VIEWCONTEXT_SKY1)
|
||||
{
|
||||
i = viewcontext - VIEWCONTEXT_SKY1;
|
||||
}
|
||||
else
|
||||
{
|
||||
i = viewcontext - VIEWCONTEXT_PLAYER1;
|
||||
}
|
||||
|
||||
if (oldview_invalid[i] != 0)
|
||||
{
|
||||
// interpolate from newview to newview
|
||||
prevview = newview;
|
||||
}
|
||||
|
||||
viewx = R_LerpFixed(prevview->x, newview->x, frac);
|
||||
viewy = R_LerpFixed(prevview->y, newview->y, frac);
|
||||
viewz = R_LerpFixed(prevview->z, newview->z, frac);
|
||||
|
||||
viewangle = R_LerpAngle(prevview->angle, newview->angle, frac);
|
||||
aimingangle = R_LerpAngle(prevview->aim, newview->aim, frac);
|
||||
|
||||
viewsin = FINESINE(viewangle>>ANGLETOFINESHIFT);
|
||||
viewcos = FINECOSINE(viewangle>>ANGLETOFINESHIFT);
|
||||
|
||||
// this is gonna create some interesting visual errors for long distance teleports...
|
||||
// might want to recalculate the view sector every frame instead...
|
||||
viewplayer = newview->player;
|
||||
viewsector = R_PointInSubsector(viewx, viewy)->sector;
|
||||
|
||||
R_SetupFreelook(newview->player, skybox);
|
||||
}
|
||||
|
||||
void R_UpdateViewInterpolation(void)
|
||||
{
|
||||
UINT8 i;
|
||||
|
||||
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
|
||||
{
|
||||
pview_old[i] = pview_new[i];
|
||||
skyview_old[i] = skyview_new[i];
|
||||
|
||||
if (oldview_invalid[i]) oldview_invalid[i]--;
|
||||
}
|
||||
}
|
||||
|
||||
void R_ResetViewInterpolation(UINT8 p)
|
||||
{
|
||||
if (p == 0)
|
||||
{
|
||||
UINT8 i;
|
||||
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
|
||||
{
|
||||
oldview_invalid[i]++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
oldview_invalid[p - 1]++;
|
||||
}
|
||||
}
|
||||
|
||||
void R_SetViewContext(enum viewcontext_e _viewcontext)
|
||||
{
|
||||
UINT8 i = 0;
|
||||
|
||||
I_Assert(_viewcontext >= VIEWCONTEXT_PLAYER1
|
||||
&& _viewcontext <= VIEWCONTEXT_SKY4);
|
||||
viewcontext = _viewcontext;
|
||||
|
||||
switch (viewcontext)
|
||||
{
|
||||
case VIEWCONTEXT_PLAYER1:
|
||||
case VIEWCONTEXT_PLAYER2:
|
||||
case VIEWCONTEXT_PLAYER3:
|
||||
case VIEWCONTEXT_PLAYER4:
|
||||
i = viewcontext - VIEWCONTEXT_PLAYER1;
|
||||
oldview = &pview_old[i];
|
||||
newview = &pview_new[i];
|
||||
break;
|
||||
case VIEWCONTEXT_SKY1:
|
||||
case VIEWCONTEXT_SKY2:
|
||||
case VIEWCONTEXT_SKY3:
|
||||
case VIEWCONTEXT_SKY4:
|
||||
i = viewcontext - VIEWCONTEXT_SKY1;
|
||||
oldview = &skyview_old[i];
|
||||
newview = &skyview_new[i];
|
||||
break;
|
||||
default:
|
||||
I_Error("viewcontext value is invalid: we should never get here without an assert!!");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
fixed_t R_InterpolateFixed(fixed_t from, fixed_t to)
|
||||
{
|
||||
if (!R_UsingFrameInterpolation())
|
||||
{
|
||||
return to;
|
||||
}
|
||||
|
||||
return (R_LerpFixed(from, to, rendertimefrac));
|
||||
}
|
||||
|
||||
angle_t R_InterpolateAngle(angle_t from, angle_t to)
|
||||
{
|
||||
if (!R_UsingFrameInterpolation())
|
||||
{
|
||||
return to;
|
||||
}
|
||||
|
||||
return (R_LerpAngle(from, to, rendertimefrac));
|
||||
}
|
||||
|
||||
void R_InterpolateMobjState(mobj_t *mobj, fixed_t frac, interpmobjstate_t *out)
|
||||
{
|
||||
if (frac == FRACUNIT)
|
||||
{
|
||||
out->x = mobj->x;
|
||||
out->y = mobj->y;
|
||||
out->z = mobj->z;
|
||||
out->scale = mobj->scale;
|
||||
out->subsector = mobj->subsector;
|
||||
out->angle = mobj->player ? mobj->player->frameangle : mobj->angle;
|
||||
return;
|
||||
}
|
||||
|
||||
out->x = R_LerpFixed(mobj->old_x, mobj->x, frac);
|
||||
out->y = R_LerpFixed(mobj->old_y, mobj->y, frac);
|
||||
out->z = R_LerpFixed(mobj->old_z, mobj->z, frac);
|
||||
out->scale = mobj->resetinterp ? mobj->scale : R_LerpFixed(mobj->old_scale, mobj->scale, frac);
|
||||
|
||||
out->subsector = R_PointInSubsector(out->x, out->y);
|
||||
|
||||
if (mobj->player)
|
||||
{
|
||||
out->angle = mobj->resetinterp ? mobj->player->frameangle : R_LerpAngle(mobj->player->old_frameangle, mobj->player->frameangle, frac);
|
||||
}
|
||||
else
|
||||
{
|
||||
out->angle = mobj->resetinterp ? mobj->angle : R_LerpAngle(mobj->old_angle, mobj->angle, frac);
|
||||
}
|
||||
}
|
||||
|
||||
void R_InterpolatePrecipMobjState(precipmobj_t *mobj, fixed_t frac, interpmobjstate_t *out)
|
||||
{
|
||||
if (frac == FRACUNIT)
|
||||
{
|
||||
out->x = mobj->x;
|
||||
out->y = mobj->y;
|
||||
out->z = mobj->z;
|
||||
out->scale = FRACUNIT;
|
||||
out->subsector = mobj->subsector;
|
||||
out->angle = mobj->angle;
|
||||
return;
|
||||
}
|
||||
|
||||
out->x = R_LerpFixed(mobj->old_x, mobj->x, frac);
|
||||
out->y = R_LerpFixed(mobj->old_y, mobj->y, frac);
|
||||
out->z = R_LerpFixed(mobj->old_z, mobj->z, frac);
|
||||
out->scale = FRACUNIT;
|
||||
|
||||
out->subsector = R_PointInSubsector(out->x, out->y);
|
||||
|
||||
out->angle = R_LerpAngle(mobj->old_angle, mobj->angle, frac);
|
||||
}
|
||||
|
||||
static void AddInterpolator(levelinterpolator_t* interpolator)
|
||||
{
|
||||
if (levelinterpolators_len >= levelinterpolators_size)
|
||||
{
|
||||
if (levelinterpolators_size == 0)
|
||||
{
|
||||
levelinterpolators_size = 128;
|
||||
}
|
||||
else
|
||||
{
|
||||
levelinterpolators_size *= 2;
|
||||
}
|
||||
|
||||
levelinterpolators = Z_ReallocAlign(
|
||||
(void*) levelinterpolators,
|
||||
sizeof(levelinterpolator_t*) * levelinterpolators_size,
|
||||
PU_LEVEL,
|
||||
NULL,
|
||||
sizeof(levelinterpolator_t*) * 8
|
||||
);
|
||||
}
|
||||
|
||||
levelinterpolators[levelinterpolators_len] = interpolator;
|
||||
levelinterpolators_len += 1;
|
||||
}
|
||||
|
||||
static levelinterpolator_t *CreateInterpolator(levelinterpolator_type_e type, thinker_t *thinker)
|
||||
{
|
||||
levelinterpolator_t *ret = (levelinterpolator_t*) Z_CallocAlign(
|
||||
sizeof(levelinterpolator_t),
|
||||
PU_LEVEL,
|
||||
NULL,
|
||||
sizeof(levelinterpolator_t) * 8
|
||||
);
|
||||
|
||||
ret->type = type;
|
||||
ret->thinker = thinker;
|
||||
|
||||
AddInterpolator(ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void R_CreateInterpolator_SectorPlane(thinker_t *thinker, sector_t *sector, boolean ceiling)
|
||||
{
|
||||
levelinterpolator_t *interp = CreateInterpolator(LVLINTERP_SectorPlane, thinker);
|
||||
interp->sectorplane.sector = sector;
|
||||
interp->sectorplane.ceiling = ceiling;
|
||||
if (ceiling)
|
||||
{
|
||||
interp->sectorplane.oldheight = interp->sectorplane.bakheight = sector->ceilingheight;
|
||||
}
|
||||
else
|
||||
{
|
||||
interp->sectorplane.oldheight = interp->sectorplane.bakheight = sector->floorheight;
|
||||
}
|
||||
}
|
||||
|
||||
void R_CreateInterpolator_SectorScroll(thinker_t *thinker, sector_t *sector, boolean ceiling)
|
||||
{
|
||||
levelinterpolator_t *interp = CreateInterpolator(LVLINTERP_SectorScroll, thinker);
|
||||
interp->sectorscroll.sector = sector;
|
||||
interp->sectorscroll.ceiling = ceiling;
|
||||
if (ceiling)
|
||||
{
|
||||
interp->sectorscroll.oldxoffs = interp->sectorscroll.bakxoffs = sector->ceiling_xoffs;
|
||||
interp->sectorscroll.oldyoffs = interp->sectorscroll.bakyoffs = sector->ceiling_yoffs;
|
||||
}
|
||||
else
|
||||
{
|
||||
interp->sectorscroll.oldxoffs = interp->sectorscroll.bakxoffs = sector->floor_xoffs;
|
||||
interp->sectorscroll.oldyoffs = interp->sectorscroll.bakyoffs = sector->floor_yoffs;
|
||||
}
|
||||
}
|
||||
|
||||
void R_CreateInterpolator_SideScroll(thinker_t *thinker, side_t *side)
|
||||
{
|
||||
levelinterpolator_t *interp = CreateInterpolator(LVLINTERP_SideScroll, thinker);
|
||||
interp->sidescroll.side = side;
|
||||
interp->sidescroll.oldtextureoffset = interp->sidescroll.baktextureoffset = side->textureoffset;
|
||||
interp->sidescroll.oldrowoffset = interp->sidescroll.bakrowoffset = side->rowoffset;
|
||||
}
|
||||
|
||||
void R_CreateInterpolator_Polyobj(thinker_t *thinker, polyobj_t *polyobj)
|
||||
{
|
||||
levelinterpolator_t *interp = CreateInterpolator(LVLINTERP_Polyobj, thinker);
|
||||
interp->polyobj.polyobj = polyobj;
|
||||
interp->polyobj.vertices_size = polyobj->numVertices;
|
||||
|
||||
interp->polyobj.oldvertices = Z_CallocAlign(sizeof(fixed_t) * 2 * polyobj->numVertices, PU_LEVEL, NULL, 32);
|
||||
interp->polyobj.bakvertices = Z_CallocAlign(sizeof(fixed_t) * 2 * polyobj->numVertices, PU_LEVEL, NULL, 32);
|
||||
for (size_t i = 0; i < polyobj->numVertices; i++)
|
||||
{
|
||||
interp->polyobj.oldvertices[i * 2 ] = interp->polyobj.bakvertices[i * 2 ] = polyobj->vertices[i]->x;
|
||||
interp->polyobj.oldvertices[i * 2 + 1] = interp->polyobj.bakvertices[i * 2 + 1] = polyobj->vertices[i]->y;
|
||||
}
|
||||
|
||||
interp->polyobj.oldcx = interp->polyobj.bakcx = polyobj->centerPt.x;
|
||||
interp->polyobj.oldcy = interp->polyobj.bakcy = polyobj->centerPt.y;
|
||||
}
|
||||
|
||||
void R_CreateInterpolator_DynSlope(thinker_t *thinker, pslope_t *slope)
|
||||
{
|
||||
levelinterpolator_t *interp = CreateInterpolator(LVLINTERP_DynSlope, thinker);
|
||||
interp->dynslope.slope = slope;
|
||||
|
||||
FV3_Copy(&interp->dynslope.oldo, &slope->o);
|
||||
FV3_Copy(&interp->dynslope.bako, &slope->o);
|
||||
|
||||
FV2_Copy(&interp->dynslope.oldd, &slope->d);
|
||||
FV2_Copy(&interp->dynslope.bakd, &slope->d);
|
||||
|
||||
interp->dynslope.oldzdelta = interp->dynslope.bakzdelta = slope->zdelta;
|
||||
}
|
||||
|
||||
void R_InitializeLevelInterpolators(void)
|
||||
{
|
||||
levelinterpolators_len = 0;
|
||||
levelinterpolators_size = 0;
|
||||
levelinterpolators = NULL;
|
||||
}
|
||||
|
||||
static void UpdateLevelInterpolatorState(levelinterpolator_t *interp)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
switch (interp->type)
|
||||
{
|
||||
case LVLINTERP_SectorPlane:
|
||||
interp->sectorplane.oldheight = interp->sectorplane.bakheight;
|
||||
interp->sectorplane.bakheight = interp->sectorplane.ceiling ? interp->sectorplane.sector->ceilingheight : interp->sectorplane.sector->floorheight;
|
||||
break;
|
||||
case LVLINTERP_SectorScroll:
|
||||
interp->sectorscroll.oldxoffs = interp->sectorscroll.bakxoffs;
|
||||
interp->sectorscroll.bakxoffs = interp->sectorscroll.ceiling ? interp->sectorscroll.sector->ceiling_xoffs : interp->sectorscroll.sector->floor_xoffs;
|
||||
interp->sectorscroll.oldyoffs = interp->sectorscroll.bakyoffs;
|
||||
interp->sectorscroll.bakyoffs = interp->sectorscroll.ceiling ? interp->sectorscroll.sector->ceiling_yoffs : interp->sectorscroll.sector->floor_yoffs;
|
||||
break;
|
||||
case LVLINTERP_SideScroll:
|
||||
interp->sidescroll.oldtextureoffset = interp->sidescroll.baktextureoffset;
|
||||
interp->sidescroll.baktextureoffset = interp->sidescroll.side->textureoffset;
|
||||
interp->sidescroll.oldrowoffset = interp->sidescroll.bakrowoffset;
|
||||
interp->sidescroll.bakrowoffset = interp->sidescroll.side->rowoffset;
|
||||
break;
|
||||
case LVLINTERP_Polyobj:
|
||||
for (i = 0; i < interp->polyobj.vertices_size; i++)
|
||||
{
|
||||
interp->polyobj.oldvertices[i * 2 ] = interp->polyobj.bakvertices[i * 2 ];
|
||||
interp->polyobj.oldvertices[i * 2 + 1] = interp->polyobj.bakvertices[i * 2 + 1];
|
||||
interp->polyobj.bakvertices[i * 2 ] = interp->polyobj.polyobj->vertices[i]->x;
|
||||
interp->polyobj.bakvertices[i * 2 + 1] = interp->polyobj.polyobj->vertices[i]->y;
|
||||
}
|
||||
interp->polyobj.oldcx = interp->polyobj.bakcx;
|
||||
interp->polyobj.oldcy = interp->polyobj.bakcy;
|
||||
interp->polyobj.bakcx = interp->polyobj.polyobj->centerPt.x;
|
||||
interp->polyobj.bakcy = interp->polyobj.polyobj->centerPt.y;
|
||||
break;
|
||||
case LVLINTERP_DynSlope:
|
||||
FV3_Copy(&interp->dynslope.oldo, &interp->dynslope.bako);
|
||||
FV2_Copy(&interp->dynslope.oldd, &interp->dynslope.bakd);
|
||||
interp->dynslope.oldzdelta = interp->dynslope.bakzdelta;
|
||||
|
||||
FV3_Copy(&interp->dynslope.bako, &interp->dynslope.slope->o);
|
||||
FV2_Copy(&interp->dynslope.bakd, &interp->dynslope.slope->d);
|
||||
interp->dynslope.bakzdelta = interp->dynslope.slope->zdelta;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void R_UpdateLevelInterpolators(void)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < levelinterpolators_len; i++)
|
||||
{
|
||||
levelinterpolator_t *interp = levelinterpolators[i];
|
||||
|
||||
UpdateLevelInterpolatorState(interp);
|
||||
}
|
||||
}
|
||||
|
||||
void R_ClearLevelInterpolatorState(thinker_t *thinker)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < levelinterpolators_len; i++)
|
||||
{
|
||||
levelinterpolator_t *interp = levelinterpolators[i];
|
||||
|
||||
if (interp->thinker == thinker)
|
||||
{
|
||||
// Do it twice to make the old state match the new
|
||||
UpdateLevelInterpolatorState(interp);
|
||||
UpdateLevelInterpolatorState(interp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void R_ApplyLevelInterpolators(fixed_t frac)
|
||||
{
|
||||
size_t i, ii;
|
||||
|
||||
for (i = 0; i < levelinterpolators_len; i++)
|
||||
{
|
||||
levelinterpolator_t *interp = levelinterpolators[i];
|
||||
|
||||
switch (interp->type)
|
||||
{
|
||||
case LVLINTERP_SectorPlane:
|
||||
if (interp->sectorplane.ceiling)
|
||||
{
|
||||
interp->sectorplane.sector->ceilingheight = R_LerpFixed(interp->sectorplane.oldheight, interp->sectorplane.bakheight, frac);
|
||||
}
|
||||
else
|
||||
{
|
||||
interp->sectorplane.sector->floorheight = R_LerpFixed(interp->sectorplane.oldheight, interp->sectorplane.bakheight, frac);
|
||||
}
|
||||
interp->sectorplane.sector->moved = true;
|
||||
break;
|
||||
case LVLINTERP_SectorScroll:
|
||||
if (interp->sectorscroll.ceiling)
|
||||
{
|
||||
interp->sectorscroll.sector->ceiling_xoffs = R_LerpFixed(interp->sectorscroll.oldxoffs, interp->sectorscroll.bakxoffs, frac);
|
||||
interp->sectorscroll.sector->ceiling_yoffs = R_LerpFixed(interp->sectorscroll.oldyoffs, interp->sectorscroll.bakyoffs, frac);
|
||||
}
|
||||
else
|
||||
{
|
||||
interp->sectorscroll.sector->floor_xoffs = R_LerpFixed(interp->sectorscroll.oldxoffs, interp->sectorscroll.bakxoffs, frac);
|
||||
interp->sectorscroll.sector->floor_yoffs = R_LerpFixed(interp->sectorscroll.oldyoffs, interp->sectorscroll.bakyoffs, frac);
|
||||
}
|
||||
break;
|
||||
case LVLINTERP_SideScroll:
|
||||
interp->sidescroll.side->textureoffset = R_LerpFixed(interp->sidescroll.oldtextureoffset, interp->sidescroll.baktextureoffset, frac);
|
||||
interp->sidescroll.side->rowoffset = R_LerpFixed(interp->sidescroll.oldrowoffset, interp->sidescroll.bakrowoffset, frac);
|
||||
break;
|
||||
case LVLINTERP_Polyobj:
|
||||
for (ii = 0; ii < interp->polyobj.vertices_size; ii++)
|
||||
{
|
||||
interp->polyobj.polyobj->vertices[ii]->x = R_LerpFixed(interp->polyobj.oldvertices[ii * 2 ], interp->polyobj.bakvertices[ii * 2 ], frac);
|
||||
interp->polyobj.polyobj->vertices[ii]->y = R_LerpFixed(interp->polyobj.oldvertices[ii * 2 + 1], interp->polyobj.bakvertices[ii * 2 + 1], frac);
|
||||
}
|
||||
interp->polyobj.polyobj->centerPt.x = R_LerpFixed(interp->polyobj.oldcx, interp->polyobj.bakcx, frac);
|
||||
interp->polyobj.polyobj->centerPt.y = R_LerpFixed(interp->polyobj.oldcy, interp->polyobj.bakcy, frac);
|
||||
break;
|
||||
case LVLINTERP_DynSlope:
|
||||
R_LerpVector3(&interp->dynslope.oldo, &interp->dynslope.bako, frac, &interp->dynslope.slope->o);
|
||||
R_LerpVector2(&interp->dynslope.oldd, &interp->dynslope.bakd, frac, &interp->dynslope.slope->d);
|
||||
interp->dynslope.slope->zdelta = R_LerpFixed(interp->dynslope.oldzdelta, interp->dynslope.bakzdelta, frac);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void R_RestoreLevelInterpolators(void)
|
||||
{
|
||||
size_t i, ii;
|
||||
|
||||
for (i = 0; i < levelinterpolators_len; i++)
|
||||
{
|
||||
levelinterpolator_t *interp = levelinterpolators[i];
|
||||
|
||||
switch (interp->type)
|
||||
{
|
||||
case LVLINTERP_SectorPlane:
|
||||
if (interp->sectorplane.ceiling)
|
||||
{
|
||||
interp->sectorplane.sector->ceilingheight = interp->sectorplane.bakheight;
|
||||
}
|
||||
else
|
||||
{
|
||||
interp->sectorplane.sector->floorheight = interp->sectorplane.bakheight;
|
||||
}
|
||||
interp->sectorplane.sector->moved = true;
|
||||
break;
|
||||
case LVLINTERP_SectorScroll:
|
||||
if (interp->sectorscroll.ceiling)
|
||||
{
|
||||
interp->sectorscroll.sector->ceiling_xoffs = interp->sectorscroll.bakxoffs;
|
||||
interp->sectorscroll.sector->ceiling_yoffs = interp->sectorscroll.bakyoffs;
|
||||
}
|
||||
else
|
||||
{
|
||||
interp->sectorscroll.sector->floor_xoffs = interp->sectorscroll.bakxoffs;
|
||||
interp->sectorscroll.sector->floor_yoffs = interp->sectorscroll.bakyoffs;
|
||||
}
|
||||
break;
|
||||
case LVLINTERP_SideScroll:
|
||||
interp->sidescroll.side->textureoffset = interp->sidescroll.baktextureoffset;
|
||||
interp->sidescroll.side->rowoffset = interp->sidescroll.bakrowoffset;
|
||||
break;
|
||||
case LVLINTERP_Polyobj:
|
||||
for (ii = 0; ii < interp->polyobj.vertices_size; ii++)
|
||||
{
|
||||
interp->polyobj.polyobj->vertices[ii]->x = interp->polyobj.bakvertices[ii * 2 ];
|
||||
interp->polyobj.polyobj->vertices[ii]->y = interp->polyobj.bakvertices[ii * 2 + 1];
|
||||
}
|
||||
interp->polyobj.polyobj->centerPt.x = interp->polyobj.bakcx;
|
||||
interp->polyobj.polyobj->centerPt.y = interp->polyobj.bakcy;
|
||||
break;
|
||||
case LVLINTERP_DynSlope:
|
||||
FV3_Copy(&interp->dynslope.slope->o, &interp->dynslope.bako);
|
||||
FV2_Copy(&interp->dynslope.slope->d, &interp->dynslope.bakd);
|
||||
interp->dynslope.slope->zdelta = interp->dynslope.bakzdelta;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void R_DestroyLevelInterpolators(thinker_t *thinker)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < levelinterpolators_len; i++)
|
||||
{
|
||||
levelinterpolator_t *interp = levelinterpolators[i];
|
||||
|
||||
if (interp->thinker == thinker)
|
||||
{
|
||||
// Swap the tail of the level interpolators to this spot
|
||||
levelinterpolators[i] = levelinterpolators[levelinterpolators_len - 1];
|
||||
levelinterpolators_len -= 1;
|
||||
|
||||
Z_Free(interp);
|
||||
i -= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static mobj_t **interpolated_mobjs = NULL;
|
||||
static size_t interpolated_mobjs_len = 0;
|
||||
static size_t interpolated_mobjs_capacity = 0;
|
||||
|
||||
// NOTE: This will NOT check that the mobj has already been added, for perf
|
||||
// reasons.
|
||||
void R_AddMobjInterpolator(mobj_t *mobj)
|
||||
{
|
||||
if (interpolated_mobjs_len >= interpolated_mobjs_capacity)
|
||||
{
|
||||
if (interpolated_mobjs_capacity == 0)
|
||||
{
|
||||
interpolated_mobjs_capacity = 256;
|
||||
}
|
||||
else
|
||||
{
|
||||
interpolated_mobjs_capacity *= 2;
|
||||
}
|
||||
|
||||
interpolated_mobjs = Z_ReallocAlign(
|
||||
interpolated_mobjs,
|
||||
sizeof(mobj_t *) * interpolated_mobjs_capacity,
|
||||
PU_LEVEL,
|
||||
NULL,
|
||||
64
|
||||
);
|
||||
}
|
||||
|
||||
interpolated_mobjs[interpolated_mobjs_len] = mobj;
|
||||
interpolated_mobjs_len += 1;
|
||||
|
||||
R_ResetMobjInterpolationState(mobj);
|
||||
mobj->resetinterp = true;
|
||||
}
|
||||
|
||||
void R_RemoveMobjInterpolator(mobj_t *mobj)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (interpolated_mobjs_len == 0) return;
|
||||
|
||||
for (i = 0; i < interpolated_mobjs_len - 1; i++)
|
||||
{
|
||||
if (interpolated_mobjs[i] == mobj)
|
||||
{
|
||||
interpolated_mobjs[i] = interpolated_mobjs[
|
||||
interpolated_mobjs_len - 1
|
||||
];
|
||||
interpolated_mobjs_len -= 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void R_InitMobjInterpolators(void)
|
||||
{
|
||||
// apparently it's not acceptable to free something already unallocated
|
||||
// Z_Free(interpolated_mobjs);
|
||||
interpolated_mobjs = NULL;
|
||||
interpolated_mobjs_len = 0;
|
||||
interpolated_mobjs_capacity = 0;
|
||||
}
|
||||
|
||||
void R_UpdateMobjInterpolators(void)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < interpolated_mobjs_len; i++)
|
||||
{
|
||||
mobj_t *mobj = interpolated_mobjs[i];
|
||||
if (!P_MobjWasRemoved(mobj))
|
||||
R_ResetMobjInterpolationState(mobj);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// P_ResetMobjInterpolationState
|
||||
//
|
||||
// Reset the rendering interpolation state of the mobj.
|
||||
//
|
||||
void R_ResetMobjInterpolationState(mobj_t *mobj)
|
||||
{
|
||||
mobj->old_x2 = mobj->old_x;
|
||||
mobj->old_y2 = mobj->old_y;
|
||||
mobj->old_z2 = mobj->old_z;
|
||||
mobj->old_angle2 = mobj->old_angle;
|
||||
mobj->old_scale2 = mobj->old_scale;
|
||||
mobj->old_x = mobj->x;
|
||||
mobj->old_y = mobj->y;
|
||||
mobj->old_z = mobj->z;
|
||||
mobj->old_angle = mobj->angle;
|
||||
mobj->old_scale = mobj->scale;
|
||||
|
||||
if (mobj->player)
|
||||
{
|
||||
mobj->player->old_frameangle2 = mobj->player->old_frameangle;
|
||||
mobj->player->old_frameangle = mobj->player->frameangle;
|
||||
}
|
||||
|
||||
mobj->resetinterp = false;
|
||||
}
|
||||
|
||||
//
|
||||
// P_ResetPrecipitationMobjInterpolationState
|
||||
//
|
||||
// Reset the rendering interpolation state of the precipmobj.
|
||||
//
|
||||
void R_ResetPrecipitationMobjInterpolationState(precipmobj_t *mobj)
|
||||
{
|
||||
mobj->old_x2 = mobj->old_x;
|
||||
mobj->old_y2 = mobj->old_y;
|
||||
mobj->old_z2 = mobj->old_z;
|
||||
mobj->old_angle2 = mobj->old_angle;
|
||||
mobj->old_x = mobj->x;
|
||||
mobj->old_y = mobj->y;
|
||||
mobj->old_z = mobj->z;
|
||||
mobj->old_angle = mobj->angle;
|
||||
}
|
158
src/r_fps.h
Normal file
158
src/r_fps.h
Normal file
|
@ -0,0 +1,158 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2000 by Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze, Andrey Budko (prboom)
|
||||
// Copyright (C) 1999-2019 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file r_fps.h
|
||||
/// \brief Uncapped framerate stuff.
|
||||
|
||||
#ifndef __R_FPS_H__
|
||||
#define __R_FPS_H__
|
||||
|
||||
#include "m_fixed.h"
|
||||
#include "p_local.h"
|
||||
#include "r_state.h"
|
||||
|
||||
extern consvar_t cv_fpscap;
|
||||
|
||||
UINT32 R_GetFramerateCap(void);
|
||||
boolean R_UsingFrameInterpolation(void);
|
||||
|
||||
enum viewcontext_e
|
||||
{
|
||||
VIEWCONTEXT_PLAYER1 = 0,
|
||||
VIEWCONTEXT_PLAYER2,
|
||||
VIEWCONTEXT_PLAYER3,
|
||||
VIEWCONTEXT_PLAYER4,
|
||||
VIEWCONTEXT_SKY1,
|
||||
VIEWCONTEXT_SKY2,
|
||||
VIEWCONTEXT_SKY3,
|
||||
VIEWCONTEXT_SKY4
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
fixed_t x;
|
||||
fixed_t y;
|
||||
fixed_t z;
|
||||
boolean sky;
|
||||
sector_t *sector;
|
||||
player_t *player;
|
||||
|
||||
angle_t angle;
|
||||
angle_t aim;
|
||||
fixed_t cos;
|
||||
fixed_t sin;
|
||||
mobj_t *mobj;
|
||||
} viewvars_t;
|
||||
|
||||
extern viewvars_t *newview;
|
||||
|
||||
typedef struct {
|
||||
fixed_t x;
|
||||
fixed_t y;
|
||||
fixed_t z;
|
||||
subsector_t *subsector;
|
||||
angle_t angle;
|
||||
fixed_t scale;
|
||||
} interpmobjstate_t;
|
||||
|
||||
// Level interpolators
|
||||
|
||||
// The union tag for levelinterpolator_t
|
||||
typedef enum {
|
||||
LVLINTERP_SectorPlane,
|
||||
LVLINTERP_SectorScroll,
|
||||
LVLINTERP_SideScroll,
|
||||
LVLINTERP_Polyobj,
|
||||
LVLINTERP_DynSlope,
|
||||
} levelinterpolator_type_e;
|
||||
|
||||
// Tagged union of a level interpolator
|
||||
typedef struct levelinterpolator_s {
|
||||
levelinterpolator_type_e type;
|
||||
thinker_t *thinker;
|
||||
union {
|
||||
struct {
|
||||
sector_t *sector;
|
||||
fixed_t oldheight;
|
||||
fixed_t bakheight;
|
||||
boolean ceiling;
|
||||
} sectorplane;
|
||||
struct {
|
||||
sector_t *sector;
|
||||
fixed_t oldxoffs, oldyoffs, bakxoffs, bakyoffs;
|
||||
boolean ceiling;
|
||||
} sectorscroll;
|
||||
struct {
|
||||
side_t *side;
|
||||
fixed_t oldtextureoffset, oldrowoffset, baktextureoffset, bakrowoffset;
|
||||
} sidescroll;
|
||||
struct {
|
||||
polyobj_t *polyobj;
|
||||
fixed_t *oldvertices;
|
||||
fixed_t *bakvertices;
|
||||
size_t vertices_size;
|
||||
fixed_t oldcx, oldcy, bakcx, bakcy;
|
||||
} polyobj;
|
||||
struct {
|
||||
pslope_t *slope;
|
||||
vector3_t oldo, bako;
|
||||
vector2_t oldd, bakd;
|
||||
fixed_t oldzdelta, bakzdelta;
|
||||
} dynslope;
|
||||
};
|
||||
} levelinterpolator_t;
|
||||
|
||||
// Interpolates the current view variables (r_state.h) against the selected view context in R_SetViewContext
|
||||
void R_InterpolateView(fixed_t frac);
|
||||
// Buffer the current new views into the old views. Call once after each real tic.
|
||||
void R_UpdateViewInterpolation(void);
|
||||
// Reset the view states (e.g. after level load) so R_InterpolateView doesn't interpolate invalid data
|
||||
void R_ResetViewInterpolation(UINT8 p);
|
||||
// Set the current view context (the viewvars pointed to by newview)
|
||||
void R_SetViewContext(enum viewcontext_e _viewcontext);
|
||||
|
||||
fixed_t R_InterpolateFixed(fixed_t from, fixed_t to);
|
||||
angle_t R_InterpolateAngle(angle_t from, angle_t to);
|
||||
|
||||
// Evaluate the interpolated mobj state for the given mobj
|
||||
void R_InterpolateMobjState(mobj_t *mobj, fixed_t frac, interpmobjstate_t *out);
|
||||
// Evaluate the interpolated mobj state for the given precipmobj
|
||||
void R_InterpolatePrecipMobjState(precipmobj_t *mobj, fixed_t frac, interpmobjstate_t *out);
|
||||
|
||||
void R_CreateInterpolator_SectorPlane(thinker_t *thinker, sector_t *sector, boolean ceiling);
|
||||
void R_CreateInterpolator_SectorScroll(thinker_t *thinker, sector_t *sector, boolean ceiling);
|
||||
void R_CreateInterpolator_SideScroll(thinker_t *thinker, side_t *side);
|
||||
void R_CreateInterpolator_Polyobj(thinker_t *thinker, polyobj_t *polyobj);
|
||||
void R_CreateInterpolator_DynSlope(thinker_t *thinker, pslope_t *slope);
|
||||
|
||||
// Initialize level interpolators after a level change
|
||||
void R_InitializeLevelInterpolators(void);
|
||||
// Update level interpolators, storing the previous and current states.
|
||||
void R_UpdateLevelInterpolators(void);
|
||||
// Clear states for all level interpolators for the thinker
|
||||
void R_ClearLevelInterpolatorState(thinker_t *thinker);
|
||||
// Apply level interpolators to the actual game state
|
||||
void R_ApplyLevelInterpolators(fixed_t frac);
|
||||
// Restore level interpolators to the real game state
|
||||
void R_RestoreLevelInterpolators(void);
|
||||
// Destroy interpolators associated with a thinker
|
||||
void R_DestroyLevelInterpolators(thinker_t *thinker);
|
||||
|
||||
// Initialize internal mobj interpolator list (e.g. during level loading)
|
||||
void R_InitMobjInterpolators(void);
|
||||
// Add interpolation state for the given mobj
|
||||
void R_AddMobjInterpolator(mobj_t *mobj);
|
||||
// Remove the interpolation state for the given mobj
|
||||
void R_RemoveMobjInterpolator(mobj_t *mobj);
|
||||
void R_UpdateMobjInterpolators(void);
|
||||
void R_ResetMobjInterpolationState(mobj_t *mobj);
|
||||
void R_ResetPrecipitationMobjInterpolationState(precipmobj_t *mobj);
|
||||
|
||||
#endif
|
260
src/r_main.c
260
src/r_main.c
|
@ -31,6 +31,7 @@
|
|||
#include "z_zone.h"
|
||||
#include "m_random.h" // quake camera shake
|
||||
#include "doomstat.h" // MAXSPLITSCREENPLAYERS
|
||||
#include "r_fps.h" // Frame interpolation/uncapped
|
||||
|
||||
#ifdef HWRENDER
|
||||
#include "hardware/hw_main.h"
|
||||
|
@ -68,7 +69,7 @@ fixed_t viewx, viewy, viewz;
|
|||
angle_t viewangle, aimingangle;
|
||||
UINT8 viewssnum;
|
||||
fixed_t viewcos, viewsin;
|
||||
boolean viewsky, skyVisible;
|
||||
boolean skyVisible;
|
||||
boolean skyVisiblePerPlayer[MAXSPLITSCREENPLAYERS]; // saved values of skyVisible for each splitscreen player
|
||||
sector_t *viewsector;
|
||||
player_t *viewplayer;
|
||||
|
@ -99,6 +100,10 @@ portal_pair *portal_base, *portal_cap;
|
|||
line_t *portalclipline;
|
||||
INT32 portalclipstart, portalclipend;
|
||||
|
||||
fixed_t rendertimefrac;
|
||||
fixed_t renderdeltatics;
|
||||
boolean renderisnewtic;
|
||||
|
||||
//
|
||||
// precalculated math tables
|
||||
//
|
||||
|
@ -793,31 +798,6 @@ subsector_t *R_IsPointInSubsector(fixed_t x, fixed_t y)
|
|||
|
||||
static mobj_t *viewmobj;
|
||||
|
||||
// recalc necessary stuff for mouseaiming
|
||||
// slopes are already calculated for the full possible view (which is 4*viewheight).
|
||||
// 18/08/18: (No it's actually 16*viewheight, thanks Jimita for finding this out)
|
||||
static void R_SetupFreelook(void)
|
||||
{
|
||||
INT32 dy = 0;
|
||||
|
||||
// clip it in the case we are looking a hardware 90 degrees full aiming
|
||||
// (lmps, network and use F12...)
|
||||
if (rendermode == render_soft
|
||||
#ifdef HWRENDER
|
||||
|| cv_grshearing.value
|
||||
#endif
|
||||
)
|
||||
G_SoftwareClipAimingPitch((INT32 *)&aimingangle);
|
||||
|
||||
if (rendermode == render_soft)
|
||||
{
|
||||
dy = (AIMINGTODY(aimingangle)/fovtan) * viewwidth/BASEVIDWIDTH;
|
||||
yslope = &yslopetab[viewheight*8 - (viewheight/2 + dy)];
|
||||
}
|
||||
centery = (viewheight/2) + dy;
|
||||
centeryfrac = centery<<FRACBITS;
|
||||
}
|
||||
|
||||
void R_SkyboxFrame(player_t *player)
|
||||
{
|
||||
camera_t *thiscam = &camera[0];
|
||||
|
@ -830,13 +810,18 @@ void R_SkyboxFrame(player_t *player)
|
|||
if (player == &players[displayplayers[i]])
|
||||
{
|
||||
thiscam = &camera[i];
|
||||
R_SetViewContext(VIEWCONTEXT_SKY1 + i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
R_SetViewContext(VIEWCONTEXT_SKY1);
|
||||
}
|
||||
|
||||
// cut-away view stuff
|
||||
viewsky = true;
|
||||
newview->sky = true;
|
||||
viewmobj = skyboxmo[0];
|
||||
#ifdef PARANOIA
|
||||
if (!viewmobj)
|
||||
|
@ -847,24 +832,24 @@ void R_SkyboxFrame(player_t *player)
|
|||
#endif
|
||||
if (player->awayviewtics)
|
||||
{
|
||||
aimingangle = player->awayviewaiming;
|
||||
viewangle = player->awayviewmobj->angle;
|
||||
newview->aim = player->awayviewaiming;
|
||||
newview->angle = player->awayviewmobj->angle;
|
||||
}
|
||||
else if (thiscam->chase)
|
||||
{
|
||||
aimingangle = thiscam->aiming;
|
||||
viewangle = thiscam->angle;
|
||||
newview->aim = thiscam->aiming;
|
||||
newview->angle = thiscam->angle;
|
||||
}
|
||||
else
|
||||
{
|
||||
aimingangle = player->aiming;
|
||||
viewangle = player->mo->angle;
|
||||
newview->aim = player->aiming;
|
||||
newview->angle = player->mo->angle;
|
||||
if (/*!demo.playback && */player->playerstate != PST_DEAD)
|
||||
{
|
||||
if (player == &players[consoleplayer])
|
||||
{
|
||||
viewangle = localangle[0]; // WARNING: camera uses this
|
||||
aimingangle = localaiming[0];
|
||||
newview->angle = localangle[0]; // WARNING: camera uses this
|
||||
newview->aim = localaiming[0];
|
||||
}
|
||||
else if (splitscreen)
|
||||
{
|
||||
|
@ -872,27 +857,27 @@ void R_SkyboxFrame(player_t *player)
|
|||
{
|
||||
if (player == &players[displayplayers[i]])
|
||||
{
|
||||
viewangle = localangle[i];
|
||||
aimingangle = localaiming[i];
|
||||
newview->angle = localangle[i];
|
||||
newview->aim = localaiming[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
viewangle += viewmobj->angle;
|
||||
newview->angle += viewmobj->angle;
|
||||
|
||||
viewplayer = player;
|
||||
newview->player = player;
|
||||
|
||||
viewx = viewmobj->x;
|
||||
viewy = viewmobj->y;
|
||||
viewz = 0;
|
||||
newview->x = viewmobj->x;
|
||||
newview->y = viewmobj->y;
|
||||
newview->z = 0;
|
||||
if (viewmobj->spawnpoint)
|
||||
viewz = ((fixed_t)viewmobj->spawnpoint->angle)<<FRACBITS;
|
||||
newview->z = ((fixed_t)viewmobj->spawnpoint->angle)<<FRACBITS;
|
||||
|
||||
viewx += quake.x;
|
||||
viewy += quake.y;
|
||||
viewz += quake.z;
|
||||
newview->x += quake.x;
|
||||
newview->y += quake.y;
|
||||
newview->z += quake.z;
|
||||
|
||||
if (mapheaderinfo[gamemap-1])
|
||||
{
|
||||
|
@ -914,35 +899,35 @@ void R_SkyboxFrame(player_t *player)
|
|||
|
||||
if (viewmobj->angle == 0)
|
||||
{
|
||||
viewx += x;
|
||||
viewy += y;
|
||||
newview->x += x;
|
||||
newview->y += y;
|
||||
}
|
||||
else if (viewmobj->angle == ANGLE_90)
|
||||
{
|
||||
viewx -= y;
|
||||
viewy += x;
|
||||
newview->x -= y;
|
||||
newview->y += x;
|
||||
}
|
||||
else if (viewmobj->angle == ANGLE_180)
|
||||
{
|
||||
viewx -= x;
|
||||
viewy -= y;
|
||||
newview->x -= x;
|
||||
newview->y -= y;
|
||||
}
|
||||
else if (viewmobj->angle == ANGLE_270)
|
||||
{
|
||||
viewx += y;
|
||||
viewy -= x;
|
||||
newview->x += y;
|
||||
newview->y -= x;
|
||||
}
|
||||
else
|
||||
{
|
||||
angle_t ang = viewmobj->angle>>ANGLETOFINESHIFT;
|
||||
viewx += FixedMul(x,FINECOSINE(ang)) - FixedMul(y, FINESINE(ang));
|
||||
viewy += FixedMul(x, FINESINE(ang)) + FixedMul(y,FINECOSINE(ang));
|
||||
newview->x += FixedMul(x,FINECOSINE(ang)) - FixedMul(y, FINESINE(ang));
|
||||
newview->y += FixedMul(x, FINESINE(ang)) + FixedMul(y,FINECOSINE(ang));
|
||||
}
|
||||
}
|
||||
if (mh->skybox_scalez > 0)
|
||||
viewz += (player->awayviewmobj->z + 20*FRACUNIT) / mh->skybox_scalez;
|
||||
newview->z += (player->awayviewmobj->z + 20*FRACUNIT) / mh->skybox_scalez;
|
||||
else if (mh->skybox_scalez < 0)
|
||||
viewz += (player->awayviewmobj->z + 20*FRACUNIT) * -mh->skybox_scalez;
|
||||
newview->z += (player->awayviewmobj->z + 20*FRACUNIT) * -mh->skybox_scalez;
|
||||
}
|
||||
else if (thiscam->chase)
|
||||
{
|
||||
|
@ -961,35 +946,35 @@ void R_SkyboxFrame(player_t *player)
|
|||
|
||||
if (viewmobj->angle == 0)
|
||||
{
|
||||
viewx += x;
|
||||
viewy += y;
|
||||
newview->x += x;
|
||||
newview->y += y;
|
||||
}
|
||||
else if (viewmobj->angle == ANGLE_90)
|
||||
{
|
||||
viewx -= y;
|
||||
viewy += x;
|
||||
newview->x -= y;
|
||||
newview->y += x;
|
||||
}
|
||||
else if (viewmobj->angle == ANGLE_180)
|
||||
{
|
||||
viewx -= x;
|
||||
viewy -= y;
|
||||
newview->x -= x;
|
||||
newview->y -= y;
|
||||
}
|
||||
else if (viewmobj->angle == ANGLE_270)
|
||||
{
|
||||
viewx += y;
|
||||
viewy -= x;
|
||||
newview->x += y;
|
||||
newview->y -= x;
|
||||
}
|
||||
else
|
||||
{
|
||||
angle_t ang = viewmobj->angle>>ANGLETOFINESHIFT;
|
||||
viewx += FixedMul(x,FINECOSINE(ang)) - FixedMul(y, FINESINE(ang));
|
||||
viewy += FixedMul(x, FINESINE(ang)) + FixedMul(y,FINECOSINE(ang));
|
||||
newview->x += FixedMul(x,FINECOSINE(ang)) - FixedMul(y, FINESINE(ang));
|
||||
newview->y += FixedMul(x, FINESINE(ang)) + FixedMul(y,FINECOSINE(ang));
|
||||
}
|
||||
}
|
||||
if (mh->skybox_scalez > 0)
|
||||
viewz += (thiscam->z + (thiscam->height>>1)) / mh->skybox_scalez;
|
||||
newview->z += (thiscam->z + (thiscam->height>>1)) / mh->skybox_scalez;
|
||||
else if (mh->skybox_scalez < 0)
|
||||
viewz += (thiscam->z + (thiscam->height>>1)) * -mh->skybox_scalez;
|
||||
newview->z += (thiscam->z + (thiscam->height>>1)) * -mh->skybox_scalez;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1007,47 +992,47 @@ void R_SkyboxFrame(player_t *player)
|
|||
|
||||
if (viewmobj->angle == 0)
|
||||
{
|
||||
viewx += x;
|
||||
viewy += y;
|
||||
newview->x += x;
|
||||
newview->y += y;
|
||||
}
|
||||
else if (viewmobj->angle == ANGLE_90)
|
||||
{
|
||||
viewx -= y;
|
||||
viewy += x;
|
||||
newview->x -= y;
|
||||
newview->y += x;
|
||||
}
|
||||
else if (viewmobj->angle == ANGLE_180)
|
||||
{
|
||||
viewx -= x;
|
||||
viewy -= y;
|
||||
newview->x -= x;
|
||||
newview->y -= y;
|
||||
}
|
||||
else if (viewmobj->angle == ANGLE_270)
|
||||
{
|
||||
viewx += y;
|
||||
viewy -= x;
|
||||
newview->x += y;
|
||||
newview->y -= x;
|
||||
}
|
||||
else
|
||||
{
|
||||
angle_t ang = viewmobj->angle>>ANGLETOFINESHIFT;
|
||||
viewx += FixedMul(x,FINECOSINE(ang)) - FixedMul(y, FINESINE(ang));
|
||||
viewy += FixedMul(x, FINESINE(ang)) + FixedMul(y,FINECOSINE(ang));
|
||||
newview->x += FixedMul(x,FINECOSINE(ang)) - FixedMul(y, FINESINE(ang));
|
||||
newview->y += FixedMul(x, FINESINE(ang)) + FixedMul(y,FINECOSINE(ang));
|
||||
}
|
||||
}
|
||||
if (mh->skybox_scalez > 0)
|
||||
viewz += player->viewz / mh->skybox_scalez;
|
||||
newview->z += player->viewz / mh->skybox_scalez;
|
||||
else if (mh->skybox_scalez < 0)
|
||||
viewz += player->viewz * -mh->skybox_scalez;
|
||||
newview->z += player->viewz * -mh->skybox_scalez;
|
||||
}
|
||||
}
|
||||
|
||||
if (viewmobj->subsector)
|
||||
viewsector = viewmobj->subsector->sector;
|
||||
newview->sector = viewmobj->subsector->sector;
|
||||
else
|
||||
viewsector = R_PointInSubsector(viewx, viewy)->sector;
|
||||
newview->sector = R_PointInSubsector(newview->x, newview->y)->sector;
|
||||
|
||||
viewsin = FINESINE(viewangle>>ANGLETOFINESHIFT);
|
||||
viewcos = FINECOSINE(viewangle>>ANGLETOFINESHIFT);
|
||||
// newview->sin = FINESINE(viewangle>>ANGLETOFINESHIFT);
|
||||
// newview->cos = FINECOSINE(viewangle>>ANGLETOFINESHIFT);
|
||||
|
||||
R_SetupFreelook();
|
||||
R_InterpolateView(R_UsingFrameInterpolation() ? rendertimefrac : FRACUNIT);
|
||||
}
|
||||
|
||||
void R_SetupFrame(player_t *player, boolean skybox)
|
||||
|
@ -1059,21 +1044,25 @@ void R_SetupFrame(player_t *player, boolean skybox)
|
|||
{
|
||||
thiscam = &camera[3];
|
||||
chasecam = (cv_chasecam4.value != 0);
|
||||
R_SetViewContext(VIEWCONTEXT_PLAYER4);
|
||||
}
|
||||
else if (splitscreen > 1 && player == &players[displayplayers[2]])
|
||||
{
|
||||
thiscam = &camera[2];
|
||||
chasecam = (cv_chasecam3.value != 0);
|
||||
R_SetViewContext(VIEWCONTEXT_PLAYER3);
|
||||
}
|
||||
else if (splitscreen && player == &players[displayplayers[1]])
|
||||
{
|
||||
thiscam = &camera[1];
|
||||
chasecam = (cv_chasecam2.value != 0);
|
||||
R_SetViewContext(VIEWCONTEXT_PLAYER2);
|
||||
}
|
||||
else
|
||||
{
|
||||
thiscam = &camera[0];
|
||||
chasecam = (cv_chasecam.value != 0);
|
||||
R_SetViewContext(VIEWCONTEXT_PLAYER1);
|
||||
}
|
||||
|
||||
if (player->spectator) // no spectator chasecam
|
||||
|
@ -1089,41 +1078,41 @@ void R_SetupFrame(player_t *player, boolean skybox)
|
|||
else if (!chasecam)
|
||||
thiscam->chase = false;
|
||||
|
||||
viewsky = !skybox;
|
||||
newview->sky = !skybox;
|
||||
if (player->awayviewtics)
|
||||
{
|
||||
// cut-away view stuff
|
||||
viewmobj = player->awayviewmobj; // should be a MT_ALTVIEWMAN
|
||||
I_Assert(viewmobj != NULL);
|
||||
viewz = viewmobj->z + 20*FRACUNIT;
|
||||
aimingangle = player->awayviewaiming;
|
||||
viewangle = viewmobj->angle;
|
||||
newview->z = viewmobj->z + 20*FRACUNIT;
|
||||
newview->aim = player->awayviewaiming;
|
||||
newview->angle = viewmobj->angle;
|
||||
}
|
||||
else if (!player->spectator && chasecam)
|
||||
// use outside cam view
|
||||
{
|
||||
viewmobj = NULL;
|
||||
viewz = thiscam->z + (thiscam->height>>1);
|
||||
aimingangle = thiscam->aiming;
|
||||
viewangle = thiscam->angle;
|
||||
newview->z = thiscam->z + (thiscam->height>>1);
|
||||
newview->aim = thiscam->aiming;
|
||||
newview->angle = thiscam->angle;
|
||||
}
|
||||
else
|
||||
// use the player's eyes view
|
||||
{
|
||||
viewz = player->viewz;
|
||||
newview->z = player->viewz;
|
||||
|
||||
viewmobj = player->mo;
|
||||
I_Assert(viewmobj != NULL);
|
||||
|
||||
aimingangle = player->aiming;
|
||||
viewangle = viewmobj->angle;
|
||||
newview->aim = player->aiming;
|
||||
newview->angle = viewmobj->angle;
|
||||
|
||||
if (!demo.playback && player->playerstate != PST_DEAD)
|
||||
{
|
||||
if (player == &players[consoleplayer])
|
||||
{
|
||||
viewangle = localangle[0]; // WARNING: camera uses this
|
||||
aimingangle = localaiming[0];
|
||||
newview->angle = localangle[0]; // WARNING: camera uses this
|
||||
newview->aim = localaiming[0];
|
||||
}
|
||||
else if (splitscreen)
|
||||
{
|
||||
|
@ -1132,47 +1121,47 @@ void R_SetupFrame(player_t *player, boolean skybox)
|
|||
{
|
||||
if (player == &players[displayplayers[i]])
|
||||
{
|
||||
viewangle = localangle[i];
|
||||
aimingangle = localaiming[i];
|
||||
newview->angle = localangle[i];
|
||||
newview->aim = localaiming[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
viewz += quake.z;
|
||||
newview->z += quake.z;
|
||||
|
||||
viewplayer = player;
|
||||
newview->player = player;
|
||||
|
||||
if (chasecam && !player->awayviewtics && !player->spectator)
|
||||
{
|
||||
viewx = thiscam->x;
|
||||
viewy = thiscam->y;
|
||||
viewx += quake.x;
|
||||
viewy += quake.y;
|
||||
newview->x = thiscam->x;
|
||||
newview->y = thiscam->y;
|
||||
newview->x += quake.x;
|
||||
newview->y += quake.y;
|
||||
|
||||
if (thiscam->subsector && thiscam->subsector->sector)
|
||||
viewsector = thiscam->subsector->sector;
|
||||
newview->sector = thiscam->subsector->sector;
|
||||
else
|
||||
viewsector = R_PointInSubsector(viewx, viewy)->sector;
|
||||
newview->sector = R_PointInSubsector(newview->x, newview->y)->sector;
|
||||
}
|
||||
else
|
||||
{
|
||||
viewx = viewmobj->x;
|
||||
viewy = viewmobj->y;
|
||||
viewx += quake.x;
|
||||
viewy += quake.y;
|
||||
newview->x = viewmobj->x;
|
||||
newview->y = viewmobj->y;
|
||||
newview->x += quake.x;
|
||||
newview->y += quake.y;
|
||||
|
||||
if (viewmobj->subsector && thiscam->subsector->sector)
|
||||
viewsector = viewmobj->subsector->sector;
|
||||
newview->sector = viewmobj->subsector->sector;
|
||||
else
|
||||
viewsector = R_PointInSubsector(viewx, viewy)->sector;
|
||||
newview->sector = R_PointInSubsector(newview->x, newview->y)->sector;
|
||||
}
|
||||
|
||||
viewsin = FINESINE(viewangle>>ANGLETOFINESHIFT);
|
||||
viewcos = FINECOSINE(viewangle>>ANGLETOFINESHIFT);
|
||||
// newview->sin = FINESINE(viewangle>>ANGLETOFINESHIFT);
|
||||
// newview->cos = FINECOSINE(viewangle>>ANGLETOFINESHIFT);
|
||||
|
||||
R_SetupFreelook();
|
||||
R_InterpolateView(R_UsingFrameInterpolation() ? rendertimefrac : FRACUNIT);
|
||||
}
|
||||
|
||||
#define ANGLED_PORTALS
|
||||
|
@ -1186,13 +1175,13 @@ static void R_PortalFrame(line_t *start, line_t *dest, portal_pair *portal)
|
|||
#endif
|
||||
|
||||
//R_SetupFrame(player, false);
|
||||
viewx = portal->viewx;
|
||||
viewy = portal->viewy;
|
||||
viewz = portal->viewz;
|
||||
newview->x = portal->viewx;
|
||||
newview->y = portal->viewy;
|
||||
newview->z = portal->viewz;
|
||||
|
||||
viewangle = portal->viewangle;
|
||||
viewsin = FINESINE(viewangle>>ANGLETOFINESHIFT);
|
||||
viewcos = FINECOSINE(viewangle>>ANGLETOFINESHIFT);
|
||||
newview->angle = portal->viewangle;
|
||||
// newview->sin = FINESINE(newview->angle>>ANGLETOFINESHIFT);
|
||||
// newview->cos = FINECOSINE(newview->angle>>ANGLETOFINESHIFT);
|
||||
|
||||
portalcullsector = dest->frontsector;
|
||||
viewsector = dest->frontsector;
|
||||
|
@ -1211,22 +1200,22 @@ static void R_PortalFrame(line_t *start, line_t *dest, portal_pair *portal)
|
|||
dest_c.y = (dest->v1->y + dest->v2->y) / 2;
|
||||
|
||||
// Heights!
|
||||
viewz += dest->frontsector->floorheight - start->frontsector->floorheight;
|
||||
newview->z += dest->frontsector->floorheight - start->frontsector->floorheight;
|
||||
|
||||
// calculate the difference in position and rotation!
|
||||
#ifdef ANGLED_PORTALS
|
||||
if (dangle == 0)
|
||||
#endif
|
||||
{ // the entrance goes straight opposite the exit, so we just need to mess with the offset.
|
||||
viewx += dest_c.x - start_c.x;
|
||||
viewy += dest_c.y - start_c.y;
|
||||
newview->x += dest_c.x - start_c.x;
|
||||
newview->y += dest_c.y - start_c.y;
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef ANGLED_PORTALS
|
||||
viewangle += dangle;
|
||||
viewsin = FINESINE(viewangle>>ANGLETOFINESHIFT);
|
||||
viewcos = FINECOSINE(viewangle>>ANGLETOFINESHIFT);
|
||||
newview->angle += dangle;
|
||||
// newview->sin = FINESINE(newview->angle>>ANGLETOFINESHIFT);
|
||||
// newview->cos = FINECOSINE(newview->angle>>ANGLETOFINESHIFT);
|
||||
//CONS_Printf("dangle == %u\n", AngleFixed(dangle)>>FRACBITS);
|
||||
|
||||
// ????
|
||||
|
@ -1234,12 +1223,12 @@ static void R_PortalFrame(line_t *start, line_t *dest, portal_pair *portal)
|
|||
fixed_t disttopoint;
|
||||
angle_t angtopoint;
|
||||
|
||||
disttopoint = R_PointToDist2(start_c.x, start_c.y, viewx, viewy);
|
||||
angtopoint = R_PointToAngle2(start_c.x, start_c.y, viewx, viewy);
|
||||
disttopoint = R_PointToDist2(start_c.x, start_c.y, newview->x, newview->y);
|
||||
angtopoint = R_PointToAngle2(start_c.x, start_c.y, newview->x, newview->y);
|
||||
angtopoint += dangle;
|
||||
|
||||
viewx = dest_c.x+FixedMul(FINECOSINE(angtopoint>>ANGLETOFINESHIFT), disttopoint);
|
||||
viewy = dest_c.y+FixedMul(FINESINE(angtopoint>>ANGLETOFINESHIFT), disttopoint);
|
||||
newview->x = dest_c.x+FixedMul(FINECOSINE(angtopoint>>ANGLETOFINESHIFT), disttopoint);
|
||||
newview->y = dest_c.y+FixedMul(FINESINE(angtopoint>>ANGLETOFINESHIFT), disttopoint);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -1544,4 +1533,7 @@ void R_RegisterEngineStuff(void)
|
|||
if (rendermode != render_soft && rendermode != render_none)
|
||||
HWR_AddCommands();
|
||||
#endif
|
||||
|
||||
// Frame interpolation/uncapped
|
||||
CV_RegisterVar(&cv_fpscap);
|
||||
}
|
||||
|
|
|
@ -29,6 +29,13 @@ extern fixed_t projection, projectiony;
|
|||
|
||||
extern size_t validcount, linecount, loopcount, framecount;
|
||||
|
||||
// The fraction of a tic being drawn (for interpolation between two tics)
|
||||
extern fixed_t rendertimefrac;
|
||||
// Evaluated delta tics for this frame (how many tics since the last frame)
|
||||
extern fixed_t renderdeltatics;
|
||||
// The current render is a new logical tic
|
||||
extern boolean renderisnewtic;
|
||||
|
||||
//
|
||||
// Lighting LUT.
|
||||
// Used for z-depth cuing per column/row,
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "w_wad.h"
|
||||
#include "z_zone.h"
|
||||
#include "p_tick.h"
|
||||
#include "r_fps.h"
|
||||
|
||||
#ifdef TIMING
|
||||
#include "p5prof.h"
|
||||
|
@ -678,8 +679,6 @@ void R_MakeSpans(INT32 x, INT32 t1, INT32 b1, INT32 t2, INT32 b2)
|
|||
void R_DrawPlanes(void)
|
||||
{
|
||||
visplane_t *pl;
|
||||
INT32 x;
|
||||
INT32 angle;
|
||||
INT32 i;
|
||||
|
||||
spanfunc = basespanfunc;
|
||||
|
@ -689,50 +688,7 @@ void R_DrawPlanes(void)
|
|||
{
|
||||
for (pl = visplanes[i]; pl; pl = pl->next)
|
||||
{
|
||||
// sky flat
|
||||
if (pl->picnum == skyflatnum)
|
||||
{
|
||||
if (!viewsky)
|
||||
{
|
||||
skyVisible = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
// use correct aspect ratio scale
|
||||
dc_iscale = skyscale;
|
||||
|
||||
// Sky is always drawn full bright,
|
||||
// i.e. colormaps[0] is used.
|
||||
// Because of this hack, sky is not affected
|
||||
// by INVUL inverse mapping.
|
||||
dc_colormap = colormaps;
|
||||
if (encoremap)
|
||||
dc_colormap += (256*32);
|
||||
dc_texturemid = skytexturemid;
|
||||
dc_texheight = textureheight[skytexture]
|
||||
>>FRACBITS;
|
||||
for (x = pl->minx; x <= pl->maxx; x++)
|
||||
{
|
||||
dc_yl = pl->top[x];
|
||||
dc_yh = pl->bottom[x];
|
||||
|
||||
if (dc_yl <= dc_yh)
|
||||
{
|
||||
angle = (pl->viewangle + xtoviewangle[x])>>ANGLETOSKYSHIFT;
|
||||
dc_iscale = FixedMul(skyscale, FINECOSINE(xtoviewangle[x]>>ANGLETOFINESHIFT));
|
||||
dc_x = x;
|
||||
dc_source =
|
||||
R_GetColumn(texturetranslation[skytexture],
|
||||
angle);
|
||||
wallcolfunc();
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pl->ffloor != NULL
|
||||
|| pl->polyobj != NULL
|
||||
)
|
||||
if (pl->ffloor != NULL || pl->polyobj != NULL)
|
||||
continue;
|
||||
|
||||
R_DrawSinglePlane(pl);
|
||||
|
@ -744,6 +700,48 @@ void R_DrawPlanes(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
static void R_DrawSkyPlane(visplane_t *pl)
|
||||
{
|
||||
INT32 x;
|
||||
INT32 angle;
|
||||
|
||||
if (!newview->sky)
|
||||
{
|
||||
skyVisible = true;
|
||||
return;
|
||||
}
|
||||
|
||||
wallcolfunc = walldrawerfunc;
|
||||
|
||||
// use correct aspect ratio scale
|
||||
dc_iscale = skyscale;
|
||||
// Sky is always drawn full bright,
|
||||
// i.e. colormaps[0] is used.
|
||||
// Because of this hack, sky is not affected
|
||||
// by INVUL inverse mapping.
|
||||
dc_colormap = colormaps;
|
||||
if (encoremap)
|
||||
dc_colormap += (256*32);
|
||||
dc_texturemid = skytexturemid;
|
||||
dc_texheight = textureheight[skytexture]
|
||||
>>FRACBITS;
|
||||
for (x = pl->minx; x <= pl->maxx; x++)
|
||||
{
|
||||
dc_yl = pl->top[x];
|
||||
dc_yh = pl->bottom[x];
|
||||
if (dc_yl <= dc_yh)
|
||||
{
|
||||
angle = (pl->viewangle + xtoviewangle[x])>>ANGLETOSKYSHIFT;
|
||||
dc_iscale = FixedMul(skyscale, FINECOSINE(xtoviewangle[x]>>ANGLETOFINESHIFT));
|
||||
dc_x = x;
|
||||
dc_source =
|
||||
R_GetColumn(texturetranslation[skytexture],
|
||||
angle);
|
||||
wallcolfunc();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void R_DrawSinglePlane(visplane_t *pl)
|
||||
{
|
||||
INT32 light = 0;
|
||||
|
@ -755,6 +753,13 @@ void R_DrawSinglePlane(visplane_t *pl)
|
|||
if (!(pl->minx <= pl->maxx))
|
||||
return;
|
||||
|
||||
// sky flat
|
||||
if (pl->picnum == skyflatnum)
|
||||
{
|
||||
R_DrawSkyPlane(pl);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifndef NOWATER
|
||||
itswater = false;
|
||||
#endif
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "z_zone.h"
|
||||
#include "m_misc.h"
|
||||
#include "i_video.h" // rendermode
|
||||
#include "r_fps.h"
|
||||
#include "r_things.h"
|
||||
#include "r_plane.h"
|
||||
#include "p_tick.h"
|
||||
|
@ -1158,13 +1159,28 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
fixed_t gz, gzt;
|
||||
INT32 heightsec, phs;
|
||||
INT32 light = 0;
|
||||
fixed_t this_scale = thing->scale;
|
||||
fixed_t this_scale;
|
||||
|
||||
fixed_t ang_scale = FRACUNIT;
|
||||
|
||||
// uncapped/interpolation
|
||||
interpmobjstate_t interp = {0};
|
||||
|
||||
// do interpolation
|
||||
if (R_UsingFrameInterpolation() && !paused)
|
||||
{
|
||||
R_InterpolateMobjState(thing, rendertimefrac, &interp);
|
||||
}
|
||||
else
|
||||
{
|
||||
R_InterpolateMobjState(thing, FRACUNIT, &interp);
|
||||
}
|
||||
|
||||
this_scale = interp.scale;
|
||||
|
||||
// transform the origin point
|
||||
tr_x = thing->x - viewx;
|
||||
tr_y = thing->y - viewy;
|
||||
tr_x = interp.x - viewx;
|
||||
tr_y = interp.y - viewy;
|
||||
|
||||
gxt = FixedMul(tr_x, viewcos);
|
||||
gyt = -FixedMul(tr_y, viewsin);
|
||||
|
@ -1229,10 +1245,7 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
|
||||
if (sprframe->rotate != SRF_SINGLE || papersprite)
|
||||
{
|
||||
if (thing->player)
|
||||
ang = R_PointToAngle (thing->x, thing->y) - thing->player->frameangle;
|
||||
else
|
||||
ang = R_PointToAngle (thing->x, thing->y) - thing->angle;
|
||||
ang = R_PointToAngle (interp.x, interp.y) - interp.angle;
|
||||
if (papersprite)
|
||||
ang_scale = abs(FINESINE(ang>>ANGLETOFINESHIFT));
|
||||
}
|
||||
|
@ -1247,7 +1260,7 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
else
|
||||
{
|
||||
// choose a different rotation based on player view
|
||||
//ang = R_PointToAngle (thing->x, thing->y) - thing->angle;
|
||||
//ang = R_PointToAngle (interp.x, interp.y) - interpangle;
|
||||
|
||||
if ((ang < ANGLE_180) && (sprframe->rotate & SRF_RIGHT)) // See from right
|
||||
rot = 6; // F7 slot
|
||||
|
@ -1300,8 +1313,8 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
offset2 *= -1;
|
||||
}
|
||||
|
||||
cosmul = FINECOSINE(thing->angle>>ANGLETOFINESHIFT);
|
||||
sinmul = FINESINE(thing->angle>>ANGLETOFINESHIFT);
|
||||
cosmul = FINECOSINE(interp.angle >> ANGLETOFINESHIFT);
|
||||
sinmul = FINESINE(interp.angle >> ANGLETOFINESHIFT);
|
||||
|
||||
tr_x += FixedMul(offset, cosmul);
|
||||
tr_y += FixedMul(offset, sinmul);
|
||||
|
@ -1343,7 +1356,7 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
if (x2 < portalclipstart || x1 > portalclipend)
|
||||
return;
|
||||
|
||||
if (P_PointOnLineSide(thing->x, thing->y, portalclipline) != 0)
|
||||
if (P_PointOnLineSide(interp.x, interp.y, portalclipline) != 0)
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1353,12 +1366,12 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
// When vertical flipped, draw sprites from the top down, at least as far as offsets are concerned.
|
||||
// sprite height - sprite topoffset is the proper inverse of the vertical offset, of course.
|
||||
// remember gz and gzt should be seperated by sprite height, not thing height - thing height can be shorter than the sprite itself sometimes!
|
||||
gz = thing->z + thing->height - FixedMul(spritecachedinfo[lump].topoffset, this_scale);
|
||||
gz = interp.z + thing->height - FixedMul(spritecachedinfo[lump].topoffset, this_scale);
|
||||
gzt = gz + FixedMul(spritecachedinfo[lump].height, this_scale);
|
||||
}
|
||||
else
|
||||
{
|
||||
gzt = thing->z + FixedMul(spritecachedinfo[lump].topoffset, this_scale);
|
||||
gzt = interp.z + FixedMul(spritecachedinfo[lump].topoffset, this_scale);
|
||||
gz = gzt - FixedMul(spritecachedinfo[lump].height, this_scale);
|
||||
}
|
||||
|
||||
|
@ -1374,7 +1387,7 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
light = thing->subsector->sector->numlights - 1;
|
||||
|
||||
for (lightnum = 1; lightnum < thing->subsector->sector->numlights; lightnum++) {
|
||||
fixed_t h = thing->subsector->sector->lightlist[lightnum].slope ? P_GetZAt(thing->subsector->sector->lightlist[lightnum].slope, thing->x, thing->y)
|
||||
fixed_t h = thing->subsector->sector->lightlist[lightnum].slope ? P_GetZAt(thing->subsector->sector->lightlist[lightnum].slope, interp.x, interp.y)
|
||||
: thing->subsector->sector->lightlist[lightnum].height;
|
||||
if (h <= gzt) {
|
||||
light = lightnum - 1;
|
||||
|
@ -1416,12 +1429,12 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
vis->scale = yscale; //<<detailshift;
|
||||
vis->sortscale = sortscale;
|
||||
vis->dispoffset = thing->info->dispoffset; // Monster Iestyn: 23/11/15
|
||||
vis->gx = thing->x;
|
||||
vis->gy = thing->y;
|
||||
vis->gx = interp.x;
|
||||
vis->gy = interp.y;
|
||||
vis->gz = gz;
|
||||
vis->gzt = gzt;
|
||||
vis->thingheight = thing->height;
|
||||
vis->pz = thing->z;
|
||||
vis->pz = interp.z;
|
||||
vis->pzt = vis->pz + vis->thingheight;
|
||||
vis->texturemid = vis->gzt - viewz;
|
||||
vis->scalestep = scalestep;
|
||||
|
@ -1539,9 +1552,22 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing)
|
|||
//SoM: 3/17/2000
|
||||
fixed_t gz ,gzt;
|
||||
|
||||
// uncapped/interpolation
|
||||
interpmobjstate_t interp = {0};
|
||||
|
||||
// do interpolation
|
||||
if (R_UsingFrameInterpolation() && !paused)
|
||||
{
|
||||
R_InterpolatePrecipMobjState(thing, rendertimefrac, &interp);
|
||||
}
|
||||
else
|
||||
{
|
||||
R_InterpolatePrecipMobjState(thing, FRACUNIT, &interp);
|
||||
}
|
||||
|
||||
// transform the origin point
|
||||
tr_x = thing->x - viewx;
|
||||
tr_y = thing->y - viewy;
|
||||
tr_x = interp.x - viewx;
|
||||
tr_y = interp.y - viewy;
|
||||
|
||||
gxt = FixedMul(tr_x, viewcos);
|
||||
gyt = -FixedMul(tr_y, viewsin);
|
||||
|
@ -1610,7 +1636,7 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing)
|
|||
if (x2 < portalclipstart || x1 > portalclipend)
|
||||
return;
|
||||
|
||||
if (P_PointOnLineSide(thing->x, thing->y, portalclipline) != 0)
|
||||
if (P_PointOnLineSide(interp.x, interp.y, portalclipline) != 0)
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1626,7 +1652,7 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing)
|
|||
|
||||
|
||||
//SoM: 3/17/2000: Disregard sprites that are out of view..
|
||||
gzt = thing->z + spritecachedinfo[lump].topoffset;
|
||||
gzt = interp.z + spritecachedinfo[lump].topoffset;
|
||||
gz = gzt - spritecachedinfo[lump].height;
|
||||
|
||||
if (thing->subsector->sector->cullheight)
|
||||
|
@ -1639,12 +1665,12 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing)
|
|||
vis = R_NewVisSprite();
|
||||
vis->scale = vis->sortscale = yscale; //<<detailshift;
|
||||
vis->dispoffset = 0; // Monster Iestyn: 23/11/15
|
||||
vis->gx = thing->x;
|
||||
vis->gy = thing->y;
|
||||
vis->gx = interp.x;
|
||||
vis->gy = interp.y;
|
||||
vis->gz = gz;
|
||||
vis->gzt = gzt;
|
||||
vis->thingheight = 4*FRACUNIT;
|
||||
vis->pz = thing->z;
|
||||
vis->pz = interp.z;
|
||||
vis->pzt = vis->pz + vis->thingheight;
|
||||
vis->texturemid = vis->gzt - viewz;
|
||||
vis->scalestep = 0;
|
||||
|
|
|
@ -143,7 +143,7 @@ extern struct cursongcredit
|
|||
{
|
||||
musicdef_t *def;
|
||||
UINT16 anim;
|
||||
INT32 x;
|
||||
fixed_t x;
|
||||
UINT8 trans;
|
||||
} cursongcredit;
|
||||
|
||||
|
|
131
src/screen.c
131
src/screen.c
|
@ -15,6 +15,7 @@
|
|||
#include "screen.h"
|
||||
#include "console.h"
|
||||
#include "am_map.h"
|
||||
#include "i_time.h"
|
||||
#include "i_system.h"
|
||||
#include "i_video.h"
|
||||
#include "r_local.h"
|
||||
|
@ -29,6 +30,8 @@
|
|||
#include "d_clisrv.h"
|
||||
#include "f_finale.h"
|
||||
|
||||
// SRB2Kart
|
||||
#include "r_fps.h" // R_GetFramerateCap
|
||||
|
||||
#if defined (USEASM) && !defined (NORUSEASM)//&& (!defined (_MSC_VER) || (_MSC_VER <= 1200))
|
||||
#define RUSEASM //MSC.NET can't patch itself
|
||||
|
@ -397,46 +400,110 @@ boolean SCR_IsAspectCorrect(INT32 width, INT32 height)
|
|||
);
|
||||
}
|
||||
|
||||
// XMOD FPS display
|
||||
// moved out of os-specific code for consistency
|
||||
static boolean fpsgraph[TICRATE];
|
||||
static tic_t lasttic;
|
||||
double averageFPS = 0.0f;
|
||||
|
||||
#define USE_FPS_SAMPLES
|
||||
|
||||
#ifdef USE_FPS_SAMPLES
|
||||
#define FPS_SAMPLE_RATE (0.05) // How often to update FPS samples, in seconds
|
||||
#define NUM_FPS_SAMPLES (16) // Number of samples to store
|
||||
|
||||
static double fps_samples[NUM_FPS_SAMPLES];
|
||||
static double updateElapsed = 0.0;
|
||||
#endif
|
||||
|
||||
static boolean fps_init = false;
|
||||
static precise_t fps_enter = 0;
|
||||
|
||||
void SCR_CalculateFPS(void)
|
||||
{
|
||||
precise_t fps_finish = 0;
|
||||
|
||||
double frameElapsed = 0.0;
|
||||
|
||||
if (fps_init == false)
|
||||
{
|
||||
fps_enter = I_GetPreciseTime();
|
||||
fps_init = true;
|
||||
}
|
||||
|
||||
fps_finish = I_GetPreciseTime();
|
||||
frameElapsed = (double)((INT64)(fps_finish - fps_enter)) / I_GetPrecisePrecision();
|
||||
fps_enter = fps_finish;
|
||||
|
||||
#ifdef USE_FPS_SAMPLES
|
||||
updateElapsed += frameElapsed;
|
||||
|
||||
if (updateElapsed >= FPS_SAMPLE_RATE)
|
||||
{
|
||||
static int sampleIndex = 0;
|
||||
int i;
|
||||
|
||||
fps_samples[sampleIndex] = frameElapsed;
|
||||
|
||||
sampleIndex++;
|
||||
if (sampleIndex >= NUM_FPS_SAMPLES)
|
||||
sampleIndex = 0;
|
||||
|
||||
averageFPS = 0.0;
|
||||
for (i = 0; i < NUM_FPS_SAMPLES; i++)
|
||||
{
|
||||
averageFPS += fps_samples[i];
|
||||
}
|
||||
|
||||
if (averageFPS > 0.0)
|
||||
{
|
||||
averageFPS = 1.0 / (averageFPS / NUM_FPS_SAMPLES);
|
||||
}
|
||||
}
|
||||
|
||||
while (updateElapsed >= FPS_SAMPLE_RATE)
|
||||
{
|
||||
updateElapsed -= FPS_SAMPLE_RATE;
|
||||
}
|
||||
#else
|
||||
// Direct, unsampled counter.
|
||||
averageFPS = 1.0 / frameElapsed;
|
||||
#endif
|
||||
}
|
||||
|
||||
void SCR_DisplayTicRate(void)
|
||||
{
|
||||
tic_t i;
|
||||
tic_t ontic = I_GetTime();
|
||||
tic_t totaltics = 0;
|
||||
const UINT8 *ticcntcolor = NULL;
|
||||
|
||||
for (i = lasttic + 1; i < TICRATE+lasttic && i < ontic; ++i)
|
||||
fpsgraph[i % TICRATE] = false;
|
||||
|
||||
fpsgraph[ontic % TICRATE] = true;
|
||||
|
||||
for (i = 0;i < TICRATE;++i)
|
||||
if (fpsgraph[i])
|
||||
++totaltics;
|
||||
|
||||
if (totaltics <= TICRATE/2) ticcntcolor = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_SALMON, GTC_CACHE);
|
||||
else if (totaltics == TICRATE) ticcntcolor = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_MINT, GTC_CACHE);
|
||||
|
||||
/*V_DrawString(vid.width-(24*vid.dupx), vid.height-(16*vid.dupy),
|
||||
V_YELLOWMAP|V_NOSCALESTART, "FPS");
|
||||
V_DrawString(vid.width-(40*vid.dupx), vid.height-( 8*vid.dupy),
|
||||
ticcntcolor|V_NOSCALESTART, va("%02d/%02u", totaltics, TICRATE));*/
|
||||
UINT32 cap = R_GetFramerateCap();
|
||||
UINT32 benchmark = (cap == 0) ? I_GetRefreshRate() : cap;
|
||||
INT32 x = 318;
|
||||
double fps = round(averageFPS);
|
||||
|
||||
// draw "FPS"
|
||||
V_DrawFixedPatch(306<<FRACBITS, 183<<FRACBITS, FRACUNIT, V_SNAPTOBOTTOM|V_SNAPTORIGHT, framecounter, R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_YELLOW, GTC_CACHE));
|
||||
// draw total frame:
|
||||
V_DrawPingNum(318, 190, V_SNAPTOBOTTOM|V_SNAPTORIGHT, TICRATE, ticcntcolor);
|
||||
// draw "/"
|
||||
V_DrawFixedPatch(306<<FRACBITS, 190<<FRACBITS, FRACUNIT, V_SNAPTOBOTTOM|V_SNAPTORIGHT, frameslash, ticcntcolor);
|
||||
|
||||
if (fps > (benchmark - 5))
|
||||
ticcntcolor = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_MINT, GTC_CACHE);
|
||||
else if (fps < 20)
|
||||
ticcntcolor = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_RASPBERRY, GTC_CACHE);
|
||||
|
||||
if (cap != 0)
|
||||
{
|
||||
UINT32 digits = 1;
|
||||
UINT32 c2 = cap;
|
||||
|
||||
while (c2 > 0)
|
||||
{
|
||||
c2 = c2 / 10;
|
||||
digits++;
|
||||
}
|
||||
|
||||
// draw total frame:
|
||||
V_DrawPingNum(x, 190, V_SNAPTOBOTTOM|V_SNAPTORIGHT, cap, ticcntcolor);
|
||||
x -= digits * 4;
|
||||
|
||||
// draw "/"
|
||||
V_DrawFixedPatch(x<<FRACBITS, 190<<FRACBITS, FRACUNIT, V_SNAPTOBOTTOM|V_SNAPTORIGHT, frameslash, ticcntcolor);
|
||||
}
|
||||
|
||||
// draw our actual framerate
|
||||
V_DrawPingNum(306, 190, V_SNAPTOBOTTOM|V_SNAPTORIGHT, totaltics, ticcntcolor);
|
||||
|
||||
|
||||
lasttic = ontic;
|
||||
V_DrawPingNum(x, 190, V_SNAPTOBOTTOM|V_SNAPTORIGHT, fps, ticcntcolor);
|
||||
}
|
||||
|
||||
// SCR_DisplayLocalPing
|
||||
|
|
|
@ -154,6 +154,7 @@ extern boolean R_SSE2;
|
|||
// ----------------
|
||||
extern viddef_t vid;
|
||||
extern INT32 setmodeneeded; // mode number to set if needed, or 0
|
||||
extern double averageFPS;
|
||||
|
||||
extern INT32 scr_bpp;
|
||||
extern UINT8 *scr_borderpatch; // patch used to fill the view borders
|
||||
|
@ -161,6 +162,7 @@ extern UINT8 *scr_borderpatch; // patch used to fill the view borders
|
|||
extern consvar_t cv_scr_width, cv_scr_height, cv_scr_depth, cv_renderview, cv_fullscreen, cv_vhseffect, cv_shittyscreen;
|
||||
// wait for page flipping to end or not
|
||||
extern consvar_t cv_vidwait;
|
||||
extern consvar_t cv_timescale;
|
||||
|
||||
// quick fix for tall/short skies, depending on bytesperpixel
|
||||
extern void (*walldrawerfunc)(void);
|
||||
|
@ -176,6 +178,8 @@ void SCR_SetDefaultMode (void);
|
|||
|
||||
void SCR_Startup (void);
|
||||
|
||||
void SCR_CalculateFPS(void);
|
||||
|
||||
FUNCMATH boolean SCR_IsAspectCorrect(INT32 width, INT32 height);
|
||||
|
||||
// move out to main code for consistency
|
||||
|
|
|
@ -160,6 +160,7 @@ static char returnWadPath[256];
|
|||
|
||||
#include "../doomdef.h"
|
||||
#include "../m_misc.h"
|
||||
#include "../i_time.h"
|
||||
#include "../i_video.h"
|
||||
#include "../i_sound.h"
|
||||
#include "../i_system.h"
|
||||
|
@ -175,6 +176,9 @@ static char returnWadPath[256];
|
|||
|
||||
#include "../m_argv.h"
|
||||
|
||||
#include "../r_main.h" // Frame interpolation/uncapped
|
||||
#include "../r_fps.h"
|
||||
|
||||
#ifdef MAC_ALERT
|
||||
#include "macosx/mac_alert.h"
|
||||
#endif
|
||||
|
@ -2927,122 +2931,80 @@ ticcmd_t *I_BaseTiccmd4(void)
|
|||
return &emptycmd4;
|
||||
}
|
||||
|
||||
#if defined (_WIN32)
|
||||
static HMODULE winmm = NULL;
|
||||
static DWORD starttickcount = 0; // hack for win2k time bug
|
||||
static p_timeGetTime pfntimeGetTime = NULL;
|
||||
static Uint64 timer_frequency;
|
||||
|
||||
// ---------
|
||||
// I_GetTime
|
||||
// Use the High Resolution Timer if available,
|
||||
// else use the multimedia timer which has 1 millisecond precision on Windowz 95,
|
||||
// but lower precision on Windows NT
|
||||
// ---------
|
||||
|
||||
tic_t I_GetTime(void)
|
||||
precise_t I_GetPreciseTime(void)
|
||||
{
|
||||
tic_t newtics = 0;
|
||||
return SDL_GetPerformanceCounter();
|
||||
}
|
||||
|
||||
if (!starttickcount) // high precision timer
|
||||
UINT64 I_GetPrecisePrecision(void)
|
||||
{
|
||||
return SDL_GetPerformanceFrequency();
|
||||
}
|
||||
|
||||
static UINT32 frame_rate;
|
||||
|
||||
static double frame_frequency;
|
||||
static UINT64 frame_epoch;
|
||||
static double elapsed_frames;
|
||||
|
||||
static void I_InitFrameTime(const UINT64 now, const UINT32 cap)
|
||||
{
|
||||
frame_rate = cap;
|
||||
frame_epoch = now;
|
||||
|
||||
//elapsed_frames = 0.0;
|
||||
|
||||
if (frame_rate == 0)
|
||||
{
|
||||
LARGE_INTEGER currtime; // use only LowPart if high resolution counter is not available
|
||||
static LARGE_INTEGER basetime = {{0, 0}};
|
||||
// Shouldn't be used, but just in case...?
|
||||
frame_frequency = 1.0;
|
||||
return;
|
||||
}
|
||||
|
||||
// use this if High Resolution timer is found
|
||||
static LARGE_INTEGER frequency;
|
||||
frame_frequency = timer_frequency / (double)frame_rate;
|
||||
}
|
||||
|
||||
if (!basetime.LowPart)
|
||||
{
|
||||
if (!QueryPerformanceFrequency(&frequency))
|
||||
frequency.QuadPart = 0;
|
||||
else
|
||||
QueryPerformanceCounter(&basetime);
|
||||
}
|
||||
double I_GetFrameTime(void)
|
||||
{
|
||||
const UINT64 now = SDL_GetPerformanceCounter();
|
||||
const UINT32 cap = R_GetFramerateCap();
|
||||
|
||||
if (frequency.LowPart && QueryPerformanceCounter(&currtime))
|
||||
{
|
||||
newtics = (INT32)((currtime.QuadPart - basetime.QuadPart) * NEWTICRATE
|
||||
/ frequency.QuadPart);
|
||||
}
|
||||
else if (pfntimeGetTime)
|
||||
{
|
||||
currtime.LowPart = pfntimeGetTime();
|
||||
if (!basetime.LowPart)
|
||||
basetime.LowPart = currtime.LowPart;
|
||||
newtics = ((currtime.LowPart - basetime.LowPart)/(1000/NEWTICRATE));
|
||||
}
|
||||
if (cap != frame_rate)
|
||||
{
|
||||
// Maybe do this in a OnChange function for cv_fpscap?
|
||||
I_InitFrameTime(now, cap);
|
||||
}
|
||||
|
||||
if (frame_rate == 0)
|
||||
{
|
||||
// Always advance a frame.
|
||||
elapsed_frames += 1.0;
|
||||
}
|
||||
else
|
||||
newtics = (GetTickCount() - starttickcount)/(1000/NEWTICRATE);
|
||||
|
||||
return newtics;
|
||||
}
|
||||
|
||||
static void I_ShutdownTimer(void)
|
||||
{
|
||||
pfntimeGetTime = NULL;
|
||||
if (winmm)
|
||||
{
|
||||
p_timeEndPeriod pfntimeEndPeriod = (p_timeEndPeriod)(LPVOID)GetProcAddress(winmm, "timeEndPeriod");
|
||||
if (pfntimeEndPeriod)
|
||||
pfntimeEndPeriod(1);
|
||||
FreeLibrary(winmm);
|
||||
winmm = NULL;
|
||||
elapsed_frames += (now - frame_epoch) / frame_frequency;
|
||||
}
|
||||
|
||||
frame_epoch = now; // moving epoch
|
||||
return elapsed_frames;
|
||||
}
|
||||
#else
|
||||
//
|
||||
// I_GetTime
|
||||
// returns time in 1/TICRATE second tics
|
||||
//
|
||||
tic_t I_GetTime (void)
|
||||
{
|
||||
static Uint64 basetime = 0;
|
||||
Uint64 ticks = SDL_GetTicks();
|
||||
|
||||
if (!basetime)
|
||||
basetime = ticks;
|
||||
|
||||
ticks -= basetime;
|
||||
|
||||
ticks = (ticks*TICRATE);
|
||||
|
||||
ticks = (ticks/1000);
|
||||
|
||||
return (tic_t)ticks;
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
//I_StartupTimer
|
||||
// I_StartupTimer
|
||||
//
|
||||
void I_StartupTimer(void)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
// for win2k time bug
|
||||
if (M_CheckParm("-gettickcount"))
|
||||
{
|
||||
starttickcount = GetTickCount();
|
||||
CONS_Printf("%s", M_GetText("Using GetTickCount()\n"));
|
||||
}
|
||||
winmm = LoadLibraryA("winmm.dll");
|
||||
if (winmm)
|
||||
{
|
||||
p_timeEndPeriod pfntimeBeginPeriod = (p_timeEndPeriod)(LPVOID)GetProcAddress(winmm, "timeBeginPeriod");
|
||||
if (pfntimeBeginPeriod)
|
||||
pfntimeBeginPeriod(1);
|
||||
pfntimeGetTime = (p_timeGetTime)(LPVOID)GetProcAddress(winmm, "timeGetTime");
|
||||
}
|
||||
I_AddExitFunc(I_ShutdownTimer);
|
||||
#endif
|
||||
timer_frequency = SDL_GetPerformanceFrequency();
|
||||
|
||||
I_InitFrameTime(0, R_GetFramerateCap());
|
||||
elapsed_frames = 0.0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void I_Sleep(void)
|
||||
void I_Sleep(UINT32 ms)
|
||||
{
|
||||
if (cv_sleep.value > 0)
|
||||
SDL_Delay(cv_sleep.value);
|
||||
SDL_Delay(ms);
|
||||
}
|
||||
|
||||
#ifdef NEWSIGNALHANDLER
|
||||
|
|
|
@ -1351,12 +1351,15 @@ void I_UpdateNoBlit(void)
|
|||
// from PrBoom's src/SDL/i_video.c
|
||||
static inline boolean I_SkipFrame(void)
|
||||
{
|
||||
#if 0
|
||||
#if 1
|
||||
// While I fixed the FPS counter bugging out with this,
|
||||
// I actually really like being able to pause and
|
||||
// use perfstats to measure rendering performance
|
||||
// without game logic changes.
|
||||
return false;
|
||||
#else
|
||||
static boolean skip = false;
|
||||
|
||||
if (rendermode != render_soft)
|
||||
return false;
|
||||
|
||||
skip = !skip;
|
||||
|
||||
switch (gamestate)
|
||||
|
@ -1371,17 +1374,20 @@ static inline boolean I_SkipFrame(void)
|
|||
return false;
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
// I_FinishUpdate
|
||||
//
|
||||
static SDL_Rect src_rect = { 0, 0, 0, 0 };
|
||||
|
||||
void I_FinishUpdate(void)
|
||||
{
|
||||
if (rendermode == render_none)
|
||||
return; //Alam: No software or OpenGl surface
|
||||
|
||||
SCR_CalculateFPS();
|
||||
|
||||
if (I_SkipFrame())
|
||||
return;
|
||||
|
||||
|
@ -1398,27 +1404,22 @@ void I_FinishUpdate(void)
|
|||
|
||||
if (rendermode == render_soft && screens[0])
|
||||
{
|
||||
SDL_Rect rect;
|
||||
|
||||
rect.x = 0;
|
||||
rect.y = 0;
|
||||
rect.w = vid.width;
|
||||
rect.h = vid.height;
|
||||
|
||||
if (!bufSurface) //Double-Check
|
||||
{
|
||||
Impl_VideoSetupSDLBuffer();
|
||||
}
|
||||
|
||||
if (bufSurface)
|
||||
{
|
||||
SDL_BlitSurface(bufSurface, NULL, vidSurface, &rect);
|
||||
SDL_BlitSurface(bufSurface, &src_rect, vidSurface, &src_rect);
|
||||
// Fury -- there's no way around UpdateTexture, the GL backend uses it anyway
|
||||
SDL_LockSurface(vidSurface);
|
||||
SDL_UpdateTexture(texture, &rect, vidSurface->pixels, vidSurface->pitch);
|
||||
SDL_UpdateTexture(texture, &src_rect, vidSurface->pixels, vidSurface->pitch);
|
||||
SDL_UnlockSurface(vidSurface);
|
||||
}
|
||||
|
||||
SDL_RenderClear(renderer);
|
||||
SDL_RenderCopy(renderer, texture, NULL, NULL);
|
||||
SDL_RenderCopy(renderer, texture, &src_rect, NULL);
|
||||
SDL_RenderPresent(renderer);
|
||||
}
|
||||
|
||||
|
@ -1428,6 +1429,7 @@ void I_FinishUpdate(void)
|
|||
OglSdlFinishUpdate(cv_vidwait.value);
|
||||
}
|
||||
#endif
|
||||
|
||||
exposevideo = SDL_FALSE;
|
||||
}
|
||||
|
||||
|
@ -1621,6 +1623,27 @@ void VID_PrepareModeList(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
static UINT32 refresh_rate;
|
||||
static UINT32 VID_GetRefreshRate(void)
|
||||
{
|
||||
int index = SDL_GetWindowDisplayIndex(window);
|
||||
SDL_DisplayMode m;
|
||||
|
||||
if (SDL_WasInit(SDL_INIT_VIDEO) == 0)
|
||||
{
|
||||
// Video not init yet.
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (SDL_GetCurrentDisplayMode(index, &m) != 0)
|
||||
{
|
||||
// Error has occurred.
|
||||
return 0;
|
||||
}
|
||||
|
||||
return m.refresh_rate;
|
||||
}
|
||||
|
||||
INT32 VID_SetMode(INT32 modeNum)
|
||||
{
|
||||
SDLdoUngrabMouse();
|
||||
|
@ -1665,6 +1688,11 @@ INT32 VID_SetMode(INT32 modeNum)
|
|||
}
|
||||
}
|
||||
|
||||
src_rect.w = vid.width;
|
||||
src_rect.h = vid.height;
|
||||
|
||||
refresh_rate = VID_GetRefreshRate();
|
||||
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
|
@ -2057,4 +2085,15 @@ void I_ShutdownGraphics(void)
|
|||
SDL_QuitSubSystem(SDL_INIT_VIDEO);
|
||||
framebuffer = SDL_FALSE;
|
||||
}
|
||||
|
||||
UINT32 I_GetRefreshRate(void)
|
||||
{
|
||||
// Moved to VID_GetRefreshRate.
|
||||
// Precalculating it like that won't work as
|
||||
// well for windowed mode since you can drag
|
||||
// the window around, but very slow PCs might have
|
||||
// trouble querying mode over and over again.
|
||||
return refresh_rate;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -42,8 +42,12 @@
|
|||
|
||||
#ifdef HAVE_BLUA
|
||||
#include "lua_hud.h"
|
||||
#include "lua_hudlib_drawlist.h"
|
||||
#include "lua_hook.h"
|
||||
#endif
|
||||
|
||||
#include "r_fps.h"
|
||||
|
||||
UINT16 objectsdrawn = 0;
|
||||
|
||||
//
|
||||
|
@ -175,6 +179,10 @@ hudinfo_t hudinfo[NUMHUDITEMS] =
|
|||
{ 240, 160}, // HUD_LAP
|
||||
};
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
static huddrawlist_h luahuddrawlist_game;
|
||||
#endif
|
||||
|
||||
//
|
||||
// STATUS BAR CODE
|
||||
//
|
||||
|
@ -422,6 +430,10 @@ void ST_Init(void)
|
|||
return;
|
||||
|
||||
ST_LoadGraphics();
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
luahuddrawlist_game = LUA_HUD_CreateDrawList();
|
||||
#endif
|
||||
}
|
||||
|
||||
// change the status bar too, when pressing F12 while viewing a demo.
|
||||
|
@ -1952,7 +1964,14 @@ static void ST_overlayDrawer(void)
|
|||
|
||||
#ifdef HAVE_BLUA
|
||||
if (!(netgame || multiplayer) || !hu_showscores)
|
||||
LUAh_GameHUD(stplyr);
|
||||
{
|
||||
if (renderisnewtic)
|
||||
{
|
||||
LUA_HUD_ClearDrawList(luahuddrawlist_game);
|
||||
LUAh_GameHUD(stplyr, luahuddrawlist_game);
|
||||
}
|
||||
LUA_HUD_DrawList(luahuddrawlist_game);
|
||||
}
|
||||
#endif
|
||||
|
||||
// draw level title Tails
|
||||
|
|
|
@ -55,6 +55,7 @@
|
|||
#include "g_game.h" // G_LoadGameData
|
||||
#include "filesrch.h"
|
||||
|
||||
#include "i_time.h"
|
||||
#include "i_video.h" // rendermode
|
||||
#include "d_netfil.h"
|
||||
#include "dehacked.h"
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include <mmsystem.h>
|
||||
|
||||
#include "../m_misc.h"
|
||||
#include "../i_time.h"
|
||||
#include "../i_video.h"
|
||||
#include "../i_sound.h"
|
||||
#include "../i_system.h"
|
||||
|
@ -45,6 +46,7 @@
|
|||
#include "../d_main.h"
|
||||
|
||||
#include "../m_argv.h"
|
||||
#include "../m_fixed.h"
|
||||
|
||||
#include "../w_wad.h"
|
||||
#include "../z_zone.h"
|
||||
|
@ -259,10 +261,25 @@ tic_t I_GetTime(void)
|
|||
return newtics;
|
||||
}
|
||||
|
||||
void I_Sleep(void)
|
||||
precise_t I_GetPreciseTime(void)
|
||||
{
|
||||
if (cv_sleep.value > 0)
|
||||
Sleep(cv_sleep.value);
|
||||
LARGE_INTEGER time;
|
||||
BOOL res = QueryPerformanceCounter(&time);
|
||||
if (!res) I_Error("QueryPerformanceCounter error"); // if this happens, you've gone back to the 90s
|
||||
return (precise_t) time.QuadPart;
|
||||
}
|
||||
|
||||
UINT64 I_GetPrecisePrecision(void)
|
||||
{
|
||||
LARGE_INTEGER time;
|
||||
BOOL res = QueryPerformanceFrequency(&time);
|
||||
if (!res) I_Error("QueryPerformanceFrequency error"); // if this happens, you've gone back to the 90s
|
||||
return (precise_t) time.QuadPart;
|
||||
}
|
||||
|
||||
void I_Sleep(UINT32 ms)
|
||||
{
|
||||
Sleep(ms);
|
||||
}
|
||||
|
||||
// should move to i_video
|
||||
|
|
Loading…
Reference in a new issue