mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2025-03-23 11:21:01 +00:00
Merge branch 'uncappedrevengeance' into next
Uncapped See merge request STJr/SRB2!1856 # Conflicts: # src/dummy/i_system.c # src/win32/win_sys.c
This commit is contained in:
commit
12c2ddb115
68 changed files with 3760 additions and 798 deletions
src
Makefile.d
Sourcefileandroid
b_bot.ccommand.cd_clisrv.cd_clisrv.hd_main.cd_net.cd_netcmd.cd_netfil.cd_player.hdummy
f_finale.cf_wipe.cg_demo.cg_game.chardware
hu_stuff.ci_system.hi_time.ci_time.hi_video.hinfo.clua_baselib.clua_hook.hlua_hooklib.clua_hud.hlua_hudlib.clua_hudlib_drawlist.clua_hudlib_drawlist.hlua_mobjlib.cm_anigif.cm_cheat.cm_menu.cm_misc.cm_perfstats.cp_ceilng.cp_enemy.cp_floor.cp_local.hp_map.cp_mobj.cp_mobj.hp_polyobj.cp_saveg.cp_setup.cp_slopes.cp_spec.cp_telept.cp_tick.cp_user.cr_bsp.cr_fps.cr_fps.hr_main.cr_main.hr_things.cscreen.cscreen.hsdl
st_stuff.cw_wad.cy_inter.c
|
@ -156,7 +156,7 @@ ifdef DEBUGMODE
|
|||
ifdef GCC48
|
||||
opts+=-Og
|
||||
else
|
||||
opts+=O0
|
||||
opts+=-O0
|
||||
endif
|
||||
endif
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@ am_map.c
|
|||
command.c
|
||||
console.c
|
||||
hu_stuff.c
|
||||
i_time.c
|
||||
y_inter.c
|
||||
st_stuff.c
|
||||
m_aatree.c
|
||||
|
@ -55,6 +56,7 @@ tables.c
|
|||
r_bsp.c
|
||||
r_data.c
|
||||
r_draw.c
|
||||
r_fps.c
|
||||
r_main.c
|
||||
r_plane.c
|
||||
r_segs.c
|
||||
|
@ -95,4 +97,5 @@ lua_taglib.c
|
|||
lua_polyobjlib.c
|
||||
lua_blockmaplib.c
|
||||
lua_hudlib.c
|
||||
lua_hudlib_drawlist.c
|
||||
lua_inputlib.c
|
||||
|
|
|
@ -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){}
|
||||
|
||||
|
|
|
@ -579,7 +579,7 @@ void B_RespawnBot(INT32 playernum)
|
|||
player->powers[pw_nocontrol] = sonic->player->powers[pw_nocontrol];
|
||||
player->pflags |= PF_AUTOBRAKE|(sonic->player->pflags & PF_DIRECTIONCHAR);
|
||||
|
||||
P_TeleportMove(tails, x, y, z);
|
||||
P_SetOrigin(tails, x, y, z);
|
||||
if (player->charability == CA_FLY)
|
||||
{
|
||||
P_SetPlayerMobjState(tails, S_PLAY_FLY);
|
||||
|
|
|
@ -2076,9 +2076,10 @@ void CV_AddValue(consvar_t *var, INT32 increment)
|
|||
{
|
||||
increment = 0;
|
||||
currentindice = max;
|
||||
break; // The value we definitely want, stop here.
|
||||
}
|
||||
else if (var->PossibleValue[max].value == var->value)
|
||||
currentindice = max;
|
||||
currentindice = max; // The value we maybe want.
|
||||
}
|
||||
|
||||
if (increment)
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include <unistd.h> //for unlink
|
||||
#endif
|
||||
|
||||
#include "i_time.h"
|
||||
#include "i_net.h"
|
||||
#include "i_system.h"
|
||||
#include "i_video.h"
|
||||
|
@ -113,6 +114,9 @@ static INT16 consistancy[BACKUPTICS];
|
|||
static UINT8 player_joining = false;
|
||||
UINT8 hu_redownloadinggamestate = 0;
|
||||
|
||||
// true when a player is connecting or disconnecting so that the gameplay has stopped in its tracks
|
||||
boolean hu_stopped = false;
|
||||
|
||||
UINT8 adminpassmd5[16];
|
||||
boolean adminpasswordset = false;
|
||||
|
||||
|
@ -2441,7 +2445,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;
|
||||
}
|
||||
|
@ -5206,8 +5213,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!!
|
||||
{
|
||||
|
@ -5231,7 +5240,7 @@ void TryRunTics(tic_t realtics)
|
|||
|
||||
if (demoplayback)
|
||||
{
|
||||
neededtic = gametic + (realtics * cv_playbackspeed.value);
|
||||
neededtic = gametic + realtics;
|
||||
// start a game after a demo
|
||||
maketic += realtics;
|
||||
firstticstosend = maketic;
|
||||
|
@ -5251,10 +5260,22 @@ void TryRunTics(tic_t realtics)
|
|||
}
|
||||
#endif
|
||||
|
||||
if (player_joining)
|
||||
return;
|
||||
ticking = neededtic > gametic;
|
||||
|
||||
if (neededtic > gametic)
|
||||
if (ticking)
|
||||
{
|
||||
if (realtics)
|
||||
hu_stopped = false;
|
||||
}
|
||||
|
||||
if (player_joining)
|
||||
{
|
||||
if (realtics)
|
||||
hu_stopped = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ticking)
|
||||
{
|
||||
if (advancedemo)
|
||||
{
|
||||
|
@ -5290,6 +5311,13 @@ void TryRunTics(tic_t realtics)
|
|||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (realtics)
|
||||
hu_stopped = true;
|
||||
}
|
||||
|
||||
return ticking;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -430,7 +430,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.
|
||||
|
@ -458,4 +458,7 @@ extern UINT8 hu_redownloadinggamestate;
|
|||
|
||||
extern UINT8 adminpassmd5[16];
|
||||
extern boolean adminpasswordset;
|
||||
|
||||
extern boolean hu_stopped;
|
||||
|
||||
#endif
|
||||
|
|
168
src/d_main.c
168
src/d_main.c
|
@ -40,6 +40,7 @@
|
|||
#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"
|
||||
|
@ -64,6 +65,7 @@
|
|||
#include "deh_tables.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
|
||||
#include "g_input.h" // tutorial mode control scheming
|
||||
|
@ -476,6 +478,7 @@ static void D_Display(void)
|
|||
|
||||
if (!automapactive && !dedicated && cv_renderview.value)
|
||||
{
|
||||
R_ApplyLevelInterpolators(R_UsingFrameInterpolation() ? rendertimefrac : FRACUNIT);
|
||||
PS_START_TIMING(ps_rendercalltime);
|
||||
if (players[displayplayer].mo || players[displayplayer].playerstate == PST_DEAD)
|
||||
{
|
||||
|
@ -524,6 +527,7 @@ static void D_Display(void)
|
|||
V_DoPostProcessor(1, postimgtype2, postimgparam2);
|
||||
}
|
||||
PS_STOP_TIMING(ps_rendercalltime);
|
||||
R_RestoreLevelInterpolators();
|
||||
}
|
||||
|
||||
if (lastdraw)
|
||||
|
@ -692,9 +696,14 @@ 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;
|
||||
static lumpnum_t gstartuplumpnum;
|
||||
|
||||
boolean interp = false;
|
||||
boolean doDisplay = false;
|
||||
|
||||
if (dedicated)
|
||||
server = true;
|
||||
|
||||
|
@ -705,6 +714,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()
|
||||
|
@ -745,6 +755,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;
|
||||
|
@ -756,7 +779,11 @@ void D_SRB2Loop(void)
|
|||
realtics = entertic - oldentertics;
|
||||
oldentertics = entertic;
|
||||
|
||||
refreshdirmenu = 0; // not sure where to put this, here as good as any?
|
||||
if (demoplayback && gamestate == GS_LEVEL)
|
||||
{
|
||||
// Nicer place to put this.
|
||||
realtics = realtics * cv_playbackspeed.value;
|
||||
}
|
||||
|
||||
#ifdef DEBUGFILE
|
||||
if (!realtics)
|
||||
|
@ -764,64 +791,119 @@ 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();
|
||||
}
|
||||
else if (rendertimeout < entertic) // in case the server hang or netsplit
|
||||
{
|
||||
// Lagless camera! Yay!
|
||||
if (gamestate == GS_LEVEL && netgame)
|
||||
if (lastdraw || singletics || gametic > rendergametic)
|
||||
{
|
||||
if (splitscreen && camera2.chase)
|
||||
P_MoveChaseCamera(&players[secondarydisplayplayer], &camera2, false);
|
||||
if (camera.chase)
|
||||
P_MoveChaseCamera(&players[displayplayer], &camera, false);
|
||||
}
|
||||
D_Display();
|
||||
rendergametic = gametic;
|
||||
rendertimeout = entertic + TICRATE/17;
|
||||
|
||||
if (moviemode)
|
||||
M_SaveFrame();
|
||||
if (takescreenshot) // Only take screenshots after drawing.
|
||||
M_DoScreenShot();
|
||||
doDisplay = true;
|
||||
}
|
||||
else if (rendertimeout < entertic) // in case the server hang or netsplit
|
||||
{
|
||||
// Lagless camera! Yay!
|
||||
if (gamestate == GS_LEVEL && netgame)
|
||||
{
|
||||
// Evaluate the chase cam once for every local realtic
|
||||
// This might actually be better suited inside G_Ticker or TryRunTics
|
||||
for (tic_t chasecamtics = 0; chasecamtics < realtics; chasecamtics++)
|
||||
{
|
||||
if (splitscreen && camera2.chase)
|
||||
P_MoveChaseCamera(&players[secondarydisplayplayer], &camera2, false);
|
||||
if (camera.chase)
|
||||
P_MoveChaseCamera(&players[displayplayer], &camera, false);
|
||||
}
|
||||
R_UpdateViewInterpolation();
|
||||
}
|
||||
|
||||
doDisplay = true;
|
||||
}
|
||||
|
||||
renderisnewtic = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
renderisnewtic = false;
|
||||
}
|
||||
|
||||
// consoleplayer -> displayplayer (hear sounds from viewpoint)
|
||||
if (interp)
|
||||
{
|
||||
// I looked at the possibility of putting in a float drawer for
|
||||
// perfstats and it's very complicated, so we'll just do this instead...
|
||||
ps_interp_frac.value.p = (precise_t)((FIXED_TO_FLOAT(g_time.timefrac)) * 1000.0f);
|
||||
ps_interp_lag.value.p = (precise_t)((deltasecs) * 1000.0f);
|
||||
|
||||
renderdeltatics = FLOAT_TO_FIXED(deltatics);
|
||||
|
||||
if (!(paused || P_AutoPause()) && deltatics < 1.0 && !hu_stopped)
|
||||
{
|
||||
rendertimefrac = g_time.timefrac;
|
||||
}
|
||||
else
|
||||
{
|
||||
rendertimefrac = FRACUNIT;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
renderdeltatics = realtics * FRACUNIT;
|
||||
rendertimefrac = FRACUNIT;
|
||||
}
|
||||
|
||||
if (interp || doDisplay)
|
||||
{
|
||||
D_Display();
|
||||
}
|
||||
|
||||
// Only take screenshots after drawing.
|
||||
if (moviemode)
|
||||
M_SaveFrame();
|
||||
if (takescreenshot)
|
||||
M_DoScreenShot();
|
||||
|
||||
// consoleplayer -> displayplayers (hear sounds from viewpoint)
|
||||
S_UpdateSounds(); // move positional sounds
|
||||
S_UpdateClosedCaptions();
|
||||
if (realtics > 0 || singletics)
|
||||
S_UpdateClosedCaptions();
|
||||
|
||||
#ifdef HW3SOUND
|
||||
HW3S_EndFrameUpdate();
|
||||
#endif
|
||||
|
||||
LUA_Step();
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1307,8 +1389,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();
|
||||
|
@ -1583,6 +1665,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)
|
||||
|
||||
if (M_CheckParm("-gametype") && M_IsNextParm())
|
||||
{
|
||||
// from Command_Map_f
|
||||
|
|
|
@ -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"
|
||||
|
@ -191,7 +192,7 @@ static CV_PossibleValue_t joyport_cons_t[] = {{1, "/dev/js0"}, {2, "/dev/js1"},
|
|||
static CV_PossibleValue_t teamscramble_cons_t[] = {{0, "Off"}, {1, "Random"}, {2, "Points"}, {0, NULL}};
|
||||
|
||||
static CV_PossibleValue_t startingliveslimit_cons_t[] = {{1, "MIN"}, {99, "MAX"}, {0, NULL}};
|
||||
static CV_PossibleValue_t sleeping_cons_t[] = {{-1, "MIN"}, {1000/TICRATE, "MAX"}, {0, NULL}};
|
||||
static CV_PossibleValue_t sleeping_cons_t[] = {{0, "MIN"}, {1000/TICRATE, "MAX"}, {0, NULL}};
|
||||
static CV_PossibleValue_t competitionboxes_cons_t[] = {{0, "Normal"}, {1, "Mystery"}, //{2, "Teleport"},
|
||||
{3, "None"}, {0, NULL}};
|
||||
|
||||
|
|
|
@ -35,6 +35,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"
|
||||
|
|
|
@ -383,6 +383,8 @@ typedef struct player_s
|
|||
|
||||
// fun thing for player sprite
|
||||
angle_t drawangle;
|
||||
angle_t old_drawangle;
|
||||
angle_t old_drawangle2;
|
||||
|
||||
// player's ring count
|
||||
INT16 rings;
|
||||
|
|
|
@ -14,24 +14,16 @@ UINT32 I_GetFreeMem(UINT32 *total)
|
|||
return 0;
|
||||
}
|
||||
|
||||
tic_t I_GetTime(void)
|
||||
{
|
||||
void I_Sleep(UINT32 ms){}
|
||||
|
||||
precise_t I_GetPreciseTime(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
precise_t I_GetPreciseTime(void)
|
||||
{
|
||||
return 0;
|
||||
UINT64 I_GetPrecisePrecision(void) {
|
||||
return 1000000;
|
||||
}
|
||||
|
||||
int I_PreciseToMicros(precise_t d)
|
||||
{
|
||||
(void)d;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void I_Sleep(void){}
|
||||
|
||||
void I_GetEvent(void){}
|
||||
|
||||
void I_OsPolling(void){}
|
||||
|
|
205
src/f_finale.c
205
src/f_finale.c
|
@ -20,6 +20,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"
|
||||
|
@ -62,8 +63,6 @@ static tic_t stoptimer;
|
|||
static boolean keypressed = false;
|
||||
|
||||
// (no longer) De-Demo'd Title Screen
|
||||
static tic_t xscrolltimer;
|
||||
static tic_t yscrolltimer;
|
||||
static INT32 menuanimtimer; // Title screen: background animation timing
|
||||
mobj_t *titlemapcameraref = NULL;
|
||||
|
||||
|
@ -229,6 +228,8 @@ static tic_t cutscene_lasttextwrite = 0;
|
|||
// STJR Intro
|
||||
char stjrintro[9] = "STJRI000";
|
||||
|
||||
static huddrawlist_h luahuddrawlist_title;
|
||||
|
||||
//
|
||||
// This alters the text string cutscene_disptext.
|
||||
// Use the typical string drawing functions to display it.
|
||||
|
@ -517,9 +518,9 @@ void F_StartIntro(void)
|
|||
}
|
||||
|
||||
//
|
||||
// F_IntroDrawScene
|
||||
// F_IntroDrawer
|
||||
//
|
||||
static void F_IntroDrawScene(void)
|
||||
void F_IntroDrawer(void)
|
||||
{
|
||||
boolean highres = true;
|
||||
INT32 cx = 8, cy = 128;
|
||||
|
@ -625,24 +626,22 @@ static void F_IntroDrawScene(void)
|
|||
if (intro_curtime > 1 && intro_curtime < (INT32)introscenetime[intro_scenenum])
|
||||
{
|
||||
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31);
|
||||
|
||||
if (intro_curtime < TICRATE-5) // Make the text shine!
|
||||
{
|
||||
sprintf(stjrintro, "STJRI%03u", intro_curtime-1);
|
||||
}
|
||||
else if (intro_curtime >= TICRATE-6 && intro_curtime < 2*TICRATE-20) // Pause on black screen for just a second
|
||||
{
|
||||
return;
|
||||
}
|
||||
else if (intro_curtime == 2*TICRATE-19)
|
||||
{
|
||||
// Fade in the text
|
||||
// The text fade out is automatically handled when switching to a new intro scene
|
||||
strncpy(stjrintro, "STJRI029", 9);
|
||||
S_ChangeMusicInternal("_stjr", false);
|
||||
|
||||
background = W_CachePatchName(stjrintro, PU_PATCH_LOWPRIORITY);
|
||||
wipestyleflags = WSF_FADEIN;
|
||||
F_WipeStartScreen();
|
||||
F_TryColormapFade(31);
|
||||
V_DrawSmallScaledPatch(bgxoffs, 84, 0, background);
|
||||
F_WipeEndScreen();
|
||||
F_RunWipe(0,true);
|
||||
}
|
||||
|
||||
if (!WipeInAction) // Draw the patch if not in a wipe
|
||||
|
@ -841,17 +840,27 @@ static void F_IntroDrawScene(void)
|
|||
V_DrawRightAlignedString(BASEVIDWIDTH-4, BASEVIDHEIGHT-12, V_ALLOWLOWERCASE|(trans<<V_ALPHASHIFT), "\x86""Press ""\x82""ENTER""\x86"" to skip...");
|
||||
}
|
||||
|
||||
if (animtimer)
|
||||
animtimer--;
|
||||
|
||||
V_DrawString(cx, cy, V_ALLOWLOWERCASE, cutscene_disptext);
|
||||
}
|
||||
|
||||
//
|
||||
// F_IntroDrawer
|
||||
// F_IntroTicker
|
||||
//
|
||||
void F_IntroDrawer(void)
|
||||
void F_IntroTicker(void)
|
||||
{
|
||||
// advance animation
|
||||
finalecount++;
|
||||
|
||||
timetonext--;
|
||||
|
||||
F_WriteText();
|
||||
|
||||
// check for skipping
|
||||
if (keypressed)
|
||||
keypressed = false;
|
||||
|
||||
wipestyleflags = WSF_CROSSFADE;
|
||||
|
||||
if (timetonext <= 0)
|
||||
{
|
||||
if (intro_scenenum == 0)
|
||||
|
@ -861,6 +870,9 @@ void F_IntroDrawer(void)
|
|||
wipestyleflags = WSF_FADEOUT;
|
||||
F_WipeStartScreen();
|
||||
F_TryColormapFade(31);
|
||||
|
||||
F_IntroDrawer();
|
||||
|
||||
F_WipeEndScreen();
|
||||
F_RunWipe(99,true);
|
||||
}
|
||||
|
@ -874,6 +886,9 @@ void F_IntroDrawer(void)
|
|||
wipestyleflags = (WSF_FADEOUT|WSF_TOWHITE);
|
||||
F_WipeStartScreen();
|
||||
F_TryColormapFade(0);
|
||||
|
||||
F_IntroDrawer();
|
||||
|
||||
F_WipeEndScreen();
|
||||
F_RunWipe(99,true);
|
||||
}
|
||||
|
@ -885,6 +900,9 @@ void F_IntroDrawer(void)
|
|||
wipestyleflags = WSF_FADEOUT;
|
||||
F_WipeStartScreen();
|
||||
F_TryColormapFade(31);
|
||||
|
||||
F_IntroDrawer();
|
||||
|
||||
F_WipeEndScreen();
|
||||
F_RunWipe(99,true);
|
||||
}
|
||||
|
@ -897,7 +915,10 @@ void F_IntroDrawer(void)
|
|||
while (quittime > nowtime)
|
||||
{
|
||||
while (!((nowtime = I_GetTime()) - lasttime))
|
||||
I_Sleep();
|
||||
{
|
||||
I_Sleep(cv_sleep.value);
|
||||
I_UpdateTime(cv_timescale.value);
|
||||
}
|
||||
lasttime = nowtime;
|
||||
|
||||
I_OsPolling();
|
||||
|
@ -920,12 +941,12 @@ void F_IntroDrawer(void)
|
|||
wipegamestate = GS_INTRO;
|
||||
return;
|
||||
}
|
||||
|
||||
F_NewCutscene(introtext[++intro_scenenum]);
|
||||
timetonext = introscenetime[intro_scenenum];
|
||||
|
||||
F_WipeStartScreen();
|
||||
wipegamestate = -1;
|
||||
wipestyleflags = WSF_CROSSFADE;
|
||||
animtimer = stoptimer = 0;
|
||||
}
|
||||
|
||||
|
@ -933,78 +954,36 @@ void F_IntroDrawer(void)
|
|||
|
||||
if (rendermode != render_none)
|
||||
{
|
||||
if (intro_scenenum == 5 && intro_curtime == 5*TICRATE)
|
||||
if (intro_scenenum == 0 && intro_curtime == 2*TICRATE-19)
|
||||
{
|
||||
patch_t *radar = W_CachePatchName("RADAR", PU_PATCH_LOWPRIORITY);
|
||||
S_ChangeMusicInternal("_stjr", false);
|
||||
|
||||
wipestyleflags = WSF_FADEIN;
|
||||
F_WipeStartScreen();
|
||||
F_WipeColorFill(31);
|
||||
V_DrawSmallScaledPatch(0, 0, 0, radar);
|
||||
W_UnlockCachedPatch(radar);
|
||||
V_DrawString(8, 128, V_ALLOWLOWERCASE, cutscene_disptext);
|
||||
F_TryColormapFade(31);
|
||||
|
||||
F_IntroDrawer();
|
||||
|
||||
F_WipeEndScreen();
|
||||
F_RunWipe(99,true);
|
||||
}
|
||||
else if (intro_scenenum == 7 && intro_curtime == 6*TICRATE) // Force a wipe here
|
||||
else if ((intro_scenenum == 5 && intro_curtime == 5*TICRATE)
|
||||
|| (intro_scenenum == 7 && intro_curtime == 6*TICRATE)
|
||||
//|| (intro_scenenum == 11 && intro_curtime == 7*TICRATE)
|
||||
|| (intro_scenenum == 15 && intro_curtime == 7*TICRATE))
|
||||
{
|
||||
patch_t *grass = W_CachePatchName("SGRASS2", PU_PATCH_LOWPRIORITY);
|
||||
|
||||
F_WipeStartScreen();
|
||||
F_WipeColorFill(31);
|
||||
V_DrawSmallScaledPatch(0, 0, 0, grass);
|
||||
W_UnlockCachedPatch(grass);
|
||||
V_DrawString(8, 128, V_ALLOWLOWERCASE, cutscene_disptext);
|
||||
|
||||
F_WipeEndScreen();
|
||||
F_RunWipe(99,true);
|
||||
}
|
||||
/*else if (intro_scenenum == 11 && intro_curtime == 7*TICRATE)
|
||||
{
|
||||
patch_t *confront = W_CachePatchName("CONFRONT", PU_PATCH_LOWPRIORITY);
|
||||
|
||||
F_WipeStartScreen();
|
||||
F_WipeColorFill(31);
|
||||
V_DrawSmallScaledPatch(0, 0, 0, confront);
|
||||
W_UnlockCachedPatch(confront);
|
||||
V_DrawString(8, 128, V_ALLOWLOWERCASE, cutscene_disptext);
|
||||
|
||||
F_WipeEndScreen();
|
||||
F_RunWipe(99,true);
|
||||
}*/
|
||||
if (intro_scenenum == 15 && intro_curtime == 7*TICRATE)
|
||||
{
|
||||
patch_t *sdo = W_CachePatchName("SONICDO2", PU_PATCH_LOWPRIORITY);
|
||||
|
||||
F_WipeStartScreen();
|
||||
F_WipeColorFill(31);
|
||||
V_DrawSmallScaledPatch(0, 0, 0, sdo);
|
||||
W_UnlockCachedPatch(sdo);
|
||||
V_DrawString(224, 8, V_ALLOWLOWERCASE, cutscene_disptext);
|
||||
F_IntroDrawer();
|
||||
|
||||
F_WipeEndScreen();
|
||||
F_RunWipe(99,true);
|
||||
}
|
||||
}
|
||||
|
||||
F_IntroDrawScene();
|
||||
}
|
||||
|
||||
//
|
||||
// F_IntroTicker
|
||||
//
|
||||
void F_IntroTicker(void)
|
||||
{
|
||||
// advance animation
|
||||
finalecount++;
|
||||
|
||||
timetonext--;
|
||||
|
||||
F_WriteText();
|
||||
|
||||
// check for skipping
|
||||
if (keypressed)
|
||||
keypressed = false;
|
||||
if (animtimer)
|
||||
animtimer--;
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -2304,6 +2283,9 @@ void F_InitMenuPresValues(void)
|
|||
M_SetMenuCurBackground((gamestate == GS_TIMEATTACK) ? "RECATTBG" : "TITLESKY");
|
||||
M_SetMenuCurFadeValue(16);
|
||||
M_SetMenuCurTitlePics();
|
||||
|
||||
LUA_HUD_DestroyDrawList(luahuddrawlist_title);
|
||||
luahuddrawlist_title = LUA_HUD_CreateDrawList();
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -2319,6 +2301,7 @@ void F_SkyScroll(INT32 scrollxspeed, INT32 scrollyspeed, const char *patchname)
|
|||
INT32 pw, ph; // scaled by dupz
|
||||
patch_t *pat;
|
||||
INT32 i, j;
|
||||
fixed_t fracmenuanimtimer, xscrolltimer, yscrolltimer;
|
||||
|
||||
if (rendermode == render_none)
|
||||
return;
|
||||
|
@ -2345,12 +2328,13 @@ void F_SkyScroll(INT32 scrollxspeed, INT32 scrollyspeed, const char *patchname)
|
|||
tilex = max(FixedCeil(FixedDiv(vid.width, pw)) >> FRACBITS, 1)+2; // one tile on both sides of center
|
||||
tiley = max(FixedCeil(FixedDiv(vid.height, ph)) >> FRACBITS, 1)+2;
|
||||
|
||||
xscrolltimer = ((menuanimtimer*scrollxspeed)/16 + patwidth*xneg) % (patwidth);
|
||||
yscrolltimer = ((menuanimtimer*scrollyspeed)/16 + patheight*yneg) % (patheight);
|
||||
fracmenuanimtimer = (menuanimtimer * FRACUNIT) - (FRACUNIT - rendertimefrac);
|
||||
xscrolltimer = ((fracmenuanimtimer*scrollxspeed)/16 + patwidth*xneg*FRACUNIT) % (patwidth * FRACUNIT);
|
||||
yscrolltimer = ((fracmenuanimtimer*scrollyspeed)/16 + patheight*yneg*FRACUNIT) % (patheight * FRACUNIT);
|
||||
|
||||
// coordinate offsets
|
||||
xscrolled = xscrolltimer * dupz;
|
||||
yscrolled = yscrolltimer * dupz;
|
||||
xscrolled = FixedInt(xscrolltimer * dupz);
|
||||
yscrolled = FixedInt(yscrolltimer * dupz);
|
||||
|
||||
for (x = (xispos) ? -pw*(tilex-1)+pw : 0, i = 0;
|
||||
i < tilex;
|
||||
|
@ -3421,7 +3405,21 @@ void F_TitleScreenDrawer(void)
|
|||
}
|
||||
|
||||
luahook:
|
||||
LUA_HUDHOOK(title);
|
||||
// The title drawer is sometimes called without first being started
|
||||
// In order to avoid use-before-initialization crashes, let's check and
|
||||
// create the drawlist if it doesn't exist.
|
||||
if (!LUA_HUD_IsDrawListValid(luahuddrawlist_title))
|
||||
{
|
||||
LUA_HUD_DestroyDrawList(luahuddrawlist_title);
|
||||
luahuddrawlist_title = LUA_HUD_CreateDrawList();
|
||||
}
|
||||
|
||||
if (renderisnewtic)
|
||||
{
|
||||
LUA_HUD_ClearDrawList(luahuddrawlist_title);
|
||||
LUA_HUDHOOK(title, luahuddrawlist_title);
|
||||
}
|
||||
LUA_HUD_DrawList(luahuddrawlist_title);
|
||||
}
|
||||
|
||||
// separate animation timer for backgrounds, since we also count
|
||||
|
@ -3858,11 +3856,27 @@ boolean F_ContinueResponder(event_t *event)
|
|||
static INT32 scenenum, cutnum;
|
||||
static INT32 picxpos, picypos, picnum, pictime, picmode, numpics, pictoloop;
|
||||
static INT32 textxpos, textypos;
|
||||
static boolean dofadenow = false, cutsceneover = false;
|
||||
static boolean cutsceneover = false;
|
||||
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)
|
||||
|
@ -3870,6 +3884,7 @@ static void F_AdvanceToNextScene(void)
|
|||
F_EndCutScene();
|
||||
return;
|
||||
}
|
||||
|
||||
++scenenum;
|
||||
|
||||
timetonext = 0;
|
||||
|
@ -3885,7 +3900,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;
|
||||
|
@ -3895,6 +3909,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);
|
||||
}
|
||||
}
|
||||
|
||||
// See also G_AfterIntermission, the only other place which handles intra-map/ending transitions
|
||||
|
@ -3969,21 +3991,6 @@ void F_StartCustomCutscene(INT32 cutscenenum, boolean precutscene, boolean reset
|
|||
//
|
||||
void F_CutsceneDrawer(void)
|
||||
{
|
||||
if (dofadenow && 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();
|
||||
}
|
||||
}
|
||||
V_DrawFill(0,0, BASEVIDWIDTH, BASEVIDHEIGHT, 31);
|
||||
|
||||
if (cutscenes[cutnum]->scene[scenenum].picname[picnum][0] != '\0')
|
||||
|
@ -3996,12 +4003,6 @@ void F_CutsceneDrawer(void)
|
|||
W_CachePatchName(cutscenes[cutnum]->scene[scenenum].picname[picnum], PU_PATCH_LOWPRIORITY));
|
||||
}
|
||||
|
||||
if (dofadenow && rendermode != render_none)
|
||||
{
|
||||
F_WipeEndScreen();
|
||||
F_RunWipe(cutscenes[cutnum]->scene[scenenum].fadeoutid, true);
|
||||
}
|
||||
|
||||
V_DrawString(textxpos, textypos, V_ALLOWLOWERCASE, cutscene_disptext);
|
||||
}
|
||||
|
||||
|
@ -4018,8 +4019,6 @@ void F_CutsceneTicker(void)
|
|||
finalecount++;
|
||||
cutscene_boostspeed = 0;
|
||||
|
||||
dofadenow = false;
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (netgame && i != serverplayer && !IsPlayerAdmin(i))
|
||||
|
|
|
@ -24,6 +24,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"
|
||||
|
@ -555,7 +556,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;
|
||||
|
||||
// Wipe styles
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "d_player.h"
|
||||
#include "d_clisrv.h"
|
||||
#include "p_setup.h"
|
||||
#include "i_time.h"
|
||||
#include "i_system.h"
|
||||
#include "m_random.h"
|
||||
#include "p_local.h"
|
||||
|
@ -1008,7 +1009,7 @@ void G_ReadMetalTic(mobj_t *metal)
|
|||
oldmetal.x = READFIXED(metal_p);
|
||||
oldmetal.y = READFIXED(metal_p);
|
||||
oldmetal.z = READFIXED(metal_p);
|
||||
P_TeleportMove(metal, oldmetal.x, oldmetal.y, oldmetal.z);
|
||||
P_MoveOrigin(metal, oldmetal.x, oldmetal.y, oldmetal.z);
|
||||
oldmetal.x = metal->x;
|
||||
oldmetal.y = metal->y;
|
||||
oldmetal.z = metal->z;
|
||||
|
|
19
src/g_game.c
19
src/g_game.c
|
@ -19,6 +19,7 @@
|
|||
#include "f_finale.h"
|
||||
#include "p_setup.h"
|
||||
#include "p_saveg.h"
|
||||
#include "i_time.h"
|
||||
#include "i_system.h"
|
||||
#include "am_map.h"
|
||||
#include "m_random.h"
|
||||
|
@ -46,6 +47,7 @@
|
|||
#include "b_bot.h"
|
||||
#include "m_cond.h" // condition sets
|
||||
#include "lua_script.h"
|
||||
#include "r_fps.h" // frame interpolation/uncapped
|
||||
|
||||
#include "lua_hud.h"
|
||||
|
||||
|
@ -1903,7 +1905,10 @@ void G_PreLevelTitleCard(void)
|
|||
{
|
||||
// draw loop
|
||||
while (!((nowtime = I_GetTime()) - lasttime))
|
||||
I_Sleep();
|
||||
{
|
||||
I_Sleep(cv_sleep.value);
|
||||
I_UpdateTime(cv_timescale.value);
|
||||
}
|
||||
lasttime = nowtime;
|
||||
|
||||
ST_runTitleCard();
|
||||
|
@ -2362,6 +2367,7 @@ void G_Ticker(boolean run)
|
|||
F_TextPromptTicker();
|
||||
AM_Ticker();
|
||||
HU_Ticker();
|
||||
|
||||
break;
|
||||
|
||||
case GS_INTERMISSION:
|
||||
|
@ -2414,7 +2420,9 @@ void G_Ticker(boolean run)
|
|||
break;
|
||||
|
||||
case GS_TITLESCREEN:
|
||||
if (titlemapinaction) P_Ticker(run); // then intentionally fall through
|
||||
if (titlemapinaction)
|
||||
P_Ticker(run);
|
||||
// then intentionally fall through
|
||||
/* FALLTHRU */
|
||||
case GS_WAITINGPLAYERS:
|
||||
F_MenuPresTicker(run);
|
||||
|
@ -2801,6 +2809,13 @@ void G_MovePlayerToSpawnOrStarpost(INT32 playernum)
|
|||
P_MovePlayerToStarpost(playernum);
|
||||
else
|
||||
P_MovePlayerToSpawn(playernum, G_FindMapStart(playernum));
|
||||
|
||||
R_ResetMobjInterpolationState(players[playernum].mo);
|
||||
|
||||
if (playernum == consoleplayer)
|
||||
P_ResetCamera(&players[playernum], &camera);
|
||||
else if (playernum == secondarydisplayplayer)
|
||||
P_ResetCamera(&players[playernum], &camera2);
|
||||
}
|
||||
|
||||
mapthing_t *G_FindCTFStart(INT32 playernum)
|
||||
|
|
|
@ -51,7 +51,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, UINT8 hflipped, FSurfaceInfo *Surface);
|
||||
EXPORT void HWRAPI(DrawModel) (model_t *model, INT32 frameIndex, float duration, float tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, UINT8 hflipped, FSurfaceInfo *Surface);
|
||||
EXPORT void HWRAPI(CreateModelVBOs) (model_t *model);
|
||||
EXPORT void HWRAPI(SetTransform) (FTransform *ptransform);
|
||||
EXPORT INT32 HWRAPI(GetTextureUsed) (void);
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "../v_video.h"
|
||||
#include "../p_local.h"
|
||||
#include "../p_setup.h"
|
||||
#include "../r_fps.h"
|
||||
#include "../r_local.h"
|
||||
#include "../r_patch.h"
|
||||
#include "../r_picformats.h"
|
||||
|
@ -38,6 +39,7 @@
|
|||
#include "../m_cheat.h"
|
||||
#include "../f_finale.h"
|
||||
#include "../r_things.h" // R_GetShadowZ
|
||||
#include "../d_main.h"
|
||||
#include "../p_slopes.h"
|
||||
#include "hw_md2.h"
|
||||
|
||||
|
@ -2968,6 +2970,7 @@ static 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)
|
||||
|
@ -3025,7 +3028,22 @@ static void HWR_Subsector(size_t num)
|
|||
|
||||
if (gl_frontsector->ffloors)
|
||||
{
|
||||
if (gl_frontsector->moved)
|
||||
boolean anyMoved = gl_frontsector->moved;
|
||||
|
||||
if (anyMoved == false)
|
||||
{
|
||||
for (rover = gl_frontsector->ffloors; rover; rover = rover->next)
|
||||
{
|
||||
sector_t *controlSec = §ors[rover->secnum];
|
||||
if (controlSec->moved == true)
|
||||
{
|
||||
anyMoved = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (anyMoved == true)
|
||||
{
|
||||
gl_frontsector->numlights = sub->sector->numlights = 0;
|
||||
R_Prep3DFloors(gl_frontsector);
|
||||
|
@ -3104,7 +3122,6 @@ static void HWR_Subsector(size_t num)
|
|||
if (gl_frontsector->ffloors)
|
||||
{
|
||||
/// \todo fix light, xoffs, yoffs, extracolormap ?
|
||||
ffloor_t * rover;
|
||||
for (rover = gl_frontsector->ffloors;
|
||||
rover; rover = rover->next)
|
||||
{
|
||||
|
@ -3616,6 +3633,18 @@ static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale)
|
|||
fixed_t slopez;
|
||||
pslope_t *groundslope;
|
||||
|
||||
// uncapped/interpolation
|
||||
interpmobjstate_t interp = {0};
|
||||
|
||||
if (R_UsingFrameInterpolation() && !paused)
|
||||
{
|
||||
R_InterpolateMobjState(thing, rendertimefrac, &interp);
|
||||
}
|
||||
else
|
||||
{
|
||||
R_InterpolateMobjState(thing, FRACUNIT, &interp);
|
||||
}
|
||||
|
||||
groundz = R_GetShadowZ(thing, &groundslope);
|
||||
|
||||
heightsec = thing->subsector->sector->heightsec;
|
||||
|
@ -3636,7 +3665,7 @@ static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale)
|
|||
return;
|
||||
}
|
||||
|
||||
floordiff = abs((flip < 0 ? thing->height : 0) + thing->z - groundz);
|
||||
floordiff = abs((flip < 0 ? thing->height : 0) + interp.z - groundz);
|
||||
|
||||
alpha = floordiff / (4*FRACUNIT) + 75;
|
||||
if (alpha >= 255) return;
|
||||
|
@ -3650,8 +3679,8 @@ static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale)
|
|||
scalemul = FixedMul(scalemul, (thing->radius*2) / gpatch->height);
|
||||
|
||||
fscale = FIXED_TO_FLOAT(scalemul);
|
||||
fx = FIXED_TO_FLOAT(thing->x);
|
||||
fy = FIXED_TO_FLOAT(thing->y);
|
||||
fx = FIXED_TO_FLOAT(interp.x);
|
||||
fy = FIXED_TO_FLOAT(interp.y);
|
||||
|
||||
// 3--2
|
||||
// | /|
|
||||
|
@ -3729,12 +3758,44 @@ static void HWR_RotateSpritePolyToAim(gl_vissprite_t *spr, FOutVector *wallVerts
|
|||
&& spr && spr->mobj && !R_ThingIsPaperSprite(spr->mobj)
|
||||
&& wallVerts)
|
||||
{
|
||||
float basey = FIXED_TO_FLOAT(spr->mobj->z);
|
||||
float lowy = wallVerts[0].y;
|
||||
if (!precip && P_MobjFlip(spr->mobj) == -1) // precip doesn't have eflags so they can't flip
|
||||
// uncapped/interpolation
|
||||
interpmobjstate_t interp = {0};
|
||||
float basey, lowy;
|
||||
|
||||
// do interpolation
|
||||
if (R_UsingFrameInterpolation() && !paused)
|
||||
{
|
||||
basey = FIXED_TO_FLOAT(spr->mobj->z + spr->mobj->height);
|
||||
if (precip)
|
||||
{
|
||||
R_InterpolatePrecipMobjState((precipmobj_t *)spr->mobj, rendertimefrac, &interp);
|
||||
}
|
||||
else
|
||||
{
|
||||
R_InterpolateMobjState(spr->mobj, rendertimefrac, &interp);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (precip)
|
||||
{
|
||||
R_InterpolatePrecipMobjState((precipmobj_t *)spr->mobj, FRACUNIT, &interp);
|
||||
}
|
||||
else
|
||||
{
|
||||
R_InterpolateMobjState(spr->mobj, FRACUNIT, &interp);
|
||||
}
|
||||
}
|
||||
|
||||
if (P_MobjFlip(spr->mobj) == -1)
|
||||
{
|
||||
basey = FIXED_TO_FLOAT(interp.z + spr->mobj->height);
|
||||
}
|
||||
else
|
||||
{
|
||||
basey = FIXED_TO_FLOAT(interp.z);
|
||||
}
|
||||
lowy = wallVerts[0].y;
|
||||
|
||||
// Rotate sprites to fully billboard with the camera
|
||||
// X, Y, AND Z need to be manipulated for the polys to rotate around the
|
||||
// origin, because of how the origin setting works I believe that should
|
||||
|
@ -5013,7 +5074,6 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
INT32 heightsec, phs;
|
||||
const boolean splat = R_ThingIsFloorSprite(thing);
|
||||
const boolean papersprite = (R_ThingIsPaperSprite(thing) && !splat);
|
||||
angle_t mobjangle = (thing->player ? thing->player->drawangle : thing->angle);
|
||||
float z1, z2;
|
||||
|
||||
fixed_t spr_width, spr_height;
|
||||
|
@ -5023,10 +5083,10 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
INT32 rollangle = 0;
|
||||
#endif
|
||||
|
||||
if (!thing)
|
||||
return;
|
||||
// uncapped/interpolation
|
||||
interpmobjstate_t interp = {0};
|
||||
|
||||
if (thing->spritexscale < 1 || thing->spriteyscale < 1)
|
||||
if (!thing)
|
||||
return;
|
||||
|
||||
INT32 blendmode;
|
||||
|
@ -5044,13 +5104,26 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
|
||||
dispoffset = thing->info->dispoffset;
|
||||
|
||||
this_scale = FIXED_TO_FLOAT(thing->scale);
|
||||
spritexscale = FIXED_TO_FLOAT(thing->spritexscale);
|
||||
spriteyscale = FIXED_TO_FLOAT(thing->spriteyscale);
|
||||
|
||||
if (R_UsingFrameInterpolation() && !paused)
|
||||
{
|
||||
R_InterpolateMobjState(thing, rendertimefrac, &interp);
|
||||
}
|
||||
else
|
||||
{
|
||||
R_InterpolateMobjState(thing, FRACUNIT, &interp);
|
||||
}
|
||||
|
||||
if (interp.spritexscale < 1 || interp.spriteyscale < 1)
|
||||
return;
|
||||
|
||||
this_scale = FIXED_TO_FLOAT(interp.scale);
|
||||
spritexscale = FIXED_TO_FLOAT(interp.spritexscale);
|
||||
spriteyscale = FIXED_TO_FLOAT(interp.spriteyscale);
|
||||
|
||||
// transform the origin point
|
||||
tr_x = FIXED_TO_FLOAT(thing->x) - gl_viewx;
|
||||
tr_y = FIXED_TO_FLOAT(thing->y) - gl_viewy;
|
||||
tr_x = FIXED_TO_FLOAT(interp.x) - gl_viewx;
|
||||
tr_y = FIXED_TO_FLOAT(interp.y) - gl_viewy;
|
||||
|
||||
// rotation around vertical axis
|
||||
tz = (tr_x * gl_viewcos) + (tr_y * gl_viewsin);
|
||||
|
@ -5073,8 +5146,8 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
}
|
||||
|
||||
// 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
|
||||
|
@ -5122,7 +5195,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
I_Error("sprframes NULL for sprite %d\n", thing->sprite);
|
||||
#endif
|
||||
|
||||
ang = R_PointToAngle (thing->x, thing->y) - mobjangle;
|
||||
ang = R_PointToAngle (interp.x, interp.y) - interp.angle;
|
||||
if (mirrored)
|
||||
ang = InvAngle(ang);
|
||||
|
||||
|
@ -5190,8 +5263,8 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
|
||||
if (thing->renderflags & RF_ABSOLUTEOFFSETS)
|
||||
{
|
||||
spr_offset = thing->spritexoffset;
|
||||
spr_topoffset = thing->spriteyoffset;
|
||||
spr_offset = interp.spritexoffset;
|
||||
spr_topoffset = interp.spriteyoffset;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -5200,14 +5273,14 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
if ((thing->renderflags & RF_FLIPOFFSETS) && flip)
|
||||
flipoffset = -1;
|
||||
|
||||
spr_offset += thing->spritexoffset * flipoffset;
|
||||
spr_topoffset += thing->spriteyoffset * flipoffset;
|
||||
spr_offset += interp.spritexoffset * flipoffset;
|
||||
spr_topoffset += interp.spriteyoffset * flipoffset;
|
||||
}
|
||||
|
||||
if (papersprite)
|
||||
{
|
||||
rightsin = FIXED_TO_FLOAT(FINESINE((mobjangle)>>ANGLETOFINESHIFT));
|
||||
rightcos = FIXED_TO_FLOAT(FINECOSINE((mobjangle)>>ANGLETOFINESHIFT));
|
||||
rightsin = FIXED_TO_FLOAT(FINESINE(interp.angle >> ANGLETOFINESHIFT));
|
||||
rightcos = FIXED_TO_FLOAT(FINECOSINE(interp.angle >> ANGLETOFINESHIFT));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -5220,14 +5293,24 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
if (thing->renderflags & RF_SHADOWEFFECTS)
|
||||
{
|
||||
mobj_t *caster = thing->target;
|
||||
interpmobjstate_t casterinterp = {};
|
||||
|
||||
if (R_UsingFrameInterpolation() && !paused)
|
||||
{
|
||||
R_InterpolateMobjState(caster, rendertimefrac, &casterinterp);
|
||||
}
|
||||
else
|
||||
{
|
||||
R_InterpolateMobjState(caster, FRACUNIT, &casterinterp);
|
||||
}
|
||||
|
||||
if (caster && !P_MobjWasRemoved(caster))
|
||||
{
|
||||
fixed_t groundz = R_GetShadowZ(thing, NULL);
|
||||
fixed_t floordiff = abs(((thing->eflags & MFE_VERTICALFLIP) ? caster->height : 0) + caster->z - groundz);
|
||||
fixed_t floordiff = abs(((thing->eflags & MFE_VERTICALFLIP) ? caster->height : 0) + casterinterp.z - groundz);
|
||||
|
||||
shadowheight = FIXED_TO_FLOAT(floordiff);
|
||||
shadowscale = FIXED_TO_FLOAT(FixedMul(FRACUNIT - floordiff/640, caster->scale));
|
||||
shadowscale = FIXED_TO_FLOAT(FixedMul(FRACUNIT - floordiff/640, casterinterp.scale));
|
||||
|
||||
if (splat)
|
||||
spritexscale *= shadowscale;
|
||||
|
@ -5268,12 +5351,12 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
|
||||
if (vflip)
|
||||
{
|
||||
gz = FIXED_TO_FLOAT(thing->z + thing->height) - (FIXED_TO_FLOAT(spr_topoffset) * this_yscale);
|
||||
gz = FIXED_TO_FLOAT(interp.z + thing->height) - (FIXED_TO_FLOAT(spr_topoffset) * this_yscale);
|
||||
gzt = gz + (FIXED_TO_FLOAT(spr_height) * this_yscale);
|
||||
}
|
||||
else
|
||||
{
|
||||
gzt = FIXED_TO_FLOAT(thing->z) + (FIXED_TO_FLOAT(spr_topoffset) * this_yscale);
|
||||
gzt = FIXED_TO_FLOAT(interp.z) + (FIXED_TO_FLOAT(spr_topoffset) * this_yscale);
|
||||
gz = gzt - (FIXED_TO_FLOAT(spr_height) * this_yscale);
|
||||
}
|
||||
|
||||
|
@ -5292,7 +5375,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
if (heightsec != -1 && phs != -1) // only clip things which are in special sectors
|
||||
{
|
||||
float top = gzt;
|
||||
float bottom = FIXED_TO_FLOAT(thing->z);
|
||||
float bottom = FIXED_TO_FLOAT(interp.z);
|
||||
|
||||
if (R_ThingIsFloorSprite(thing))
|
||||
top = bottom;
|
||||
|
@ -5309,13 +5392,24 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
|
||||
if ((thing->flags2 & MF2_LINKDRAW) && thing->tracer)
|
||||
{
|
||||
interpmobjstate_t tracer_interp = {};
|
||||
|
||||
if (! R_ThingVisible(thing->tracer))
|
||||
return;
|
||||
|
||||
if (R_UsingFrameInterpolation() && !paused)
|
||||
{
|
||||
R_InterpolateMobjState(thing->tracer, rendertimefrac, &tracer_interp);
|
||||
}
|
||||
else
|
||||
{
|
||||
R_InterpolateMobjState(thing->tracer, FRACUNIT, &tracer_interp);
|
||||
}
|
||||
|
||||
// calculate tz for tracer, same way it is calculated for this sprite
|
||||
// transform the origin point
|
||||
tr_x = FIXED_TO_FLOAT(thing->tracer->x) - gl_viewx;
|
||||
tr_y = FIXED_TO_FLOAT(thing->tracer->y) - gl_viewy;
|
||||
tr_x = FIXED_TO_FLOAT(tracer_interp.x) - gl_viewx;
|
||||
tr_y = FIXED_TO_FLOAT(tracer_interp.y) - gl_viewy;
|
||||
|
||||
// rotation around vertical axis
|
||||
tracertz = (tr_x * gl_viewcos) + (tr_y * gl_viewsin);
|
||||
|
@ -5438,6 +5532,9 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing)
|
|||
unsigned rot = 0;
|
||||
UINT8 flip;
|
||||
|
||||
if (!thing)
|
||||
return;
|
||||
|
||||
// Visibility check by the blend mode.
|
||||
if (thing->frame & FF_TRANSMASK)
|
||||
{
|
||||
|
@ -5445,9 +5542,22 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing)
|
|||
return;
|
||||
}
|
||||
|
||||
// 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 = FIXED_TO_FLOAT(thing->x) - gl_viewx;
|
||||
tr_y = FIXED_TO_FLOAT(thing->y) - gl_viewy;
|
||||
tr_x = FIXED_TO_FLOAT(interp.x) - gl_viewx;
|
||||
tr_y = FIXED_TO_FLOAT(interp.y) - gl_viewy;
|
||||
|
||||
// rotation around vertical axis
|
||||
tz = (tr_x * gl_viewcos) + (tr_y * gl_viewsin);
|
||||
|
@ -5456,8 +5566,8 @@ static 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)
|
||||
|
@ -5520,7 +5630,7 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing)
|
|||
vis->colormap = NULL;
|
||||
|
||||
// set top/bottom coords
|
||||
vis->gzt = FIXED_TO_FLOAT(thing->z + spritecachedinfo[lumpoff].topoffset);
|
||||
vis->gzt = FIXED_TO_FLOAT(interp.z + spritecachedinfo[lumpoff].topoffset);
|
||||
vis->gz = vis->gzt - FIXED_TO_FLOAT(spritecachedinfo[lumpoff].height);
|
||||
|
||||
vis->precip = true;
|
||||
|
@ -6656,6 +6766,7 @@ void HWR_DoPostProcessor(player_t *player)
|
|||
// 10 by 10 grid. 2 coordinates (xy)
|
||||
float v[SCREENVERTS][SCREENVERTS][2];
|
||||
static double disStart = 0;
|
||||
|
||||
UINT8 x, y;
|
||||
INT32 WAVELENGTH;
|
||||
INT32 AMPLITUDE;
|
||||
|
@ -6664,15 +6775,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++)
|
||||
|
@ -6686,7 +6797,7 @@ void HWR_DoPostProcessor(player_t *player)
|
|||
}
|
||||
HWD.pfnPostImgRedraw(v);
|
||||
if (!(paused || P_AutoPause()))
|
||||
disStart += 1;
|
||||
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"
|
||||
|
@ -1338,8 +1339,8 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
|
|||
{
|
||||
patch_t *gpatch, *blendgpatch;
|
||||
GLPatch_t *hwrPatch = NULL, *hwrBlendPatch = NULL;
|
||||
INT32 durs = spr->mobj->state->tics;
|
||||
INT32 tics = spr->mobj->tics;
|
||||
float durs = (float)spr->mobj->state->tics;
|
||||
float tics = (float)spr->mobj->tics;
|
||||
const boolean papersprite = (R_ThingIsPaperSprite(spr->mobj) && !R_ThingIsFloorSprite(spr->mobj));
|
||||
const UINT8 flip = (UINT8)(!(spr->mobj->eflags & MFE_VERTICALFLIP) != !R_ThingVerticallyFlipped(spr->mobj));
|
||||
const UINT8 hflip = (UINT8)(!(spr->mobj->mirrored) != !R_ThingHorizontallyFlipped(spr->mobj));
|
||||
|
@ -1349,6 +1350,16 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
|
|||
angle_t ang;
|
||||
INT32 mod;
|
||||
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)
|
||||
|
@ -1498,8 +1509,8 @@ boolean HWR_DrawModel(gl_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;
|
||||
}
|
||||
|
||||
frame = (spr->mobj->frame & FF_FRAMEMASK);
|
||||
|
@ -1523,7 +1534,11 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
|
|||
}
|
||||
|
||||
#ifdef USE_MODEL_NEXTFRAME
|
||||
#define INTERPOLERATION_LIMIT TICRATE/4
|
||||
// Interpolate the model interpolation. (lol)
|
||||
tics -= FixedToFloat(rendertimefrac);
|
||||
|
||||
#define INTERPOLERATION_LIMIT (TICRATE * 0.25f)
|
||||
|
||||
if (cv_glmodelinterpolation.value && tics <= durs && tics <= INTERPOLERATION_LIMIT)
|
||||
{
|
||||
if (durs > INTERPOLERATION_LIMIT)
|
||||
|
@ -1572,13 +1587,13 @@ boolean HWR_DrawModel(gl_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 (flip)
|
||||
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)->sprites[spr->mobj->sprite2];
|
||||
|
@ -1589,16 +1604,13 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
|
|||
|
||||
if (sprframe->rotate || papersprite)
|
||||
{
|
||||
fixed_t anglef = AngleFixed(spr->mobj->angle);
|
||||
|
||||
if (spr->mobj->player)
|
||||
anglef = AngleFixed(spr->mobj->player->drawangle);
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -1620,7 +1632,7 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
|
|||
p.rotaxis = (UINT8)(sprinfo->pivot[(spr->mobj->frame & FF_FRAMEMASK)].rotaxis);
|
||||
|
||||
// for NiGHTS specifically but should work everywhere else
|
||||
ang = R_PointToAngle (spr->mobj->x, spr->mobj->y) - (spr->mobj->player ? spr->mobj->player->drawangle : spr->mobj->angle);
|
||||
ang = R_PointToAngle (interp.x, interp.y) - interp.angle;
|
||||
if ((sprframe->rotate & SRF_RIGHT) && (ang < ANGLE_180)) // See from right
|
||||
p.rollflip = 1;
|
||||
else if ((sprframe->rotate & SRF_LEFT) && (ang >= ANGLE_180)) // See from left
|
||||
|
|
|
@ -2672,7 +2672,7 @@ EXPORT void HWRAPI(CreateModelVBOs) (model_t *model)
|
|||
|
||||
#define BUFFER_OFFSET(i) ((void*)(i))
|
||||
|
||||
static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, UINT8 hflipped, FSurfaceInfo *Surface)
|
||||
static void DrawModelEx(model_t *model, INT32 frameIndex, float duration, float tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, UINT8 hflipped, FSurfaceInfo *Surface)
|
||||
{
|
||||
static GLRGBAFloat poly = {0,0,0,0};
|
||||
static GLRGBAFloat tint = {0,0,0,0};
|
||||
|
@ -2701,11 +2701,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;
|
||||
|
@ -2977,7 +2977,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, UINT8 hflipped, FSurfaceInfo *Surface)
|
||||
EXPORT void HWRAPI(DrawModel) (model_t *model, INT32 frameIndex, float duration, float tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, UINT8 hflipped, FSurfaceInfo *Surface)
|
||||
{
|
||||
DrawModelEx(model, frameIndex, duration, tics, nextFrameIndex, pos, scale, flipped, hflipped, Surface);
|
||||
}
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
#endif
|
||||
|
||||
#include "lua_hud.h"
|
||||
#include "lua_hudlib_drawlist.h"
|
||||
#include "lua_hook.h"
|
||||
|
||||
// coords are scaled
|
||||
|
@ -166,10 +167,14 @@ static tic_t cechotimer = 0;
|
|||
static tic_t cechoduration = 5*TICRATE;
|
||||
static INT32 cechoflags = 0;
|
||||
|
||||
static huddrawlist_h luahuddrawlist_scores;
|
||||
|
||||
//======================================================================
|
||||
// HEADS UP INIT
|
||||
//======================================================================
|
||||
|
||||
static tic_t resynch_ticker = 0;
|
||||
|
||||
#ifndef NONET
|
||||
// just after
|
||||
static void Command_Say_f(void);
|
||||
|
@ -332,6 +337,8 @@ void HU_Init(void)
|
|||
|
||||
// set shift translation table
|
||||
shiftxform = english_shiftxform;
|
||||
|
||||
luahuddrawlist_scores = LUA_HUD_CreateDrawList();
|
||||
}
|
||||
|
||||
static inline void HU_Stop(void)
|
||||
|
@ -382,12 +389,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.
|
||||
|
@ -400,10 +407,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
|
||||
|
||||
|
@ -874,6 +881,39 @@ 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)
|
||||
{
|
||||
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;
|
||||
|
||||
if (hu_redownloadinggamestate)
|
||||
resynch_ticker++;
|
||||
}
|
||||
|
||||
#ifndef NONET
|
||||
|
@ -1102,7 +1142,7 @@ boolean HU_Responder(event_t *ev)
|
|||
if (chatlen+pastelen > HU_MAXMSGLEN)
|
||||
return true; // we can't paste this!!
|
||||
|
||||
memmove(&w_chat[c_input + pastelen], &w_chat[c_input], pastelen);
|
||||
memmove(&w_chat[c_input + pastelen], &w_chat[c_input], (chatlen - c_input) + 1); // +1 for '\0'
|
||||
memcpy(&w_chat[c_input], paste, pastelen); // copy all of that.
|
||||
c_input += pastelen;
|
||||
return true;
|
||||
|
@ -1854,8 +1894,6 @@ static void HU_DrawCEcho(void)
|
|||
echoptr = line;
|
||||
echoptr++;
|
||||
}
|
||||
|
||||
--cechotimer;
|
||||
}
|
||||
|
||||
static void HU_drawGametype(void)
|
||||
|
@ -1917,9 +1955,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
|
||||
|
@ -1929,30 +1964,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)
|
||||
|
@ -1979,7 +1994,13 @@ void HU_Drawer(void)
|
|||
}
|
||||
else
|
||||
HU_DrawCoopOverlay();
|
||||
LUA_HUDHOOK(scores);
|
||||
|
||||
if (renderisnewtic)
|
||||
{
|
||||
LUA_HUD_ClearDrawList(luahuddrawlist_scores);
|
||||
LUA_HUDHOOK(scores, luahuddrawlist_scores);
|
||||
}
|
||||
LUA_HUD_DrawList(luahuddrawlist_scores);
|
||||
}
|
||||
|
||||
if (gamestate != GS_LEVEL)
|
||||
|
@ -1992,12 +2013,9 @@ void HU_Drawer(void)
|
|||
// draw desynch text
|
||||
if (hu_redownloadinggamestate)
|
||||
{
|
||||
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, ".");
|
||||
|
|
|
@ -42,23 +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.
|
||||
/** \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 Converts a precise_t to microseconds and casts it to a 32 bit integer.
|
||||
/** \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.
|
||||
*/
|
||||
int I_PreciseToMicros(precise_t);
|
||||
UINT64 I_GetPrecisePrecision(void);
|
||||
|
||||
/** \brief The I_Sleep function
|
||||
/** \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 = CVAR_INIT ("timescale", "1.0", CV_NETVAR|CV_CHEAT|CV_FLOAT, timescale_cons_t, 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__
|
|
@ -151,4 +151,6 @@ void I_BeginRead(void);
|
|||
*/
|
||||
void I_EndRead(void);
|
||||
|
||||
UINT32 I_GetRefreshRate(void);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -770,9 +770,9 @@ state_t states[NUMSTATES] =
|
|||
|
||||
// 1-Up box sprites (uses player sprite)
|
||||
{SPR_PLAY, SPR2_LIFE, 2, {NULL}, 0, 18, S_PLAY_BOX2}, // S_PLAY_BOX1
|
||||
{SPR_NULL, 0, 1, {NULL}, 0, 0, S_PLAY_BOX1}, // S_PLAY_BOX2
|
||||
{SPR_NULL, 0, 1, {NULL}, 0, 18, S_PLAY_BOX1}, // S_PLAY_BOX2
|
||||
{SPR_PLAY, SPR2_LIFE, 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_PLAY, SPR2_LIFE, 20, {NULL}, 0, 4, S_NULL}, // S_PLAY_ICON3
|
||||
|
||||
// Level end sign (uses player sprite)
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
#include "m_misc.h" // M_MapNumber
|
||||
#include "b_bot.h" // B_UpdateBotleader
|
||||
#include "d_clisrv.h" // CL_RemovePlayer
|
||||
#include "i_system.h" // I_GetPreciseTime, I_PreciseToMicros
|
||||
#include "i_system.h" // I_GetPreciseTime, I_GetPrecisePrecision
|
||||
|
||||
#include "lua_script.h"
|
||||
#include "lua_libs.h"
|
||||
|
@ -1783,7 +1783,42 @@ static int lib_pTeleportMove(lua_State *L)
|
|||
INLEVEL
|
||||
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
|
||||
INLEVEL
|
||||
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
|
||||
INLEVEL
|
||||
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;
|
||||
|
@ -3909,7 +3944,7 @@ static int lib_gTicsToMilliseconds(lua_State *L)
|
|||
|
||||
static int lib_getTimeMicros(lua_State *L)
|
||||
{
|
||||
lua_pushinteger(L, I_PreciseToMicros(I_GetPreciseTime()));
|
||||
lua_pushinteger(L, I_GetPreciseTime() / (I_GetPrecisePrecision() / 1000000));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -4048,6 +4083,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},
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "d_player.h"
|
||||
#include "s_sound.h"
|
||||
#include "d_event.h"
|
||||
#include "lua_hudlib_drawlist.h"
|
||||
|
||||
/*
|
||||
Do you know what an 'X Macro' is? Such a macro is called over each element of
|
||||
|
@ -110,12 +111,12 @@ ENUM (STRING_HOOK);
|
|||
|
||||
/* dead simple, LUA_HOOK(GameQuit) */
|
||||
#define LUA_HOOK(type) LUA_HookVoid(HOOK(type))
|
||||
#define LUA_HUDHOOK(type) LUA_HookHUD(HUD_HOOK(type))
|
||||
#define LUA_HUDHOOK(type,drawlist) LUA_HookHUD(HUD_HOOK(type),(drawlist))
|
||||
|
||||
extern boolean hook_cmd_running;
|
||||
|
||||
void LUA_HookVoid(int hook);
|
||||
void LUA_HookHUD(int hook);
|
||||
void LUA_HookHUD(int hook, huddrawlist_h drawlist);
|
||||
|
||||
int LUA_HookMobj(mobj_t *, int hook);
|
||||
int LUA_Hook2Mobj(mobj_t *, mobj_t *, int hook);
|
||||
|
|
|
@ -641,7 +641,7 @@ int LUA_HookKey(event_t *event, int hook_type)
|
|||
return hook.status;
|
||||
}
|
||||
|
||||
void LUA_HookHUD(int hook_type)
|
||||
void LUA_HookHUD(int hook_type, huddrawlist_h list)
|
||||
{
|
||||
const hook_t * map = &hudHookIds[hook_type];
|
||||
Hook_State hook;
|
||||
|
@ -650,12 +650,15 @@ void LUA_HookHUD(int hook_type)
|
|||
start_hook_stack();
|
||||
begin_hook_values(&hook);
|
||||
|
||||
LUA_SetHudHook(hook_type);
|
||||
LUA_SetHudHook(hook_type, list);
|
||||
|
||||
hud_running = true; // local hook
|
||||
init_hook_call(&hook, 0, res_none);
|
||||
call_mapped(&hook, map);
|
||||
hud_running = false;
|
||||
|
||||
lua_pushnil(gL);
|
||||
lua_setfield(gL, LUA_REGISTRYINDEX, "HUD_DRAW_LIST");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
@ -47,4 +52,6 @@ extern boolean hud_running;
|
|||
|
||||
boolean LUA_HudEnabled(enum hud option);
|
||||
|
||||
void LUA_SetHudHook(int hook);
|
||||
void LUA_SetHudHook(int hook, huddrawlist_h list);
|
||||
|
||||
#endif // __LUA_HUD_H__
|
||||
|
|
144
src/lua_hudlib.c
144
src/lua_hudlib.c
|
@ -645,7 +645,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);
|
||||
|
@ -659,7 +660,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;
|
||||
}
|
||||
|
||||
|
@ -668,7 +676,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);
|
||||
|
@ -685,7 +694,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;
|
||||
}
|
||||
|
||||
|
@ -694,7 +710,8 @@ static int libd_drawStretched(lua_State *L)
|
|||
fixed_t x, y, hscale, vscale;
|
||||
INT32 flags;
|
||||
patch_t *patch;
|
||||
const UINT8 *colormap = NULL;
|
||||
UINT8 *colormap = NULL;
|
||||
huddrawlist_h list;
|
||||
|
||||
HUDONLY
|
||||
x = luaL_checkinteger(L, 1);
|
||||
|
@ -712,7 +729,14 @@ static int libd_drawStretched(lua_State *L)
|
|||
|
||||
flags &= ~V_PARAMMASK; // Don't let crashes happen.
|
||||
|
||||
V_DrawStretchyFixedPatch(x, y, hscale, vscale, 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_AddDrawStretched(list, x, y, hscale, vscale, patch, flags, colormap);
|
||||
else
|
||||
V_DrawStretchyFixedPatch(x, y, hscale, vscale, flags, patch, colormap);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -721,7 +745,8 @@ static int libd_drawCropped(lua_State *L)
|
|||
fixed_t x, y, hscale, vscale, sx, sy, w, h;
|
||||
INT32 flags;
|
||||
patch_t *patch;
|
||||
const UINT8 *colormap = NULL;
|
||||
UINT8 *colormap = NULL;
|
||||
huddrawlist_h list;
|
||||
|
||||
HUDONLY
|
||||
x = luaL_checkinteger(L, 1);
|
||||
|
@ -751,13 +776,22 @@ static int libd_drawCropped(lua_State *L)
|
|||
|
||||
flags &= ~V_PARAMMASK; // Don't let crashes happen.
|
||||
|
||||
V_DrawCroppedPatch(x, y, hscale, vscale, flags, patch, colormap, sx, sy, w, h);
|
||||
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_AddDrawCropped(list, x, y, hscale, vscale, patch, flags, colormap, sx, sy, w, h);
|
||||
else
|
||||
V_DrawCroppedPatch(x, y, hscale, vscale, flags, patch, colormap, sx, sy, w, h);
|
||||
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);
|
||||
|
@ -765,13 +799,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);
|
||||
|
@ -780,12 +823,20 @@ 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;
|
||||
}
|
||||
|
||||
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);
|
||||
|
@ -793,12 +844,21 @@ 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_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);
|
||||
|
@ -808,6 +868,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
|
||||
|
@ -899,6 +968,7 @@ static int libd_drawNameTag(lua_State *L)
|
|||
UINT16 outlinecolor;
|
||||
UINT8 *basecolormap = NULL;
|
||||
UINT8 *outlinecolormap = NULL;
|
||||
huddrawlist_h list;
|
||||
|
||||
HUDONLY
|
||||
|
||||
|
@ -914,7 +984,15 @@ static int libd_drawNameTag(lua_State *L)
|
|||
outlinecolormap = R_GetTranslationColormap(TC_DEFAULT, outlinecolor, GTC_CACHE);
|
||||
|
||||
flags &= ~V_PARAMMASK; // Don't let crashes happen.
|
||||
V_DrawNameTag(x, y, flags, FRACUNIT, basecolormap, outlinecolormap, 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_AddDrawNameTag(list, x, y, str, flags, basecolor, outlinecolor, basecolormap, outlinecolormap);
|
||||
else
|
||||
V_DrawNameTag(x, y, flags, FRACUNIT, basecolormap, outlinecolormap, str);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -929,6 +1007,7 @@ static int libd_drawScaledNameTag(lua_State *L)
|
|||
UINT16 outlinecolor;
|
||||
UINT8 *basecolormap = NULL;
|
||||
UINT8 *outlinecolormap = NULL;
|
||||
huddrawlist_h list;
|
||||
|
||||
HUDONLY
|
||||
|
||||
|
@ -947,7 +1026,15 @@ static int libd_drawScaledNameTag(lua_State *L)
|
|||
outlinecolormap = R_GetTranslationColormap(TC_DEFAULT, outlinecolor, GTC_CACHE);
|
||||
|
||||
flags &= ~V_PARAMMASK; // Don't let crashes happen.
|
||||
V_DrawNameTag(FixedInt(x), FixedInt(y), flags, scale, basecolormap, outlinecolormap, 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_AddDrawScaledNameTag(list, x, y, str, flags, scale, basecolor, outlinecolor, basecolormap, outlinecolormap);
|
||||
else
|
||||
V_DrawNameTag(FixedInt(x), FixedInt(y), flags, scale, basecolormap, outlinecolormap, str);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -957,6 +1044,7 @@ static int libd_drawLevelTitle(lua_State *L)
|
|||
INT32 y;
|
||||
const char *str;
|
||||
INT32 flags;
|
||||
huddrawlist_h list;
|
||||
|
||||
HUDONLY
|
||||
|
||||
|
@ -967,7 +1055,14 @@ static int libd_drawLevelTitle(lua_State *L)
|
|||
|
||||
flags &= ~V_PARAMMASK; // Don't let crashes happen.
|
||||
|
||||
V_DrawLevelTitle(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_AddDrawLevelTitle(list, x, y, str, flags);
|
||||
else
|
||||
V_DrawLevelTitle(x, y, flags, str);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1060,6 +1155,7 @@ static int libd_getStringColormap(lua_State *L)
|
|||
|
||||
static int libd_fadeScreen(lua_State *L)
|
||||
{
|
||||
huddrawlist_h list;
|
||||
UINT16 color = luaL_checkinteger(L, 1);
|
||||
UINT8 strength = luaL_checkinteger(L, 2);
|
||||
const UINT8 maxstrength = ((color & 0xFF00) ? 32 : 10);
|
||||
|
@ -1072,13 +1168,24 @@ static int libd_fadeScreen(lua_State *L)
|
|||
if (strength > maxstrength)
|
||||
return luaL_error(L, "%s fade strength %d out of range (0 - %d)", ((color & 0xFF00) ? "COLORMAP" : "TRANSMAP"), strength, maxstrength);
|
||||
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, "HUD_DRAW_LIST");
|
||||
list = (huddrawlist_h) lua_touserdata(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
if (strength == maxstrength) // Allow as a shortcut for drawfill...
|
||||
{
|
||||
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, ((color & 0xFF00) ? 31 : color));
|
||||
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;
|
||||
}
|
||||
|
||||
V_DrawFadeScreen(color, strength);
|
||||
if (LUA_HUD_IsDrawListValid(list))
|
||||
LUA_HUD_AddFadeScreen(list, color, strength);
|
||||
else
|
||||
V_DrawFadeScreen(color, strength);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1356,10 +1463,13 @@ boolean LUA_HudEnabled(enum hud option)
|
|||
return false;
|
||||
}
|
||||
|
||||
void LUA_SetHudHook(int hook)
|
||||
void LUA_SetHudHook(int hook, huddrawlist_h list)
|
||||
{
|
||||
lua_getref(gL, lib_draw_ref);
|
||||
|
||||
lua_pushlightuserdata(gL, list);
|
||||
lua_setfield(gL, LUA_REGISTRYINDEX, "HUD_DRAW_LIST");
|
||||
|
||||
switch (hook)
|
||||
{
|
||||
case HUD_HOOK(game): {
|
||||
|
|
572
src/lua_hudlib_drawlist.c
Normal file
572
src/lua_hudlib_drawlist.c
Normal file
|
@ -0,0 +1,572 @@
|
|||
// 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_DrawStretched,
|
||||
DI_DrawCropped,
|
||||
DI_DrawNum,
|
||||
DI_DrawPaddedNum,
|
||||
DI_DrawFill,
|
||||
DI_DrawString,
|
||||
DI_DrawNameTag,
|
||||
DI_DrawScaledNameTag,
|
||||
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_fixedcenter,
|
||||
align_fixedright,
|
||||
align_small,
|
||||
align_smallfixed,
|
||||
align_smallfixedcenter,
|
||||
align_smallfixedright,
|
||||
align_smallcenter,
|
||||
align_smallright,
|
||||
align_smallthin,
|
||||
align_smallthincenter,
|
||||
align_smallthinright,
|
||||
align_smallthinfixed,
|
||||
align_smallthinfixedcenter,
|
||||
align_smallthinfixedright,
|
||||
align_thin,
|
||||
align_thinfixed,
|
||||
align_thinfixedcenter,
|
||||
align_thinfixedright,
|
||||
align_thincenter,
|
||||
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_AddDrawStretched(
|
||||
huddrawlist_h list,
|
||||
fixed_t x,
|
||||
fixed_t y,
|
||||
fixed_t hscale,
|
||||
fixed_t vscale,
|
||||
patch_t *patch,
|
||||
INT32 flags,
|
||||
UINT8 *colormap
|
||||
)
|
||||
{
|
||||
size_t i = AllocateDrawItem(list);
|
||||
drawitem_t *item = &list->items[i];
|
||||
item->type = DI_DrawStretched;
|
||||
item->x = x;
|
||||
item->y = y;
|
||||
item->hscale = hscale;
|
||||
item->vscale = vscale;
|
||||
item->patch = patch;
|
||||
item->flags = flags;
|
||||
item->colormap = colormap;
|
||||
}
|
||||
|
||||
void LUA_HUD_AddDrawCropped(
|
||||
huddrawlist_h list,
|
||||
fixed_t x,
|
||||
fixed_t y,
|
||||
fixed_t hscale,
|
||||
fixed_t vscale,
|
||||
patch_t *patch,
|
||||
INT32 flags,
|
||||
UINT8 *colormap,
|
||||
fixed_t sx,
|
||||
fixed_t sy,
|
||||
fixed_t w,
|
||||
fixed_t h
|
||||
)
|
||||
{
|
||||
size_t i = AllocateDrawItem(list);
|
||||
drawitem_t *item = &list->items[i];
|
||||
item->type = DI_DrawCropped;
|
||||
item->x = x;
|
||||
item->y = y;
|
||||
item->hscale = hscale;
|
||||
item->vscale = vscale;
|
||||
item->patch = patch;
|
||||
item->flags = flags;
|
||||
item->colormap = colormap;
|
||||
item->sx = sx;
|
||||
item->sy = sy;
|
||||
item->w = w;
|
||||
item->h = h;
|
||||
}
|
||||
|
||||
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_AddDrawNameTag(
|
||||
huddrawlist_h list,
|
||||
INT32 x,
|
||||
INT32 y,
|
||||
const char *str,
|
||||
INT32 flags,
|
||||
UINT16 basecolor,
|
||||
UINT16 outlinecolor,
|
||||
UINT8 *basecolormap,
|
||||
UINT8 *outlinecolormap
|
||||
)
|
||||
{
|
||||
size_t i = AllocateDrawItem(list);
|
||||
drawitem_t *item = &list->items[i];
|
||||
item->type = DI_DrawNameTag;
|
||||
item->x = x;
|
||||
item->y = y;
|
||||
item->str = CopyString(list, str);
|
||||
item->flags = flags;
|
||||
item->basecolor = basecolor;
|
||||
item->outlinecolor = outlinecolor;
|
||||
item->basecolormap = basecolormap;
|
||||
item->outlinecolormap = outlinecolormap;
|
||||
}
|
||||
|
||||
void LUA_HUD_AddDrawScaledNameTag(
|
||||
huddrawlist_h list,
|
||||
fixed_t x,
|
||||
fixed_t y,
|
||||
const char *str,
|
||||
INT32 flags,
|
||||
fixed_t scale,
|
||||
UINT16 basecolor,
|
||||
UINT16 outlinecolor,
|
||||
UINT8 *basecolormap,
|
||||
UINT8 *outlinecolormap
|
||||
)
|
||||
{
|
||||
size_t i = AllocateDrawItem(list);
|
||||
drawitem_t *item = &list->items[i];
|
||||
item->type = DI_DrawScaledNameTag;
|
||||
item->x = x;
|
||||
item->y = y;
|
||||
item->str = CopyString(list, str);
|
||||
item->flags = flags;
|
||||
item->scale = scale;
|
||||
item->basecolor = basecolor;
|
||||
item->outlinecolor = outlinecolor;
|
||||
item->basecolormap = basecolormap;
|
||||
item->outlinecolormap = outlinecolormap;
|
||||
}
|
||||
|
||||
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_DrawStretched:
|
||||
V_DrawStretchyFixedPatch(item->x, item->y, item->hscale, item->vscale, item->flags, item->patch, item->colormap);
|
||||
break;
|
||||
case DI_DrawCropped:
|
||||
V_DrawCroppedPatch(item->x, item->y, item->hscale, item->vscale, item->flags, item->patch, item->colormap, item->sx, item->sy, item->w, item->h);
|
||||
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;
|
||||
case align_fixedcenter:
|
||||
V_DrawCenteredStringAtFixed(item->x, item->y, item->flags, item->str);
|
||||
break;
|
||||
case align_fixedright:
|
||||
V_DrawRightAlignedStringAtFixed(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_smallfixed:
|
||||
V_DrawSmallStringAtFixed(item->x, item->y, item->flags, item->str);
|
||||
break;
|
||||
case align_smallfixedcenter:
|
||||
V_DrawCenteredSmallStringAtFixed(item->x, item->y, item->flags, item->str);
|
||||
break;
|
||||
case align_smallfixedright:
|
||||
V_DrawRightAlignedSmallStringAtFixed(item->x, item->y, item->flags, item->str);
|
||||
break;
|
||||
case align_smallcenter:
|
||||
V_DrawCenteredSmallString(item->x, item->y, item->flags, item->str);
|
||||
break;
|
||||
case align_smallright:
|
||||
V_DrawRightAlignedSmallString(item->x, item->y, item->flags, item->str);
|
||||
break;
|
||||
case align_smallthin:
|
||||
V_DrawSmallThinString(item->x, item->y, item->flags, item->str);
|
||||
break;
|
||||
case align_smallthincenter:
|
||||
V_DrawCenteredSmallThinString(item->x, item->y, item->flags, item->str);
|
||||
break;
|
||||
case align_smallthinright:
|
||||
V_DrawRightAlignedSmallThinString(item->x, item->y, item->flags, item->str);
|
||||
break;
|
||||
case align_smallthinfixed:
|
||||
V_DrawSmallThinStringAtFixed(item->x, item->y, item->flags, item->str);
|
||||
break;
|
||||
case align_smallthinfixedcenter:
|
||||
V_DrawCenteredSmallThinStringAtFixed(item->x, item->y, item->flags, item->str);
|
||||
break;
|
||||
case align_smallthinfixedright:
|
||||
V_DrawRightAlignedSmallThinStringAtFixed(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_thincenter:
|
||||
V_DrawCenteredThinString(item->x, item->y, item->flags, item->str);
|
||||
break;
|
||||
case align_thinright:
|
||||
V_DrawRightAlignedThinString(item->x, item->y, item->flags, item->str);
|
||||
break;
|
||||
case align_thinfixed:
|
||||
V_DrawThinStringAtFixed(item->x, item->y, item->flags, item->str);
|
||||
break;
|
||||
case align_thinfixedcenter:
|
||||
V_DrawCenteredThinStringAtFixed(item->x, item->y, item->flags, item->str);
|
||||
break;
|
||||
case align_thinfixedright:
|
||||
V_DrawRightAlignedThinStringAtFixed(item->x, item->y, item->flags, item->str);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case DI_DrawNameTag:
|
||||
V_DrawNameTag(item->x, item->y, item->flags, FRACUNIT, item->basecolormap, item->outlinecolormap, item->str);
|
||||
break;
|
||||
case DI_DrawScaledNameTag:
|
||||
V_DrawNameTag(FixedInt(item->x), FixedInt(item->y), item->flags, item->scale, item->basecolormap, item->outlinecolormap, 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;
|
||||
}
|
||||
}
|
||||
}
|
152
src/lua_hudlib_drawlist.h
Normal file
152
src/lua_hudlib_drawlist.h
Normal file
|
@ -0,0 +1,152 @@
|
|||
// 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_AddDrawStretched(
|
||||
huddrawlist_h list,
|
||||
fixed_t x,
|
||||
fixed_t y,
|
||||
fixed_t hscale,
|
||||
fixed_t vscale,
|
||||
patch_t *patch,
|
||||
INT32 flags,
|
||||
UINT8 *colormap
|
||||
);
|
||||
void LUA_HUD_AddDrawCropped(
|
||||
huddrawlist_h list,
|
||||
fixed_t x,
|
||||
fixed_t y,
|
||||
fixed_t hscale,
|
||||
fixed_t vscale,
|
||||
patch_t *patch,
|
||||
INT32 flags,
|
||||
UINT8 *colormap,
|
||||
fixed_t sx,
|
||||
fixed_t sy,
|
||||
fixed_t w,
|
||||
fixed_t h
|
||||
);
|
||||
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_AddDrawNameTag(
|
||||
huddrawlist_h list,
|
||||
INT32 x,
|
||||
INT32 y,
|
||||
const char *str,
|
||||
INT32 flags,
|
||||
UINT16 basecolor,
|
||||
UINT16 outlinecolor,
|
||||
UINT8 *basecolormap,
|
||||
UINT8 *outlinecolormap
|
||||
);
|
||||
void LUA_HUD_AddDrawScaledNameTag(
|
||||
huddrawlist_h list,
|
||||
fixed_t x,
|
||||
fixed_t y,
|
||||
const char *str,
|
||||
INT32 flags,
|
||||
fixed_t scale,
|
||||
UINT16 basecolor,
|
||||
UINT16 outlinecolor,
|
||||
UINT8 *basecolormap,
|
||||
UINT8 *outlinecolormap
|
||||
);
|
||||
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__
|
|
@ -458,7 +458,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));
|
||||
|
@ -767,6 +767,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:
|
||||
|
|
|
@ -608,7 +608,7 @@ static void GIF_framewrite(void)
|
|||
{
|
||||
// golden's attempt at creating a "dynamic delay"
|
||||
UINT16 mingifdelay = 10; // minimum gif delay in milliseconds (keep at 10 because gifs can't get more precise).
|
||||
gif_delayus += I_PreciseToMicros(I_GetPreciseTime() - gif_prevframetime); // increase delay by how much time was spent between last measurement
|
||||
gif_delayus += (I_GetPreciseTime() - gif_prevframetime) / (I_GetPrecisePrecision() / 1000000); // increase delay by how much time was spent between last measurement
|
||||
|
||||
if (gif_delayus/1000 >= mingifdelay) // delay is big enough to be able to effect gif frame delay?
|
||||
{
|
||||
|
@ -621,7 +621,7 @@ static void GIF_framewrite(void)
|
|||
{
|
||||
float delayf = ceil(100.0f/NEWTICRATE);
|
||||
|
||||
delay = (UINT16)I_PreciseToMicros((I_GetPreciseTime() - gif_prevframetime))/10/1000;
|
||||
delay = (UINT16)((I_GetPreciseTime() - gif_prevframetime)) / (I_GetPrecisePrecision() / 1000000) /10/1000;
|
||||
|
||||
if (delay < (UINT16)(delayf))
|
||||
delay = (UINT16)(delayf);
|
||||
|
|
|
@ -475,7 +475,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);
|
||||
|
@ -696,7 +696,7 @@ void Command_Teleport_f(void)
|
|||
}
|
||||
|
||||
P_MapStart();
|
||||
if (!P_TeleportMove(p->mo, intx, inty, intz))
|
||||
if (!P_SetOrigin(p->mo, intx, inty, intz))
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Unable to teleport to that spot!\n"));
|
||||
else
|
||||
S_StartSound(p->mo, sfx_mixup);
|
||||
|
@ -1315,13 +1315,13 @@ void OP_ObjectplaceMovement(player_t *player)
|
|||
if (cmd->forwardmove != 0)
|
||||
{
|
||||
P_Thrust(player->mo, player->mo->angle, (cmd->forwardmove*player->mo->scale/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)
|
||||
{
|
||||
P_Thrust(player->mo, player->mo->angle-ANGLE_90, (cmd->sidemove*player->mo->scale/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;
|
||||
}
|
||||
|
||||
|
|
202
src/m_menu.c
202
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"
|
||||
|
||||
|
@ -171,10 +173,10 @@ static INT32 vidm_nummodes;
|
|||
static INT32 vidm_column_size;
|
||||
|
||||
// new menus
|
||||
static tic_t recatkdrawtimer = 0;
|
||||
static tic_t ntsatkdrawtimer = 0;
|
||||
static fixed_t recatkdrawtimer = 0;
|
||||
static fixed_t ntsatkdrawtimer = 0;
|
||||
|
||||
static tic_t charseltimer = 0;
|
||||
static fixed_t charseltimer = 0;
|
||||
static fixed_t char_scroll = 0;
|
||||
#define charscrollamt 128*FRACUNIT
|
||||
|
||||
|
@ -207,17 +209,17 @@ menu_t SPauseDef;
|
|||
static levelselect_t levelselect = {0, NULL};
|
||||
static UINT8 levelselectselect[3];
|
||||
static patch_t *levselp[2][3];
|
||||
static INT32 lsoffs[2];
|
||||
static fixed_t lsoffs[2];
|
||||
|
||||
#define lsrow levelselectselect[0]
|
||||
#define lscol levelselectselect[1]
|
||||
#define lshli levelselectselect[2]
|
||||
|
||||
#define lshseperation 101
|
||||
#define lsbasevseperation (62*vid.height)/(BASEVIDHEIGHT*vid.dupy) //62
|
||||
#define lsbasevseperation ((62*vid.height)/(BASEVIDHEIGHT*vid.dupy)) //62
|
||||
#define lsheadingheight 16
|
||||
#define getheadingoffset(row) (levelselect.rows[row].header[0] ? lsheadingheight : 0)
|
||||
#define lsvseperation(row) lsbasevseperation + getheadingoffset(row)
|
||||
#define lsvseperation(row) (lsbasevseperation + getheadingoffset(row))
|
||||
#define lswide(row) levelselect.rows[row].mapavailable[3]
|
||||
|
||||
#define lsbasex 19
|
||||
|
@ -1386,6 +1388,7 @@ static menuitem_t OP_VideoOptionsMenu[] =
|
|||
#ifdef HWRENDER
|
||||
{IT_HEADER, NULL, "Renderer", NULL, 208},
|
||||
{IT_CALL | IT_STRING, NULL, "OpenGL Options...", M_OpenGLOptionsMenu, 214},
|
||||
{IT_STRING | IT_CVAR, NULL, "FPS Cap", &cv_fpscap, 219},
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -5496,7 +5499,7 @@ static void M_HandleLevelPlatter(INT32 choice)
|
|||
{
|
||||
if (!lsoffs[0]) // prevent sound spam
|
||||
{
|
||||
lsoffs[0] = -8;
|
||||
lsoffs[0] = -8 * FRACUNIT;
|
||||
S_StartSound(NULL,sfx_s3kb7);
|
||||
}
|
||||
return;
|
||||
|
@ -5505,7 +5508,7 @@ static void M_HandleLevelPlatter(INT32 choice)
|
|||
}
|
||||
lsrow++;
|
||||
|
||||
lsoffs[0] = lsvseperation(lsrow);
|
||||
lsoffs[0] = lsvseperation(lsrow) * FRACUNIT;
|
||||
|
||||
if (levelselect.rows[lsrow].header[0])
|
||||
lshli = lsrow;
|
||||
|
@ -5524,7 +5527,7 @@ static void M_HandleLevelPlatter(INT32 choice)
|
|||
{
|
||||
if (!lsoffs[0]) // prevent sound spam
|
||||
{
|
||||
lsoffs[0] = 8;
|
||||
lsoffs[0] = 8 * FRACUNIT;
|
||||
S_StartSound(NULL,sfx_s3kb7);
|
||||
}
|
||||
return;
|
||||
|
@ -5533,7 +5536,7 @@ static void M_HandleLevelPlatter(INT32 choice)
|
|||
}
|
||||
lsrow--;
|
||||
|
||||
lsoffs[0] = -lsvseperation(iter);
|
||||
lsoffs[0] = -lsvseperation(iter) * FRACUNIT;
|
||||
|
||||
if (levelselect.rows[lsrow].header[0])
|
||||
lshli = lsrow;
|
||||
|
@ -5574,7 +5577,7 @@ static void M_HandleLevelPlatter(INT32 choice)
|
|||
}
|
||||
else if (!lsoffs[0]) // prevent sound spam
|
||||
{
|
||||
lsoffs[0] = -8;
|
||||
lsoffs[0] = -8 * FRACUNIT;
|
||||
S_StartSound(NULL,sfx_s3kb2);
|
||||
}
|
||||
break;
|
||||
|
@ -5600,14 +5603,14 @@ static void M_HandleLevelPlatter(INT32 choice)
|
|||
{
|
||||
lscol++;
|
||||
|
||||
lsoffs[1] = (lswide(lsrow) ? 8 : -lshseperation);
|
||||
lsoffs[1] = (lswide(lsrow) ? 8 : -lshseperation) * FRACUNIT;
|
||||
S_StartSound(NULL,sfx_s3kb7);
|
||||
|
||||
ifselectvalnextmap(lscol) else ifselectvalnextmap(0)
|
||||
}
|
||||
else if (!lsoffs[1]) // prevent sound spam
|
||||
{
|
||||
lsoffs[1] = 8;
|
||||
lsoffs[1] = 8 * FRACUNIT;
|
||||
S_StartSound(NULL,sfx_s3kb7);
|
||||
}
|
||||
break;
|
||||
|
@ -5632,14 +5635,14 @@ static void M_HandleLevelPlatter(INT32 choice)
|
|||
{
|
||||
lscol--;
|
||||
|
||||
lsoffs[1] = (lswide(lsrow) ? -8 : lshseperation);
|
||||
lsoffs[1] = (lswide(lsrow) ? -8 : lshseperation) * FRACUNIT;
|
||||
S_StartSound(NULL,sfx_s3kb7);
|
||||
|
||||
ifselectvalnextmap(lscol) else ifselectvalnextmap(0)
|
||||
}
|
||||
else if (!lsoffs[1]) // prevent sound spam
|
||||
{
|
||||
lsoffs[1] = -8;
|
||||
lsoffs[1] = -8 * FRACUNIT;
|
||||
S_StartSound(NULL,sfx_s3kb7);
|
||||
}
|
||||
break;
|
||||
|
@ -5802,7 +5805,7 @@ static void M_DrawRecordAttackForeground(void)
|
|||
|
||||
for (i = -12; i < (BASEVIDHEIGHT/height) + 12; i++)
|
||||
{
|
||||
INT32 y = ((i*height) - (height - ((recatkdrawtimer*2)%height)));
|
||||
INT32 y = ((i*height) - (height - ((FixedInt(recatkdrawtimer*2))%height)));
|
||||
// don't draw above the screen
|
||||
{
|
||||
INT32 sy = FixedMul(y, dupz<<FRACBITS) >> FRACBITS;
|
||||
|
@ -5819,17 +5822,18 @@ static void M_DrawRecordAttackForeground(void)
|
|||
}
|
||||
|
||||
// draw clock
|
||||
fa = (FixedAngle(((recatkdrawtimer * 4) % 360)<<FRACBITS)>>ANGLETOFINESHIFT) & FINEMASK;
|
||||
fa = (FixedAngle(((FixedInt(recatkdrawtimer * 4)) % 360)<<FRACBITS)>>ANGLETOFINESHIFT) & FINEMASK;
|
||||
V_DrawSciencePatch(160<<FRACBITS, (80<<FRACBITS) + (4*FINESINE(fa)), 0, clock, FRACUNIT);
|
||||
|
||||
// Increment timer.
|
||||
recatkdrawtimer++;
|
||||
recatkdrawtimer += renderdeltatics;
|
||||
if (recatkdrawtimer < 0) recatkdrawtimer = 0;
|
||||
}
|
||||
|
||||
// NiGHTS Attack background.
|
||||
static void M_DrawNightsAttackMountains(void)
|
||||
{
|
||||
static INT32 bgscrollx;
|
||||
static fixed_t bgscrollx;
|
||||
INT32 dupz = (vid.dupx < vid.dupy ? vid.dupx : vid.dupy);
|
||||
patch_t *background = W_CachePatchName(curbgname, PU_PATCH);
|
||||
INT16 w = background->width;
|
||||
|
@ -5845,7 +5849,7 @@ static void M_DrawNightsAttackMountains(void)
|
|||
if (x < BASEVIDWIDTH)
|
||||
V_DrawScaledPatch(x, y, V_SNAPTOLEFT, background);
|
||||
|
||||
bgscrollx += (FRACUNIT/2);
|
||||
bgscrollx += FixedMul(FRACUNIT/2, renderdeltatics);
|
||||
if (bgscrollx > w<<FRACBITS)
|
||||
bgscrollx &= 0xFFFF;
|
||||
}
|
||||
|
@ -5876,7 +5880,7 @@ static void M_DrawNightsAttackBackground(void)
|
|||
M_DrawNightsAttackMountains();
|
||||
|
||||
// back top foreground patch
|
||||
x = 0-(ntsatkdrawtimer%backtopwidth);
|
||||
x = 0-(FixedInt(ntsatkdrawtimer)%backtopwidth);
|
||||
V_DrawScaledPatch(x, y, V_SNAPTOTOP|V_SNAPTOLEFT, backtopfg);
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
|
@ -5887,7 +5891,7 @@ static void M_DrawNightsAttackBackground(void)
|
|||
}
|
||||
|
||||
// front top foreground patch
|
||||
x = 0-((ntsatkdrawtimer*2)%fronttopwidth);
|
||||
x = 0-(FixedInt(ntsatkdrawtimer*2)%fronttopwidth);
|
||||
V_DrawScaledPatch(x, y, V_SNAPTOTOP|V_SNAPTOLEFT, fronttopfg);
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
|
@ -5898,7 +5902,7 @@ static void M_DrawNightsAttackBackground(void)
|
|||
}
|
||||
|
||||
// back bottom foreground patch
|
||||
x = 0-(ntsatkdrawtimer%backbottomwidth);
|
||||
x = 0-(FixedInt(ntsatkdrawtimer)%backbottomwidth);
|
||||
y = BASEVIDHEIGHT - backbottomheight;
|
||||
V_DrawScaledPatch(x, y, V_SNAPTOBOTTOM|V_SNAPTOLEFT, backbottomfg);
|
||||
for (i = 0; i < 3; i++)
|
||||
|
@ -5910,7 +5914,7 @@ static void M_DrawNightsAttackBackground(void)
|
|||
}
|
||||
|
||||
// front bottom foreground patch
|
||||
x = 0-((ntsatkdrawtimer*2)%frontbottomwidth);
|
||||
x = 0-(FixedInt(ntsatkdrawtimer*2)%frontbottomwidth);
|
||||
y = BASEVIDHEIGHT - frontbottomheight;
|
||||
V_DrawScaledPatch(x, y, V_SNAPTOBOTTOM|V_SNAPTOLEFT, frontbottomfg);
|
||||
for (i = 0; i < 3; i++)
|
||||
|
@ -5922,7 +5926,8 @@ static void M_DrawNightsAttackBackground(void)
|
|||
}
|
||||
|
||||
// Increment timer.
|
||||
ntsatkdrawtimer++;
|
||||
ntsatkdrawtimer += renderdeltatics;
|
||||
if (ntsatkdrawtimer < 0) ntsatkdrawtimer = 0;
|
||||
}
|
||||
|
||||
// NiGHTS Attack floating Super Sonic.
|
||||
|
@ -5930,15 +5935,15 @@ static patch_t *ntssupersonic[2];
|
|||
static void M_DrawNightsAttackSuperSonic(void)
|
||||
{
|
||||
const UINT8 *colormap = R_GetTranslationColormap(TC_DEFAULT, SKINCOLOR_YELLOW, GTC_CACHE);
|
||||
INT32 timer = (ntsatkdrawtimer/4) % 2;
|
||||
angle_t fa = (FixedAngle(((ntsatkdrawtimer * 4) % 360)<<FRACBITS)>>ANGLETOFINESHIFT) & FINEMASK;
|
||||
INT32 timer = FixedInt(ntsatkdrawtimer/4) % 2;
|
||||
angle_t fa = (FixedAngle((FixedInt(ntsatkdrawtimer * 4) % 360)<<FRACBITS)>>ANGLETOFINESHIFT) & FINEMASK;
|
||||
V_DrawFixedPatch(235<<FRACBITS, (120<<FRACBITS) - (8*FINESINE(fa)), FRACUNIT, 0, ntssupersonic[timer], colormap);
|
||||
}
|
||||
|
||||
static void M_DrawLevelPlatterMenu(void)
|
||||
{
|
||||
UINT8 iter = lsrow, sizeselect = (lswide(lsrow) ? 1 : 0);
|
||||
INT32 y = lsbasey + lsoffs[0] - getheadingoffset(lsrow);
|
||||
INT32 y = lsbasey + FixedInt(lsoffs[0]) - getheadingoffset(lsrow);
|
||||
const INT32 cursorx = (sizeselect ? 0 : (lscol*lshseperation));
|
||||
|
||||
if (currentMenu->prevMenu == &SP_TimeAttackDef)
|
||||
|
@ -6006,7 +6011,7 @@ static void M_DrawLevelPlatterMenu(void)
|
|||
|
||||
// draw cursor box
|
||||
if (levellistmode != LLM_CREATESERVER || lsrow)
|
||||
V_DrawSmallScaledPatch(lsbasex + cursorx + lsoffs[1], lsbasey+lsoffs[0], 0, (levselp[sizeselect][((skullAnimCounter/4) ? 1 : 0)]));
|
||||
V_DrawSmallScaledPatch(lsbasex + cursorx + FixedInt(lsoffs[1]), lsbasey+FixedInt(lsoffs[0]), 0, (levselp[sizeselect][((skullAnimCounter/4) ? 1 : 0)]));
|
||||
|
||||
#if 0
|
||||
if (levelselect.rows[lsrow].maplist[lscol] > 0)
|
||||
|
@ -6014,13 +6019,26 @@ static void M_DrawLevelPlatterMenu(void)
|
|||
#endif
|
||||
|
||||
// handle movement of cursor box
|
||||
if (lsoffs[0] > 1 || lsoffs[0] < -1)
|
||||
lsoffs[0] = 2*lsoffs[0]/3;
|
||||
fixed_t cursormovefrac = FixedDiv(2, 3);
|
||||
if (lsoffs[0] > FRACUNIT || lsoffs[0] < -FRACUNIT)
|
||||
{
|
||||
fixed_t offs = lsoffs[0];
|
||||
fixed_t newoffs = FixedMul(offs, cursormovefrac);
|
||||
fixed_t deltaoffs = newoffs - offs;
|
||||
newoffs = offs + FixedMul(deltaoffs, renderdeltatics);
|
||||
lsoffs[0] = newoffs;
|
||||
}
|
||||
else
|
||||
lsoffs[0] = 0;
|
||||
|
||||
if (lsoffs[1] > 1 || lsoffs[1] < -1)
|
||||
lsoffs[1] = 2*lsoffs[1]/3;
|
||||
if (lsoffs[1] > FRACUNIT || lsoffs[1] < -FRACUNIT)
|
||||
{
|
||||
fixed_t offs = lsoffs[1];
|
||||
fixed_t newoffs = FixedMul(offs, cursormovefrac);
|
||||
fixed_t deltaoffs = newoffs - offs;
|
||||
newoffs = offs + FixedMul(deltaoffs, renderdeltatics);
|
||||
lsoffs[1] = newoffs;
|
||||
}
|
||||
else
|
||||
lsoffs[1] = 0;
|
||||
|
||||
|
@ -7647,7 +7665,7 @@ static void M_HandleEmblemHints(INT32 choice)
|
|||
|
||||
static musicdef_t *curplaying = NULL;
|
||||
static INT32 st_sel = 0, st_cc = 0;
|
||||
static tic_t st_time = 0;
|
||||
static fixed_t st_time = 0;
|
||||
static patch_t* st_radio[9];
|
||||
static patch_t* st_launchpad[4];
|
||||
|
||||
|
@ -7711,16 +7729,17 @@ static void M_DrawSoundTest(void)
|
|||
{
|
||||
if (cv_soundtest.value)
|
||||
{
|
||||
frame[1] = (2-st_time);
|
||||
frame[1] = (2 - (st_time >> FRACBITS));
|
||||
frame[2] = ((cv_soundtest.value - 1) % 9);
|
||||
frame[3] += (((cv_soundtest.value - 1) / 9) % (FIRSTSUPERCOLOR - frame[3]));
|
||||
if (st_time < 2)
|
||||
st_time++;
|
||||
if (st_time < (2 << FRACBITS))
|
||||
st_time += renderdeltatics;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (curplaying->stoppingtics && st_time >= curplaying->stoppingtics)
|
||||
fixed_t stoppingtics = (fixed_t)(curplaying->stoppingtics) << FRACBITS;
|
||||
if (stoppingtics && st_time >= stoppingtics)
|
||||
{
|
||||
curplaying = NULL;
|
||||
st_time = 0;
|
||||
|
@ -7731,11 +7750,11 @@ static void M_DrawSoundTest(void)
|
|||
angle_t ang;
|
||||
//bpm = FixedDiv((60*TICRATE)<<FRACBITS, bpm); -- bake this in on load
|
||||
|
||||
work = st_time<<FRACBITS;
|
||||
work = st_time;
|
||||
work %= bpm;
|
||||
|
||||
if (st_time >= (FRACUNIT>>1)) // prevent overflow jump - takes about 15 minutes of loop on the same song to reach
|
||||
st_time = (work>>FRACBITS);
|
||||
if (st_time >= (FRACUNIT << (FRACBITS - 2))) // prevent overflow jump - takes about 15 minutes of loop on the same song to reach
|
||||
st_time = work;
|
||||
|
||||
work = FixedDiv(work*180, bpm);
|
||||
frame[0] = 8-(work/(20<<FRACBITS));
|
||||
|
@ -7746,7 +7765,7 @@ static void M_DrawSoundTest(void)
|
|||
hscale -= bounce/16;
|
||||
vscale += bounce/16;
|
||||
|
||||
st_time++;
|
||||
st_time += renderdeltatics;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7786,7 +7805,7 @@ static void M_DrawSoundTest(void)
|
|||
|
||||
V_DrawFill(y, 20, vid.width/vid.dupx, 24, 159);
|
||||
{
|
||||
static fixed_t st_scroll = -1;
|
||||
static fixed_t st_scroll = -FRACUNIT;
|
||||
const char* titl;
|
||||
x = 16;
|
||||
V_DrawString(x, 10, 0, "NOW PLAYING:");
|
||||
|
@ -7802,10 +7821,12 @@ static void M_DrawSoundTest(void)
|
|||
|
||||
i = V_LevelNameWidth(titl);
|
||||
|
||||
if (++st_scroll >= i)
|
||||
st_scroll %= i;
|
||||
st_scroll += renderdeltatics;
|
||||
|
||||
x -= st_scroll;
|
||||
while (st_scroll >= (i << FRACBITS))
|
||||
st_scroll -= i << FRACBITS;
|
||||
|
||||
x -= st_scroll >> FRACBITS;
|
||||
|
||||
while (x < BASEVIDWIDTH-y)
|
||||
x += i;
|
||||
|
@ -8329,8 +8350,8 @@ static void M_StartTutorial(INT32 choice)
|
|||
// ==============
|
||||
|
||||
static INT32 saveSlotSelected = 1;
|
||||
static INT32 loadgamescroll = 0;
|
||||
static UINT8 loadgameoffset = 0;
|
||||
static fixed_t loadgamescroll = 0;
|
||||
static fixed_t loadgameoffset = 0;
|
||||
|
||||
static void M_CacheLoadGameData(void)
|
||||
{
|
||||
|
@ -8355,14 +8376,14 @@ static void M_DrawLoadGameData(void)
|
|||
{
|
||||
prev_i = i;
|
||||
savetodraw = (saveSlotSelected + i + numsaves)%numsaves;
|
||||
x = (BASEVIDWIDTH/2 - 42 + loadgamescroll) + (i*hsep);
|
||||
x = (BASEVIDWIDTH/2 - 42 + FixedInt(loadgamescroll)) + (i*hsep);
|
||||
y = 33 + 9;
|
||||
|
||||
{
|
||||
INT32 diff = x - (BASEVIDWIDTH/2 - 42);
|
||||
if (diff < 0)
|
||||
diff = -diff;
|
||||
diff = (42 - diff)/3 - loadgameoffset;
|
||||
diff = (42 - diff)/3 - FixedInt(loadgameoffset);
|
||||
if (diff < 0)
|
||||
diff = 0;
|
||||
y -= diff;
|
||||
|
@ -8647,14 +8668,23 @@ skiplife:
|
|||
static void M_DrawLoad(void)
|
||||
{
|
||||
M_DrawMenuTitle();
|
||||
fixed_t scrollfrac = FixedDiv(2, 3);
|
||||
|
||||
if (loadgamescroll > 1 || loadgamescroll < -1)
|
||||
loadgamescroll = 2*loadgamescroll/3;
|
||||
if (loadgamescroll > FRACUNIT || loadgamescroll < -FRACUNIT)
|
||||
{
|
||||
fixed_t newscroll = FixedMul(loadgamescroll, scrollfrac);
|
||||
fixed_t deltascroll = FixedMul(newscroll - loadgamescroll, renderdeltatics);
|
||||
loadgamescroll += deltascroll;
|
||||
}
|
||||
else
|
||||
loadgamescroll = 0;
|
||||
|
||||
if (loadgameoffset > 1)
|
||||
loadgameoffset = 2*loadgameoffset/3;
|
||||
if (loadgameoffset > FRACUNIT)
|
||||
{
|
||||
fixed_t newoffs = FixedMul(loadgameoffset, scrollfrac);
|
||||
fixed_t deltaoffs = FixedMul(newoffs - loadgameoffset, renderdeltatics);
|
||||
loadgameoffset += deltaoffs;
|
||||
}
|
||||
else
|
||||
loadgameoffset = 0;
|
||||
|
||||
|
@ -8863,7 +8893,7 @@ static void M_ReadSaveStrings(void)
|
|||
UINT8 lastseen = 0;
|
||||
|
||||
loadgamescroll = 0;
|
||||
loadgameoffset = 14;
|
||||
loadgameoffset = 14 * FRACUNIT;
|
||||
|
||||
for (i = 1; (i < MAXSAVEGAMES); i++) // slot 0 is no save
|
||||
{
|
||||
|
@ -8954,7 +8984,7 @@ static void M_HandleLoadSave(INT32 choice)
|
|||
++saveSlotSelected;
|
||||
if (saveSlotSelected >= numsaves)
|
||||
saveSlotSelected -= numsaves;
|
||||
loadgamescroll = 90;
|
||||
loadgamescroll = 90 * FRACUNIT;
|
||||
break;
|
||||
|
||||
case KEY_LEFTARROW:
|
||||
|
@ -8962,7 +8992,7 @@ static void M_HandleLoadSave(INT32 choice)
|
|||
--saveSlotSelected;
|
||||
if (saveSlotSelected < 0)
|
||||
saveSlotSelected += numsaves;
|
||||
loadgamescroll = -90;
|
||||
loadgamescroll = -90 * FRACUNIT;
|
||||
break;
|
||||
|
||||
case KEY_ENTER:
|
||||
|
@ -8987,7 +9017,7 @@ static void M_HandleLoadSave(INT32 choice)
|
|||
else if (!loadgameoffset)
|
||||
{
|
||||
S_StartSound(NULL, sfx_lose);
|
||||
loadgameoffset = 14;
|
||||
loadgameoffset = 14 * FRACUNIT;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -9013,7 +9043,7 @@ static void M_HandleLoadSave(INT32 choice)
|
|||
}
|
||||
else
|
||||
S_StartSound(NULL, sfx_lose);
|
||||
loadgameoffset = 14;
|
||||
loadgameoffset = 14 * FRACUNIT;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -9073,13 +9103,13 @@ static void M_LoadGame(INT32 choice)
|
|||
//
|
||||
void M_ForceSaveSlotSelected(INT32 sslot)
|
||||
{
|
||||
loadgameoffset = 14;
|
||||
loadgameoffset = 14 * FRACUNIT;
|
||||
|
||||
// Already there? Whatever, then!
|
||||
if (sslot == saveSlotSelected)
|
||||
return;
|
||||
|
||||
loadgamescroll = 90;
|
||||
loadgamescroll = 90 * FRACUNIT;
|
||||
if (saveSlotSelected <= numsaves/2)
|
||||
loadgamescroll = -loadgamescroll;
|
||||
|
||||
|
@ -9323,8 +9353,8 @@ static void M_DrawSetupChoosePlayerMenu(void)
|
|||
INT32 x, y;
|
||||
INT32 w = (vid.width/vid.dupx);
|
||||
|
||||
if (abs(char_scroll) > FRACUNIT)
|
||||
char_scroll -= (char_scroll>>2);
|
||||
if (abs(char_scroll) > FRACUNIT/4)
|
||||
char_scroll -= FixedMul((char_scroll>>2), renderdeltatics);
|
||||
else // close enough.
|
||||
char_scroll = 0; // just be exact now.
|
||||
|
||||
|
@ -9352,7 +9382,7 @@ static void M_DrawSetupChoosePlayerMenu(void)
|
|||
|
||||
// Don't render the title map
|
||||
hidetitlemap = true;
|
||||
charseltimer++;
|
||||
charseltimer += renderdeltatics;
|
||||
|
||||
// Background and borders
|
||||
V_DrawFill(0, 0, bgwidth, vid.height, V_SNAPTOTOP|colormap[101]);
|
||||
|
@ -9364,7 +9394,7 @@ static void M_DrawSetupChoosePlayerMenu(void)
|
|||
V_DrawFill(0, 0, bw, vid.height, V_NOSCALESTART|col);
|
||||
}
|
||||
|
||||
y = (charseltimer%32);
|
||||
y = (charseltimer / FRACUNIT) % 32;
|
||||
V_DrawMappedPatch(0, y-bgheight, V_SNAPTOTOP, charbg, colormap);
|
||||
V_DrawMappedPatch(0, y, V_SNAPTOTOP, charbg, colormap);
|
||||
V_DrawMappedPatch(0, y+bgheight, V_SNAPTOTOP, charbg, colormap);
|
||||
|
@ -10631,7 +10661,7 @@ static void M_Marathon(INT32 choice)
|
|||
titlemapinaction = TITLEMAP_OFF; // Nope don't give us HOMs please
|
||||
M_SetupNextMenu(&SP_MarathonDef);
|
||||
itemOn = marathonstart; // "Start" is selected.
|
||||
recatkdrawtimer = 50-8;
|
||||
recatkdrawtimer = (50-8) * FRACUNIT;
|
||||
char_scroll = 0;
|
||||
}
|
||||
|
||||
|
@ -10712,13 +10742,16 @@ void M_DrawMarathon(void)
|
|||
x = (((BASEVIDWIDTH-82)/2)+11)<<FRACBITS;
|
||||
y = (((BASEVIDHEIGHT-82)/2)+12-10)<<FRACBITS;
|
||||
|
||||
cnt = (36*(recatkdrawtimer<<FRACBITS))/TICRATE;
|
||||
cnt = (36 * recatkdrawtimer) / TICRATE;
|
||||
fa = (FixedAngle(cnt)>>ANGLETOFINESHIFT) & FINEMASK;
|
||||
y -= (10*FINECOSINE(fa));
|
||||
|
||||
recatkdrawtimer++;
|
||||
if (renderisnewtic)
|
||||
{
|
||||
recatkdrawtimer += FRACUNIT;
|
||||
}
|
||||
|
||||
soffset = cnt = (recatkdrawtimer%50);
|
||||
soffset = cnt = ((recatkdrawtimer >> FRACBITS) % 50);
|
||||
if (!useBlackRock)
|
||||
{
|
||||
if (cnt > 8)
|
||||
|
@ -10757,7 +10790,7 @@ void M_DrawMarathon(void)
|
|||
}
|
||||
|
||||
w = char_scroll + (((8-cnt)*(8-cnt))<<(FRACBITS-5));
|
||||
if (soffset == 50-1)
|
||||
if (soffset == 50-1 && renderisnewtic)
|
||||
w += FRACUNIT/2;
|
||||
|
||||
{
|
||||
|
@ -10812,11 +10845,11 @@ void M_DrawMarathon(void)
|
|||
|
||||
if (!soffset)
|
||||
{
|
||||
char_scroll += (360<<FRACBITS)/42; // like a clock, ticking at 42bpm!
|
||||
char_scroll += (360 * renderdeltatics)/42; // like a clock, ticking at 42bpm!
|
||||
if (char_scroll >= 360<<FRACBITS)
|
||||
char_scroll -= 360<<FRACBITS;
|
||||
if (recatkdrawtimer > (10*TICRATE))
|
||||
recatkdrawtimer -= (10*TICRATE);
|
||||
if (recatkdrawtimer > ((10 << FRACBITS) * TICRATE))
|
||||
recatkdrawtimer -= ((10 << FRACBITS) * TICRATE);
|
||||
}
|
||||
|
||||
M_DrawMenuTitle();
|
||||
|
@ -11028,7 +11061,7 @@ static INT32 menuRoomIndex = 0;
|
|||
|
||||
static void M_DrawRoomMenu(void)
|
||||
{
|
||||
static int frame = -12;
|
||||
static fixed_t frame = -(12 << FRACBITS);
|
||||
int dot_frame;
|
||||
char text[4];
|
||||
|
||||
|
@ -11039,7 +11072,7 @@ static void M_DrawRoomMenu(void)
|
|||
|
||||
if (m_waiting_mode)
|
||||
{
|
||||
dot_frame = frame / 4;
|
||||
dot_frame = (int)(frame >> FRACBITS) / 4;
|
||||
dots = dot_frame + 3;
|
||||
|
||||
strcpy(text, " ");
|
||||
|
@ -11052,8 +11085,9 @@ static void M_DrawRoomMenu(void)
|
|||
strncpy(&text[dot_frame], "...", min(dots, 3 - dot_frame));
|
||||
}
|
||||
|
||||
if (++frame == 12)
|
||||
frame = -12;
|
||||
frame += renderdeltatics;
|
||||
while (frame >= (12 << FRACBITS))
|
||||
frame -= 12 << FRACBITS;
|
||||
|
||||
currentMenu->menuitems[0].text = text;
|
||||
}
|
||||
|
@ -11819,7 +11853,7 @@ static void M_HandleConnectIP(INT32 choice)
|
|||
// ========================
|
||||
// Tails 03-02-2002
|
||||
|
||||
static UINT8 multi_tics;
|
||||
static fixed_t multi_tics;
|
||||
static UINT8 multi_frame;
|
||||
static UINT8 multi_spr2;
|
||||
|
||||
|
@ -11887,10 +11921,11 @@ static void M_DrawSetupMultiPlayerMenu(void)
|
|||
y += 11;
|
||||
|
||||
// anim the player in the box
|
||||
if (--multi_tics <= 0)
|
||||
multi_tics -= renderdeltatics;
|
||||
while (multi_tics <= 0)
|
||||
{
|
||||
multi_frame++;
|
||||
multi_tics = 4;
|
||||
multi_tics += 4*FRACUNIT;
|
||||
}
|
||||
|
||||
#define charw 74
|
||||
|
@ -12161,7 +12196,7 @@ static void M_SetupMultiPlayer(INT32 choice)
|
|||
(void)choice;
|
||||
|
||||
multi_frame = 0;
|
||||
multi_tics = 4;
|
||||
multi_tics = 4*FRACUNIT;
|
||||
strcpy(setupm_name, cv_playername.string);
|
||||
|
||||
// set for player 1
|
||||
|
@ -12205,7 +12240,7 @@ static void M_SetupMultiPlayer2(INT32 choice)
|
|||
(void)choice;
|
||||
|
||||
multi_frame = 0;
|
||||
multi_tics = 4;
|
||||
multi_tics = 4*FRACUNIT;
|
||||
strcpy (setupm_name, cv_playername2.string);
|
||||
|
||||
// set for splitscreen secondary player
|
||||
|
@ -13536,7 +13571,8 @@ void M_QuitResponse(INT32 ch)
|
|||
{
|
||||
V_DrawScaledPatch(0, 0, 0, W_CachePatchName("GAMEQUIT", PU_PATCH)); // 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"
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "i_system.h"
|
||||
#include "z_zone.h"
|
||||
#include "p_local.h"
|
||||
#include "r_fps.h"
|
||||
|
||||
#ifdef HWRENDER
|
||||
#include "hardware/hw_main.h"
|
||||
|
@ -122,6 +123,12 @@ perfstatrow_t commoncounter_rows[] = {
|
|||
{0}
|
||||
};
|
||||
|
||||
perfstatrow_t interpolation_rows[] = {
|
||||
{"intpfrc", "Interp frac: ", &ps_interp_frac, PS_TIME},
|
||||
{"intplag", "Interp lag: ", &ps_interp_lag, PS_TIME},
|
||||
{0}
|
||||
};
|
||||
|
||||
#ifdef HWRENDER
|
||||
perfstatrow_t batchcount_rows[] = {
|
||||
{"polygon", "Polygons: ", &ps_hw_numpolys, 0},
|
||||
|
@ -261,7 +268,7 @@ static INT32 PS_GetMetricAverage(ps_metric_t *metric, boolean time_metric)
|
|||
for (i = 0; i < cv_ps_samplesize.value; i++)
|
||||
{
|
||||
if (time_metric)
|
||||
sum += I_PreciseToMicros(*((precise_t*)history_read_pos));
|
||||
sum += (*((precise_t*)history_read_pos)) / (I_GetPrecisePrecision() / 1000000);
|
||||
else
|
||||
sum += *((INT32*)history_read_pos);
|
||||
history_read_pos += value_size;
|
||||
|
@ -281,7 +288,7 @@ static INT32 PS_GetMetricMinOrMax(ps_metric_t *metric, boolean time_metric, bool
|
|||
{
|
||||
INT32 value;
|
||||
if (time_metric)
|
||||
value = I_PreciseToMicros(*((precise_t*)history_read_pos));
|
||||
value = (*((precise_t*)history_read_pos)) / (I_GetPrecisePrecision() / 1000000);
|
||||
else
|
||||
value = *((INT32*)history_read_pos);
|
||||
|
||||
|
@ -309,7 +316,7 @@ static INT32 PS_GetMetricSD(ps_metric_t *metric, boolean time_metric)
|
|||
{
|
||||
INT64 value;
|
||||
if (time_metric)
|
||||
value = I_PreciseToMicros(*((precise_t*)history_read_pos));
|
||||
value = (*((precise_t*)history_read_pos)) / (I_GetPrecisePrecision() / 1000000);
|
||||
else
|
||||
value = *((INT32*)history_read_pos);
|
||||
|
||||
|
@ -339,7 +346,7 @@ static INT32 PS_GetMetricScreenValue(ps_metric_t *metric, boolean time_metric)
|
|||
else
|
||||
{
|
||||
if (time_metric)
|
||||
return I_PreciseToMicros(metric->value.p);
|
||||
return (metric->value.p) / (I_GetPrecisePrecision() / 1000000);
|
||||
else
|
||||
return metric->value.i;
|
||||
}
|
||||
|
@ -473,6 +480,9 @@ static void PS_UpdateFrameStats(void)
|
|||
if (PS_IsLevelActive())
|
||||
PS_UpdateRowHistories(commoncounter_rows, true);
|
||||
|
||||
if (R_UsingFrameInterpolation())
|
||||
PS_UpdateRowHistories(interpolation_rows, true);
|
||||
|
||||
#ifdef HWRENDER
|
||||
if (rendermode == render_opengl && cv_glbatching.value)
|
||||
{
|
||||
|
@ -634,7 +644,7 @@ static void PS_DrawRenderStats(void)
|
|||
{
|
||||
const boolean hires = PS_HighResolution();
|
||||
const int half_row = hires ? 5 : 4;
|
||||
int x, y;
|
||||
int x, y, cy = 10;
|
||||
|
||||
PS_DrawDescriptorHeader();
|
||||
|
||||
|
@ -645,7 +655,7 @@ static void PS_DrawRenderStats(void)
|
|||
if (PS_IsLevelActive())
|
||||
{
|
||||
x = hires ? 115 : 90;
|
||||
PS_DrawPerfRows(x, 10, V_BLUEMAP, commoncounter_rows);
|
||||
cy = PS_DrawPerfRows(x, 10, V_BLUEMAP, commoncounter_rows) + half_row;
|
||||
|
||||
#ifdef HWRENDER
|
||||
if (rendermode == render_opengl && cv_glbatching.value)
|
||||
|
@ -659,6 +669,12 @@ static void PS_DrawRenderStats(void)
|
|||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (R_UsingFrameInterpolation())
|
||||
{
|
||||
x = hires ? 115 : 90;
|
||||
PS_DrawPerfRows(x, cy, V_ROSYMAP, interpolation_rows);
|
||||
}
|
||||
}
|
||||
|
||||
static void PS_DrawGameLogicStats(void)
|
||||
|
|
|
@ -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"
|
||||
|
@ -334,6 +335,9 @@ INT32 EV_DoCeiling(mtag_t tag, line_t *line, ceiling_e type)
|
|||
|
||||
ceiling->type = type;
|
||||
firstone = 0;
|
||||
|
||||
// interpolation
|
||||
R_CreateInterpolator_SectorPlane(&ceiling->thinker, sec, true);
|
||||
}
|
||||
return rtn;
|
||||
}
|
||||
|
@ -398,6 +402,10 @@ INT32 EV_DoCrush(mtag_t tag, line_t *line, ceiling_e type)
|
|||
}
|
||||
|
||||
ceiling->type = type;
|
||||
|
||||
// interpolation
|
||||
R_CreateInterpolator_SectorPlane(&ceiling->thinker, sec, false);
|
||||
R_CreateInterpolator_SectorPlane(&ceiling->thinker, sec, true);
|
||||
}
|
||||
return rtn;
|
||||
}
|
||||
|
|
|
@ -1333,7 +1333,7 @@ void A_FaceStabHurl(mobj_t *actor)
|
|||
hwork->destscale = FixedSqrt(step*basesize);
|
||||
P_SetScale(hwork, hwork->destscale);
|
||||
hwork->fuse = 2;
|
||||
P_TeleportMove(hwork, actor->x + xo*(15-step), actor->y + yo*(15-step), actor->z + (actor->height - hwork->height)/2 + (P_MobjFlip(actor)*(8<<FRACBITS)));
|
||||
P_MoveOrigin(hwork, actor->x + xo*(15-step), actor->y + yo*(15-step), actor->z + (actor->height - hwork->height)/2 + (P_MobjFlip(actor)*(8<<FRACBITS)));
|
||||
step -= NUMGRADS;
|
||||
}
|
||||
|
||||
|
@ -2095,7 +2095,7 @@ void A_CrushclawAim(mobj_t *actor)
|
|||
#undef anglimit
|
||||
#undef angfactor
|
||||
|
||||
P_TeleportMove(actor,
|
||||
P_MoveOrigin(actor,
|
||||
crab->x + P_ReturnThrustX(actor, actor->angle, locvar1*crab->scale),
|
||||
crab->y + P_ReturnThrustY(actor, actor->angle, locvar1*crab->scale),
|
||||
crab->z + locvar2*crab->scale);
|
||||
|
@ -2233,7 +2233,7 @@ void A_CrushclawLaunch(mobj_t *actor)
|
|||
fixed_t idx = dx, idy = dy, idz = dz;
|
||||
while (chain)
|
||||
{
|
||||
P_TeleportMove(chain, actor->target->x + idx, actor->target->y + idy, actor->target->z + idz);
|
||||
P_MoveOrigin(chain, actor->target->x + idx, actor->target->y + idy, actor->target->z + idz);
|
||||
chain->movefactor = chain->z;
|
||||
idx += dx;
|
||||
idy += dy;
|
||||
|
@ -11181,7 +11181,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);
|
||||
|
@ -11226,7 +11226,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);
|
||||
|
@ -11893,12 +11893,12 @@ void A_FlickyCenter(mobj_t *actor)
|
|||
if (actor->target && P_AproxDistance(actor->target->x - originx, actor->target->y - originy) < actor->extravalue1)
|
||||
{
|
||||
actor->extravalue2 = 1;
|
||||
P_TeleportMove(actor, actor->target->x, actor->target->y, actor->target->z);
|
||||
P_SetOrigin(actor, actor->target->x, actor->target->y, actor->target->z);
|
||||
}
|
||||
else if(actor->extravalue2)
|
||||
{
|
||||
actor->extravalue2 = 0;
|
||||
P_TeleportMove(actor, originx, originy, originz);
|
||||
P_SetOrigin(actor, originx, originy, originz);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12431,7 +12431,7 @@ void A_LightBeamReset(mobj_t *actor)
|
|||
actor->momy = (P_SignedRandom()*FINECOSINE(((actor->spawnpoint->angle*ANG1)>>ANGLETOFINESHIFT) & FINEMASK))/128;
|
||||
actor->momz = (P_SignedRandom()*FRACUNIT)/128;
|
||||
|
||||
P_TeleportMove(actor,
|
||||
P_SetOrigin(actor,
|
||||
actor->spawnpoint->x*FRACUNIT - (P_SignedRandom()*FINESINE(((actor->spawnpoint->angle*ANG1)>>ANGLETOFINESHIFT) & FINEMASK))/2,
|
||||
actor->spawnpoint->y*FRACUNIT + (P_SignedRandom()*FINECOSINE(((actor->spawnpoint->angle*ANG1)>>ANGLETOFINESHIFT) & FINEMASK))/2,
|
||||
actor->spawnpoint->z*FRACUNIT + (P_SignedRandom()*FRACUNIT)/2);
|
||||
|
@ -12988,7 +12988,7 @@ void A_DoNPCSkid(mobj_t *actor)
|
|||
actor->momy = (2*actor->momy)/3;
|
||||
}
|
||||
|
||||
P_TeleportMove(actor, x, y, z);
|
||||
P_MoveOrigin(actor, x, y, z);
|
||||
|
||||
// Spawn a particle every 3 tics.
|
||||
if (!(leveltime % 3))
|
||||
|
@ -13329,7 +13329,7 @@ void A_Boss5MakeJunk(mobj_t *actor)
|
|||
if (locvar1 > 0)
|
||||
P_SetMobjState(broked, locvar1);
|
||||
if (!P_MobjWasRemoved(broked))
|
||||
P_TeleportMove(broked, broked->x + broked->momx, broked->y + broked->momy, broked->z);
|
||||
P_MoveOrigin(broked, broked->x + broked->momx, broked->y + broked->momy, broked->z);
|
||||
ang += ANGLE_45;
|
||||
}
|
||||
|
||||
|
@ -13538,7 +13538,7 @@ void A_DustDevilThink(mobj_t *actor)
|
|||
//Chained thinker for the spiralling dust column.
|
||||
while (layer && !P_MobjWasRemoved(layer)) {
|
||||
angle_t fa = layer->angle >> ANGLETOFINESHIFT;
|
||||
P_TeleportMove(layer, layer->x + 5 * FixedMul(scale, FINECOSINE(fa)), layer->y + 5 * FixedMul(scale, FINESINE(fa)), layer->z);
|
||||
P_MoveOrigin(layer, layer->x + 5 * FixedMul(scale, FINECOSINE(fa)), layer->y + 5 * FixedMul(scale, FINESINE(fa)), layer->z);
|
||||
layer->scale = scale;
|
||||
layer->angle += ANG10 / 2;
|
||||
layer->momx = actor->momx;
|
||||
|
@ -14547,7 +14547,7 @@ void A_DragonWing(mobj_t *actor)
|
|||
actor->angle = target->angle + actor->movedir;
|
||||
x = target->x + P_ReturnThrustX(actor, actor->angle, -target->radius);
|
||||
y = target->y + P_ReturnThrustY(actor, actor->angle, -target->radius);
|
||||
P_TeleportMove(actor, x, y, target->z);
|
||||
P_MoveOrigin(actor, x, y, target->z);
|
||||
}
|
||||
|
||||
// Function: A_DragonSegment
|
||||
|
@ -14588,7 +14588,7 @@ void A_DragonSegment(mobj_t *actor)
|
|||
zdist = P_ReturnThrustY(target, zangle, radius);
|
||||
|
||||
actor->angle = hangle;
|
||||
P_TeleportMove(actor, target->x + xdist, target->y + ydist, target->z + zdist);
|
||||
P_MoveOrigin(actor, target->x + xdist, target->y + ydist, target->z + zdist);
|
||||
}
|
||||
|
||||
// Function: A_ChangeHeight
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "m_random.h"
|
||||
#include "p_local.h"
|
||||
#include "p_slopes.h"
|
||||
#include "r_fps.h"
|
||||
#include "r_state.h"
|
||||
#include "s_sound.h"
|
||||
#include "z_zone.h"
|
||||
|
@ -523,6 +524,8 @@ void T_ContinuousFalling(continuousfall_t *faller)
|
|||
{
|
||||
faller->sector->ceilingheight = faller->ceilingstartheight;
|
||||
faller->sector->floorheight = faller->floorstartheight;
|
||||
|
||||
R_ClearLevelInterpolatorState(&faller->thinker);
|
||||
}
|
||||
|
||||
P_CheckSector(faller->sector, false); // you might think this is irrelevant. you would be wrong
|
||||
|
@ -1709,6 +1712,9 @@ void EV_DoFloor(mtag_t tag, line_t *line, floor_e floortype)
|
|||
}
|
||||
|
||||
firstone = 0;
|
||||
|
||||
// interpolation
|
||||
R_CreateInterpolator_SectorPlane(&dofloor->thinker, sec, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1805,6 +1811,10 @@ void EV_DoElevator(mtag_t tag, line_t *line, elevator_e elevtype)
|
|||
}
|
||||
|
||||
elevator->ceilingdestheight = elevator->floordestheight + sec->ceilingheight - sec->floorheight;
|
||||
|
||||
// interpolation
|
||||
R_CreateInterpolator_SectorPlane(&elevator->thinker, sec, false);
|
||||
R_CreateInterpolator_SectorPlane(&elevator->thinker, sec, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1953,6 +1963,10 @@ void EV_BounceSector(sector_t *sec, fixed_t momz, line_t *sourceline)
|
|||
bouncer->speed = momz/2;
|
||||
bouncer->distance = FRACUNIT;
|
||||
bouncer->low = true;
|
||||
|
||||
// interpolation
|
||||
R_CreateInterpolator_SectorPlane(&bouncer->thinker, sec, false);
|
||||
R_CreateInterpolator_SectorPlane(&bouncer->thinker, sec, true);
|
||||
}
|
||||
|
||||
// For T_ContinuousFalling special
|
||||
|
@ -1978,6 +1992,10 @@ void EV_DoContinuousFall(sector_t *sec, sector_t *backsector, fixed_t spd, boole
|
|||
|
||||
faller->destheight = backwards ? backsector->ceilingheight : backsector->floorheight;
|
||||
faller->direction = backwards ? 1 : -1;
|
||||
|
||||
// interpolation
|
||||
R_CreateInterpolator_SectorPlane(&faller->thinker, sec, false);
|
||||
R_CreateInterpolator_SectorPlane(&faller->thinker, sec, true);
|
||||
}
|
||||
|
||||
// Some other 3dfloor special things Tails 03-11-2002 (Search p_mobj.c for description)
|
||||
|
@ -2030,6 +2048,10 @@ INT32 EV_StartCrumble(sector_t *sec, ffloor_t *rover, boolean floating,
|
|||
|
||||
crumble->sector->crumblestate = CRUMBLE_ACTIVATED;
|
||||
|
||||
// interpolation
|
||||
R_CreateInterpolator_SectorPlane(&crumble->thinker, sec, false);
|
||||
R_CreateInterpolator_SectorPlane(&crumble->thinker, sec, true);
|
||||
|
||||
TAG_ITER_SECTORS(tag, i)
|
||||
{
|
||||
foundsec = §ors[i];
|
||||
|
@ -2081,6 +2103,10 @@ void EV_MarioBlock(ffloor_t *rover, sector_t *sector, mobj_t *puncher)
|
|||
block->ceilingstartheight = block->sector->ceilingheight;
|
||||
block->tag = (INT16)rover->master->args[0];
|
||||
|
||||
// interpolation
|
||||
R_CreateInterpolator_SectorPlane(&block->thinker, roversec, false);
|
||||
R_CreateInterpolator_SectorPlane(&block->thinker, roversec, true);
|
||||
|
||||
if (itsamonitor)
|
||||
{
|
||||
oldx = thing->x;
|
||||
|
@ -2089,9 +2115,9 @@ void EV_MarioBlock(ffloor_t *rover, sector_t *sector, mobj_t *puncher)
|
|||
}
|
||||
|
||||
P_UnsetThingPosition(thing);
|
||||
thing->x = sector->soundorg.x;
|
||||
thing->y = sector->soundorg.y;
|
||||
thing->z = topheight;
|
||||
thing->x = thing->old_x = sector->soundorg.x;
|
||||
thing->y = thing->old_y = sector->soundorg.y;
|
||||
thing->z = thing->old_z = topheight;
|
||||
thing->momz = FixedMul(6*FRACUNIT, thing->scale);
|
||||
P_SetThingPosition(thing);
|
||||
if (thing->flags & MF_SHOOTABLE)
|
||||
|
@ -2112,9 +2138,9 @@ void EV_MarioBlock(ffloor_t *rover, sector_t *sector, mobj_t *puncher)
|
|||
if (itsamonitor && thing)
|
||||
{
|
||||
P_UnsetThingPosition(thing);
|
||||
thing->x = oldx;
|
||||
thing->y = oldy;
|
||||
thing->z = oldz;
|
||||
thing->x = thing->old_x = oldx;
|
||||
thing->y = thing->old_y = oldy;
|
||||
thing->z = thing->old_z = oldz;
|
||||
thing->momx = 1;
|
||||
thing->momy = 1;
|
||||
P_SetThingPosition(thing);
|
||||
|
|
|
@ -91,6 +91,7 @@ typedef struct camera_s
|
|||
// Camera demobjerization
|
||||
// Info for drawing: position.
|
||||
fixed_t x, y, z;
|
||||
boolean reset;
|
||||
|
||||
//More drawing info: to determine current sprite.
|
||||
angle_t angle; // orientation
|
||||
|
@ -413,7 +414,8 @@ boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam);
|
|||
boolean P_CheckMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff);
|
||||
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);
|
||||
void P_BounceMove(mobj_t *mo);
|
||||
boolean P_CheckSight(mobj_t *t1, mobj_t *t2);
|
||||
|
|
33
src/p_map.c
33
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"
|
||||
|
@ -74,7 +75,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
|
||||
|
@ -106,6 +107,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
|
||||
// =========================================================================
|
||||
|
@ -1153,9 +1178,9 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
|||
return true; // underneath
|
||||
|
||||
if (tmthing->eflags & MFE_VERTICALFLIP)
|
||||
P_TeleportMove(thing, thing->x, thing->y, tmthing->z - thing->height - FixedMul(FRACUNIT, tmthing->scale));
|
||||
P_SetOrigin(thing, thing->x, thing->y, tmthing->z - thing->height - FixedMul(FRACUNIT, tmthing->scale));
|
||||
else
|
||||
P_TeleportMove(thing, thing->x, thing->y, tmthing->z + tmthing->height + FixedMul(FRACUNIT, tmthing->scale));
|
||||
P_SetOrigin(thing, thing->x, thing->y, tmthing->z + tmthing->height + FixedMul(FRACUNIT, tmthing->scale));
|
||||
if (thing->flags & MF_SHOOTABLE)
|
||||
P_DamageMobj(thing, tmthing, tmthing, 1, DMG_SPIKE);
|
||||
return true;
|
||||
|
@ -1915,7 +1940,7 @@ static boolean PIT_CheckLine(line_t *ld)
|
|||
cosradius = FixedMul(dist, FINECOSINE(langle>>ANGLETOFINESHIFT));
|
||||
sinradius = FixedMul(dist, FINESINE(langle>>ANGLETOFINESHIFT));
|
||||
tmthing->flags |= MF_NOCLIP;
|
||||
P_TeleportMove(tmthing, result.x + cosradius - tmthing->momx, result.y + sinradius - tmthing->momy, tmthing->z);
|
||||
P_MoveOrigin(tmthing, result.x + cosradius - tmthing->momx, result.y + sinradius - tmthing->momy, tmthing->z);
|
||||
tmthing->flags &= ~MF_NOCLIP;
|
||||
}
|
||||
#endif
|
||||
|
|
93
src/p_mobj.c
93
src/p_mobj.c
|
@ -19,6 +19,7 @@
|
|||
#include "hu_stuff.h"
|
||||
#include "p_local.h"
|
||||
#include "p_setup.h"
|
||||
#include "r_fps.h"
|
||||
#include "r_main.h"
|
||||
#include "r_skins.h"
|
||||
#include "r_sky.h"
|
||||
|
@ -4023,15 +4024,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])
|
||||
|
@ -4051,6 +4059,7 @@ void P_RainThinker(precipmobj_t *mobj)
|
|||
return;
|
||||
|
||||
mobj->z = mobj->ceilingz;
|
||||
R_ResetPrecipitationMobjInterpolationState(mobj);
|
||||
P_SetPrecipMobjState(mobj, S_RAIN1);
|
||||
|
||||
return;
|
||||
|
@ -4657,7 +4666,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;
|
||||
}
|
||||
}
|
||||
|
@ -5578,7 +5587,7 @@ static void P_Boss9Thinker(mobj_t *mobj)
|
|||
mobj->hprev->destscale = FRACUNIT + (2*TICRATE - mobj->fuse)*(FRACUNIT/2)/TICRATE + FixedMul(FINECOSINE(angle>>ANGLETOFINESHIFT),FRACUNIT/2);
|
||||
P_SetScale(mobj->hprev, mobj->hprev->destscale);
|
||||
|
||||
P_TeleportMove(mobj->hprev, mobj->x, mobj->y, mobj->z + mobj->height/2 - mobj->hprev->height/2);
|
||||
P_MoveOrigin(mobj->hprev, mobj->x, mobj->y, mobj->z + mobj->height/2 - mobj->hprev->height/2);
|
||||
mobj->hprev->momx = mobj->momx;
|
||||
mobj->hprev->momy = mobj->momy;
|
||||
mobj->hprev->momz = mobj->momz;
|
||||
|
@ -6433,7 +6442,7 @@ void P_Attract(mobj_t *source, mobj_t *dest, boolean nightsgrab) // Home in on y
|
|||
if (dist < source->movefactor)
|
||||
{
|
||||
source->momx = source->momy = source->momz = 0;
|
||||
P_TeleportMove(source, tx, ty, tz);
|
||||
P_MoveOrigin(source, tx, ty, tz);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -7042,7 +7051,7 @@ static void P_UpdateMinecartSegments(mobj_t *mobj)
|
|||
dx = seg->extravalue1;
|
||||
dy = seg->extravalue2;
|
||||
sang = seg->cusval;
|
||||
P_TeleportMove(seg, x + s*dx + c*dy, y - c*dx + s*dy, z);
|
||||
P_MoveOrigin(seg, x + s*dx + c*dy, y - c*dx + s*dy, z);
|
||||
seg->angle = ang + FixedAngle(FRACUNIT*sang);
|
||||
seg->flags2 = (seg->flags2 & ~MF2_DONTDRAW) | (mobj->flags2 & MF2_DONTDRAW);
|
||||
seg = seg->tracer;
|
||||
|
@ -7809,6 +7818,9 @@ static void P_MobjSceneryThink(mobj_t *mobj)
|
|||
mobj->z = mobj->target->z + mobj->target->height + FixedMul((16 + abs((signed)(leveltime % TICRATE) - TICRATE/2))*FRACUNIT, mobj->target->scale);
|
||||
else
|
||||
mobj->z = mobj->target->z - FixedMul((16 + abs((signed)(leveltime % TICRATE) - TICRATE/2))*FRACUNIT, mobj->target->scale) - mobj->height;
|
||||
|
||||
mobj->old_z = mobj->z;
|
||||
|
||||
break;
|
||||
case MT_LOCKONINF:
|
||||
if (!(mobj->flags2 & MF2_STRONGBOX))
|
||||
|
@ -7820,6 +7832,9 @@ static void P_MobjSceneryThink(mobj_t *mobj)
|
|||
mobj->z = mobj->threshold + FixedMul((16 + abs((signed)(leveltime % TICRATE) - TICRATE/2))*FRACUNIT, mobj->scale);
|
||||
else
|
||||
mobj->z = mobj->threshold - FixedMul((16 + abs((signed)(leveltime % TICRATE) - TICRATE/2))*FRACUNIT, mobj->scale);
|
||||
|
||||
mobj->old_z = mobj->z;
|
||||
|
||||
break;
|
||||
case MT_DROWNNUMBERS:
|
||||
if (!P_DrownNumbersSceneryThink(mobj))
|
||||
|
@ -8658,7 +8673,7 @@ static boolean P_EggRobo1Think(mobj_t *mobj)
|
|||
< mobj->scale)
|
||||
S_StartSound(mobj, mobj->info->seesound);
|
||||
|
||||
P_TeleportMove(mobj,
|
||||
P_MoveOrigin(mobj,
|
||||
(15*(mobj->x >> 4)) + (basex >> 4) + P_ReturnThrustX(mobj, mobj->angle, SPECTATORRADIUS >> 4),
|
||||
(15*(mobj->y >> 4)) + (basey >> 4) + P_ReturnThrustY(mobj, mobj->angle, SPECTATORRADIUS >> 4),
|
||||
mobj->z);
|
||||
|
@ -8684,9 +8699,9 @@ static boolean P_EggRobo1Think(mobj_t *mobj)
|
|||
if (!didmove)
|
||||
{
|
||||
if (P_AproxDistance(mobj->x - basex, mobj->y - basey) < mobj->scale)
|
||||
P_TeleportMove(mobj, basex, basey, mobj->z);
|
||||
P_MoveOrigin(mobj, basex, basey, mobj->z);
|
||||
else
|
||||
P_TeleportMove(mobj,
|
||||
P_MoveOrigin(mobj,
|
||||
(15*(mobj->x >> 4)) + (basex >> 4),
|
||||
(15*(mobj->y >> 4)) + (basey >> 4),
|
||||
mobj->z);
|
||||
|
@ -8808,11 +8823,11 @@ static void P_NiGHTSDroneThink(mobj_t *mobj)
|
|||
sparkleoffset = goaloffset + FixedMul(15*FRACUNIT, mobj->scale);
|
||||
}
|
||||
|
||||
P_TeleportMove(goalpost, mobj->x, mobj->y, mobj->z + goaloffset);
|
||||
P_TeleportMove(sparkle, mobj->x, mobj->y, mobj->z + sparkleoffset);
|
||||
P_MoveOrigin(goalpost, mobj->x, mobj->y, mobj->z + goaloffset);
|
||||
P_MoveOrigin(sparkle, mobj->x, mobj->y, mobj->z + sparkleoffset);
|
||||
if (goalpost->movefactor != mobj->z || goalpost->friction != mobj->height)
|
||||
{
|
||||
P_TeleportMove(droneman, mobj->x, mobj->y, mobj->z + dronemanoffset);
|
||||
P_MoveOrigin(droneman, mobj->x, mobj->y, mobj->z + dronemanoffset);
|
||||
goalpost->movefactor = mobj->z;
|
||||
goalpost->friction = mobj->height;
|
||||
}
|
||||
|
@ -8822,12 +8837,12 @@ static void P_NiGHTSDroneThink(mobj_t *mobj)
|
|||
{
|
||||
if (goalpost->x != mobj->x || goalpost->y != mobj->y)
|
||||
{
|
||||
P_TeleportMove(goalpost, mobj->x, mobj->y, goalpost->z);
|
||||
P_TeleportMove(sparkle, mobj->x, mobj->y, sparkle->z);
|
||||
P_MoveOrigin(goalpost, mobj->x, mobj->y, goalpost->z);
|
||||
P_MoveOrigin(sparkle, mobj->x, mobj->y, sparkle->z);
|
||||
}
|
||||
|
||||
if (droneman->x != mobj->x || droneman->y != mobj->y)
|
||||
P_TeleportMove(droneman, mobj->x, mobj->y,
|
||||
P_MoveOrigin(droneman, mobj->x, mobj->y,
|
||||
droneman->z >= mobj->floorz && droneman->z <= mobj->ceilingz ? droneman->z : mobj->z);
|
||||
}
|
||||
|
||||
|
@ -9026,7 +9041,7 @@ static void P_SaloonDoorThink(mobj_t *mobj)
|
|||
fma = (mobj->angle >> ANGLETOFINESHIFT) & FINEMASK;
|
||||
c = 48*FINECOSINE(fma);
|
||||
s = 48*FINESINE(fma);
|
||||
P_TeleportMove(mobj, x + c0 + c, y + s0 + s, z);
|
||||
P_MoveOrigin(mobj, x + c0 + c, y + s0 + s, z);
|
||||
}
|
||||
|
||||
static void P_PyreFlyThink(mobj_t *mobj)
|
||||
|
@ -9581,7 +9596,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
|||
P_RemoveMobj(mobj);
|
||||
return false;
|
||||
}
|
||||
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)
|
||||
|
@ -10993,6 +11008,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;
|
||||
}
|
||||
|
||||
|
@ -11040,6 +11057,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;
|
||||
}
|
||||
|
||||
|
@ -11159,6 +11178,8 @@ void P_RemoveMobj(mobj_t *mobj)
|
|||
memset((UINT8 *)mobj + sizeof(thinker_t), 0xff, sizeof(mobj_t) - sizeof(thinker_t));
|
||||
#endif
|
||||
|
||||
R_RemoveMobjInterpolator(mobj);
|
||||
|
||||
// free block
|
||||
if (!mobj->thinker.next)
|
||||
{ // Uh-oh, the mobj doesn't think, P_RemoveThinker would never go through!
|
||||
|
@ -12562,7 +12583,7 @@ static boolean P_SetupNiGHTSDrone(mapthing_t *mthing, mobj_t *mobj)
|
|||
dronemangoaldiff = max(mobjinfo[MT_NIGHTSDRONE_MAN].height - mobjinfo[MT_NIGHTSDRONE_GOAL].height, 0);
|
||||
|
||||
if (flip && mobj->height != oldheight)
|
||||
P_TeleportMove(mobj, mobj->x, mobj->y, mobj->z - (mobj->height - oldheight));
|
||||
P_MoveOrigin(mobj, mobj->x, mobj->y, mobj->z - (mobj->height - oldheight));
|
||||
|
||||
if (!flip)
|
||||
{
|
||||
|
@ -12631,9 +12652,9 @@ static boolean P_SetupNiGHTSDrone(mapthing_t *mthing, mobj_t *mobj)
|
|||
// correct Z position
|
||||
if (flip)
|
||||
{
|
||||
P_TeleportMove(goalpost, goalpost->x, goalpost->y, mobj->z + goaloffset);
|
||||
P_TeleportMove(sparkle, sparkle->x, sparkle->y, mobj->z + sparkleoffset);
|
||||
P_TeleportMove(droneman, droneman->x, droneman->y, mobj->z + dronemanoffset);
|
||||
P_MoveOrigin(goalpost, goalpost->x, goalpost->y, mobj->z + goaloffset);
|
||||
P_MoveOrigin(sparkle, sparkle->x, sparkle->y, mobj->z + sparkleoffset);
|
||||
P_MoveOrigin(droneman, droneman->x, droneman->y, mobj->z + dronemanoffset);
|
||||
}
|
||||
|
||||
// Remember position preference for later
|
||||
|
@ -14086,9 +14107,43 @@ mobj_t *P_SpawnMobjFromMobj(mobj_t *mobj, fixed_t xofs, fixed_t yofs, fixed_t zo
|
|||
newmobj->eflags |= MFE_VERTICALFLIP;
|
||||
newmobj->flags2 |= MF2_OBJECTFLIP;
|
||||
newmobj->z = mobj->z + mobj->height - zofs - elementheight;
|
||||
|
||||
newmobj->old_z = mobj->old_z + mobj->height - zofs - elementheight;
|
||||
newmobj->old_z2 = mobj->old_z2 + mobj->height - zofs - elementheight;
|
||||
}
|
||||
else
|
||||
{
|
||||
newmobj->old_z = mobj->old_z + zofs;
|
||||
newmobj->old_z2 = mobj->old_z2 + zofs;
|
||||
}
|
||||
|
||||
newmobj->destscale = mobj->destscale;
|
||||
P_SetScale(newmobj, mobj->scale);
|
||||
|
||||
newmobj->old_x2 = mobj->old_x2 + xofs;
|
||||
newmobj->old_y2 = mobj->old_y2 + yofs;
|
||||
newmobj->old_x = mobj->old_x + xofs;
|
||||
newmobj->old_y = mobj->old_y + yofs;
|
||||
|
||||
// This angle hack is needed for Lua scripts that set the angle after
|
||||
// spawning, to avoid erroneous interpolation.
|
||||
if (mobj->player)
|
||||
{
|
||||
newmobj->old_angle2 = mobj->player->old_drawangle2;
|
||||
newmobj->old_angle = mobj->player->old_drawangle;
|
||||
}
|
||||
else
|
||||
{
|
||||
newmobj->old_angle2 = mobj->old_angle2;
|
||||
newmobj->old_angle = mobj->old_angle;
|
||||
}
|
||||
|
||||
newmobj->old_scale2 = mobj->old_scale2;
|
||||
newmobj->old_scale = mobj->old_scale;
|
||||
newmobj->old_spritexscale = mobj->old_spritexscale;
|
||||
newmobj->old_spriteyscale = mobj->old_spriteyscale;
|
||||
newmobj->old_spritexoffset = mobj->old_spritexoffset;
|
||||
newmobj->old_spriteyoffset = mobj->old_spriteyoffset;
|
||||
|
||||
return newmobj;
|
||||
}
|
||||
|
|
15
src/p_mobj.h
15
src/p_mobj.h
|
@ -281,6 +281,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;
|
||||
|
@ -288,6 +290,8 @@ typedef struct mobj_s
|
|||
|
||||
// More drawing info: to determine current sprite.
|
||||
angle_t angle, pitch, roll; // orientation
|
||||
angle_t old_angle, old_pitch, old_roll; // orientation interpolation
|
||||
angle_t old_angle2, old_pitch2, old_roll2;
|
||||
angle_t rollangle;
|
||||
spritenum_t sprite; // used to find patch_t and flip value
|
||||
UINT32 frame; // frame number, plus bits see p_pspr.h
|
||||
|
@ -298,6 +302,8 @@ typedef struct mobj_s
|
|||
INT32 blendmode; // blend mode
|
||||
fixed_t spritexscale, spriteyscale;
|
||||
fixed_t spritexoffset, spriteyoffset;
|
||||
fixed_t old_spritexscale, old_spriteyscale;
|
||||
fixed_t old_spritexoffset, old_spriteyoffset;
|
||||
struct pslope_s *floorspriteslope; // The slope that the floorsprite is rotated by
|
||||
|
||||
struct msecnode_s *touching_sectorlist; // a linked list of sectors where this object appears
|
||||
|
@ -373,6 +379,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;
|
||||
|
||||
|
@ -387,6 +395,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
|
||||
boolean mirrored; // The object's rotations will be mirrored left to right, e.g., see frame AL from the right and AR from the left
|
||||
fixed_t shadowscale; // If this object casts a shadow, and the size relative to radius
|
||||
|
@ -408,6 +417,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;
|
||||
|
@ -415,6 +426,8 @@ typedef struct precipmobj_s
|
|||
|
||||
// More drawing info: to determine current sprite.
|
||||
angle_t angle, pitch, roll; // orientation
|
||||
angle_t old_angle, old_pitch, old_roll; // orientation interpolation
|
||||
angle_t old_angle2, old_pitch2, old_roll2;
|
||||
angle_t rollangle;
|
||||
spritenum_t sprite; // used to find patch_t and flip value
|
||||
UINT32 frame; // frame number, plus bits see p_pspr.h
|
||||
|
@ -425,6 +438,8 @@ typedef struct precipmobj_s
|
|||
INT32 blendmode; // blend mode
|
||||
fixed_t spritexscale, spriteyscale;
|
||||
fixed_t spritexoffset, spriteyoffset;
|
||||
fixed_t old_spritexscale, old_spriteyscale;
|
||||
fixed_t old_spritexoffset, old_spriteyoffset;
|
||||
struct pslope_s *floorspriteslope; // The slope that the floorsprite is rotated by
|
||||
|
||||
struct mprecipsecnode_s *touching_sectorlist; // a linked list of sectors where this object appears
|
||||
|
|
|
@ -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"
|
||||
|
@ -2049,6 +2050,9 @@ boolean EV_DoPolyObjRotate(polyrotdata_t *prdata)
|
|||
|
||||
oldpo = po;
|
||||
|
||||
// interpolation
|
||||
R_CreateInterpolator_Polyobj(&th->thinker, po);
|
||||
|
||||
th->turnobjs = 0;
|
||||
if (!(prdata->flags & TMPR_DONTROTATEOTHERS))
|
||||
th->turnobjs |= PTF_OTHERS;
|
||||
|
@ -2114,6 +2118,9 @@ boolean 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)))
|
||||
|
@ -2129,8 +2136,10 @@ boolean EV_DoPolyObjMove(polymovedata_t *pmdata)
|
|||
boolean EV_DoPolyObjWaypoint(polywaypointdata_t *pwdata)
|
||||
{
|
||||
polyobj_t *po;
|
||||
polyobj_t *oldpo;
|
||||
polywaypoint_t *th;
|
||||
mobj_t *first = NULL;
|
||||
INT32 start;
|
||||
|
||||
if (!(po = Polyobj_GetForNum(pwdata->polyObjNum)))
|
||||
{
|
||||
|
@ -2181,6 +2190,26 @@ boolean EV_DoPolyObjWaypoint(polywaypointdata_t *pwdata)
|
|||
th->continuous = false;
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
th->pointnum = first->health;
|
||||
|
||||
return true;
|
||||
|
@ -2229,6 +2258,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)))
|
||||
|
@ -2269,6 +2301,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)))
|
||||
|
@ -2340,6 +2375,9 @@ boolean 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)))
|
||||
|
@ -2386,6 +2424,9 @@ boolean EV_DoPolyObjRotDisplace(polyrotdisplacedata_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)))
|
||||
|
@ -2490,6 +2531,9 @@ boolean EV_DoPolyObjFlag(polyflagdata_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)))
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "p_setup.h"
|
||||
#include "p_saveg.h"
|
||||
#include "r_data.h"
|
||||
#include "r_fps.h"
|
||||
#include "r_textures.h"
|
||||
#include "r_things.h"
|
||||
#include "r_skins.h"
|
||||
|
@ -3060,6 +3061,8 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker)
|
|||
|
||||
mobj->info = (mobjinfo_t *)next; // temporarily, set when leave this function
|
||||
|
||||
R_AddMobjInterpolator(mobj);
|
||||
|
||||
return &mobj->thinker;
|
||||
}
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
@ -33,6 +34,7 @@
|
|||
#include "r_picformats.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"
|
||||
|
@ -7313,7 +7315,10 @@ static void P_RunSpecialStageWipe(void)
|
|||
{
|
||||
// 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();
|
||||
|
@ -7615,7 +7620,10 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate)
|
|||
Patch_FreeTag(PU_PATCH_ROTATED);
|
||||
Z_FreeTags(PU_LEVEL, PU_PURGELEVEL - 1);
|
||||
|
||||
R_InitializeLevelInterpolators();
|
||||
|
||||
P_InitThinkers();
|
||||
R_InitMobjInterpolators();
|
||||
P_InitCachedActions();
|
||||
|
||||
if (!fromnetsave && savedata.lives > 0)
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "r_main.h"
|
||||
#include "p_maputl.h"
|
||||
#include "w_wad.h"
|
||||
#include "r_fps.h"
|
||||
|
||||
pslope_t *slopelist = NULL;
|
||||
UINT16 slopecount = 0;
|
||||
|
@ -189,6 +190,9 @@ static inline void P_AddDynLineSlopeThinker (pslope_t* slope, dynplanetype_t typ
|
|||
th->sourceline = sourceline;
|
||||
th->extent = extent;
|
||||
P_AddThinker(THINK_DYNSLOPE, &th->thinker);
|
||||
|
||||
// interpolation
|
||||
R_CreateInterpolator_DynSlope(&th->thinker, slope);
|
||||
}
|
||||
|
||||
static inline void P_AddDynVertexSlopeThinker (pslope_t* slope, const INT16 tags[3], const vector3_t vx[3])
|
||||
|
|
42
src/p_spec.c
42
src/p_spec.c
|
@ -21,6 +21,7 @@
|
|||
#include "p_local.h"
|
||||
#include "p_setup.h" // levelflats for flat animation
|
||||
#include "r_data.h"
|
||||
#include "r_fps.h"
|
||||
#include "r_textures.h"
|
||||
#include "m_random.h"
|
||||
#include "p_mobj.h"
|
||||
|
@ -2480,7 +2481,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
|
|||
if (mo->player)
|
||||
{
|
||||
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);
|
||||
if (splitscreen && mo->player == &players[secondarydisplayplayer] && camera2.chase)
|
||||
{
|
||||
camera2.x += x;
|
||||
|
@ -2726,7 +2727,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
|
|||
// Reset bot too.
|
||||
if (bot) {
|
||||
if (line->args[0])
|
||||
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;
|
||||
|
@ -2767,7 +2768,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;
|
||||
|
@ -5703,6 +5704,10 @@ static void P_AddFloatThinker(sector_t *sec, UINT16 tag, line_t *sourceline)
|
|||
floater->sector = sec;
|
||||
floater->tag = (INT16)tag;
|
||||
floater->sourceline = sourceline;
|
||||
|
||||
// interpolation
|
||||
R_CreateInterpolator_SectorPlane(&floater->thinker, sec, false);
|
||||
R_CreateInterpolator_SectorPlane(&floater->thinker, sec, true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -5732,6 +5737,9 @@ static void P_AddPlaneDisplaceThinker(INT32 type, fixed_t speed, INT32 control,
|
|||
displace->speed = speed;
|
||||
displace->type = type;
|
||||
displace->reverse = reverse;
|
||||
|
||||
// interpolation
|
||||
R_CreateInterpolator_SectorPlane(&displace->thinker, §ors[affectee], false);
|
||||
}
|
||||
|
||||
/** Adds a Mario block thinker, which changes the block's texture between blank
|
||||
|
@ -5791,6 +5799,10 @@ static void P_AddRaiseThinker(sector_t *sec, INT16 tag, fixed_t speed, fixed_t c
|
|||
raise->flags |= RF_REVERSE;
|
||||
if (spindash)
|
||||
raise->flags |= RF_SPINDASH;
|
||||
|
||||
// interpolation
|
||||
R_CreateInterpolator_SectorPlane(&raise->thinker, sec, false);
|
||||
R_CreateInterpolator_SectorPlane(&raise->thinker, sec, true);
|
||||
}
|
||||
|
||||
static void P_AddAirbob(sector_t *sec, INT16 tag, fixed_t dist, boolean raise, boolean spindash, boolean dynamic)
|
||||
|
@ -5816,6 +5828,10 @@ static void P_AddAirbob(sector_t *sec, INT16 tag, fixed_t dist, boolean raise, b
|
|||
airbob->flags |= RF_SPINDASH;
|
||||
if (dynamic)
|
||||
airbob->flags |= RF_DYNAMIC;
|
||||
|
||||
// interpolation
|
||||
R_CreateInterpolator_SectorPlane(&airbob->thinker, sec, false);
|
||||
R_CreateInterpolator_SectorPlane(&airbob->thinker, sec, true);
|
||||
}
|
||||
|
||||
/** Adds a thwomp thinker.
|
||||
|
@ -5856,6 +5872,10 @@ static inline void P_AddThwompThinker(sector_t *sec, line_t *sourceline, fixed_t
|
|||
sec->ceilingdata = thwomp;
|
||||
// Start with 'resting' texture
|
||||
sides[sourceline->sidenum[0]].midtexture = sides[sourceline->sidenum[0]].bottomtexture;
|
||||
|
||||
// interpolation
|
||||
R_CreateInterpolator_SectorPlane(&thwomp->thinker, sec, false);
|
||||
R_CreateInterpolator_SectorPlane(&thwomp->thinker, sec, true);
|
||||
}
|
||||
|
||||
/** Adds a thinker which checks if any MF_ENEMY objects with health are in the defined area.
|
||||
|
@ -7524,6 +7544,22 @@ static void Add_Scroller(INT32 type, fixed_t dx, fixed_t dy, INT32 control, INT3
|
|||
}
|
||||
}
|
||||
P_AddThinker(THINK_MAIN, &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;
|
||||
}
|
||||
}
|
||||
|
||||
static void P_SpawnPlaneScroller(line_t *l, fixed_t dx, fixed_t dy, INT32 control, INT32 affectee, INT32 accel, INT32 exclusive)
|
||||
|
|
|
@ -122,7 +122,7 @@ void P_MixUp(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle,
|
|||
*/
|
||||
boolean P_Teleport(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle, boolean flash, boolean dontstopmove)
|
||||
{
|
||||
if (!P_TeleportMove(thing, x, y, z))
|
||||
if (!P_SetOrigin(thing, x, y, z))
|
||||
return false;
|
||||
|
||||
if (!dontstopmove)
|
||||
|
|
50
src/p_tick.c
50
src/p_tick.c
|
@ -23,6 +23,9 @@
|
|||
#include "lua_hook.h"
|
||||
#include "m_perfstats.h"
|
||||
#include "i_system.h" // I_GetPreciseTime
|
||||
#include "r_main.h"
|
||||
#include "r_fps.h"
|
||||
#include "i_video.h" // rendermode
|
||||
|
||||
// Object place
|
||||
#include "m_cheat.h"
|
||||
|
@ -254,6 +257,7 @@ void P_RemoveThinkerDelayed(thinker_t *thinker)
|
|||
* thinker->prev->next = thinker->next */
|
||||
(next->prev = currentthinker = thinker->prev)->next = next;
|
||||
|
||||
R_DestroyLevelInterpolators(thinker);
|
||||
Z_Free(thinker);
|
||||
}
|
||||
|
||||
|
@ -616,8 +620,10 @@ void P_Ticker(boolean run)
|
|||
if (OP_FreezeObjectplace())
|
||||
{
|
||||
P_MapStart();
|
||||
R_UpdateMobjInterpolators();
|
||||
OP_ObjectplaceMovement(&players[0]);
|
||||
P_MoveChaseCamera(&players[0], &camera, false);
|
||||
R_UpdateViewInterpolation();
|
||||
P_MapEnd();
|
||||
S_SetStackAdjustmentStart();
|
||||
return;
|
||||
|
@ -640,6 +646,8 @@ void P_Ticker(boolean run)
|
|||
|
||||
if (run)
|
||||
{
|
||||
R_UpdateMobjInterpolators();
|
||||
|
||||
if (demorecording)
|
||||
G_WriteDemoTiccmd(&players[consoleplayer].cmd, 0);
|
||||
if (demoplayback)
|
||||
|
@ -763,6 +771,42 @@ void P_Ticker(boolean run)
|
|||
LUA_HOOK(PostThinkFrame);
|
||||
}
|
||||
|
||||
if (run)
|
||||
{
|
||||
R_UpdateLevelInterpolators();
|
||||
R_UpdateViewInterpolation();
|
||||
|
||||
// Hack: ensure newview is assigned every tic.
|
||||
// Ensures view interpolation is T-1 to T in poor network conditions
|
||||
// We need a better way to assign view state decoupled from game logic
|
||||
if (rendermode != render_none)
|
||||
{
|
||||
player_t *player1 = &players[displayplayer];
|
||||
if (player1->mo && skyboxmo[0] && cv_skybox.value)
|
||||
{
|
||||
R_SkyboxFrame(player1);
|
||||
}
|
||||
if (player1->mo)
|
||||
{
|
||||
R_SetupFrame(player1);
|
||||
}
|
||||
|
||||
if (splitscreen)
|
||||
{
|
||||
player_t *player2 = &players[secondarydisplayplayer];
|
||||
if (player2->mo && skyboxmo[0] && cv_skybox.value)
|
||||
{
|
||||
R_SkyboxFrame(player2);
|
||||
}
|
||||
if (player2->mo)
|
||||
{
|
||||
R_SetupFrame(player2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
P_MapEnd();
|
||||
|
||||
// Z_CheckMemCleanup();
|
||||
|
@ -783,6 +827,8 @@ void P_PreTicker(INT32 frames)
|
|||
{
|
||||
P_MapStart();
|
||||
|
||||
R_UpdateMobjInterpolators();
|
||||
|
||||
LUA_HOOK(PreThinkFrame);
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
|
@ -821,6 +867,10 @@ void P_PreTicker(INT32 frames)
|
|||
|
||||
LUA_HOOK(PostThinkFrame);
|
||||
|
||||
R_UpdateLevelInterpolators();
|
||||
R_UpdateViewInterpolation();
|
||||
R_ResetViewInterpolation(0);
|
||||
|
||||
P_MapEnd();
|
||||
}
|
||||
|
||||
|
|
23
src/p_user.c
23
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_skins.h"
|
||||
|
@ -1996,6 +1997,14 @@ mobj_t *P_SpawnGhostMobj(mobj_t *mobj)
|
|||
ghost2->flags2 |= (mobj->player->followmobj->flags2 & MF2_LINKDRAW);
|
||||
}
|
||||
|
||||
// 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_drawangle2 : mobj->old_angle2);
|
||||
ghost->old_pitch = mobj->old_pitch2;
|
||||
ghost->old_roll = mobj->old_roll2;
|
||||
|
||||
return ghost;
|
||||
}
|
||||
|
||||
|
@ -6931,7 +6940,7 @@ static void P_MoveNiGHTSToDrone(player_t *player)
|
|||
}
|
||||
|
||||
player->mo->momx = player->mo->momy = player->mo->momz = 0;
|
||||
P_TeleportMove(player->mo, player->drone->x, player->drone->y, player->drone->z + zofs);
|
||||
P_MoveOrigin(player->mo, player->drone->x, player->drone->y, player->drone->z + zofs);
|
||||
P_SetTarget(&player->drone, NULL);
|
||||
}
|
||||
|
||||
|
@ -9647,6 +9656,7 @@ void P_ResetCamera(player_t *player, camera_t *thiscam)
|
|||
thiscam->x = x;
|
||||
thiscam->y = y;
|
||||
thiscam->z = z;
|
||||
thiscam->reset = true;
|
||||
|
||||
if ((thiscam == &camera && G_ControlStyle(1) == CS_SIMPLE)
|
||||
|| (thiscam == &camera2 && G_ControlStyle(2) == CS_SIMPLE))
|
||||
|
@ -10997,7 +11007,7 @@ static void P_MinecartThink(player_t *player)
|
|||
}
|
||||
|
||||
// Move player to minecart.
|
||||
P_TeleportMove(player->mo, minecart->x - minecart->momx, minecart->y - minecart->momy, minecart->z + max(minecart->momz, 0) + 8*FRACUNIT);
|
||||
P_MoveOrigin(player->mo, minecart->x - minecart->momx, minecart->y - minecart->momy, minecart->z + max(minecart->momz, 0) + 8*FRACUNIT);
|
||||
if (player->powers[pw_carry] != CR_MINECART)
|
||||
return;
|
||||
player->mo->momx = player->mo->momy = player->mo->momz = 0;
|
||||
|
@ -11236,6 +11246,7 @@ static void P_DoMetalJetFume(player_t *player, mobj_t *fume)
|
|||
tic_t dashmode = min(player->dashmode, DASHMODE_MAX);
|
||||
boolean underwater = mo->eflags & MFE_UNDERWATER;
|
||||
statenum_t stat = fume->state-states;
|
||||
boolean resetinterp = false;
|
||||
|
||||
if (panim != PA_WALK && panim != PA_RUN && panim != PA_DASH) // turn invisible when not in a coherent movement state
|
||||
{
|
||||
|
@ -11287,6 +11298,7 @@ static void P_DoMetalJetFume(player_t *player, mobj_t *fume)
|
|||
{
|
||||
P_SetMobjState(fume, (stat = fume->info->seestate));
|
||||
P_SetScale(fume, mo->scale);
|
||||
resetinterp = true;
|
||||
}
|
||||
|
||||
if (dashmode > DASHMODE_THRESHOLD && stat != fume->info->seestate) // If in dashmode, grow really big and flash
|
||||
|
@ -11330,6 +11342,7 @@ static void P_DoMetalJetFume(player_t *player, mobj_t *fume)
|
|||
fume->y = mo->y + P_ReturnThrustY(fume, angle, dist);
|
||||
fume->z = mo->z + heightoffset - (fume->height >> 1);
|
||||
P_SetThingPosition(fume);
|
||||
if (resetinterp) R_ResetMobjInterpolationState(fume);
|
||||
|
||||
// If dashmode is high enough, spawn a trail
|
||||
if (player->normalspeed >= skins[player->skin].normalspeed*2)
|
||||
|
@ -11732,7 +11745,7 @@ void P_PlayerThink(player_t *player)
|
|||
// P_TouchSpecialThing case MT_NIGHTSBUMPER, that position is fudged in the time
|
||||
// between that routine in the previous tic
|
||||
// and reaching here in the current tic
|
||||
P_TeleportMove(player->mo, player->mo->hnext->x, player->mo->hnext->y
|
||||
P_MoveOrigin(player->mo, player->mo->hnext->x, player->mo->hnext->y
|
||||
, player->mo->hnext->z + FixedMul(player->mo->hnext->height/4, player->mo->hnext->scale));
|
||||
P_SetTarget(&player->mo->hnext, NULL);
|
||||
}
|
||||
|
@ -12556,7 +12569,7 @@ void P_PlayerAfterThink(player_t *player)
|
|||
player->mo->momx = (chain->x - player->mo->x)*2;
|
||||
player->mo->momy = (chain->y - player->mo->y)*2;
|
||||
player->mo->momz = (chain->z - (player->mo->height-chain->height/2) - player->mo->z)*2;
|
||||
P_TeleportMove(player->mo, chain->x, chain->y, chain->z - (player->mo->height-chain->height/2));
|
||||
P_MoveOrigin(player->mo, chain->x, chain->y, chain->z - (player->mo->height-chain->height/2));
|
||||
if (!player->powers[pw_flashing]) // handle getting hurt
|
||||
{
|
||||
player->pflags |= PF_JUMPED;
|
||||
|
@ -12650,7 +12663,7 @@ void P_PlayerAfterThink(player_t *player)
|
|||
mo->tics = walktics;
|
||||
}
|
||||
|
||||
P_TeleportMove(player->mo, rock->x, rock->y, rock->z + ((mo->eflags & MFE_VERTICALFLIP) ? -mo->height : rock->height));
|
||||
P_MoveOrigin(player->mo, rock->x, rock->y, rock->z + ((mo->eflags & MFE_VERTICALFLIP) ? -mo->height : rock->height));
|
||||
break;
|
||||
}
|
||||
case CR_PTERABYTE: // being carried by a Pterabyte
|
||||
|
|
20
src/r_bsp.c
20
src/r_bsp.c
|
@ -840,6 +840,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)
|
||||
|
@ -866,7 +867,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);
|
||||
|
@ -914,7 +931,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)
|
||||
|
|
817
src/r_fps.c
Normal file
817
src/r_fps.c
Normal file
|
@ -0,0 +1,817 @@
|
|||
// 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
|
||||
#include "m_perfstats.h" // ps_metric_t
|
||||
#ifdef HWRENDER
|
||||
#include "hardware/hw_main.h" // for cv_glshearing
|
||||
#endif
|
||||
|
||||
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 = CVAR_INIT ("fpscap", "Match refresh rate", CV_SAVE, fpscap_cons_t, NULL);
|
||||
|
||||
ps_metric_t ps_interp_frac = {0};
|
||||
ps_metric_t ps_interp_lag = {0};
|
||||
|
||||
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 p1view_old;
|
||||
static viewvars_t p1view_new;
|
||||
static viewvars_t p2view_old;
|
||||
static viewvars_t p2view_new;
|
||||
static viewvars_t sky1view_old;
|
||||
static viewvars_t sky1view_new;
|
||||
static viewvars_t sky2view_old;
|
||||
static viewvars_t sky2view_new;
|
||||
|
||||
static viewvars_t *oldview = &p1view_old;
|
||||
static int oldview_invalid[MAXSPLITSCREENPLAYERS] = {0, 0};
|
||||
viewvars_t *newview = &p1view_new;
|
||||
|
||||
|
||||
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)
|
||||
{
|
||||
#ifndef HWRENDER
|
||||
(void)player;
|
||||
(void)skybox;
|
||||
#endif
|
||||
|
||||
// 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
|
||||
|| (rendermode == render_opengl
|
||||
&& (cv_glshearing.value == 1
|
||||
|| (cv_glshearing.value == 2 && R_IsViewpointThirdPerson(player, skybox))))
|
||||
#endif
|
||||
)
|
||||
{
|
||||
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 || viewcontext == VIEWCONTEXT_PLAYER1)
|
||||
{
|
||||
i = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
i = 1;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
// well, this ain't pretty
|
||||
if (newview == &sky1view_new || newview == &sky2view_new)
|
||||
{
|
||||
skybox = 1;
|
||||
}
|
||||
|
||||
R_SetupFreelook(newview->player, skybox);
|
||||
}
|
||||
|
||||
void R_UpdateViewInterpolation(void)
|
||||
{
|
||||
p1view_old = p1view_new;
|
||||
p2view_old = p2view_new;
|
||||
sky1view_old = sky1view_new;
|
||||
sky2view_old = sky2view_new;
|
||||
if (oldview_invalid[0] > 0) oldview_invalid[0]--;
|
||||
if (oldview_invalid[1] > 0) oldview_invalid[1]--;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
I_Assert(_viewcontext == VIEWCONTEXT_PLAYER1
|
||||
|| _viewcontext == VIEWCONTEXT_PLAYER2
|
||||
|| _viewcontext == VIEWCONTEXT_SKY1
|
||||
|| _viewcontext == VIEWCONTEXT_SKY2);
|
||||
viewcontext = _viewcontext;
|
||||
|
||||
switch (viewcontext)
|
||||
{
|
||||
case VIEWCONTEXT_PLAYER1:
|
||||
oldview = &p1view_old;
|
||||
newview = &p1view_new;
|
||||
break;
|
||||
case VIEWCONTEXT_PLAYER2:
|
||||
oldview = &p2view_old;
|
||||
newview = &p2view_new;
|
||||
break;
|
||||
case VIEWCONTEXT_SKY1:
|
||||
oldview = &sky1view_old;
|
||||
newview = &sky1view_new;
|
||||
break;
|
||||
case VIEWCONTEXT_SKY2:
|
||||
oldview = &sky2view_old;
|
||||
newview = &sky2view_new;
|
||||
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->drawangle : mobj->angle;
|
||||
out->spritexscale = mobj->spritexscale;
|
||||
out->spriteyscale = mobj->spriteyscale;
|
||||
out->spritexoffset = mobj->spritexoffset;
|
||||
out->spriteyoffset = mobj->spriteyoffset;
|
||||
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->spritexscale = mobj->resetinterp ? mobj->spritexscale : R_LerpFixed(mobj->old_spritexscale, mobj->spritexscale, frac);
|
||||
out->spriteyscale = mobj->resetinterp ? mobj->spriteyscale : R_LerpFixed(mobj->old_spriteyscale, mobj->spriteyscale, frac);
|
||||
|
||||
// Sprite offsets are not interpolated until we have a way to interpolate them explicitly in Lua.
|
||||
// It seems existing mods visually break more often than not if it is interpolated.
|
||||
out->spritexoffset = mobj->spritexoffset;
|
||||
out->spriteyoffset = mobj->spriteyoffset;
|
||||
|
||||
out->subsector = R_PointInSubsector(out->x, out->y);
|
||||
|
||||
if (mobj->player)
|
||||
{
|
||||
out->angle = mobj->resetinterp ? mobj->player->drawangle : R_LerpAngle(mobj->player->old_drawangle, mobj->player->drawangle, 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;
|
||||
out->spritexscale = mobj->spritexscale;
|
||||
out->spriteyscale = mobj->spriteyscale;
|
||||
out->spritexoffset = mobj->spritexoffset;
|
||||
out->spriteyoffset = mobj->spriteyoffset;
|
||||
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->spritexscale = R_LerpFixed(mobj->old_spritexscale, mobj->spritexscale, frac);
|
||||
out->spriteyscale = R_LerpFixed(mobj->old_spriteyscale, mobj->spriteyscale, frac);
|
||||
out->spritexoffset = R_LerpFixed(mobj->old_spritexoffset, mobj->spritexoffset, frac);
|
||||
out->spriteyoffset = R_LerpFixed(mobj->old_spriteyoffset, mobj->spriteyoffset, frac);
|
||||
|
||||
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_pitch2 = mobj->old_pitch;
|
||||
mobj->old_roll2 = mobj->old_roll;
|
||||
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_pitch = mobj->pitch;
|
||||
mobj->old_roll = mobj->roll;
|
||||
mobj->old_scale = mobj->scale;
|
||||
mobj->old_spritexscale = mobj->spritexscale;
|
||||
mobj->old_spriteyscale = mobj->spriteyscale;
|
||||
mobj->old_spritexoffset = mobj->spritexoffset;
|
||||
mobj->old_spriteyoffset = mobj->spriteyoffset;
|
||||
|
||||
if (mobj->player)
|
||||
{
|
||||
mobj->player->old_drawangle2 = mobj->player->old_drawangle;
|
||||
mobj->player->old_drawangle = mobj->player->drawangle;
|
||||
}
|
||||
|
||||
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_pitch2 = mobj->old_pitch;
|
||||
mobj->old_roll2 = mobj->old_roll;
|
||||
mobj->old_x = mobj->x;
|
||||
mobj->old_y = mobj->y;
|
||||
mobj->old_z = mobj->z;
|
||||
mobj->old_angle = mobj->angle;
|
||||
mobj->old_spritexscale = mobj->spritexscale;
|
||||
mobj->old_spriteyscale = mobj->spriteyscale;
|
||||
mobj->old_spritexoffset = mobj->spritexoffset;
|
||||
mobj->old_spriteyoffset = mobj->spriteyoffset;
|
||||
}
|
162
src/r_fps.h
Normal file
162
src/r_fps.h
Normal file
|
@ -0,0 +1,162 @@
|
|||
// 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"
|
||||
#include "m_perfstats.h" // ps_metric_t
|
||||
|
||||
extern consvar_t cv_fpscap;
|
||||
|
||||
extern ps_metric_t ps_interp_frac;
|
||||
extern ps_metric_t ps_interp_lag;
|
||||
|
||||
UINT32 R_GetFramerateCap(void);
|
||||
boolean R_UsingFrameInterpolation(void);
|
||||
|
||||
enum viewcontext_e
|
||||
{
|
||||
VIEWCONTEXT_PLAYER1 = 0,
|
||||
VIEWCONTEXT_PLAYER2,
|
||||
VIEWCONTEXT_SKY1,
|
||||
VIEWCONTEXT_SKY2
|
||||
};
|
||||
|
||||
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;
|
||||
fixed_t spritexscale;
|
||||
fixed_t spriteyscale;
|
||||
fixed_t spritexoffset;
|
||||
fixed_t spriteyoffset;
|
||||
} 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
|
197
src/r_main.c
197
src/r_main.c
|
@ -35,6 +35,7 @@
|
|||
#include "r_portal.h"
|
||||
#include "r_main.h"
|
||||
#include "i_system.h" // I_GetPreciseTime
|
||||
#include "r_fps.h" // Frame interpolation/uncapped
|
||||
|
||||
#ifdef HWRENDER
|
||||
#include "hardware/hw_main.h"
|
||||
|
@ -75,6 +76,10 @@ sector_t *viewsector;
|
|||
player_t *viewplayer;
|
||||
mobj_t *r_viewmobj;
|
||||
|
||||
fixed_t rendertimefrac;
|
||||
fixed_t renderdeltatics;
|
||||
boolean renderisnewtic;
|
||||
|
||||
//
|
||||
// precalculated math tables
|
||||
//
|
||||
|
@ -1084,41 +1089,6 @@ subsector_t *R_PointInSubsectorOrNull(fixed_t x, fixed_t y)
|
|||
//
|
||||
// R_SetupFrame
|
||||
//
|
||||
|
||||
// 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)
|
||||
{
|
||||
#ifndef HWRENDER
|
||||
(void)player;
|
||||
(void)skybox;
|
||||
#endif
|
||||
|
||||
// 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
|
||||
|| (rendermode == render_opengl
|
||||
&& (cv_glshearing.value == 1
|
||||
|| (cv_glshearing.value == 2 && R_IsViewpointThirdPerson(player, skybox))))
|
||||
#endif
|
||||
)
|
||||
{
|
||||
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];
|
||||
}
|
||||
|
||||
void R_SetupFrame(player_t *player)
|
||||
{
|
||||
camera_t *thiscam;
|
||||
|
@ -1129,11 +1099,13 @@ void R_SetupFrame(player_t *player)
|
|||
{
|
||||
thiscam = &camera2;
|
||||
chasecam = (cv_chasecam2.value != 0);
|
||||
R_SetViewContext(VIEWCONTEXT_PLAYER2);
|
||||
}
|
||||
else
|
||||
{
|
||||
thiscam = &camera;
|
||||
chasecam = (cv_chasecam.value != 0);
|
||||
R_SetViewContext(VIEWCONTEXT_PLAYER1);
|
||||
}
|
||||
|
||||
if (player->climbing || (player->powers[pw_carry] == CR_NIGHTSMODE) || player->playerstate == PST_DEAD || gamestate == GS_TITLESCREEN || tutorialmode)
|
||||
|
@ -1149,81 +1121,83 @@ void R_SetupFrame(player_t *player)
|
|||
else if (!chasecam)
|
||||
thiscam->chase = false;
|
||||
|
||||
newview->sky = false;
|
||||
|
||||
if (player->awayviewtics)
|
||||
{
|
||||
// cut-away view stuff
|
||||
r_viewmobj = player->awayviewmobj; // should be a MT_ALTVIEWMAN
|
||||
I_Assert(r_viewmobj != NULL);
|
||||
viewz = r_viewmobj->z + 20*FRACUNIT;
|
||||
aimingangle = player->awayviewaiming;
|
||||
viewangle = r_viewmobj->angle;
|
||||
newview->z = r_viewmobj->z + 20*FRACUNIT;
|
||||
newview->aim = player->awayviewaiming;
|
||||
newview->angle = r_viewmobj->angle;
|
||||
}
|
||||
else if (!player->spectator && chasecam)
|
||||
// use outside cam view
|
||||
{
|
||||
r_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;
|
||||
|
||||
r_viewmobj = player->mo;
|
||||
I_Assert(r_viewmobj != NULL);
|
||||
|
||||
aimingangle = player->aiming;
|
||||
viewangle = r_viewmobj->angle;
|
||||
newview->aim = player->aiming;
|
||||
newview->angle = r_viewmobj->angle;
|
||||
|
||||
if (!demoplayback && player->playerstate != PST_DEAD)
|
||||
{
|
||||
if (player == &players[consoleplayer])
|
||||
{
|
||||
viewangle = localangle; // WARNING: camera uses this
|
||||
aimingangle = localaiming;
|
||||
newview->angle = localangle; // WARNING: camera uses this
|
||||
newview->aim = localaiming;
|
||||
}
|
||||
else if (player == &players[secondarydisplayplayer])
|
||||
{
|
||||
viewangle = localangle2;
|
||||
aimingangle = localaiming2;
|
||||
newview->angle = localangle2;
|
||||
newview->aim = localaiming2;
|
||||
}
|
||||
}
|
||||
}
|
||||
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)
|
||||
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 = r_viewmobj->x;
|
||||
viewy = r_viewmobj->y;
|
||||
viewx += quake.x;
|
||||
viewy += quake.y;
|
||||
newview->x = r_viewmobj->x;
|
||||
newview->y = r_viewmobj->y;
|
||||
newview->x += quake.x;
|
||||
newview->y += quake.y;
|
||||
|
||||
if (r_viewmobj->subsector)
|
||||
viewsector = r_viewmobj->subsector->sector;
|
||||
newview->sector = r_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(player, false);
|
||||
R_InterpolateView(R_UsingFrameInterpolation() ? rendertimefrac : FRACUNIT);
|
||||
}
|
||||
|
||||
void R_SkyboxFrame(player_t *player)
|
||||
|
@ -1232,11 +1206,18 @@ void R_SkyboxFrame(player_t *player)
|
|||
|
||||
if (splitscreen && player == &players[secondarydisplayplayer]
|
||||
&& player != &players[consoleplayer])
|
||||
{
|
||||
thiscam = &camera2;
|
||||
R_SetViewContext(VIEWCONTEXT_SKY2);
|
||||
}
|
||||
else
|
||||
{
|
||||
thiscam = &camera;
|
||||
R_SetViewContext(VIEWCONTEXT_SKY1);
|
||||
}
|
||||
|
||||
// cut-away view stuff
|
||||
newview->sky = true;
|
||||
r_viewmobj = skyboxmo[0];
|
||||
#ifdef PARANOIA
|
||||
if (!r_viewmobj)
|
||||
|
@ -1247,39 +1228,39 @@ 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 (!demoplayback && player->playerstate != PST_DEAD)
|
||||
{
|
||||
if (player == &players[consoleplayer])
|
||||
{
|
||||
viewangle = localangle; // WARNING: camera uses this
|
||||
aimingangle = localaiming;
|
||||
newview->angle = localangle; // WARNING: camera uses this
|
||||
newview->aim = localaiming;
|
||||
}
|
||||
else if (player == &players[secondarydisplayplayer])
|
||||
{
|
||||
viewangle = localangle2;
|
||||
aimingangle = localaiming2;
|
||||
newview->angle = localangle2;
|
||||
newview->aim = localaiming2;
|
||||
}
|
||||
}
|
||||
}
|
||||
viewangle += r_viewmobj->angle;
|
||||
newview->angle += r_viewmobj->angle;
|
||||
|
||||
viewplayer = player;
|
||||
newview->player = player;
|
||||
|
||||
viewx = r_viewmobj->x;
|
||||
viewy = r_viewmobj->y;
|
||||
viewz = r_viewmobj->z; // 26/04/17: use actual Z position instead of spawnpoint angle!
|
||||
newview->x = r_viewmobj->x;
|
||||
newview->y = r_viewmobj->y;
|
||||
newview->z = r_viewmobj->z; // 26/04/17: use actual Z position instead of spawnpoint angle!
|
||||
|
||||
if (mapheaderinfo[gamemap-1])
|
||||
{
|
||||
|
@ -1321,56 +1302,75 @@ void R_SkyboxFrame(player_t *player)
|
|||
|
||||
if (r_viewmobj->angle == 0)
|
||||
{
|
||||
viewx += x;
|
||||
viewy += y;
|
||||
newview->x += x;
|
||||
newview->y += y;
|
||||
}
|
||||
else if (r_viewmobj->angle == ANGLE_90)
|
||||
{
|
||||
viewx -= y;
|
||||
viewy += x;
|
||||
newview->x -= y;
|
||||
newview->y += x;
|
||||
}
|
||||
else if (r_viewmobj->angle == ANGLE_180)
|
||||
{
|
||||
viewx -= x;
|
||||
viewy -= y;
|
||||
newview->x -= x;
|
||||
newview->y -= y;
|
||||
}
|
||||
else if (r_viewmobj->angle == ANGLE_270)
|
||||
{
|
||||
viewx += y;
|
||||
viewy -= x;
|
||||
newview->x += y;
|
||||
newview->y -= x;
|
||||
}
|
||||
else
|
||||
{
|
||||
angle_t ang = r_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 += campos.z / mh->skybox_scalez;
|
||||
newview->z += campos.z / mh->skybox_scalez;
|
||||
else if (mh->skybox_scalez < 0)
|
||||
viewz += campos.z * -mh->skybox_scalez;
|
||||
newview->z += campos.z * -mh->skybox_scalez;
|
||||
}
|
||||
|
||||
if (r_viewmobj->subsector)
|
||||
viewsector = r_viewmobj->subsector->sector;
|
||||
newview->sector = r_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(player, true);
|
||||
R_InterpolateView(R_UsingFrameInterpolation() ? rendertimefrac : FRACUNIT);
|
||||
}
|
||||
|
||||
boolean R_ViewpointHasChasecam(player_t *player)
|
||||
{
|
||||
camera_t *thiscam;
|
||||
boolean chasecam = false;
|
||||
|
||||
if (splitscreen && player == &players[secondarydisplayplayer] && player != &players[consoleplayer])
|
||||
{
|
||||
thiscam = &camera2;
|
||||
chasecam = (cv_chasecam2.value != 0);
|
||||
R_SetViewContext(VIEWCONTEXT_PLAYER2);
|
||||
if (thiscam->reset)
|
||||
{
|
||||
R_ResetViewInterpolation(2);
|
||||
thiscam->reset = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
thiscam = &camera;
|
||||
chasecam = (cv_chasecam.value != 0);
|
||||
R_SetViewContext(VIEWCONTEXT_PLAYER1);
|
||||
if (thiscam->reset)
|
||||
{
|
||||
R_ResetViewInterpolation(1);
|
||||
thiscam->reset = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (player->climbing || (player->powers[pw_carry] == CR_NIGHTSMODE) || player->playerstate == PST_DEAD || gamestate == GS_TITLESCREEN || tutorialmode)
|
||||
chasecam = true; // force chasecam on
|
||||
|
@ -1642,4 +1642,7 @@ void R_RegisterEngineStuff(void)
|
|||
CV_RegisterVar(&cv_maxportals);
|
||||
|
||||
CV_RegisterVar(&cv_movebob);
|
||||
|
||||
// Frame interpolation/uncapped
|
||||
CV_RegisterVar(&cv_fpscap);
|
||||
}
|
||||
|
|
|
@ -35,6 +35,13 @@ extern fixed_t fovtan;
|
|||
|
||||
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,
|
||||
|
|
283
src/r_things.c
283
src/r_things.c
|
@ -23,6 +23,7 @@
|
|||
#include "info.h" // spr2names
|
||||
#include "i_video.h" // rendermode
|
||||
#include "i_system.h"
|
||||
#include "r_fps.h"
|
||||
#include "r_things.h"
|
||||
#include "r_patch.h"
|
||||
#include "r_patchrotation.h"
|
||||
|
@ -1134,13 +1135,33 @@ static void R_SplitSprite(vissprite_t *sprite)
|
|||
//
|
||||
fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope)
|
||||
{
|
||||
fixed_t halfHeight;
|
||||
boolean isflipped = thing->eflags & MFE_VERTICALFLIP;
|
||||
fixed_t floorz;
|
||||
fixed_t ceilingz;
|
||||
fixed_t z, groundz = isflipped ? INT32_MAX : INT32_MIN;
|
||||
pslope_t *slope, *groundslope = NULL;
|
||||
msecnode_t *node;
|
||||
sector_t *sector;
|
||||
ffloor_t *rover;
|
||||
#define CHECKZ (isflipped ? z > thing->z+thing->height/2 && z < groundz : z < thing->z+thing->height/2 && z > groundz)
|
||||
|
||||
// for frame interpolation
|
||||
interpmobjstate_t interp = {0};
|
||||
|
||||
if (R_UsingFrameInterpolation() && !paused)
|
||||
{
|
||||
R_InterpolateMobjState(thing, rendertimefrac, &interp);
|
||||
}
|
||||
else
|
||||
{
|
||||
R_InterpolateMobjState(thing, FRACUNIT, &interp);
|
||||
}
|
||||
|
||||
halfHeight = interp.z + (thing->height >> 1);
|
||||
floorz = P_GetFloorZ(thing, interp.subsector->sector, interp.x, interp.y, NULL);
|
||||
ceilingz = P_GetCeilingZ(thing, interp.subsector->sector, interp.x, interp.y, NULL);
|
||||
|
||||
#define CHECKZ (isflipped ? z > halfHeight && z < groundz : z < halfHeight && z > groundz)
|
||||
|
||||
for (node = thing->touching_sectorlist; node; node = node->m_sectorlist_next)
|
||||
{
|
||||
|
@ -1151,7 +1172,7 @@ fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope)
|
|||
if (sector->heightsec != -1)
|
||||
z = isflipped ? sectors[sector->heightsec].ceilingheight : sectors[sector->heightsec].floorheight;
|
||||
else
|
||||
z = isflipped ? P_GetSectorCeilingZAt(sector, thing->x, thing->y) : P_GetSectorFloorZAt(sector, thing->x, thing->y);
|
||||
z = isflipped ? P_GetSectorCeilingZAt(sector, interp.x, interp.y) : P_GetSectorFloorZAt(sector, interp.x, interp.y);
|
||||
|
||||
if CHECKZ
|
||||
{
|
||||
|
@ -1165,7 +1186,7 @@ fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope)
|
|||
if (!(rover->fofflags & FOF_EXISTS) || !(rover->fofflags & FOF_RENDERPLANES) || (rover->alpha < 90 && !(rover->fofflags & FOF_SWIMMABLE)))
|
||||
continue;
|
||||
|
||||
z = isflipped ? P_GetFFloorBottomZAt(rover, thing->x, thing->y) : P_GetFFloorTopZAt(rover, thing->x, thing->y);
|
||||
z = isflipped ? P_GetFFloorBottomZAt(rover, interp.x, interp.y) : P_GetFFloorTopZAt(rover, interp.x, interp.y);
|
||||
if CHECKZ
|
||||
{
|
||||
groundz = z;
|
||||
|
@ -1174,72 +1195,39 @@ fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope)
|
|||
}
|
||||
}
|
||||
|
||||
if (isflipped ? (thing->ceilingz < groundz - (!groundslope ? 0 : FixedMul(abs(groundslope->zdelta), thing->radius*3/2)))
|
||||
: (thing->floorz > groundz + (!groundslope ? 0 : FixedMul(abs(groundslope->zdelta), thing->radius*3/2))))
|
||||
// Check polyobjects and see if groundz needs to be altered
|
||||
{
|
||||
groundz = isflipped ? thing->ceilingz : thing->floorz;
|
||||
// This isn't very precise, but the precise method was far too slow.
|
||||
// (Polies are just naturally pretty flickery anyway :P)
|
||||
polyobj_t *po = interp.subsector->polyList;
|
||||
|
||||
while (po)
|
||||
{
|
||||
if (!(po->flags & POF_RENDERPLANES) || !P_MobjInsidePolyobj(po, thing))
|
||||
{
|
||||
po = (polyobj_t *)(po->link.next);
|
||||
continue;
|
||||
}
|
||||
|
||||
// We're inside it! Yess...
|
||||
z = isflipped ? po->lines[0]->backsector->floorheight : po->lines[0]->backsector->ceilingheight;
|
||||
if CHECKZ
|
||||
{
|
||||
groundz = z;
|
||||
groundslope = NULL;
|
||||
}
|
||||
|
||||
po = (polyobj_t *)(po->link.next);
|
||||
}
|
||||
}
|
||||
|
||||
if (isflipped ? (ceilingz < groundz - (!groundslope ? 0 : FixedMul(abs(groundslope->zdelta), thing->radius*3/2)))
|
||||
: (floorz > groundz + (!groundslope ? 0 : FixedMul(abs(groundslope->zdelta), thing->radius*3/2))))
|
||||
{
|
||||
groundz = isflipped ? ceilingz : floorz;
|
||||
groundslope = NULL;
|
||||
}
|
||||
|
||||
#if 0 // Unfortunately, this drops CEZ2 down to sub-17 FPS on my i7.
|
||||
// NOTE: this section was not updated to reflect reverse gravity support
|
||||
// Check polyobjects and see if groundz needs to be altered, for rings only because they don't update floorz
|
||||
if (thing->type == MT_RING)
|
||||
{
|
||||
INT32 xl, xh, yl, yh, bx, by;
|
||||
|
||||
xl = (unsigned)(thing->x - thing->radius - bmaporgx)>>MAPBLOCKSHIFT;
|
||||
xh = (unsigned)(thing->x + thing->radius - bmaporgx)>>MAPBLOCKSHIFT;
|
||||
yl = (unsigned)(thing->y - thing->radius - bmaporgy)>>MAPBLOCKSHIFT;
|
||||
yh = (unsigned)(thing->y + thing->radius - bmaporgy)>>MAPBLOCKSHIFT;
|
||||
|
||||
BMBOUNDFIX(xl, xh, yl, yh);
|
||||
|
||||
validcount++;
|
||||
|
||||
for (by = yl; by <= yh; by++)
|
||||
for (bx = xl; bx <= xh; bx++)
|
||||
{
|
||||
INT32 offset;
|
||||
polymaplink_t *plink; // haleyjd 02/22/06
|
||||
|
||||
if (bx < 0 || by < 0 || bx >= bmapwidth || by >= bmapheight)
|
||||
continue;
|
||||
|
||||
offset = by*bmapwidth + bx;
|
||||
|
||||
// haleyjd 02/22/06: consider polyobject lines
|
||||
plink = polyblocklinks[offset];
|
||||
|
||||
while (plink)
|
||||
{
|
||||
polyobj_t *po = plink->po;
|
||||
|
||||
if (po->validcount != validcount) // if polyobj hasn't been checked
|
||||
{
|
||||
po->validcount = validcount;
|
||||
|
||||
if (!P_MobjInsidePolyobj(po, thing) || !(po->flags & POF_RENDERPLANES))
|
||||
{
|
||||
plink = (polymaplink_t *)(plink->link.next);
|
||||
continue;
|
||||
}
|
||||
|
||||
// We're inside it! Yess...
|
||||
z = po->lines[0]->backsector->ceilingheight;
|
||||
|
||||
if (z < thing->z+thing->height/2 && z > groundz)
|
||||
{
|
||||
groundz = z;
|
||||
groundslope = NULL;
|
||||
}
|
||||
}
|
||||
plink = (polymaplink_t *)(plink->link.next);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (shadowslope != NULL)
|
||||
*shadowslope = groundslope;
|
||||
|
||||
|
@ -1252,9 +1240,24 @@ static void R_SkewShadowSprite(
|
|||
fixed_t groundz, INT32 spriteheight, fixed_t scalemul,
|
||||
fixed_t *shadowyscale, fixed_t *shadowskew)
|
||||
{
|
||||
|
||||
// haha let's try some dumb stuff
|
||||
fixed_t xslope, zslope;
|
||||
angle_t sloperelang = (R_PointToAngle(thing->x, thing->y) - groundslope->xydirection) >> ANGLETOFINESHIFT;
|
||||
angle_t sloperelang;
|
||||
|
||||
// for frame interpolation
|
||||
interpmobjstate_t interp = {0};
|
||||
|
||||
if (R_UsingFrameInterpolation() && !paused)
|
||||
{
|
||||
R_InterpolateMobjState(thing, rendertimefrac, &interp);
|
||||
}
|
||||
else
|
||||
{
|
||||
R_InterpolateMobjState(thing, FRACUNIT, &interp);
|
||||
}
|
||||
|
||||
sloperelang = (R_PointToAngle(interp.x, interp.y) - groundslope->xydirection) >> ANGLETOFINESHIFT;
|
||||
|
||||
xslope = FixedMul(FINESINE(sloperelang), groundslope->zdelta);
|
||||
zslope = FixedMul(FINECOSINE(sloperelang), groundslope->zdelta);
|
||||
|
@ -1282,11 +1285,21 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale,
|
|||
fixed_t groundz;
|
||||
pslope_t *groundslope;
|
||||
boolean isflipped = thing->eflags & MFE_VERTICALFLIP;
|
||||
interpmobjstate_t interp = {0};
|
||||
|
||||
groundz = R_GetShadowZ(thing, &groundslope);
|
||||
|
||||
if (abs(groundz-viewz)/tz > 4) return; // Prevent stretchy shadows and possible crashes
|
||||
|
||||
if (R_UsingFrameInterpolation() && !paused)
|
||||
{
|
||||
R_InterpolateMobjState(thing, rendertimefrac, &interp);
|
||||
}
|
||||
else
|
||||
{
|
||||
R_InterpolateMobjState(thing, FRACUNIT, &interp);
|
||||
}
|
||||
|
||||
heightsec = thing->subsector->sector->heightsec;
|
||||
if (viewplayer->mo && viewplayer->mo->subsector)
|
||||
phs = viewplayer->mo->subsector->sector->heightsec;
|
||||
|
@ -1305,7 +1318,7 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale,
|
|||
return;
|
||||
}
|
||||
|
||||
floordiff = abs((isflipped ? thing->height : 0) + thing->z - groundz);
|
||||
floordiff = abs((isflipped ? thing->height : 0) + interp.z - groundz);
|
||||
|
||||
trans = floordiff / (100*FRACUNIT) + 3;
|
||||
if (trans >= 9) return;
|
||||
|
@ -1345,11 +1358,11 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale,
|
|||
shadow->mobjflags = 0;
|
||||
shadow->sortscale = vis->sortscale;
|
||||
shadow->dispoffset = vis->dispoffset - 5;
|
||||
shadow->gx = thing->x;
|
||||
shadow->gy = thing->y;
|
||||
shadow->gx = interp.x;
|
||||
shadow->gy = interp.y;
|
||||
shadow->gzt = (isflipped ? shadow->pzt : shadow->pz) + patch->height * shadowyscale / 2;
|
||||
shadow->gz = shadow->gzt - patch->height * shadowyscale;
|
||||
shadow->texturemid = FixedMul(thing->scale, FixedDiv(shadow->gzt - viewz, shadowyscale));
|
||||
shadow->texturemid = FixedMul(interp.scale, FixedDiv(shadow->gzt - viewz, shadowyscale));
|
||||
if (thing->skin && ((skin_t *)thing->skin)->flags & SF_HIRES)
|
||||
shadow->texturemid = FixedMul(shadow->texturemid, ((skin_t *)thing->skin)->highresscale);
|
||||
shadow->scalestep = 0;
|
||||
|
@ -1363,7 +1376,7 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale,
|
|||
|
||||
shadow->xscale = FixedMul(xscale, shadowxscale); //SoM: 4/17/2000
|
||||
shadow->scale = FixedMul(yscale, shadowyscale);
|
||||
shadow->thingscale = thing->scale;
|
||||
shadow->thingscale = interp.scale;
|
||||
shadow->sector = vis->sector;
|
||||
shadow->szt = (INT16)((centeryfrac - FixedMul(shadow->gzt - viewz, yscale))>>FRACBITS);
|
||||
shadow->sz = (INT16)((centeryfrac - FixedMul(shadow->gz - viewz, yscale))>>FRACBITS);
|
||||
|
@ -1391,7 +1404,7 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale,
|
|||
|
||||
// R_GetPlaneLight won't work on sloped lights!
|
||||
for (lightnum = 1; lightnum < thing->subsector->sector->numlights; lightnum++) {
|
||||
fixed_t h = P_GetLightZAt(&thing->subsector->sector->lightlist[lightnum], thing->x, thing->y);
|
||||
fixed_t h = P_GetLightZAt(&thing->subsector->sector->lightlist[lightnum], interp.x, interp.y);
|
||||
if (h <= shadow->gzt) {
|
||||
light = lightnum - 1;
|
||||
break;
|
||||
|
@ -1469,7 +1482,7 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
fixed_t gz = 0, gzt = 0;
|
||||
INT32 heightsec, phs;
|
||||
INT32 light = 0;
|
||||
fixed_t this_scale = thing->scale;
|
||||
fixed_t this_scale;
|
||||
fixed_t spritexscale, spriteyscale;
|
||||
|
||||
// rotsprite
|
||||
|
@ -1481,9 +1494,24 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
INT32 rollangle = 0;
|
||||
#endif
|
||||
|
||||
// uncapped/interpolation
|
||||
interpmobjstate_t interp = {0};
|
||||
|
||||
// do interpolation
|
||||
if (R_UsingFrameInterpolation() && !paused)
|
||||
{
|
||||
R_InterpolateMobjState(oldthing, rendertimefrac, &interp);
|
||||
}
|
||||
else
|
||||
{
|
||||
R_InterpolateMobjState(oldthing, 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;
|
||||
|
||||
basetz = tz = FixedMul(tr_x, viewcos) + FixedMul(tr_y, viewsin); // near/far distance
|
||||
|
||||
|
@ -1560,7 +1588,7 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
|
||||
if (sprframe->rotate != SRF_SINGLE || papersprite)
|
||||
{
|
||||
ang = R_PointToAngle (thing->x, thing->y) - (thing->player ? thing->player->drawangle : thing->angle);
|
||||
ang = R_PointToAngle (interp.x, interp.y) - interp.angle;
|
||||
if (mirrored)
|
||||
ang = InvAngle(ang);
|
||||
}
|
||||
|
@ -1575,7 +1603,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 ((sprframe->rotate & SRF_RIGHT) && (ang < ANGLE_180)) // See from right
|
||||
rot = 6; // F7 slot
|
||||
|
@ -1644,15 +1672,15 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
flip = !flip != !hflip;
|
||||
|
||||
// calculate edges of the shape
|
||||
spritexscale = thing->spritexscale;
|
||||
spriteyscale = thing->spriteyscale;
|
||||
spritexscale = interp.spritexscale;
|
||||
spriteyscale = interp.spriteyscale;
|
||||
if (spritexscale < 1 || spriteyscale < 1)
|
||||
return;
|
||||
|
||||
if (thing->renderflags & RF_ABSOLUTEOFFSETS)
|
||||
{
|
||||
spr_offset = thing->spritexoffset;
|
||||
spr_topoffset = thing->spriteyoffset;
|
||||
spr_offset = interp.spritexoffset;
|
||||
spr_topoffset = interp.spriteyoffset;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1661,8 +1689,8 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
if ((thing->renderflags & RF_FLIPOFFSETS) && flip)
|
||||
flipoffset = -1;
|
||||
|
||||
spr_offset += thing->spritexoffset * flipoffset;
|
||||
spr_topoffset += thing->spriteyoffset * flipoffset;
|
||||
spr_offset += interp.spritexoffset * flipoffset;
|
||||
spr_topoffset += interp.spriteyoffset * flipoffset;
|
||||
}
|
||||
|
||||
if (flip)
|
||||
|
@ -1684,8 +1712,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);
|
||||
|
@ -1701,7 +1729,7 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
paperoffset = -paperoffset;
|
||||
paperdistance = -paperdistance;
|
||||
}
|
||||
centerangle = viewangle - thing->angle;
|
||||
centerangle = viewangle - interp.angle;
|
||||
|
||||
tr_x += FixedMul(offset2, cosmul);
|
||||
tr_y += FixedMul(offset2, sinmul);
|
||||
|
@ -1789,6 +1817,7 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
|
||||
if ((thing->flags2 & MF2_LINKDRAW) && thing->tracer) // toast 16/09/16 (SYMMETRY)
|
||||
{
|
||||
interpmobjstate_t tracer_interp = {0};
|
||||
fixed_t linkscale;
|
||||
|
||||
thing = thing->tracer;
|
||||
|
@ -1796,8 +1825,17 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
if (! R_ThingVisible(thing))
|
||||
return;
|
||||
|
||||
tr_x = (thing->x + sort_x) - viewx;
|
||||
tr_y = (thing->y + sort_y) - viewy;
|
||||
if (R_UsingFrameInterpolation() && !paused)
|
||||
{
|
||||
R_InterpolateMobjState(thing, rendertimefrac, &tracer_interp);
|
||||
}
|
||||
else
|
||||
{
|
||||
R_InterpolateMobjState(thing, FRACUNIT, &tracer_interp);
|
||||
}
|
||||
|
||||
tr_x = (tracer_interp.x + sort_x) - viewx;
|
||||
tr_y = (tracer_interp.y + sort_y) - viewy;
|
||||
tz = FixedMul(tr_x, viewcos) + FixedMul(tr_y, viewsin);
|
||||
linkscale = FixedDiv(projectiony, tz);
|
||||
|
||||
|
@ -1812,8 +1850,8 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
}
|
||||
else if (splat)
|
||||
{
|
||||
tr_x = (thing->x + sort_x) - viewx;
|
||||
tr_y = (thing->y + sort_y) - viewy;
|
||||
tr_x = (interp.x + sort_x) - viewx;
|
||||
tr_y = (interp.y + sort_y) - viewy;
|
||||
sort_z = FixedMul(tr_x, viewcos) + FixedMul(tr_y, viewsin);
|
||||
sortscale = FixedDiv(projectiony, sort_z);
|
||||
}
|
||||
|
@ -1821,8 +1859,8 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
// Calculate the splat's sortscale
|
||||
if (splat)
|
||||
{
|
||||
tr_x = (thing->x - sort_x) - viewx;
|
||||
tr_y = (thing->y - sort_y) - viewy;
|
||||
tr_x = (interp.x - sort_x) - viewx;
|
||||
tr_y = (interp.y - sort_y) - viewy;
|
||||
sort_z = FixedMul(tr_x, viewcos) + FixedMul(tr_y, viewsin);
|
||||
sortsplat = FixedDiv(projectiony, sort_z);
|
||||
}
|
||||
|
@ -1833,7 +1871,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;
|
||||
}
|
||||
|
||||
|
@ -1868,6 +1906,16 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
if (shadoweffects)
|
||||
{
|
||||
mobj_t *caster = thing->target;
|
||||
interpmobjstate_t casterinterp = {};
|
||||
|
||||
if (R_UsingFrameInterpolation() && !paused)
|
||||
{
|
||||
R_InterpolateMobjState(caster, rendertimefrac, &casterinterp);
|
||||
}
|
||||
else
|
||||
{
|
||||
R_InterpolateMobjState(caster, FRACUNIT, &casterinterp);
|
||||
}
|
||||
|
||||
if (caster && !P_MobjWasRemoved(caster))
|
||||
{
|
||||
|
@ -1876,9 +1924,9 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
if (abs(groundz-viewz)/tz > 4)
|
||||
return; // Prevent stretchy shadows and possible crashes
|
||||
|
||||
floordiff = abs((isflipped ? caster->height : 0) + caster->z - groundz);
|
||||
floordiff = abs((isflipped ? caster->height : 0) + casterinterp.z - groundz);
|
||||
trans += ((floordiff / (100*FRACUNIT)) + 3);
|
||||
shadowscale = FixedMul(FRACUNIT - floordiff/640, caster->scale);
|
||||
shadowscale = FixedMul(FRACUNIT - floordiff/640, casterinterp.scale);
|
||||
}
|
||||
else
|
||||
trans += 3;
|
||||
|
@ -1907,7 +1955,7 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
{
|
||||
R_SkewShadowSprite(thing, thing->standingslope, groundz, patch->height, shadowscale, &spriteyscale, &sheartan);
|
||||
|
||||
gzt = (isflipped ? (thing->z + thing->height) : thing->z) + patch->height * spriteyscale / 2;
|
||||
gzt = (isflipped ? (interp.z + thing->height) : interp.z) + patch->height * spriteyscale / 2;
|
||||
gz = gzt - patch->height * spriteyscale;
|
||||
|
||||
cut |= SC_SHEAR;
|
||||
|
@ -1922,12 +1970,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 = oldthing->z + oldthing->height - FixedMul(spr_topoffset, FixedMul(spriteyscale, this_scale));
|
||||
gz = interp.z + oldthing->height - FixedMul(spr_topoffset, FixedMul(spriteyscale, this_scale));
|
||||
gzt = gz + FixedMul(spr_height, FixedMul(spriteyscale, this_scale));
|
||||
}
|
||||
else
|
||||
{
|
||||
gzt = oldthing->z + FixedMul(spr_topoffset, FixedMul(spriteyscale, this_scale));
|
||||
gzt = interp.z + FixedMul(spr_topoffset, FixedMul(spriteyscale, this_scale));
|
||||
gz = gzt - FixedMul(spr_height, FixedMul(spriteyscale, this_scale));
|
||||
}
|
||||
}
|
||||
|
@ -1946,7 +1994,7 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
|
||||
// R_GetPlaneLight won't work on sloped lights!
|
||||
for (lightnum = 1; lightnum < thing->subsector->sector->numlights; lightnum++) {
|
||||
fixed_t h = P_GetLightZAt(&thing->subsector->sector->lightlist[lightnum], thing->x, thing->y);
|
||||
fixed_t h = P_GetLightZAt(&thing->subsector->sector->lightlist[lightnum], interp.x, interp.y);
|
||||
if (h <= top) {
|
||||
light = lightnum - 1;
|
||||
break;
|
||||
|
@ -1972,7 +2020,7 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
if (heightsec != -1 && phs != -1) // only clip things which are in special sectors
|
||||
{
|
||||
fixed_t top = gzt;
|
||||
fixed_t bottom = thing->z;
|
||||
fixed_t bottom = interp.z;
|
||||
|
||||
if (splat)
|
||||
top = bottom;
|
||||
|
@ -1996,12 +2044,12 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
vis->sortscale = sortscale;
|
||||
vis->sortsplat = sortsplat;
|
||||
vis->dispoffset = 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 = FixedDiv(gzt - viewz, spriteyscale);
|
||||
vis->scalestep = scalestep;
|
||||
|
@ -2036,7 +2084,7 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
|
||||
vis->xscale = FixedMul(spritexscale, xscale); //SoM: 4/17/2000
|
||||
vis->scale = FixedMul(spriteyscale, yscale); //<<detailshift;
|
||||
vis->thingscale = oldthing->scale;
|
||||
vis->thingscale = interp.scale;
|
||||
|
||||
vis->spritexscale = spritexscale;
|
||||
vis->spriteyscale = spriteyscale;
|
||||
|
@ -2144,9 +2192,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;
|
||||
|
||||
tz = FixedMul(tr_x, viewcos) + FixedMul(tr_y, viewsin); // near/far distance
|
||||
|
||||
|
@ -2210,13 +2271,13 @@ 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;
|
||||
}
|
||||
|
||||
|
||||
//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)
|
||||
|
@ -2229,12 +2290,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;
|
||||
|
|
132
src/screen.c
132
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"
|
||||
|
@ -33,12 +34,15 @@
|
|||
#include "s_sound.h" // ditto
|
||||
#include "g_game.h" // ditto
|
||||
#include "p_local.h" // P_AutoPause()
|
||||
|
||||
#ifdef HWRENDER
|
||||
#include "hardware/hw_main.h"
|
||||
#include "hardware/hw_light.h"
|
||||
#include "hardware/hw_model.h"
|
||||
#endif
|
||||
|
||||
// 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
|
||||
|
@ -67,6 +71,7 @@ static CV_PossibleValue_t scr_depth_cons_t[] = {{8, "8 bits"}, {16, "16 bits"},
|
|||
consvar_t cv_scr_width = CVAR_INIT ("scr_width", "1280", CV_SAVE, CV_Unsigned, NULL);
|
||||
consvar_t cv_scr_height = CVAR_INIT ("scr_height", "800", CV_SAVE, CV_Unsigned, NULL);
|
||||
consvar_t cv_scr_depth = CVAR_INIT ("scr_depth", "16 bits", CV_SAVE, scr_depth_cons_t, NULL);
|
||||
|
||||
consvar_t cv_renderview = CVAR_INIT ("renderview", "On", 0, CV_OnOff, NULL);
|
||||
|
||||
CV_PossibleValue_t cv_renderer_t[] = {
|
||||
|
@ -447,46 +452,117 @@ 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;
|
||||
INT32 ticcntcolor = 0;
|
||||
const INT32 h = vid.height-(8*vid.dupy);
|
||||
UINT32 cap = R_GetFramerateCap();
|
||||
double fps = round(averageFPS);
|
||||
|
||||
if (gamestate == GS_NULL)
|
||||
return;
|
||||
|
||||
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 = V_REDMAP;
|
||||
else if (totaltics == TICRATE) ticcntcolor = V_GREENMAP;
|
||||
|
||||
if (cv_ticrate.value == 2) // compact counter
|
||||
V_DrawString(vid.width-(16*vid.dupx), h,
|
||||
ticcntcolor|V_NOSCALESTART|V_USERHUDTRANS, va("%02d", totaltics));
|
||||
else if (cv_ticrate.value == 1) // full counter
|
||||
if (cap > 0)
|
||||
{
|
||||
V_DrawString(vid.width-(72*vid.dupx), h,
|
||||
V_YELLOWMAP|V_NOSCALESTART|V_USERHUDTRANS, "FPS:");
|
||||
V_DrawString(vid.width-(40*vid.dupx), h,
|
||||
ticcntcolor|V_NOSCALESTART|V_USERHUDTRANS, va("%02d/%02u", totaltics, TICRATE));
|
||||
if (fps <= cap / 2.0) ticcntcolor = V_REDMAP;
|
||||
else if (fps <= cap * 0.90) ticcntcolor = V_YELLOWMAP;
|
||||
else ticcntcolor = V_GREENMAP;
|
||||
}
|
||||
else
|
||||
{
|
||||
ticcntcolor = V_GREENMAP;
|
||||
}
|
||||
|
||||
lasttic = ontic;
|
||||
if (cv_ticrate.value == 2) // compact counter
|
||||
{
|
||||
V_DrawRightAlignedString(vid.width, h,
|
||||
ticcntcolor|V_NOSCALESTART|V_USERHUDTRANS, va("%04.2f", averageFPS)); // use averageFPS directly
|
||||
}
|
||||
else if (cv_ticrate.value == 1) // full counter
|
||||
{
|
||||
const char *drawnstr;
|
||||
INT32 width;
|
||||
|
||||
// The highest assignable cap is < 1000, so 3 characters is fine.
|
||||
if (cap > 0)
|
||||
drawnstr = va("%3.0f/%3u", fps, cap);
|
||||
else
|
||||
drawnstr = va("%4.2f", averageFPS);
|
||||
|
||||
width = V_StringWidth(drawnstr, V_NOSCALESTART);
|
||||
|
||||
V_DrawString(vid.width - ((7 * 8 * vid.dupx) + V_StringWidth("FPS: ", V_NOSCALESTART)), h,
|
||||
V_YELLOWMAP|V_NOSCALESTART|V_USERHUDTRANS, "FPS:");
|
||||
V_DrawString(vid.width - width, h,
|
||||
ticcntcolor|V_NOSCALESTART|V_USERHUDTRANS, drawnstr);
|
||||
}
|
||||
}
|
||||
|
||||
void SCR_DisplayLocalPing(void)
|
||||
|
|
|
@ -182,6 +182,8 @@ extern viddef_t vid;
|
|||
extern INT32 setmodeneeded; // mode number to set if needed, or 0
|
||||
extern UINT8 setrenderneeded;
|
||||
|
||||
extern double averageFPS;
|
||||
|
||||
void SCR_ChangeRenderer(void);
|
||||
|
||||
extern CV_PossibleValue_t cv_renderer_t[];
|
||||
|
@ -192,6 +194,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_renderer, cv_fullscreen;
|
||||
// wait for page flipping to end or not
|
||||
extern consvar_t cv_vidwait;
|
||||
extern consvar_t cv_timescale;
|
||||
|
||||
// Initialize the screen
|
||||
void SCR_Startup(void);
|
||||
|
@ -211,6 +214,8 @@ void SCR_CheckDefaultMode(void);
|
|||
// Set the mode number which is saved in the config
|
||||
void SCR_SetDefaultMode(void);
|
||||
|
||||
void SCR_CalculateFPS(void);
|
||||
|
||||
FUNCMATH boolean SCR_IsAspectCorrect(INT32 width, INT32 height);
|
||||
|
||||
// move out to main code for consistency
|
||||
|
|
|
@ -181,6 +181,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"
|
||||
|
@ -196,7 +197,8 @@ static char returnWadPath[256];
|
|||
|
||||
#include "../m_argv.h"
|
||||
|
||||
#include "../m_menu.h"
|
||||
#include "../r_main.h" // Frame interpolation/uncapped
|
||||
#include "../r_fps.h"
|
||||
|
||||
#ifdef MAC_ALERT
|
||||
#include "macosx/mac_alert.h"
|
||||
|
@ -2153,52 +2155,78 @@ ticcmd_t *I_BaseTiccmd2(void)
|
|||
|
||||
static Uint64 timer_frequency;
|
||||
|
||||
static double tic_frequency;
|
||||
static Uint64 tic_epoch;
|
||||
|
||||
tic_t I_GetTime(void)
|
||||
{
|
||||
static double elapsed;
|
||||
|
||||
const Uint64 now = SDL_GetPerformanceCounter();
|
||||
|
||||
elapsed += (now - tic_epoch) / tic_frequency;
|
||||
tic_epoch = now; // moving epoch
|
||||
|
||||
return (tic_t)elapsed;
|
||||
}
|
||||
|
||||
precise_t I_GetPreciseTime(void)
|
||||
{
|
||||
return SDL_GetPerformanceCounter();
|
||||
}
|
||||
|
||||
int I_PreciseToMicros(precise_t d)
|
||||
UINT64 I_GetPrecisePrecision(void)
|
||||
{
|
||||
// d is going to be converted into a double. So remove the highest bits
|
||||
// to avoid loss of precision in the lower bits, for the (probably rare) case
|
||||
// that the higher bits are actually used.
|
||||
d &= ((precise_t)1 << 53) - 1; // The mantissa of a double can handle 53 bits at most.
|
||||
// The resulting double from the calculation is converted first to UINT64 to avoid overflow,
|
||||
// which is undefined behaviour when converting floating point values to integers.
|
||||
return (int)(UINT64)(d / (timer_frequency / 1000000.0));
|
||||
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)
|
||||
{
|
||||
// Shouldn't be used, but just in case...?
|
||||
frame_frequency = 1.0;
|
||||
return;
|
||||
}
|
||||
|
||||
frame_frequency = timer_frequency / (double)frame_rate;
|
||||
}
|
||||
|
||||
double I_GetFrameTime(void)
|
||||
{
|
||||
const UINT64 now = SDL_GetPerformanceCounter();
|
||||
const UINT32 cap = R_GetFramerateCap();
|
||||
|
||||
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
|
||||
{
|
||||
elapsed_frames += (now - frame_epoch) / frame_frequency;
|
||||
}
|
||||
|
||||
frame_epoch = now; // moving epoch
|
||||
return elapsed_frames;
|
||||
}
|
||||
|
||||
//
|
||||
//I_StartupTimer
|
||||
// I_StartupTimer
|
||||
//
|
||||
void I_StartupTimer(void)
|
||||
{
|
||||
timer_frequency = SDL_GetPerformanceFrequency();
|
||||
tic_epoch = SDL_GetPerformanceCounter();
|
||||
|
||||
tic_frequency = timer_frequency / (double)NEWTICRATE;
|
||||
I_InitFrameTime(0, R_GetFramerateCap());
|
||||
elapsed_frames = 0.0;
|
||||
}
|
||||
|
||||
void I_Sleep(void)
|
||||
void I_Sleep(UINT32 ms)
|
||||
{
|
||||
if (cv_sleep.value != -1)
|
||||
SDL_Delay(cv_sleep.value);
|
||||
SDL_Delay(ms);
|
||||
}
|
||||
|
||||
#ifdef NEWSIGNALHANDLER
|
||||
|
|
|
@ -1178,12 +1178,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)
|
||||
|
@ -1199,17 +1202,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;
|
||||
|
||||
|
@ -1228,27 +1234,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);
|
||||
}
|
||||
#ifdef HWRENDER
|
||||
|
@ -1257,6 +1258,7 @@ void I_FinishUpdate(void)
|
|||
OglSdlFinishUpdate(cv_vidwait.value);
|
||||
}
|
||||
#endif
|
||||
|
||||
exposevideo = SDL_FALSE;
|
||||
}
|
||||
|
||||
|
@ -1473,8 +1475,15 @@ static SDL_bool Impl_CreateContext(void)
|
|||
int flags = 0; // Use this to set SDL_RENDERER_* flags now
|
||||
if (usesdl2soft)
|
||||
flags |= SDL_RENDERER_SOFTWARE;
|
||||
#if 0
|
||||
// This shit is BROKEN.
|
||||
// - The version of SDL we're using cannot toggle VSync at runtime. We'll need a new SDL version implemented to have this work properly.
|
||||
// - cv_vidwait is initialized before config is loaded, so it's forced to default value at runtime, and forced off when switching. The config loading code would need restructured.
|
||||
// - With both this & frame interpolation on, I_FinishUpdate takes x10 longer. At this point, it is simpler to use a standard FPS cap.
|
||||
// So you can probably guess why I'm kinda over this, I'm just disabling it.
|
||||
else if (cv_vidwait.value)
|
||||
flags |= SDL_RENDERER_PRESENTVSYNC;
|
||||
#endif
|
||||
|
||||
if (!renderer)
|
||||
renderer = SDL_CreateRenderer(window, -1, flags);
|
||||
|
@ -1593,6 +1602,27 @@ boolean VID_CheckRenderer(void)
|
|||
return rendererchanged;
|
||||
}
|
||||
|
||||
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();
|
||||
|
@ -1610,6 +1640,11 @@ INT32 VID_SetMode(INT32 modeNum)
|
|||
vid.modenum = modeNum;
|
||||
|
||||
//Impl_SetWindowName("SRB2 "VERSIONSTRING);
|
||||
src_rect.w = vid.width;
|
||||
src_rect.h = vid.height;
|
||||
|
||||
refresh_rate = VID_GetRefreshRate();
|
||||
|
||||
VID_CheckRenderer();
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
@ -1961,3 +1996,13 @@ void I_GetCursorPosition(INT32 *x, INT32 *y)
|
|||
{
|
||||
SDL_GetMouseState(x, y);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -43,8 +43,11 @@
|
|||
#endif
|
||||
|
||||
#include "lua_hud.h"
|
||||
#include "lua_hudlib_drawlist.h"
|
||||
#include "lua_hook.h"
|
||||
|
||||
#include "r_fps.h"
|
||||
|
||||
UINT16 objectsdrawn = 0;
|
||||
|
||||
//
|
||||
|
@ -161,6 +164,9 @@ hudinfo_t hudinfo[NUMHUDITEMS] =
|
|||
{ 288, 176, V_SNAPTORIGHT|V_SNAPTOBOTTOM}, // HUD_POWERUPS
|
||||
};
|
||||
|
||||
static huddrawlist_h luahuddrawlist_game;
|
||||
static huddrawlist_h luahuddrawlist_titlecard;
|
||||
|
||||
//
|
||||
// STATUS BAR CODE
|
||||
//
|
||||
|
@ -420,6 +426,9 @@ void ST_Init(void)
|
|||
return;
|
||||
|
||||
ST_LoadGraphics();
|
||||
|
||||
luahuddrawlist_game = LUA_HUD_CreateDrawList();
|
||||
luahuddrawlist_titlecard = LUA_HUD_CreateDrawList();
|
||||
}
|
||||
|
||||
// change the status bar too, when pressing F12 while viewing a demo.
|
||||
|
@ -1402,7 +1411,12 @@ void ST_drawTitleCard(void)
|
|||
lt_lasttic = lt_ticker;
|
||||
|
||||
luahook:
|
||||
LUA_HUDHOOK(titlecard);
|
||||
if (renderisnewtic)
|
||||
{
|
||||
LUA_HUD_ClearDrawList(luahuddrawlist_titlecard);
|
||||
LUA_HUDHOOK(titlecard, luahuddrawlist_titlecard);
|
||||
}
|
||||
LUA_HUD_DrawList(luahuddrawlist_titlecard);
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -2526,7 +2540,7 @@ static void ST_doHuntIconsAndSound(void)
|
|||
interval = newinterval;
|
||||
}
|
||||
|
||||
if (!(P_AutoPause() || paused) && interval > 0 && leveltime && leveltime % interval == 0)
|
||||
if (!(P_AutoPause() || paused) && interval > 0 && leveltime && leveltime % interval == 0 && renderisnewtic)
|
||||
S_StartSound(NULL, sfx_emfind);
|
||||
}
|
||||
|
||||
|
@ -2588,7 +2602,7 @@ static void ST_doItemFinderIconsAndSound(void)
|
|||
|
||||
}
|
||||
|
||||
if (!(P_AutoPause() || paused) && interval > 0 && leveltime && leveltime % interval == 0)
|
||||
if (!(P_AutoPause() || paused) && interval > 0 && leveltime && leveltime % interval == 0 && renderisnewtic)
|
||||
S_StartSound(NULL, sfx_emfind);
|
||||
}
|
||||
|
||||
|
@ -2742,7 +2756,12 @@ static void ST_overlayDrawer(void)
|
|||
ST_drawPowerupHUD(); // same as it ever was...
|
||||
|
||||
if (!(netgame || multiplayer) || !hu_showscores)
|
||||
LUA_HUDHOOK(game);
|
||||
{
|
||||
if (renderisnewtic)
|
||||
{
|
||||
LUA_HUDHOOK(game, luahuddrawlist_game);
|
||||
}
|
||||
}
|
||||
|
||||
// draw level title Tails
|
||||
if (stagetitle && (!WipeInAction) && (!WipeStageTitle))
|
||||
|
@ -2820,6 +2839,10 @@ void ST_Drawer(void)
|
|||
|
||||
if (st_overlay)
|
||||
{
|
||||
if (renderisnewtic)
|
||||
{
|
||||
LUA_HUD_ClearDrawList(luahuddrawlist_game);
|
||||
}
|
||||
// No deadview!
|
||||
stplyr = &players[displayplayer];
|
||||
ST_overlayDrawer();
|
||||
|
@ -2829,5 +2852,7 @@ void ST_Drawer(void)
|
|||
stplyr = &players[secondarydisplayplayer];
|
||||
ST_overlayDrawer();
|
||||
}
|
||||
|
||||
LUA_HUD_DrawList(luahuddrawlist_game);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
#include "r_textures.h"
|
||||
#include "r_patch.h"
|
||||
#include "r_picformats.h"
|
||||
#include "i_time.h"
|
||||
#include "i_system.h"
|
||||
#include "i_video.h" // rendermode
|
||||
#include "md5.h"
|
||||
|
|
102
src/y_inter.c
102
src/y_inter.c
|
@ -38,6 +38,7 @@
|
|||
#include "lua_hook.h" // IntermissionThinker hook
|
||||
|
||||
#include "lua_hud.h"
|
||||
#include "lua_hudlib_drawlist.h"
|
||||
|
||||
#ifdef HWRENDER
|
||||
#include "hardware/hw_main.h"
|
||||
|
@ -83,6 +84,10 @@ typedef union
|
|||
INT32 passedx3;
|
||||
INT32 passedx4;
|
||||
|
||||
INT32 emeraldbounces;
|
||||
INT32 emeraldmomy;
|
||||
INT32 emeraldy;
|
||||
|
||||
y_bonus_t bonuses[2];
|
||||
patch_t *bonuspatches[2];
|
||||
|
||||
|
@ -161,6 +166,8 @@ static INT32 endtic = -1;
|
|||
intertype_t intertype = int_none;
|
||||
intertype_t intermissiontypes[NUMGAMETYPES];
|
||||
|
||||
static huddrawlist_h luahuddrawlist_intermission;
|
||||
|
||||
static void Y_RescaleScreenBuffer(void);
|
||||
static void Y_AwardCoopBonuses(void);
|
||||
static void Y_AwardSpecialStageBonus(void);
|
||||
|
@ -429,7 +436,13 @@ void Y_IntermissionDrawer(void)
|
|||
else if (bgtile)
|
||||
V_DrawPatchFill(bgtile);
|
||||
|
||||
LUA_HUDHOOK(intermission);
|
||||
if (renderisnewtic)
|
||||
{
|
||||
LUA_HUD_ClearDrawList(luahuddrawlist_intermission);
|
||||
LUA_HUDHOOK(intermission, luahuddrawlist_intermission);
|
||||
}
|
||||
LUA_HUD_DrawList(luahuddrawlist_intermission);
|
||||
|
||||
if (!LUA_HudEnabled(hud_intermissiontally))
|
||||
goto skiptallydrawer;
|
||||
|
||||
|
@ -646,7 +659,6 @@ void Y_IntermissionDrawer(void)
|
|||
}
|
||||
|
||||
// draw the emeralds
|
||||
//if (intertic & 1)
|
||||
if (LUA_HudEnabled(hud_intermissionemeralds))
|
||||
{
|
||||
boolean drawthistic = !(ALL7EMERALDS(emeralds) && (intertic & 1));
|
||||
|
@ -663,10 +675,6 @@ void Y_IntermissionDrawer(void)
|
|||
}
|
||||
else if (em < 7)
|
||||
{
|
||||
static UINT8 emeraldbounces = 0;
|
||||
static INT32 emeraldmomy = 20;
|
||||
static INT32 emeraldy = -40;
|
||||
|
||||
if (drawthistic)
|
||||
for (i = 0; i < 7; ++i)
|
||||
{
|
||||
|
@ -677,45 +685,15 @@ void Y_IntermissionDrawer(void)
|
|||
|
||||
emeraldx = 152 + (em-3)*28;
|
||||
|
||||
if (intertic <= 1)
|
||||
if (intertic > 1)
|
||||
{
|
||||
emeraldbounces = 0;
|
||||
emeraldmomy = 20;
|
||||
emeraldy = -40;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!stagefailed)
|
||||
if (stagefailed && data.spec.emeraldy < (vid.height/vid.dupy)+16)
|
||||
{
|
||||
if (emeraldbounces < 3)
|
||||
{
|
||||
emeraldy += (++emeraldmomy);
|
||||
if (emeraldy > 74)
|
||||
{
|
||||
S_StartSound(NULL, sfx_tink); // tink
|
||||
emeraldbounces++;
|
||||
emeraldmomy = -(emeraldmomy/2);
|
||||
emeraldy = 74;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (emeraldy < (vid.height/vid.dupy)+16)
|
||||
{
|
||||
emeraldy += (++emeraldmomy);
|
||||
emeraldx += intertic - 6;
|
||||
}
|
||||
if (emeraldbounces < 1 && emeraldy > 74)
|
||||
{
|
||||
S_StartSound(NULL, sfx_shldls); // nope
|
||||
emeraldbounces++;
|
||||
emeraldmomy = -(emeraldmomy/2);
|
||||
emeraldy = 74;
|
||||
}
|
||||
emeraldx += intertic - 6;
|
||||
}
|
||||
|
||||
if (drawthistic)
|
||||
V_DrawScaledPatch(emeraldx, emeraldy, 0, emeraldpics[0][em]);
|
||||
V_DrawScaledPatch(emeraldx, data.spec.emeraldy, 0, emeraldpics[0][em]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1153,6 +1131,45 @@ void Y_Ticker(void)
|
|||
S_ChangeMusicInternal("_clear", false); // don't loop it
|
||||
tallydonetic = -1;
|
||||
}
|
||||
|
||||
// emerald bounce
|
||||
if (intertic <= 1)
|
||||
{
|
||||
data.spec.emeraldbounces = 0;
|
||||
data.spec.emeraldmomy = 20;
|
||||
data.spec.emeraldy = -40;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!stagefailed)
|
||||
{
|
||||
if (data.spec.emeraldbounces < 3)
|
||||
{
|
||||
data.spec.emeraldy += (++data.spec.emeraldmomy);
|
||||
if (data.spec.emeraldy > 74)
|
||||
{
|
||||
S_StartSound(NULL, sfx_tink); // tink
|
||||
data.spec.emeraldbounces++;
|
||||
data.spec.emeraldmomy = -(data.spec.emeraldmomy/2);
|
||||
data.spec.emeraldy = 74;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (data.spec.emeraldy < (vid.height/vid.dupy)+16)
|
||||
{
|
||||
data.spec.emeraldy += (++data.spec.emeraldmomy);
|
||||
}
|
||||
if (data.spec.emeraldbounces < 1 && data.spec.emeraldy > 74)
|
||||
{
|
||||
S_StartSound(NULL, sfx_shldls); // nope
|
||||
data.spec.emeraldbounces++;
|
||||
data.spec.emeraldmomy = -(data.spec.emeraldmomy/2);
|
||||
data.spec.emeraldy = 74;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (intertic < 2*TICRATE) // TWO second pause before tally begins, thank you mazmazz
|
||||
return;
|
||||
|
@ -1583,6 +1600,9 @@ void Y_StartIntermission(void)
|
|||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
LUA_HUD_DestroyDrawList(luahuddrawlist_intermission);
|
||||
luahuddrawlist_intermission = LUA_HUD_CreateDrawList();
|
||||
}
|
||||
|
||||
//
|
||||
|
|
Loading…
Reference in a new issue