Merge branch 'master' of https://git.do.srb2.org/KartKrew/Kart.git into testers

This commit is contained in:
toaster 2022-01-20 19:29:10 +00:00
commit 66d8989531
24 changed files with 246 additions and 118 deletions

View file

@ -8,6 +8,11 @@ else
EXENAME?=srb2kart64.exe EXENAME?=srb2kart64.exe
endif endif
# disable dynamicbase if under msys2
ifdef MSYSTEM
libs+=-Wl,--disable-dynamicbase
endif
sources+=win32/Srb2win.rc sources+=win32/Srb2win.rc
opts+=-DSTDC_HEADERS opts+=-DSTDC_HEADERS
libs+=-ladvapi32 -lkernel32 -lmsvcrt -luser32 libs+=-ladvapi32 -lkernel32 -lmsvcrt -luser32

View file

@ -5235,8 +5235,10 @@ static void SV_Maketic(void)
maketic++; maketic++;
} }
void TryRunTics(tic_t realtics) boolean TryRunTics(tic_t realtics)
{ {
boolean ticking;
// the machine has lagged but it is not so bad // the machine has lagged but it is not so bad
if (realtics > TICRATE/7) // FIXME: consistency failure!! if (realtics > TICRATE/7) // FIXME: consistency failure!!
{ {
@ -5280,7 +5282,9 @@ void TryRunTics(tic_t realtics)
} }
#endif #endif
if (neededtic > gametic) ticking = neededtic > gametic;
if (ticking)
{ {
if (realtics) if (realtics)
hu_stopped = false; hu_stopped = false;
@ -5290,10 +5294,10 @@ void TryRunTics(tic_t realtics)
{ {
if (realtics) if (realtics)
hu_stopped = true; hu_stopped = true;
return; return false;
} }
if (neededtic > gametic) if (ticking)
{ {
if (advancedemo) if (advancedemo)
{ {
@ -5330,6 +5334,8 @@ void TryRunTics(tic_t realtics)
if (realtics) if (realtics)
hu_stopped = true; hu_stopped = true;
} }
return ticking;
} }

View file

@ -488,7 +488,7 @@ boolean Playing(void);
void D_QuitNetGame(void); void D_QuitNetGame(void);
//? How many ticks to run? //? How many ticks to run?
void TryRunTics(tic_t realtic); boolean TryRunTics(tic_t realtic);
// extra data for lmps // extra data for lmps
// these functions scare me. they contain magic. // these functions scare me. they contain magic.

View file

@ -293,6 +293,8 @@ static void D_Display(void)
{ {
for (i = 0; i <= r_splitscreen; ++i) for (i = 0; i <= r_splitscreen; ++i)
{ {
R_SetViewContext(VIEWCONTEXT_PLAYER1 + i);
R_InterpolateViewRollAngle(rendertimefrac);
R_CheckViewMorph(i); R_CheckViewMorph(i);
} }
} }
@ -685,6 +687,7 @@ tic_t rendergametic;
void D_SRB2Loop(void) void D_SRB2Loop(void)
{ {
tic_t oldentertics = 0, entertic = 0, realtics = 0, rendertimeout = INFTICS; tic_t oldentertics = 0, entertic = 0, realtics = 0, rendertimeout = INFTICS;
boolean ticked;
if (dedicated) if (dedicated)
server = true; server = true;
@ -772,11 +775,23 @@ void D_SRB2Loop(void)
realtics = 1; realtics = 1;
// process tics (but maybe not if realtic == 0) // process tics (but maybe not if realtic == 0)
TryRunTics(realtics); ticked = TryRunTics(realtics);
if (cv_frameinterpolation.value == 1 && !(paused || P_AutoPause() || hu_stopped)) if (cv_frameinterpolation.value == 1 && !(paused || P_AutoPause()))
{ {
fixed_t entertimefrac = I_GetTimeFrac(); static float tictime;
float entertime = I_GetTimeFrac();
fixed_t entertimefrac;
if (ticked)
tictime = entertime;
if (aproxfps < 35.0)
entertimefrac = FRACUNIT;
else
entertimefrac = FLOAT_TO_FIXED(entertime - tictime);
// renderdeltatics is a bit awkard to evaluate, since the system time interface is whole tic-based // renderdeltatics is a bit awkard to evaluate, since the system time interface is whole tic-based
renderdeltatics = realtics * FRACUNIT; renderdeltatics = realtics * FRACUNIT;
if (entertimefrac > rendertimefrac) if (entertimefrac > rendertimefrac)

View file

@ -290,6 +290,12 @@ typedef struct botvars_s
tic_t spindashconfirm; // When high enough, they will try spindashing tic_t spindashconfirm; // When high enough, they will try spindashing
} botvars_t; } botvars_t;
// player_t struct for all skybox variables
typedef struct {
mobj_t * viewpoint;
mobj_t * centerpoint;
} skybox_t;
// ======================================================================== // ========================================================================
// PLAYER STRUCTURE // PLAYER STRUCTURE
// ======================================================================== // ========================================================================
@ -311,6 +317,8 @@ typedef struct player_s
// bounded/scaled total momentum. // bounded/scaled total momentum.
fixed_t bob; fixed_t bob;
skybox_t skybox;
angle_t viewrollangle; angle_t viewrollangle;
angle_t old_viewrollangle; angle_t old_viewrollangle;
// camera tilt // camera tilt

View file

@ -60,7 +60,7 @@ boolean nodrawers; // for comparative timing purposes
boolean noblit; // for comparative timing purposes boolean noblit; // for comparative timing purposes
tic_t demostarttime; // for comparative timing purposes tic_t demostarttime; // for comparative timing purposes
static char demoname[128]; static char demoname[MAX_WADPATH];
static UINT8 *demobuffer = NULL; static UINT8 *demobuffer = NULL;
static UINT8 *demotime_p, *demoinfo_p; static UINT8 *demotime_p, *demoinfo_p;
UINT8 *demo_p; UINT8 *demo_p;
@ -3791,7 +3791,7 @@ void G_SaveDemo(void)
demo_slug[strindex] = 0; demo_slug[strindex] = 0;
if (dash) demo_slug[strindex-1] = 0; if (dash) demo_slug[strindex-1] = 0;
writepoint = strstr(demoname, "-") + 1; writepoint = strstr(strrchr(demoname, *PATHSEP), "-") + 1;
demo_slug[128 - (writepoint - demoname) - 4] = 0; demo_slug[128 - (writepoint - demoname) - 4] = 0;
sprintf(writepoint, "%s.lmp", demo_slug); sprintf(writepoint, "%s.lmp", demo_slug);
} }
@ -3808,7 +3808,7 @@ void G_SaveDemo(void)
md5_buffer((char *)p+16, (demobuffer + length) - (p+16), p); md5_buffer((char *)p+16, (demobuffer + length) - (p+16), p);
#endif #endif
if (FIL_WriteFile(va(pandf, srb2home, demoname), demobuffer, demo_p - demobuffer)) // finally output the file. if (FIL_WriteFile(demoname, demobuffer, demo_p - demobuffer)) // finally output the file.
demo.savemode = DSM_SAVED; demo.savemode = DSM_SAVED;
free(demobuffer); free(demobuffer);
demo.recording = false; demo.recording = false;

View file

@ -6221,7 +6221,7 @@ void HWR_RenderPlayerView(void)
const float fpov = FIXED_TO_FLOAT(cv_fov[viewssnum].value+player->fovadd); const float fpov = FIXED_TO_FLOAT(cv_fov[viewssnum].value+player->fovadd);
postimg_t *type = &postimgtype[viewssnum]; postimg_t *type = &postimgtype[viewssnum];
const boolean skybox = (skyboxmo[0] && cv_skybox.value); // True if there's a skybox object and skyboxes are on const boolean skybox = (player->skybox.viewpoint && cv_skybox.value); // True if there's a skybox object and skyboxes are on
FRGBAFloat ClearColor; FRGBAFloat ClearColor;

View file

@ -46,9 +46,9 @@ UINT32 I_GetFreeMem(UINT32 *total);
*/ */
tic_t I_GetTime(void); tic_t I_GetTime(void);
/** \brief Get the current time as a fraction of a tic since the last tic. /** \brief Get the current time in tics including fractions.
*/ */
fixed_t I_GetTimeFrac(void); float I_GetTimeFrac(void);
/** \brief Returns precise time value for performance measurement. /** \brief Returns precise time value for performance measurement.
*/ */

View file

@ -3811,7 +3811,7 @@ static mobj_t *K_SpawnKartMissile(mobj_t *source, mobjtype_t type, angle_t an, I
y = source->y + source->momy + FixedMul(finalspeed, FINESINE(an>>ANGLETOFINESHIFT)); y = source->y + source->momy + FixedMul(finalspeed, FINESINE(an>>ANGLETOFINESHIFT));
z = source->z; // spawn on the ground please z = source->z; // spawn on the ground please
th = P_SpawnMobj(x, y, z, type); th = P_SpawnMobj(x, y, z, type); // this will never return null because collision isn't processed here
K_FlipFromObject(th, source); K_FlipFromObject(th, source);
@ -3830,7 +3830,10 @@ static mobj_t *K_SpawnKartMissile(mobj_t *source, mobjtype_t type, angle_t an, I
{ {
// floorz and ceilingz aren't properly set to account for FOFs and Polyobjects on spawn // floorz and ceilingz aren't properly set to account for FOFs and Polyobjects on spawn
// This should set it for FOFs // This should set it for FOFs
P_SetOrigin(th, th->x, th->y, th->z); P_SetOrigin(th, th->x, th->y, th->z); // however, THIS can fuck up your day. just absolutely ruin you.
if (P_MobjWasRemoved(th))
return NULL;
// spawn on the ground if the player is on the ground // spawn on the ground if the player is on the ground
if (P_MobjFlip(source) < 0) if (P_MobjFlip(source) < 0)
{ {
@ -3898,7 +3901,7 @@ static mobj_t *K_SpawnKartMissile(mobj_t *source, mobjtype_t type, angle_t an, I
P_SetTarget(&throwmo->target, source); P_SetTarget(&throwmo->target, source);
} }
return NULL; return th;
} }
UINT16 K_DriftSparkColor(player_t *player, INT32 charge) UINT16 K_DriftSparkColor(player_t *player, INT32 charge)
@ -4705,10 +4708,11 @@ mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t mapthing,
{ {
if (mapthing == MT_BALLHOG) // Messy if (mapthing == MT_BALLHOG) // Messy
{ {
mo = NULL; // can't return multiple projectiles
if (dir == -1) if (dir == -1)
{ {
// Shoot backward // Shoot backward
mo = K_SpawnKartMissile(player->mo, mapthing, (player->mo->angle + ANGLE_180) - 0x06000000, 0, PROJSPEED/8); K_SpawnKartMissile(player->mo, mapthing, (player->mo->angle + ANGLE_180) - 0x06000000, 0, PROJSPEED/8);
K_SpawnKartMissile(player->mo, mapthing, (player->mo->angle + ANGLE_180) - 0x03000000, 0, PROJSPEED/8); K_SpawnKartMissile(player->mo, mapthing, (player->mo->angle + ANGLE_180) - 0x03000000, 0, PROJSPEED/8);
K_SpawnKartMissile(player->mo, mapthing, player->mo->angle + ANGLE_180, 0, PROJSPEED/8); K_SpawnKartMissile(player->mo, mapthing, player->mo->angle + ANGLE_180, 0, PROJSPEED/8);
K_SpawnKartMissile(player->mo, mapthing, (player->mo->angle + ANGLE_180) + 0x03000000, 0, PROJSPEED/8); K_SpawnKartMissile(player->mo, mapthing, (player->mo->angle + ANGLE_180) + 0x03000000, 0, PROJSPEED/8);
@ -4717,7 +4721,7 @@ mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t mapthing,
else else
{ {
// Shoot forward // Shoot forward
mo = K_SpawnKartMissile(player->mo, mapthing, player->mo->angle - 0x06000000, 0, PROJSPEED); K_SpawnKartMissile(player->mo, mapthing, player->mo->angle - 0x06000000, 0, PROJSPEED);
K_SpawnKartMissile(player->mo, mapthing, player->mo->angle - 0x03000000, 0, PROJSPEED); K_SpawnKartMissile(player->mo, mapthing, player->mo->angle - 0x03000000, 0, PROJSPEED);
K_SpawnKartMissile(player->mo, mapthing, player->mo->angle, 0, PROJSPEED); K_SpawnKartMissile(player->mo, mapthing, player->mo->angle, 0, PROJSPEED);
K_SpawnKartMissile(player->mo, mapthing, player->mo->angle + 0x03000000, 0, PROJSPEED); K_SpawnKartMissile(player->mo, mapthing, player->mo->angle + 0x03000000, 0, PROJSPEED);
@ -5329,6 +5333,9 @@ void K_KillBananaChain(mobj_t *banana, mobj_t *inflictor, mobj_t *source)
mobj_t *cachenext; mobj_t *cachenext;
killnext: killnext:
if (P_MobjWasRemoved(banana))
return;
cachenext = banana->hnext; cachenext = banana->hnext;
if (banana->health) if (banana->health)

View file

@ -2015,8 +2015,12 @@ static int lib_pSetSkyboxMobj(lua_State *L)
if (w > 1 || w < 0) if (w > 1 || w < 0)
return luaL_error(L, "skybox mobj index %d is out of range for P_SetSkyboxMobj argument #2 (expected 0 or 1)", w); return luaL_error(L, "skybox mobj index %d is out of range for P_SetSkyboxMobj argument #2 (expected 0 or 1)", w);
#if 0
if (!user || P_IsLocalPlayer(user)) if (!user || P_IsLocalPlayer(user))
skyboxmo[w] = mo; skyboxmo[w] = mo;
#else
CONS_Alert(CONS_WARNING, "TODO: P_SetSkyboxMobj is unimplemented\n");
#endif
return 0; return 0;
} }

View file

@ -2555,26 +2555,25 @@ const char *M_FileError(FILE *fp)
/** Return the number of parts of this path. /** Return the number of parts of this path.
*/ */
int M_PathParts(const char *path) int M_PathParts(const char *p)
{ {
int n; int parts = 0;
const char *p;
const char *t; if (p == NULL)
if (path == NULL)
return 0; return 0;
for (n = 0, p = path ;; ++n)
#ifdef _WIN32
if (!strncmp(&p[1], ":\\", 2))
p += 3;
#endif
while (*(p += strspn(p, PATHSEP)))
{ {
t = p; parts++;
if (( p = strchr(p, PATHSEP[0]) )) p += strcspn(p, PATHSEP);
p += strspn(p, PATHSEP);
else
{
if (*t)/* there is something after the final delimiter */
n++;
break;
}
} }
return n;
return parts;
} }
/** Check whether a path is an absolute path. /** Check whether a path is an absolute path.
@ -2592,50 +2591,43 @@ boolean M_IsPathAbsolute(const char *path)
*/ */
void M_MkdirEachUntil(const char *cpath, int start, int end, int mode) void M_MkdirEachUntil(const char *cpath, int start, int end, int mode)
{ {
char path[MAX_WADPATH]; char path[256];
char *p; char *p;
char *t; int n;
int c;
if (end > 0 && end <= start) if (end > 0 && end <= start)
return; return;
strlcpy(path, cpath, sizeof path); strlcpy(path, cpath, sizeof path);
#ifdef _WIN32 #ifdef _WIN32
if (strncmp(&path[1], ":\\", 2) == 0) if (!strncmp(&path[1], ":\\", 2))
p = &path[3]; p = &path[3];
else else
#endif #endif
p = path; p = path;
if (end > 0) while (end != 0 && *(p += strspn(p, PATHSEP)))
end -= start;
for (; start > 0; --start)
{ {
p += strspn(p, PATHSEP); n = strcspn(p, PATHSEP);
if (!( p = strchr(p, PATHSEP[0]) ))
return;
}
p += strspn(p, PATHSEP);
for (;;)
{
if (end > 0 && !--end)
break;
t = p; if (start > 0)
if (( p = strchr(p, PATHSEP[0]) )) start--;
{
*p = '\0';
I_mkdir(path, mode);
*p = PATHSEP[0];
p += strspn(p, PATHSEP);
}
else else
{ {
if (*t) c = p[n];
I_mkdir(path, mode); p[n] = '\0';
break;
I_mkdir(path, mode);
p[n] = c;
} }
p += n;
if (end > 0)
end--;
} }
} }
@ -2697,4 +2689,4 @@ const char * M_Ftrim (double f)
dig[i + 1] = '\0'; dig[i + 1] = '\0';
return &dig[1];/* skip the 0 */ return &dig[1];/* skip the 0 */
} }
} }

View file

@ -3496,6 +3496,9 @@ void P_SlideMove(mobj_t *mo)
vertex_t v1, v2; // fake vertexes vertex_t v1, v2; // fake vertexes
line_t junk; // fake linedef line_t junk; // fake linedef
if (P_MobjWasRemoved(mo))
return;
if (tmhitthing && mo->z + mo->height > tmhitthing->z && mo->z < tmhitthing->z + tmhitthing->height) if (tmhitthing && mo->z + mo->height > tmhitthing->z && mo->z < tmhitthing->z + tmhitthing->height)
{ {
// Don't mess with your momentum if it's a pushable object. Pushables do their own crazy things already. // Don't mess with your momentum if it's a pushable object. Pushables do their own crazy things already.

View file

@ -1689,6 +1689,8 @@ void P_XYMovement(mobj_t *mo)
if (mo->flags & MF_SLIDEME) if (mo->flags & MF_SLIDEME)
{ {
P_SlideMove(mo); P_SlideMove(mo);
if (P_MobjWasRemoved(mo))
return;
xmove = ymove = 0; xmove = ymove = 0;
} }
else else
@ -10867,6 +10869,9 @@ void P_SpawnPlayer(INT32 playernum)
p->awayviewmobj = NULL; p->awayviewmobj = NULL;
p->awayviewtics = 0; p->awayviewtics = 0;
p->skybox.viewpoint = skyboxviewpnts[0];
p->skybox.centerpoint = skyboxcenterpnts[0];
P_SetTarget(&p->follower, NULL); // cleanse follower from existence P_SetTarget(&p->follower, NULL); // cleanse follower from existence
// set the scale to the mobj's destscale so settings get correctly set. if we don't, they sometimes don't. // set the scale to the mobj's destscale so settings get correctly set. if we don't, they sometimes don't.

View file

@ -60,6 +60,8 @@ typedef enum
AWAYVIEW = 0x01, AWAYVIEW = 0x01,
FOLLOWITEM = 0x02, FOLLOWITEM = 0x02,
FOLLOWER = 0x04, FOLLOWER = 0x04,
SKYBOXVIEW = 0x08,
SKYBOXCENTER = 0x10,
} player_saveflags; } player_saveflags;
static inline void P_ArchivePlayer(void) static inline void P_ArchivePlayer(void)
@ -178,6 +180,12 @@ static void P_NetArchivePlayers(void)
if (players[i].follower) if (players[i].follower)
flags |= FOLLOWER; flags |= FOLLOWER;
if (players[i].skybox.viewpoint)
flags |= SKYBOXVIEW;
if (players[i].skybox.centerpoint)
flags |= SKYBOXCENTER;
WRITEINT16(save_p, players[i].lastsidehit); WRITEINT16(save_p, players[i].lastsidehit);
WRITEINT16(save_p, players[i].lastlinehit); WRITEINT16(save_p, players[i].lastlinehit);
@ -190,6 +198,12 @@ static void P_NetArchivePlayers(void)
WRITEUINT16(save_p, flags); WRITEUINT16(save_p, flags);
if (flags & SKYBOXVIEW)
WRITEUINT32(save_p, players[i].skybox.viewpoint->mobjnum);
if (flags & SKYBOXCENTER)
WRITEUINT32(save_p, players[i].skybox.centerpoint->mobjnum);
if (flags & AWAYVIEW) if (flags & AWAYVIEW)
WRITEUINT32(save_p, players[i].awayviewmobj->mobjnum); WRITEUINT32(save_p, players[i].awayviewmobj->mobjnum);
@ -447,6 +461,12 @@ static void P_NetUnArchivePlayers(void)
flags = READUINT16(save_p); flags = READUINT16(save_p);
if (flags & SKYBOXVIEW)
players[i].skybox.viewpoint = (mobj_t *)(size_t)READUINT32(save_p);
if (flags & SKYBOXCENTER)
players[i].skybox.centerpoint = (mobj_t *)(size_t)READUINT32(save_p);
if (flags & AWAYVIEW) if (flags & AWAYVIEW)
players[i].awayviewmobj = (mobj_t *)(size_t)READUINT32(save_p); players[i].awayviewmobj = (mobj_t *)(size_t)READUINT32(save_p);
@ -4130,6 +4150,20 @@ static void P_RelinkPointers(void)
} }
if (mobj->player) if (mobj->player)
{ {
if ( mobj->player->skybox.viewpoint)
{
temp = (UINT32)(size_t)mobj->player->skybox.viewpoint;
mobj->player->skybox.viewpoint = NULL;
if (!P_SetTarget(&mobj->player->skybox.viewpoint, P_FindNewPosition(temp)))
CONS_Debug(DBG_GAMELOGIC, "skybox.viewpoint not found on %d\n", mobj->type);
}
if ( mobj->player->skybox.centerpoint)
{
temp = (UINT32)(size_t)mobj->player->skybox.centerpoint;
mobj->player->skybox.centerpoint = NULL;
if (!P_SetTarget(&mobj->player->skybox.centerpoint, P_FindNewPosition(temp)))
CONS_Debug(DBG_GAMELOGIC, "skybox.centerpoint not found on %d\n", mobj->type);
}
if ( mobj->player->awayviewmobj) if ( mobj->player->awayviewmobj)
{ {
temp = (UINT32)(size_t)mobj->player->awayviewmobj; temp = (UINT32)(size_t)mobj->player->awayviewmobj;

View file

@ -3514,6 +3514,7 @@ static void P_InitLevelSettings(void)
speedscramble = encorescramble = -1; speedscramble = encorescramble = -1;
} }
#if 0
// Respawns all the mapthings and mobjs in the map from the already loaded map data. // Respawns all the mapthings and mobjs in the map from the already loaded map data.
void P_RespawnThings(void) void P_RespawnThings(void)
{ {
@ -3548,6 +3549,7 @@ void P_RespawnThings(void)
skyboxmo[0] = skyboxviewpnts[(viewid >= 0) ? viewid : 0]; skyboxmo[0] = skyboxviewpnts[(viewid >= 0) ? viewid : 0];
skyboxmo[1] = skyboxcenterpnts[(centerid >= 0) ? centerid : 0]; skyboxmo[1] = skyboxcenterpnts[(centerid >= 0) ? centerid : 0];
} }
#endif
static void P_RunLevelScript(const char *scriptname) static void P_RunLevelScript(const char *scriptname)
{ {
@ -3622,14 +3624,19 @@ static void P_ResetSpawnpoints(void)
// reset the player starts // reset the player starts
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < MAXPLAYERS; i++)
{
playerstarts[i] = bluectfstarts[i] = redctfstarts[i] = NULL; playerstarts[i] = bluectfstarts[i] = redctfstarts[i] = NULL;
if (playeringame[i])
{
players[i].skybox.viewpoint = NULL;
players[i].skybox.centerpoint = NULL;
}
}
for (i = 0; i < MAX_DM_STARTS; i++) for (i = 0; i < MAX_DM_STARTS; i++)
deathmatchstarts[i] = NULL; deathmatchstarts[i] = NULL;
for (i = 0; i < 2; i++)
skyboxmo[i] = NULL;
for (i = 0; i < 16; i++) for (i = 0; i < 16; i++)
skyboxviewpnts[i] = skyboxcenterpnts[i] = NULL; skyboxviewpnts[i] = skyboxcenterpnts[i] = NULL;
} }
@ -3798,12 +3805,20 @@ static void P_InitGametype(void)
//@TODO I'd like to fix dedis crashing when recording replays for the future too... //@TODO I'd like to fix dedis crashing when recording replays for the future too...
if (!demo.playback && multiplayer && !dedicated) if (!demo.playback && multiplayer && !dedicated)
{ {
static char buf[256]; char buf[MAX_WADPATH];
char *path; char ver[128];
sprintf(buf, "media"PATHSEP"replay"PATHSEP"online"PATHSEP"%d-%s", (int) (time(NULL)), G_BuildMapName(gamemap)); int parts;
path = va("%s"PATHSEP"media"PATHSEP"replay"PATHSEP"online", srb2home); #ifdef DEVELOP
M_MkdirEach(path, M_PathParts(path) - 4, 0755); sprintf(ver, "%s-%s", compbranch, comprevision);
#else
strcpy(ver, VERSIONSTRING);
#endif
sprintf(buf, "%s"PATHSEP"media"PATHSEP"replay"PATHSEP"online"PATHSEP"%s"PATHSEP"%d-%s",
srb2home, ver, (int) (time(NULL)), G_BuildMapName(gamemap));
parts = M_PathParts(buf);
M_MkdirEachUntil(buf, parts - 5, parts - 1, 0755);
G_RecordDemo(buf); G_RecordDemo(buf);
} }
@ -4068,8 +4083,6 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate)
P_SpawnSpecialsAfterSlopes(); P_SpawnSpecialsAfterSlopes();
P_SpawnMapThings(!fromnetsave); P_SpawnMapThings(!fromnetsave);
skyboxmo[0] = skyboxviewpnts[0];
skyboxmo[1] = skyboxcenterpnts[0];
for (numcoopstarts = 0; numcoopstarts < MAXPLAYERS; numcoopstarts++) for (numcoopstarts = 0; numcoopstarts < MAXPLAYERS; numcoopstarts++)
if (!playerstarts[numcoopstarts]) if (!playerstarts[numcoopstarts])

View file

@ -52,7 +52,6 @@
// Not sure if this is necessary, but it was in w_wad.c, so I'm putting it here too -Shadow Hog // Not sure if this is necessary, but it was in w_wad.c, so I'm putting it here too -Shadow Hog
#include <errno.h> #include <errno.h>
mobj_t *skyboxmo[2]; // current skybox mobjs: 0 = viewpoint, 1 = centerpoint
mobj_t *skyboxviewpnts[16]; // array of MT_SKYBOX viewpoint mobjs mobj_t *skyboxviewpnts[16]; // array of MT_SKYBOX viewpoint mobjs
mobj_t *skyboxcenterpnts[16]; // array of MT_SKYBOX centerpoint mobjs mobj_t *skyboxcenterpnts[16]; // array of MT_SKYBOX centerpoint mobjs
@ -2090,6 +2089,19 @@ static mobj_t *P_GetObjectTypeInSectorNum(mobjtype_t type, size_t s)
return NULL; return NULL;
} }
static void P_SwitchSkybox(INT32 ldflags, player_t *player, skybox_t *skybox)
{
if (!(ldflags & ML_EFFECT4)) // Solid Midtexture turns off viewpoint setting
{
player->skybox.viewpoint = skybox->viewpoint;
}
if (ldflags & ML_BLOCKPLAYERS) // Block Enemies turns ON centerpoint setting
{
player->skybox.centerpoint = skybox->centerpoint;
}
}
/** Processes the line special triggered by an object. /** Processes the line special triggered by an object.
* *
* \param line Line with the special command on it. * \param line Line with the special command on it.
@ -3155,7 +3167,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
break; break;
} }
case 448: // Change skybox viewpoint/centerpoint case 448: // Change skybox viewpoint/centerpoint
if ((mo && mo->player && P_IsLocalPlayer(mo->player)) || (line->flags & ML_NOCLIMB)) if ((mo && mo->player) || (line->flags & ML_NOCLIMB))
{ {
INT32 viewid = sides[line->sidenum[0]].textureoffset>>FRACBITS; INT32 viewid = sides[line->sidenum[0]].textureoffset>>FRACBITS;
INT32 centerid = sides[line->sidenum[0]].rowoffset>>FRACBITS; INT32 centerid = sides[line->sidenum[0]].rowoffset>>FRACBITS;
@ -3168,23 +3180,32 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
} }
else else
{ {
skybox_t skybox;
// set viewpoint mobj // set viewpoint mobj
if (!(line->flags & ML_EFFECT4)) // Solid Midtexture turns off viewpoint setting if (viewid >= 0 && viewid < 16)
{ skybox.viewpoint = skyboxviewpnts[viewid];
if (viewid >= 0 && viewid < 16) else
skyboxmo[0] = skyboxviewpnts[viewid]; skybox.viewpoint = NULL;
else
skyboxmo[0] = NULL;
}
// set centerpoint mobj // set centerpoint mobj
if (line->flags & ML_BLOCKPLAYERS) // Block Enemies turns ON centerpoint setting if (centerid >= 0 && centerid < 16)
skybox.centerpoint = skyboxcenterpnts[centerid];
else
skybox.centerpoint = NULL;
if (line->flags & ML_NOCLIMB) // Applies to all players
{ {
if (centerid >= 0 && centerid < 16) INT32 i;
skyboxmo[1] = skyboxcenterpnts[centerid];
else for (i = 0; i < MAXPLAYERS; ++i)
skyboxmo[1] = NULL; {
if (playeringame[i])
P_SwitchSkybox(line->flags, &players[i], &skybox);
}
} }
else
P_SwitchSkybox(line->flags, mo->player, &skybox);
} }
CONS_Debug(DBG_GAMELOGIC, "Line type 448 Executor: viewid = %d, centerid = %d, viewpoint? = %s, centerpoint? = %s\n", CONS_Debug(DBG_GAMELOGIC, "Line type 448 Executor: viewid = %d, centerid = %d, viewpoint? = %s, centerpoint? = %s\n",
@ -3599,6 +3620,10 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
INT32 delay = (sides[line->sidenum[0]].rowoffset>>FRACBITS); INT32 delay = (sides[line->sidenum[0]].rowoffset>>FRACBITS);
if (mo && mo->player) if (mo && mo->player)
{ {
// Don't award rings while SPB is targetting you
if (mo->player->pflags & PF_RINGLOCK)
return;
if (delay <= 0 || !(leveltime % delay)) if (delay <= 0 || !(leveltime % delay))
P_GivePlayerRings(mo->player, rings); P_GivePlayerRings(mo->player, rings);
} }

View file

@ -17,7 +17,6 @@
#ifndef __P_SPEC__ #ifndef __P_SPEC__
#define __P_SPEC__ #define __P_SPEC__
extern mobj_t *skyboxmo[2]; // current skybox mobjs: 0 = viewpoint, 1 = centerpoint
extern mobj_t *skyboxviewpnts[16]; // array of MT_SKYBOX viewpoint mobjs extern mobj_t *skyboxviewpnts[16]; // array of MT_SKYBOX viewpoint mobjs
extern mobj_t *skyboxcenterpnts[16]; // array of MT_SKYBOX centerpoint mobjs extern mobj_t *skyboxcenterpnts[16]; // array of MT_SKYBOX centerpoint mobjs

View file

@ -80,12 +80,19 @@ static void R_SetupFreelook(player_t *player, boolean skybox)
#undef AIMINGTODY #undef AIMINGTODY
void R_InterpolateViewRollAngle(fixed_t frac)
{
viewroll = oldview->roll + R_LerpAngle(oldview->roll, newview->roll, frac);
}
void R_InterpolateView(fixed_t frac) void R_InterpolateView(fixed_t frac)
{ {
if (frac < 0) if (frac < 0)
frac = 0; frac = 0;
#if 0
if (frac > FRACUNIT) if (frac > FRACUNIT)
frac = FRACUNIT; frac = FRACUNIT;
#endif
viewx = oldview->x + R_LerpFixed(oldview->x, newview->x, frac); viewx = oldview->x + R_LerpFixed(oldview->x, newview->x, frac);
viewy = oldview->y + R_LerpFixed(oldview->y, newview->y, frac); viewy = oldview->y + R_LerpFixed(oldview->y, newview->y, frac);
@ -93,7 +100,7 @@ void R_InterpolateView(fixed_t frac)
viewangle = oldview->angle + R_LerpAngle(oldview->angle, newview->angle, frac); viewangle = oldview->angle + R_LerpAngle(oldview->angle, newview->angle, frac);
aimingangle = oldview->aim + R_LerpAngle(oldview->aim, newview->aim, frac); aimingangle = oldview->aim + R_LerpAngle(oldview->aim, newview->aim, frac);
viewroll = oldview->roll + R_LerpAngle(oldview->roll, newview->roll, frac); R_InterpolateViewRollAngle(frac);
viewsin = FINESINE(viewangle>>ANGLETOFINESHIFT); viewsin = FINESINE(viewangle>>ANGLETOFINESHIFT);
viewcos = FINECOSINE(viewangle>>ANGLETOFINESHIFT); viewcos = FINECOSINE(viewangle>>ANGLETOFINESHIFT);

View file

@ -51,6 +51,8 @@ extern viewvars_t *newview;
// Interpolates the current view variables (r_state.h) against the selected view context in R_SetViewContext // Interpolates the current view variables (r_state.h) against the selected view context in R_SetViewContext
void R_InterpolateView(fixed_t frac); void R_InterpolateView(fixed_t frac);
// Special function just for software
void R_InterpolateViewRollAngle(fixed_t frac);
// Buffer the current new views into the old views. Call once after each real tic. // Buffer the current new views into the old views. Call once after each real tic.
void R_UpdateViewInterpolation(void); void R_UpdateViewInterpolation(void);
// Set the current view context (the viewvars pointed to by newview) // Set the current view context (the viewvars pointed to by newview)

View file

@ -28,7 +28,7 @@
#include "am_map.h" #include "am_map.h"
#include "d_main.h" #include "d_main.h"
#include "v_video.h" #include "v_video.h"
#include "p_spec.h" // skyboxmo //#include "p_spec.h"
#include "p_setup.h" #include "p_setup.h"
#include "z_zone.h" #include "z_zone.h"
#include "m_random.h" // quake camera shake #include "m_random.h" // quake camera shake
@ -1331,7 +1331,7 @@ void R_SkyboxFrame(player_t *player)
// cut-away view stuff // cut-away view stuff
newview->sky = true; newview->sky = true;
r_viewmobj = skyboxmo[0]; r_viewmobj = player->skybox.viewpoint;
#ifdef PARANOIA #ifdef PARANOIA
if (!r_viewmobj) if (!r_viewmobj)
{ {
@ -1372,6 +1372,7 @@ void R_SkyboxFrame(player_t *player)
{ {
mapheader_t *mh = mapheaderinfo[gamemap-1]; mapheader_t *mh = mapheaderinfo[gamemap-1];
vector3_t campos = {0,0,0}; // Position of player's actual view point vector3_t campos = {0,0,0}; // Position of player's actual view point
mobj_t *center = player->skybox.centerpoint;
if (player->awayviewtics) { if (player->awayviewtics) {
campos.x = player->awayviewmobj->x; campos.x = player->awayviewmobj->x;
@ -1393,18 +1394,18 @@ void R_SkyboxFrame(player_t *player)
campos.y += quake.y; campos.y += quake.y;
campos.z += quake.z; campos.z += quake.z;
if (skyboxmo[1]) // Is there a viewpoint? if (center) // Is there a viewpoint?
{ {
fixed_t x = 0, y = 0; fixed_t x = 0, y = 0;
if (mh->skybox_scalex > 0) if (mh->skybox_scalex > 0)
x = (campos.x - skyboxmo[1]->x) / mh->skybox_scalex; x = (campos.x - center->x) / mh->skybox_scalex;
else if (mh->skybox_scalex < 0) else if (mh->skybox_scalex < 0)
x = (campos.x - skyboxmo[1]->x) * -mh->skybox_scalex; x = (campos.x - center->x) * -mh->skybox_scalex;
if (mh->skybox_scaley > 0) if (mh->skybox_scaley > 0)
y = (campos.y - skyboxmo[1]->y) / mh->skybox_scaley; y = (campos.y - center->y) / mh->skybox_scaley;
else if (mh->skybox_scaley < 0) else if (mh->skybox_scaley < 0)
y = (campos.y - skyboxmo[1]->y) * -mh->skybox_scaley; y = (campos.y - center->y) * -mh->skybox_scaley;
if (r_viewmobj->angle == 0) if (r_viewmobj->angle == 0)
{ {
@ -1617,8 +1618,8 @@ void R_RenderPlayerView(void)
// Add skybox portals caused by sky visplanes. // Add skybox portals caused by sky visplanes.
if (cv_skybox.value && skyboxmo[0]) if (cv_skybox.value && player->skybox.viewpoint)
Portal_AddSkyboxPortals(); Portal_AddSkyboxPortals(player);
// Portal rendering. Hijacks the BSP traversal. // Portal rendering. Hijacks the BSP traversal.
ps_sw_portaltime = I_GetPreciseTime(); ps_sw_portaltime = I_GetPreciseTime();

View file

@ -127,6 +127,4 @@ typedef struct planemgr_s
extern visffloor_t ffloor[MAXFFLOORS]; extern visffloor_t ffloor[MAXFFLOORS];
extern INT32 numffloors; extern INT32 numffloors;
void Portal_AddSkyboxPortals (void);
#endif #endif

View file

@ -256,12 +256,17 @@ static boolean TrimVisplaneBounds (const visplane_t* plane, INT16* start, INT16*
* Applies the necessary offsets and rotation to give * Applies the necessary offsets and rotation to give
* a depth illusion to the skybox. * a depth illusion to the skybox.
*/ */
void Portal_AddSkybox (const visplane_t* plane) void Portal_AddSkybox
( const player_t * player,
const visplane_t * plane)
{ {
INT16 start, end; INT16 start, end;
mapheader_t *mh; mapheader_t *mh;
portal_t* portal; portal_t* portal;
mobj_t *viewpoint = player->skybox.viewpoint;
mobj_t *center = player->skybox.centerpoint;
if (TrimVisplaneBounds(plane, &start, &end)) if (TrimVisplaneBounds(plane, &start, &end))
return; return;
@ -269,28 +274,28 @@ void Portal_AddSkybox (const visplane_t* plane)
Portal_ClipVisplane(plane, portal); Portal_ClipVisplane(plane, portal);
portal->viewx = skyboxmo[0]->x; portal->viewx = viewpoint->x;
portal->viewy = skyboxmo[0]->y; portal->viewy = viewpoint->y;
portal->viewz = skyboxmo[0]->z; portal->viewz = viewpoint->z;
portal->viewangle = viewangle + skyboxmo[0]->angle; portal->viewangle = viewangle + viewpoint->angle;
mh = mapheaderinfo[gamemap-1]; mh = mapheaderinfo[gamemap-1];
// If a relative viewpoint exists, offset the viewpoint. // If a relative viewpoint exists, offset the viewpoint.
if (skyboxmo[1]) if (center)
{ {
fixed_t x = 0, y = 0; fixed_t x = 0, y = 0;
angle_t ang = skyboxmo[0]->angle>>ANGLETOFINESHIFT; angle_t ang = viewpoint->angle>>ANGLETOFINESHIFT;
if (mh->skybox_scalex > 0) if (mh->skybox_scalex > 0)
x = (viewx - skyboxmo[1]->x) / mh->skybox_scalex; x = (viewx - center->x) / mh->skybox_scalex;
else if (mh->skybox_scalex < 0) else if (mh->skybox_scalex < 0)
x = (viewx - skyboxmo[1]->x) * -mh->skybox_scalex; x = (viewx - center->x) * -mh->skybox_scalex;
if (mh->skybox_scaley > 0) if (mh->skybox_scaley > 0)
y = (viewy - skyboxmo[1]->y) / mh->skybox_scaley; y = (viewy - center->y) / mh->skybox_scaley;
else if (mh->skybox_scaley < 0) else if (mh->skybox_scaley < 0)
y = (viewy - skyboxmo[1]->y) * -mh->skybox_scaley; y = (viewy - center->y) * -mh->skybox_scaley;
// Apply transform to account for the skybox viewport angle. // Apply transform to account for the skybox viewport angle.
portal->viewx += FixedMul(x,FINECOSINE(ang)) - FixedMul(y, FINESINE(ang)); portal->viewx += FixedMul(x,FINECOSINE(ang)) - FixedMul(y, FINESINE(ang));
@ -308,7 +313,7 @@ void Portal_AddSkybox (const visplane_t* plane)
/** Creates portals for the currently existing sky visplanes. /** Creates portals for the currently existing sky visplanes.
* The visplanes are also removed and cleared from the list. * The visplanes are also removed and cleared from the list.
*/ */
void Portal_AddSkyboxPortals (void) void Portal_AddSkyboxPortals (const player_t *player)
{ {
visplane_t *pl; visplane_t *pl;
INT32 i; INT32 i;
@ -320,7 +325,7 @@ void Portal_AddSkyboxPortals (void)
{ {
if (pl->picnum == skyflatnum) if (pl->picnum == skyflatnum)
{ {
Portal_AddSkybox(pl); Portal_AddSkybox(player, pl);
pl->minx = 0; pl->minx = 0;
pl->maxx = -1; pl->maxx = -1;

View file

@ -52,10 +52,10 @@ extern INT32 portalclipstart, portalclipend;
void Portal_InitList (void); void Portal_InitList (void);
void Portal_Remove (portal_t* portal); void Portal_Remove (portal_t* portal);
void Portal_Add2Lines (const INT32 line1, const INT32 line2, const INT32 x1, const INT32 x2); void Portal_Add2Lines (const INT32 line1, const INT32 line2, const INT32 x1, const INT32 x2);
void Portal_AddSkybox (const visplane_t* plane); void Portal_AddSkybox (const player_t* player, const visplane_t* plane);
void Portal_ClipRange (portal_t* portal); void Portal_ClipRange (portal_t* portal);
void Portal_ClipApply (const portal_t* portal); void Portal_ClipApply (const portal_t* portal);
void Portal_AddSkyboxPortals (void); void Portal_AddSkyboxPortals (const player_t* player);
#endif #endif

View file

@ -1658,11 +1658,10 @@ tic_t I_GetTime(void)
return (tic_t)f; return (tic_t)f;
} }
fixed_t I_GetTimeFrac(void) float I_GetTimeFrac(void)
{ {
UpdateElapsedTics(); UpdateElapsedTics();
return elapsed_tics;
return FLOAT_TO_FIXED((float) (elapsed_tics - floor(elapsed_tics)));
} }
precise_t I_GetPreciseTime(void) precise_t I_GetPreciseTime(void)