Merge branch 'udmf-argenums' into udmf-fofs-mkii

This commit is contained in:
MascaraSnake 2020-04-18 17:23:02 +02:00
commit 8e5effa07b
63 changed files with 3355 additions and 3521 deletions

View file

@ -738,12 +738,6 @@ linedeftypes
flags2text = "[1] Use control sector tag";
flags64text = "[6] No sound effect";
}
65
{
title = "Bridge Thinker <disabled>";
prefix = "(65)";
}
}
polyobject

View file

@ -1857,7 +1857,7 @@ udmf
4 = "Subtract light G";
8 = "Subtract light B";
16 = "Subtract light A";
32 = "Subtract light R";
32 = "Subtract fade R";
64 = "Subtract fade G";
128 = "Subtract fade B";
256 = "Subtract fade A";
@ -1897,7 +1897,7 @@ udmf
4 = "Subtract light G";
8 = "Subtract light B";
16 = "Subtract light A";
32 = "Subtract light R";
32 = "Subtract fade R";
64 = "Subtract fade G";
128 = "Subtract fade B";
256 = "Subtract fade A";

View file

@ -16,6 +16,7 @@ set(SRB2_CORE_SOURCES
f_finale.c
f_wipe.c
filesrch.c
g_demo.c
g_game.c
g_input.c
hu_stuff.c
@ -71,6 +72,7 @@ set(SRB2_CORE_HEADERS
f_finale.h
fastcmp.h
filesrch.h
g_demo.h
g_game.h
g_input.h
g_state.h

View file

@ -422,6 +422,7 @@ OBJS:=$(i_main_o) \
$(OBJDIR)/z_zone.o \
$(OBJDIR)/f_finale.o \
$(OBJDIR)/f_wipe.o \
$(OBJDIR)/g_demo.o \
$(OBJDIR)/g_game.o \
$(OBJDIR)/g_input.o \
$(OBJDIR)/am_map.o \

View file

@ -19,10 +19,10 @@ boolean allow_fullscreen = false;
consvar_t cv_vidwait = {"vid_wait", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
void I_StartupGraphics(void){}
void I_StartupHardwareGraphics(void){}
void I_ShutdownGraphics(void){}
void VID_StartupOpenGL(void){}
void I_SetPalette(RGBA_t *palette)
{
(void)palette;
@ -52,10 +52,8 @@ INT32 VID_SetMode(INT32 modenum)
return 0;
}
void VID_CheckRenderer(void)
{
// ..............
}
void VID_CheckRenderer(void) {}
void VID_CheckGLLoaded(rendermode_t oldrender) {}
const char *VID_GetModeName(INT32 modenum)
{

View file

@ -459,6 +459,21 @@ boolean B_CheckRespawn(player_t *player)
if (!sonic || sonic->health <= 0)
return false;
#ifdef HAVE_BLUA
// B_RespawnBot doesn't do anything if the condition above this isn't met
{
UINT8 shouldForce = LUAh_BotRespawn(sonic, tails);
if (P_MobjWasRemoved(sonic) || P_MobjWasRemoved(tails))
return (shouldForce == 1); // mobj was removed
if (shouldForce == 1)
return true;
else if (shouldForce == 2)
return false;
}
#endif
// Check if Sonic is busy first.
// If he's doing any of these things, he probably doesn't want to see us.
if (sonic->player->pflags & (PF_GLIDING|PF_SLIDING|PF_BOUNCING)

View file

@ -97,6 +97,7 @@ static void CON_InputInit(void);
static void CON_RecalcSize(void);
static void CON_ChangeHeight(void);
static void CON_DrawBackpic(void);
static void CONS_hudlines_Change(void);
static void CONS_backcolor_Change(void);
@ -1530,6 +1531,51 @@ static void CON_DrawHudlines(void)
con_clearlines = y; // this is handled by HU_Erase();
}
// Lactozilla: Draws the console's background picture.
static void CON_DrawBackpic(void)
{
patch_t *con_backpic;
lumpnum_t piclump;
int x, w, h;
// Get the lumpnum for CONSBACK, or fallback into MISSING.
piclump = W_CheckNumForName("CONSBACK");
if (piclump == LUMPERROR)
piclump = W_GetNumForName("MISSING");
// Cache the Software patch.
con_backpic = W_CacheSoftwarePatchNum(piclump, PU_PATCH);
// Center the backpic, and draw a vertically cropped patch.
w = (con_backpic->width * vid.dupx);
x = (vid.width / 2) - (w / 2);
h = con_curlines/vid.dupy;
// If the patch doesn't fill the entire screen,
// then fill the sides with a solid color.
if (x > 0)
{
column_t *column = (column_t *)((UINT8 *)(con_backpic) + LONG(con_backpic->columnofs[0]));
if (!column->topdelta)
{
UINT8 *source = (UINT8 *)(column) + 3;
INT32 color = (source[0] | V_NOSCALESTART);
// left side
V_DrawFill(0, 0, x, con_curlines, color);
// right side
V_DrawFill((x + w), 0, (vid.width - w), con_curlines, color);
}
}
// Cache the patch normally.
con_backpic = W_CachePatchNum(piclump, PU_PATCH);
V_DrawCroppedPatch(x << FRACBITS, 0, FRACUNIT, V_NOSCALESTART, con_backpic,
0, ( BASEVIDHEIGHT - h ), BASEVIDWIDTH, h);
// Unlock the cached patch.
W_UnlockCachedPatch(con_backpic);
}
// draw the console background, text, and prompt if enough place
//
static void CON_DrawConsole(void)
@ -1551,19 +1597,7 @@ static void CON_DrawConsole(void)
// draw console background
if (cons_backpic.value || con_forcepic)
{
patch_t *con_backpic = W_CachePatchName("CONSBACK", PU_PATCH);
int h;
h = con_curlines/vid.dupy;
// Jimita: CON_DrawBackpic just called V_DrawScaledPatch
//V_DrawScaledPatch(0, 0, 0, con_backpic);
V_DrawCroppedPatch(0, 0, FRACUNIT, 0, con_backpic,
0, ( BASEVIDHEIGHT - h ), BASEVIDWIDTH, h);
W_UnlockCachedPatch(con_backpic);
}
CON_DrawBackpic();
else
{
// inu: no more width (was always 0 and vid.width)

View file

@ -1338,7 +1338,7 @@ static void SV_SendServerInfo(INT32 node, tic_t servertime)
netbuffer->u.serverinfo.numberofplayer = (UINT8)D_NumPlayers();
netbuffer->u.serverinfo.maxplayer = (UINT8)cv_maxplayers.value;
if (FindRejoinerNum(node) != -1)
if (!node || FindRejoinerNum(node) != -1)
netbuffer->u.serverinfo.refusereason = 0;
else if (!cv_allownewplayer.value)
netbuffer->u.serverinfo.refusereason = 1;
@ -4875,7 +4875,8 @@ static inline void PingUpdate(void)
{
for (i = 1; i < MAXPLAYERS; i++)
{
if (playeringame[i] && (realpingtable[i] / pingmeasurecount > (unsigned)cv_maxping.value))
if (playeringame[i] && !players[i].quittime
&& (realpingtable[i] / pingmeasurecount > (unsigned)cv_maxping.value))
{
if (players[i].jointime > 30 * TICRATE)
laggers[i] = true;
@ -4894,8 +4895,8 @@ static inline void PingUpdate(void)
if (playeringame[i] && laggers[i])
{
pingtimeout[i]++;
// ok your net has been bad for too long, you deserve to die.
if (pingtimeout[i] > cv_pingtimeout.value)
// ok your net has been bad for too long, you deserve to die.
{
pingtimeout[i] = 0;
SendKick(i, KICK_MSG_PING_HIGH | KICK_MSG_KEEP_BODY);

View file

@ -1284,11 +1284,10 @@ void D_SRB2Main(void)
// Set cv_renderer to the new render mode
VID_CheckRenderer();
SCR_ChangeRendererCVars(setrenderneeded);
SCR_ChangeRendererCVars(rendermode);
// check the renderer's state, and then clear setrenderneeded
// check the renderer's state
D_CheckRendererState();
setrenderneeded = 0;
}
wipegamestate = gamestate;

View file

@ -1252,7 +1252,7 @@ static void SendNameAndColor(void)
players[consoleplayer].skincolor = cv_playercolor.value;
if (players[consoleplayer].mo)
if (players[consoleplayer].mo && !players[consoleplayer].powers[pw_dye])
players[consoleplayer].mo->color = players[consoleplayer].skincolor;
if (metalrecording)
@ -1364,8 +1364,9 @@ static void SendNameAndColor2(void)
if (botingame)
{
players[secondplaya].skincolor = botcolor;
if (players[secondplaya].mo)
if (players[secondplaya].mo && !players[secondplaya].powers[pw_dye])
players[secondplaya].mo->color = players[secondplaya].skincolor;
SetPlayerSkinByNum(secondplaya, botskin-1);
return;
}
@ -1378,7 +1379,7 @@ static void SendNameAndColor2(void)
// don't use secondarydisplayplayer: the second player must be 1
players[secondplaya].skincolor = cv_playercolor2.value;
if (players[secondplaya].mo)
if (players[secondplaya].mo && !players[secondplaya].powers[pw_dye])
players[secondplaya].mo->color = players[secondplaya].skincolor;
if (cv_forceskin.value >= 0 && (netgame || multiplayer)) // Server wants everyone to use the same player

View file

@ -48,6 +48,7 @@ typedef enum
SF_FASTEDGE = 1<<12, // Faster edge teeter?
SF_MULTIABILITY = 1<<13, // Revenge of Final Demo.
SF_NONIGHTSROTATION = 1<<14, // Disable sprite rotation for NiGHTS
SF_NONIGHTSSUPER = 1<<15, // Disable super colors for NiGHTS (if you have SF_SUPER)
// free up to and including 1<<31
} skinflags_t;
@ -278,6 +279,9 @@ typedef enum
pw_nights_linkfreeze,
pw_nocontrol, //for linedef exec 427
pw_dye, // for dyes
pw_justlaunched, // Launched off a slope this tic (0=none, 1=standard launch, 2=half-pipe launch)
NUMPOWERS

View file

@ -2909,6 +2909,7 @@ static actionpointer_t actionpointers[] =
{{A_SetRandomTics}, "A_SETRANDOMTICS"},
{{A_ChangeColorRelative}, "A_CHANGECOLORRELATIVE"},
{{A_ChangeColorAbsolute}, "A_CHANGECOLORABSOLUTE"},
{{A_Dye}, "A_DYE"},
{{A_MoveRelative}, "A_MOVERELATIVE"},
{{A_MoveAbsolute}, "A_MOVEABSOLUTE"},
{{A_Thrust}, "A_THRUST"},
@ -9132,7 +9133,11 @@ static const char *const POWERS_LIST[] = {
//for linedef exec 427
"NOCONTROL",
"JUSTLAUNCHED",
//for dyes
"DYE",
"JUSTLAUNCHED"
};
static const char *const HUDITEMS_LIST[] = {
@ -9467,6 +9472,7 @@ struct {
{"SF_FASTEDGE",SF_FASTEDGE},
{"SF_MULTIABILITY",SF_MULTIABILITY},
{"SF_NONIGHTSROTATION",SF_NONIGHTSROTATION},
{"SF_NONIGHTSSUPER",SF_NONIGHTSSUPER},
// Dashmode constants
{"DASHMODE_THRESHOLD",DASHMODE_THRESHOLD},
@ -9648,11 +9654,11 @@ struct {
{"FF_CUTEXTRA",FF_CUTEXTRA}, ///< Cuts out hidden translucent pixels.
{"FF_CUTLEVEL",FF_CUTLEVEL}, ///< Cuts out all hidden pixels.
{"FF_CUTSPRITES",FF_CUTSPRITES}, ///< Final step in making 3D water.
{"FF_BOTHPLANES",FF_BOTHPLANES}, ///< Renders both planes all the time.
{"FF_BOTHPLANES",FF_BOTHPLANES}, ///< Render inside and outside planes.
{"FF_EXTRA",FF_EXTRA}, ///< Gets cut by ::FF_CUTEXTRA.
{"FF_TRANSLUCENT",FF_TRANSLUCENT}, ///< See through!
{"FF_FOG",FF_FOG}, ///< Fog "brush."
{"FF_INVERTPLANES",FF_INVERTPLANES}, ///< Reverse the plane visibility rules.
{"FF_INVERTPLANES",FF_INVERTPLANES}, ///< Only render inside planes.
{"FF_ALLSIDES",FF_ALLSIDES}, ///< Render inside and outside sides.
{"FF_INVERTSIDES",FF_INVERTSIDES}, ///< Only render inside sides.
{"FF_DOUBLESHADOW",FF_DOUBLESHADOW}, ///< Make two lightlist entries to reset light?

View file

@ -339,7 +339,4 @@ void I_StartupGraphics(void)
}
void I_StartupHardwareGraphics(void)
{
// oh yeah woo yeah oh yeah woo yeah oh yeah woo yeah oh yeah woo yeah oh yeah woo yeah oh yeah woo yeah oh yeah woo y
}
void VID_StartupOpenGL(void) {}

View file

@ -378,10 +378,8 @@ INT32 VID_SetMode (INT32 modenum) //, UINT8 *palette)
return 1;
}
void VID_CheckRenderer(void)
{
// ..............
}
void VID_CheckRenderer(void) {}
void VID_CheckGLLoaded(rendermode_t oldrender) {}

View file

@ -11,10 +11,10 @@ boolean allow_fullscreen = false;
consvar_t cv_vidwait = {"vid_wait", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
void I_StartupGraphics(void){}
void I_StartupHardwareGraphics(void){}
void I_ShutdownGraphics(void){}
void VID_StartupOpenGL(void){}
void I_SetPalette(RGBA_t *palette)
{
(void)palette;
@ -40,10 +40,8 @@ INT32 VID_SetMode(INT32 modenum)
return 0;
}
void VID_CheckRenderer(void)
{
// ..............
}
void VID_CheckRenderer(void) {}
void VID_CheckGLLoaded(rendermode_t oldrender) {}
const char *VID_GetModeName(INT32 modenum)
{

2501
src/g_demo.c Normal file

File diff suppressed because it is too large Load diff

86
src/g_demo.h Normal file
View file

@ -0,0 +1,86 @@
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
// Copyright (C) 1993-1996 by id Software, Inc.
// Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2020 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 g_demo.h
/// \brief Demo recording and playback
#ifndef __G_DEMO__
#define __G_DEMO__
#include "doomdef.h"
#include "doomstat.h"
#include "d_event.h"
// ======================================
// DEMO playback/recording related stuff.
// ======================================
// demoplaying back and demo recording
extern boolean demoplayback, titledemo, demorecording, timingdemo;
extern tic_t demostarttime;
// Quit after playing a demo from cmdline.
extern boolean singledemo;
extern boolean demo_start;
extern boolean demosynced;
extern mobj_t *metalplayback;
// Only called by startup code.
void G_RecordDemo(const char *name);
void G_RecordMetal(void);
void G_BeginRecording(void);
void G_BeginMetal(void);
// Only called by shutdown code.
void G_SetDemoTime(UINT32 ptime, UINT32 pscore, UINT16 prings);
UINT8 G_CmpDemoTime(char *oldname, char *newname);
typedef enum
{
GHC_NORMAL = 0,
GHC_SUPER,
GHC_FIREFLOWER,
GHC_INVINCIBLE,
GHC_NIGHTSSKIN, // not actually a colour
GHC_RETURNSKIN // ditto
} ghostcolor_t;
// Record/playback tics
void G_ReadDemoTiccmd(ticcmd_t *cmd, INT32 playernum);
void G_WriteDemoTiccmd(ticcmd_t *cmd, INT32 playernum);
void G_GhostAddThok(void);
void G_GhostAddSpin(void);
void G_GhostAddRev(void);
void G_GhostAddColor(ghostcolor_t color);
void G_GhostAddFlip(void);
void G_GhostAddScale(fixed_t scale);
void G_GhostAddHit(mobj_t *victim);
void G_WriteGhostTic(mobj_t *ghost);
void G_ConsGhostTic(void);
void G_GhostTicker(void);
void G_ReadMetalTic(mobj_t *metal);
void G_WriteMetalTic(mobj_t *metal);
void G_SaveMetal(UINT8 **buffer);
void G_LoadMetal(UINT8 **buffer);
void G_DeferedPlayDemo(const char *demo);
void G_DoPlayDemo(char *defdemoname);
void G_TimeDemo(const char *name);
void G_AddGhost(char *defdemoname);
void G_FreeGhosts(void);
void G_DoPlayMetal(void);
void G_DoneLevelLoad(void);
void G_StopMetalDemo(void);
ATTRNORETURN void FUNCNORETURN G_StopMetalRecording(boolean kill);
void G_StopDemo(void);
boolean G_CheckDemoStatus(void);
#endif // __G_DEMO__

File diff suppressed because it is too large Load diff

View file

@ -17,6 +17,7 @@
#include "doomdef.h"
#include "doomstat.h"
#include "d_event.h"
#include "g_demo.h"
extern char gamedatafilename[64];
extern char timeattackfolder[64];
@ -31,21 +32,6 @@ extern char player_names[MAXPLAYERS][MAXPLAYERNAME+1];
extern player_t players[MAXPLAYERS];
extern boolean playeringame[MAXPLAYERS];
// ======================================
// DEMO playback/recording related stuff.
// ======================================
// demoplaying back and demo recording
extern boolean demoplayback, titledemo, demorecording, timingdemo;
extern tic_t demostarttime;
// Quit after playing a demo from cmdline.
extern boolean singledemo;
extern boolean demo_start;
extern boolean demosynced;
extern mobj_t *metalplayback;
// gametic at level start
extern tic_t levelstarttic;
@ -173,7 +159,6 @@ void G_DoLoadLevel(boolean resetplayer);
void G_StartTitleCard(void);
void G_PreLevelTitleCard(void);
boolean G_IsTitleCardAvailable(void);
void G_DeferedPlayDemo(const char *demo);
// Can be called by the startup code or M_Responder, calls P_SetupLevel.
void G_LoadGame(UINT32 slot, INT16 mapoverride);
@ -184,54 +169,6 @@ void G_SaveGame(UINT32 slot);
void G_SaveGameOver(UINT32 slot, boolean modifylives);
// Only called by startup code.
void G_RecordDemo(const char *name);
void G_RecordMetal(void);
void G_BeginRecording(void);
void G_BeginMetal(void);
// Only called by shutdown code.
void G_SetDemoTime(UINT32 ptime, UINT32 pscore, UINT16 prings);
UINT8 G_CmpDemoTime(char *oldname, char *newname);
typedef enum
{
GHC_NORMAL = 0,
GHC_SUPER,
GHC_FIREFLOWER,
GHC_INVINCIBLE,
GHC_NIGHTSSKIN, // not actually a colour
GHC_RETURNSKIN // ditto
} ghostcolor_t;
// Record/playback tics
void G_ReadDemoTiccmd(ticcmd_t *cmd, INT32 playernum);
void G_WriteDemoTiccmd(ticcmd_t *cmd, INT32 playernum);
void G_GhostAddThok(void);
void G_GhostAddSpin(void);
void G_GhostAddRev(void);
void G_GhostAddColor(ghostcolor_t color);
void G_GhostAddFlip(void);
void G_GhostAddScale(fixed_t scale);
void G_GhostAddHit(mobj_t *victim);
void G_WriteGhostTic(mobj_t *ghost);
void G_ConsGhostTic(void);
void G_GhostTicker(void);
void G_ReadMetalTic(mobj_t *metal);
void G_WriteMetalTic(mobj_t *metal);
void G_SaveMetal(UINT8 **buffer);
void G_LoadMetal(UINT8 **buffer);
void G_DoPlayDemo(char *defdemoname);
void G_TimeDemo(const char *name);
void G_AddGhost(char *defdemoname);
void G_DoPlayMetal(void);
void G_DoneLevelLoad(void);
void G_StopMetalDemo(void);
ATTRNORETURN void FUNCNORETURN G_StopMetalRecording(boolean kill);
void G_StopDemo(void);
boolean G_CheckDemoStatus(void);
extern UINT32 gametypedefaultrules[NUMGAMETYPES];
extern UINT32 gametypetol[NUMGAMETYPES];
extern INT16 gametyperankings[NUMGAMETYPES];

View file

@ -291,7 +291,7 @@ void HWR_DrawStretchyFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t
if (cx >= -0.1f && cx <= 0.1f && SHORT(gpatch->width) == BASEVIDWIDTH && cy >= -0.1f && cy <= 0.1f && SHORT(gpatch->height) == BASEVIDHEIGHT)
{
// Need to temporarily cache the real patch to get the colour of the top left pixel
patch_t *realpatch = W_CacheLumpNumPwad(gpatch->wadnum, gpatch->lumpnum, PU_STATIC);
patch_t *realpatch = W_CacheSoftwarePatchNumPwad(gpatch->wadnum, gpatch->lumpnum, PU_STATIC);
const column_t *column = (const column_t *)((const UINT8 *)(realpatch) + LONG((realpatch)->columnofs[0]));
if (!column->topdelta)
{
@ -450,7 +450,7 @@ void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscal
if (cx >= -0.1f && cx <= 0.1f && SHORT(gpatch->width) == BASEVIDWIDTH && cy >= -0.1f && cy <= 0.1f && SHORT(gpatch->height) == BASEVIDHEIGHT)
{
// Need to temporarily cache the real patch to get the colour of the top left pixel
patch_t *realpatch = W_CacheLumpNumPwad(gpatch->wadnum, gpatch->lumpnum, PU_STATIC);
patch_t *realpatch = W_CacheSoftwarePatchNumPwad(gpatch->wadnum, gpatch->lumpnum, PU_STATIC);
const column_t *column = (const column_t *)((const UINT8 *)(realpatch) + LONG((realpatch)->columnofs[0]));
if (!column->topdelta)
{

View file

@ -1879,7 +1879,9 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
{
for (rover = gr_backsector->ffloors; rover; rover = rover->next)
{
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERSIDES) || (rover->flags & FF_INVERTSIDES))
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERSIDES))
continue;
if (!(rover->flags & FF_ALLSIDES) && rover->flags & FF_INVERTSIDES)
continue;
if (*rover->topheight < lowcut || *rover->bottomheight > highcut)
continue;
@ -2019,7 +2021,9 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
{
for (rover = gr_frontsector->ffloors; rover; rover = rover->next)
{
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERSIDES) || !(rover->flags & FF_ALLSIDES))
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERSIDES))
continue;
if (!(rover->flags & FF_ALLSIDES || rover->flags & FF_INVERTSIDES))
continue;
if (*rover->topheight < lowcut || *rover->bottomheight > highcut)
continue;
@ -3404,7 +3408,7 @@ static void HWR_Subsector(size_t num)
if (centerHeight <= locCeilingHeight &&
centerHeight >= locFloorHeight &&
((dup_viewz < cullHeight && !(rover->flags & FF_INVERTPLANES)) ||
((dup_viewz < cullHeight && (rover->flags & FF_BOTHPLANES || !(rover->flags & FF_INVERTPLANES))) ||
(dup_viewz > cullHeight && (rover->flags & FF_BOTHPLANES || rover->flags & FF_INVERTPLANES))))
{
if (rover->flags & FF_FOG)
@ -3465,7 +3469,7 @@ static void HWR_Subsector(size_t num)
if (centerHeight >= locFloorHeight &&
centerHeight <= locCeilingHeight &&
((dup_viewz > cullHeight && !(rover->flags & FF_INVERTPLANES)) ||
((dup_viewz > cullHeight && (rover->flags & FF_BOTHPLANES || !(rover->flags & FF_INVERTPLANES))) ||
(dup_viewz < cullHeight && (rover->flags & FF_BOTHPLANES || rover->flags & FF_INVERTPLANES))))
{
if (rover->flags & FF_FOG)
@ -3956,7 +3960,10 @@ static void HWR_DrawDropShadow(mobj_t *thing, gr_vissprite_t *spr, fixed_t scale
{
light = R_GetPlaneLight(thing->subsector->sector, floorz, false); // Always use the light at the top instead of whatever I was doing before
lightlevel = *thing->subsector->sector->lightlist[light].lightlevel;
if (*thing->subsector->sector->lightlist[light].lightlevel > 255)
lightlevel = 255;
else
lightlevel = *thing->subsector->sector->lightlist[light].lightlevel;
if (*thing->subsector->sector->lightlist[light].extra_colormap)
colormap = *thing->subsector->sector->lightlist[light].extra_colormap;
@ -4157,7 +4164,7 @@ static void HWR_SplitSprite(gr_vissprite_t *spr)
if (h <= temp)
{
if (!(spr->mobj->frame & FF_FULLBRIGHT))
lightlevel = *list[i-1].lightlevel;
lightlevel = *list[i-1].lightlevel > 255 ? 255 : *list[i-1].lightlevel;
colormap = *list[i-1].extra_colormap;
break;
}
@ -4172,7 +4179,7 @@ static void HWR_SplitSprite(gr_vissprite_t *spr)
if (!(list[i].flags & FF_NOSHADE) && (list[i].flags & FF_CUTSPRITES))
{
if (!(spr->mobj->frame & FF_FULLBRIGHT))
lightlevel = *list[i].lightlevel;
lightlevel = *list[i].lightlevel > 255 ? 255 : *list[i].lightlevel;
colormap = *list[i].extra_colormap;
}
@ -4393,7 +4400,7 @@ static void HWR_DrawSprite(gr_vissprite_t *spr)
extracolormap_t *colormap = sector->extra_colormap;
if (!(spr->mobj->frame & FF_FULLBRIGHT))
lightlevel = sector->lightlevel;
lightlevel = sector->lightlevel > 255 ? 255 : sector->lightlevel;
if (colormap)
Surf.FlatColor.rgba = HWR_Lighting(lightlevel, colormap->rgba, colormap->fadergba, false, false);
@ -4490,7 +4497,7 @@ static inline void HWR_DrawPrecipitationSprite(gr_vissprite_t *spr)
light = R_GetPlaneLight(sector, spr->mobj->z + spr->mobj->height, false); // Always use the light at the top instead of whatever I was doing before
if (!(spr->mobj->frame & FF_FULLBRIGHT))
lightlevel = *sector->lightlist[light].lightlevel;
lightlevel = *sector->lightlist[light].lightlevel > 255 ? 255 : *sector->lightlist[light].lightlevel;
if (*sector->lightlist[light].extra_colormap)
colormap = *sector->lightlist[light].extra_colormap;
@ -4498,7 +4505,7 @@ static inline void HWR_DrawPrecipitationSprite(gr_vissprite_t *spr)
else
{
if (!(spr->mobj->frame & FF_FULLBRIGHT))
lightlevel = sector->lightlevel;
lightlevel = sector->lightlevel > 255 ? 255 : sector->lightlevel;
if (sector->extra_colormap)
colormap = sector->extra_colormap;
@ -6319,7 +6326,6 @@ void HWR_Shutdown(void)
CONS_Printf("HWR_Shutdown()\n");
HWR_FreeExtraSubsectors();
HWR_FreePolyPool();
HWR_FreeMipmapCache();
HWR_FreeTextureCache();
HWD.pfnFlushScreenTextures();
}

View file

@ -1221,7 +1221,7 @@ boolean HWR_DrawModel(gr_vissprite_t *spr)
light = R_GetPlaneLight(sector, spr->mobj->z + spr->mobj->height, false); // Always use the light at the top instead of whatever I was doing before
if (!(spr->mobj->frame & FF_FULLBRIGHT))
lightlevel = *sector->lightlist[light].lightlevel;
lightlevel = *sector->lightlist[light].lightlevel > 255 ? 255 : *sector->lightlist[light].lightlevel;
if (*sector->lightlist[light].extra_colormap)
colormap = *sector->lightlist[light].extra_colormap;
@ -1229,7 +1229,7 @@ boolean HWR_DrawModel(gr_vissprite_t *spr)
else
{
if (!(spr->mobj->frame & FF_FULLBRIGHT))
lightlevel = sector->lightlevel;
lightlevel = sector->lightlevel > 255 ? 255 : sector->lightlevel;
if (sector->extra_colormap)
colormap = sector->extra_colormap;

View file

@ -36,10 +36,10 @@ typedef enum
*/
extern rendermode_t rendermode;
/** \brief hardware renderer loaded
/** \brief OpenGL state
0 = never loaded, 1 = loaded successfully, -1 = failed loading
*/
extern INT32 hwrenderloaded;
extern INT32 vid_opengl_state;
/** \brief use highcolor modes if true
*/
@ -49,11 +49,7 @@ extern boolean highcolor;
*/
void I_StartupGraphics(void);
/** \brief setup hardware mode
*/
void I_StartupHardwareGraphics(void);
/** \brief restore old video mode
/** \brief shutdown video mode
*/
void I_ShutdownGraphics(void);
@ -97,6 +93,14 @@ INT32 VID_SetMode(INT32 modenum);
*/
void VID_CheckRenderer(void);
/** \brief Load OpenGL mode
*/
void VID_StartupOpenGL(void);
/** \brief Checks if OpenGL loaded
*/
void VID_CheckGLLoaded(rendermode_t oldrender);
/** \brief The VID_GetModeName function
\param modenum video mode number

View file

@ -165,6 +165,7 @@ void A_SetTics();
void A_SetRandomTics();
void A_ChangeColorRelative();
void A_ChangeColorAbsolute();
void A_Dye();
void A_MoveRelative();
void A_MoveAbsolute();
void A_Thrust();

View file

@ -220,10 +220,16 @@ static const char *GetUserdataUType(lua_State *L)
// or players[0].powers -> "player_t.powers"
static int lib_userdataType(lua_State *L)
{
int type;
lua_settop(L, 1); // pop everything except arg 1 (in case somebody decided to add more)
luaL_checktype(L, 1, LUA_TUSERDATA);
lua_pushstring(L, GetUserdataUType(L));
return 1;
type = lua_type(L, 1);
if (type == LUA_TLIGHTUSERDATA || type == LUA_TUSERDATA)
{
lua_pushstring(L, GetUserdataUType(L));
return 1;
}
else
return luaL_typerror(L, 1, "userdata");
}
static int lib_isPlayerAdmin(lua_State *L)

View file

@ -430,22 +430,8 @@ static int lib_cvRegisterVar(lua_State *L)
static int lib_cvFindVar(lua_State *L)
{
consvar_t *cv;
if (( cv = CV_FindVar(luaL_checkstring(L,1)) ))
{
lua_settop(L,1);/* We only want one argument in the stack. */
lua_pushlightuserdata(L, cv);/* Now the second value on stack. */
luaL_getmetatable(L, META_CVAR);
/*
The metatable is the last value on the stack, so this
applies it to the second value, which is the cvar.
*/
lua_setmetatable(L,2);
lua_pushvalue(L,2);
return 1;
}
else
return 0;
LUA_PushLightUserdata(L, CV_FindVar(luaL_checkstring(L,1)), META_CVAR);
return 1;
}
// CONS_Printf for a single player

View file

@ -40,6 +40,7 @@ enum hook {
hook_JumpSpinSpecial,
hook_BotTiccmd,
hook_BotAI,
hook_BotRespawn,
hook_LinedefExecute,
hook_PlayerMsg,
hook_HurtMsg,
@ -91,6 +92,7 @@ boolean LUAh_MobjDeath(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8
#define LUAh_JumpSpinSpecial(player) LUAh_PlayerHook(player, hook_JumpSpinSpecial) // Hook for P_DoJumpStuff (Spin button effect (mid-air))
boolean LUAh_BotTiccmd(player_t *bot, ticcmd_t *cmd); // Hook for B_BuildTiccmd
boolean LUAh_BotAI(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd); // Hook for B_BuildTailsTiccmd by skin name
boolean LUAh_BotRespawn(mobj_t *sonic, mobj_t *tails); // Hook for B_CheckRespawn
boolean LUAh_LinedefExecute(line_t *line, mobj_t *mo, sector_t *sector); // Hook for linedef executors
boolean LUAh_PlayerMsg(int source, int target, int flags, char *msg); // Hook for chat messages
boolean LUAh_HurtMsg(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8 damagetype); // Hook for hurt messages

View file

@ -52,6 +52,7 @@ const char *const hookNames[hook_MAX+1] = {
"JumpSpinSpecial",
"BotTiccmd",
"BotAI",
"BotRespawn",
"LinedefExecute",
"PlayerMsg",
"HurtMsg",
@ -80,9 +81,7 @@ struct hook_s
UINT16 id;
union {
mobjtype_t mt;
char *skinname;
char *musname;
char *funcname;
char *str;
} s;
boolean error;
};
@ -151,28 +150,16 @@ static int lib_addHook(lua_State *L)
break;
case hook_BotAI:
case hook_ShouldJingleContinue:
hook.s.skinname = NULL;
hook.s.str = NULL;
if (lua_isstring(L, 2))
{ // lowercase copy
const char *s = lua_tostring(L, 2);
char *p = hook.s.skinname = ZZ_Alloc(strlen(s)+1);
do {
*p = tolower(*s);
++p;
} while(*(++s));
*p = 0;
hook.s.str = Z_StrDup(lua_tostring(L, 2));
strlwr(hook.s.str);
}
break;
case hook_LinedefExecute: // Linedef executor functions
{ // uppercase copy
const char *s = luaL_checkstring(L, 2);
char *p = hook.s.funcname = ZZ_Alloc(strlen(s)+1);
do {
*p = toupper(*s);
++p;
} while(*(++s));
*p = 0;
}
hook.s.str = Z_StrDup(luaL_checkstring(L, 2));
strupr(hook.s.str);
break;
default:
break;
@ -1075,7 +1062,7 @@ boolean LUAh_BotAI(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd)
for (hookp = roothook; hookp; hookp = hookp->next)
{
if (hookp->type != hook_BotAI
|| (hookp->s.skinname && strcmp(hookp->s.skinname, ((skin_t*)tails->skin)->name)))
|| (hookp->s.str && strcmp(hookp->s.str, ((skin_t*)tails->skin)->name)))
continue;
if (lua_gettop(gL) == 0)
@ -1125,6 +1112,51 @@ boolean LUAh_BotAI(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd)
return hooked;
}
// Hook for B_CheckRespawn
boolean LUAh_BotRespawn(mobj_t *sonic, mobj_t *tails)
{
hook_p hookp;
UINT8 shouldRespawn = 0; // 0 = default, 1 = force yes, 2 = force no.
if (!gL || !(hooksAvailable[hook_BotRespawn/8] & (1<<(hook_BotRespawn%8))))
return false;
lua_settop(gL, 0);
for (hookp = roothook; hookp; hookp = hookp->next)
{
if (hookp->type != hook_BotRespawn)
continue;
if (lua_gettop(gL) == 0)
{
LUA_PushUserdata(gL, sonic, META_MOBJ);
LUA_PushUserdata(gL, tails, META_MOBJ);
}
lua_pushfstring(gL, FMT_HOOKID, hookp->id);
lua_gettable(gL, LUA_REGISTRYINDEX);
lua_pushvalue(gL, -3);
lua_pushvalue(gL, -3);
if (lua_pcall(gL, 2, 1, 0)) {
if (!hookp->error || cv_debug & DBG_LUA)
CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
lua_pop(gL, 1);
hookp->error = true;
continue;
}
if (!lua_isnil(gL, -1))
{
if (lua_toboolean(gL, -1))
shouldRespawn = 1; // Force yes
else
shouldRespawn = 2; // Force no
}
lua_pop(gL, 1);
}
lua_settop(gL, 0);
return shouldRespawn;
}
// Hook for linedef executors
boolean LUAh_LinedefExecute(line_t *line, mobj_t *mo, sector_t *sector)
{
@ -1137,7 +1169,7 @@ boolean LUAh_LinedefExecute(line_t *line, mobj_t *mo, sector_t *sector)
for (hookp = linedefexecutorhooks; hookp; hookp = hookp->next)
{
if (strcmp(hookp->s.funcname, line->stringargs[0]))
if (strcmp(hookp->s.str, line->stringargs[0]))
continue;
if (lua_gettop(gL) == 0)
@ -1675,7 +1707,7 @@ boolean LUAh_ShouldJingleContinue(player_t *player, const char *musname)
for (hookp = roothook; hookp; hookp = hookp->next)
{
if (hookp->type != hook_ShouldJingleContinue
|| (hookp->s.musname && strcmp(hookp->s.musname, musname)))
|| (hookp->s.str && strcmp(hookp->s.str, musname)))
continue;
if (lua_gettop(gL) == 0)

View file

@ -388,10 +388,7 @@ static int lib_setSpriteInfo(lua_State *L)
lua_Integer i = 0;
const char *str = NULL;
if (lua_isnumber(L, 2))
{
i = lua_tointeger(L, 2);
i++; // shift index in case of missing rotsprite support
}
else
str = luaL_checkstring(L, 2);

View file

@ -571,6 +571,27 @@ fixed_t LUA_EvalMath(const char *word)
return res;
}
/*
LUA_PushUserdata but no userdata is created.
You can't invalidate it therefore.
*/
void LUA_PushLightUserdata (lua_State *L, void *data, const char *meta)
{
if (data)
{
lua_pushlightuserdata(L, data);
luaL_getmetatable(L, meta);
/*
The metatable is the last value on the stack, so this
applies it to the second value, which is the userdata.
*/
lua_setmetatable(L, -2);
}
else
lua_pushnil(L);
}
// Takes a pointer, any pointer, and a metatable name
// Creates a userdata for that pointer with the given metatable
// Pushes it to the stack and stores it in the registry.

View file

@ -44,6 +44,7 @@ void LUA_LoadLump(UINT16 wad, UINT16 lump);
void LUA_DumpFile(const char *filename);
#endif
fixed_t LUA_EvalMath(const char *word);
void LUA_PushLightUserdata(lua_State *L, void *data, const char *meta);
void LUA_PushUserdata(lua_State *L, void *data, const char *meta);
void LUA_InvalidateUserdata(void *data);
void LUA_InvalidateLevel(void);

View file

@ -38,8 +38,20 @@ typedef INT32 fixed_t;
/*!
\brief convert fixed_t into floating number
*/
#define FIXED_TO_FLOAT(x) (((float)(x)) / ((float)FRACUNIT))
#define FLOAT_TO_FIXED(f) (fixed_t)((f) * ((float)FRACUNIT))
FUNCMATH FUNCINLINE static ATTRINLINE float FixedToFloat(fixed_t x)
{
return x / (float)FRACUNIT;
}
FUNCMATH FUNCINLINE static ATTRINLINE fixed_t FloatToFixed(float f)
{
return (fixed_t)(f * FRACUNIT);
}
// for backwards compat
#define FIXED_TO_FLOAT(x) FixedToFloat(x) // (((float)(x)) / ((float)FRACUNIT))
#define FLOAT_TO_FIXED(f) FloatToFixed(f) // (fixed_t)((f) * ((float)FRACUNIT))
#if defined (__WATCOMC__) && FRACBITS == 16

View file

@ -522,6 +522,8 @@ static menuitem_t MISC_AddonsMenu[] =
// ---------------------------------
static menuitem_t MAPauseMenu[] =
{
{IT_CALL | IT_STRING, NULL, "Emblem Hints...", M_EmblemHints, 32},
{IT_CALL | IT_STRING, NULL, "Continue", M_SelectableClearMenus,48},
{IT_CALL | IT_STRING, NULL, "Retry", M_ModeAttackRetry, 56},
{IT_CALL | IT_STRING, NULL, "Abort", M_ModeAttackEndGame, 64},
@ -529,6 +531,7 @@ static menuitem_t MAPauseMenu[] =
typedef enum
{
mapause_hints,
mapause_continue,
mapause_retry,
mapause_abort
@ -730,9 +733,9 @@ static menuitem_t SR_SoundTestMenu[] =
static menuitem_t SR_EmblemHintMenu[] =
{
{IT_STRING | IT_ARROWS, NULL, "Page", M_HandleEmblemHints, 10},
{IT_STRING|IT_CVAR, NULL, "Emblem Radar", &cv_itemfinder, 20},
{IT_WHITESTRING|IT_SUBMENU, NULL, "Back", &SPauseDef, 30}
{IT_STRING | IT_ARROWS, NULL, "Page", M_HandleEmblemHints, 10},
{IT_STRING|IT_CVAR, NULL, "Emblem Radar", &cv_itemfinder, 20},
{IT_WHITESTRING|IT_CALL, NULL, "Back", M_GoBack, 30}
};
// --------------------------------
@ -2098,7 +2101,7 @@ static void M_VideoOptions(INT32 choice)
{
(void)choice;
#ifdef HWRENDER
if (hwrenderloaded == -1)
if (vid_opengl_state == -1)
{
OP_VideoOptionsMenu[op_video_renderer].status = (IT_TRANSTEXT | IT_PAIR);
OP_VideoOptionsMenu[op_video_renderer].patch = "Renderer";
@ -3634,6 +3637,7 @@ void M_StartControlPanel(void)
else if (modeattacking)
{
currentMenu = &MAPauseDef;
MAPauseMenu[mapause_hints].status = (M_SecretUnlocked(SECRET_EMBLEMHINTS)) ? (IT_STRING | IT_CALL) : (IT_DISABLED);
itemOn = mapause_continue;
}
else if (!(netgame || multiplayer)) // Single Player
@ -7304,6 +7308,7 @@ static void M_EmblemHints(INT32 choice)
SR_EmblemHintMenu[0].status = (local > NUMHINTS*2) ? (IT_STRING | IT_ARROWS) : (IT_DISABLED);
SR_EmblemHintMenu[1].status = (M_SecretUnlocked(SECRET_ITEMFINDER)) ? (IT_CVAR|IT_STRING) : (IT_SECRET);
hintpage = 1;
SR_EmblemHintDef.prevMenu = currentMenu;
M_SetupNextMenu(&SR_EmblemHintDef);
itemOn = 2; // always start on back.
}
@ -7984,12 +7989,20 @@ static void M_CustomLevelSelect(INT32 choice)
static void M_SinglePlayerMenu(INT32 choice)
{
(void)choice;
SP_MainMenu[sptutorial].status =
tutorialmap ? IT_CALL|IT_STRING : IT_NOTHING|IT_DISABLED;
SP_MainMenu[sprecordattack].status =
(M_SecretUnlocked(SECRET_RECORDATTACK)) ? IT_CALL|IT_STRING : IT_SECRET;
SP_MainMenu[spnightsmode].status =
(M_SecretUnlocked(SECRET_NIGHTSMODE)) ? IT_CALL|IT_STRING : IT_SECRET;
levellistmode = LLM_RECORDATTACK;
if (M_GametypeHasLevels(-1))
SP_MainMenu[sprecordattack].status = (M_SecretUnlocked(SECRET_RECORDATTACK)) ? IT_CALL|IT_STRING : IT_SECRET;
else
SP_MainMenu[sprecordattack].status = IT_NOTHING|IT_DISABLED;
levellistmode = LLM_NIGHTSATTACK;
if (M_GametypeHasLevels(-1))
SP_MainMenu[spnightsmode].status = (M_SecretUnlocked(SECRET_NIGHTSMODE)) ? IT_CALL|IT_STRING : IT_SECRET;
else
SP_MainMenu[spnightsmode].status = IT_NOTHING|IT_DISABLED;
SP_MainMenu[sptutorial].status = tutorialmap ? IT_CALL|IT_STRING : IT_NOTHING|IT_DISABLED;
M_SetupNextMenu(&SP_MainDef);
}

View file

@ -189,6 +189,7 @@ void A_SetTics(mobj_t *actor);
void A_SetRandomTics(mobj_t *actor);
void A_ChangeColorRelative(mobj_t *actor);
void A_ChangeColorAbsolute(mobj_t *actor);
void A_Dye(mobj_t *actor);
void A_MoveRelative(mobj_t *actor);
void A_MoveAbsolute(mobj_t *actor);
void A_Thrust(mobj_t *actor);
@ -8773,6 +8774,42 @@ void A_ChangeColorAbsolute(mobj_t *actor)
actor->color = (UINT8)locvar2;
}
// Function: A_Dye
//
// Description: Colorizes an object.
//
// var1 = if (var1 != 0), dye your target instead of yourself
// var2 = color value to dye
//
void A_Dye(mobj_t *actor)
{
INT32 locvar1 = var1;
INT32 locvar2 = var2;
mobj_t *target = ((locvar1 && actor->target) ? actor->target : actor);
UINT8 color = (UINT8)locvar2;
#ifdef HAVE_BLUA
if (LUA_CallAction("A_Dye", actor))
return;
#endif
if (color >= MAXTRANSLATIONS)
return;
if (!color)
target->colorized = false;
else
target->colorized = true;
// What if it's a player?
if (target->player)
{
target->player->powers[pw_dye] = color;
return;
}
target->color = color;
}
// Function: A_MoveRelative
//
// Description: Moves an object (wrapper for P_Thrust)

View file

@ -27,19 +27,6 @@
// FLOORS
// ==========================================================================
//
// Mini-P_IsObjectOnGroundIn for T_MovePlane hack
//
static inline boolean P_MobjReadyToMove(mobj_t *mo, sector_t *sec, boolean sectorisffloor, boolean sectorisquicksand)
{
if (sectorisquicksand)
return (mo->z > sec->floorheight && mo->z < sec->ceilingheight);
else if (!!(mo->flags & MF_SPAWNCEILING) ^ !!(mo->eflags & MFE_VERTICALFLIP))
return ((sectorisffloor) ? (mo->z+mo->height != sec->floorheight) : (mo->z+mo->height != sec->ceilingheight));
else
return ((sectorisffloor) ? (mo->z != sec->ceilingheight) : (mo->z != sec->floorheight));
}
//
// Move a plane (floor or ceiling) and check for crushing
//
@ -49,14 +36,6 @@ result_e T_MovePlane(sector_t *sector, fixed_t speed, fixed_t dest, boolean crus
boolean flag;
fixed_t lastpos;
fixed_t destheight; // used to keep floors/ceilings from moving through each other
// Stuff used for mobj hacks.
INT32 secnum = -1;
mobj_t *mo = NULL;
sector_t *sec = NULL;
ffloor_t *rover = NULL;
boolean sectorisffloor = false;
boolean sectorisquicksand = false;
sector->moved = true;
switch (floorOrCeiling)
@ -194,83 +173,6 @@ result_e T_MovePlane(sector_t *sector, fixed_t speed, fixed_t dest, boolean crus
break;
}
// Hack for buggy mobjs to move by gravity with moving planes.
if (sector->tagline)
sectorisffloor = true;
// Optimization condition. If the sector is not an FOF, declare sec as the main sector outside of the loop.
if (!sectorisffloor)
sec = sector;
// Optimization condition. Only run the logic if there is any Things in the sector.
if (sectorisffloor || sec->thinglist)
{
// If this is an FOF being checked, check all the affected sectors for moving mobjs.
while ((sectorisffloor ? (secnum = P_FindSectorFromLineTag(sector->tagline, secnum)) : (secnum = 1)) >= 0)
{
if (sectorisffloor)
{
// Get actual sector from the list of sectors.
sec = &sectors[secnum];
// Can't use P_InQuicksand because it will return the incorrect result
// because of checking for heights.
for (rover = sec->ffloors; rover; rover = rover->next)
{
if (rover->target == sec && (rover->flags & FF_QUICKSAND))
{
sectorisquicksand = true;
break;
}
}
}
for (mo = sec->thinglist; mo; mo = mo->snext)
{
// The object should be ready to move as defined by this function.
if (!P_MobjReadyToMove(mo, sec, sectorisffloor, sectorisquicksand))
continue;
// The object should not be moving at all.
if (mo->momx || mo->momy || mo->momz)
continue;
// These objects will be affected by this condition.
switch (mo->type)
{
case MT_GOOP: // Egg Slimer's goop objects
case MT_SPINFIRE: // Elemental Shield flame balls
case MT_SPIKE: // Floor Spike
// Is the object hang from the ceiling?
// In that case, swap the planes used.
// verticalflip inverts
if (!!(mo->flags & MF_SPAWNCEILING) ^ !!(mo->eflags & MFE_VERTICALFLIP))
{
if (sectorisffloor && !sectorisquicksand)
mo->z = mo->ceilingz - mo->height;
else
mo->z = mo->ceilingz = mo->subsector->sector->ceilingheight - mo->height;
}
else
{
if (sectorisffloor && !sectorisquicksand)
mo->z = mo->floorz;
else
mo->z = mo->floorz = mo->subsector->sector->floorheight;
}
break;
// Kill warnings...
default:
break;
}
}
// Break from loop if there is no FOFs to check.
if (!sectorisffloor)
break;
}
}
return ok;
}
@ -1276,478 +1178,6 @@ void T_FloatSector(levelspecthink_t *floater)
}
}
//
// T_BridgeThinker
//
// Kind of like T_RaiseSector,
// but spreads out across
// multiple FOFs at varying
// intensity.
//
void T_BridgeThinker(levelspecthink_t *bridge)
{
msecnode_t *node;
mobj_t *thing;
sector_t *sector;
sector_t *controlsec = NULL;
INT32 i, k;
INT16 j;
boolean playeronme = false;
fixed_t ceilingdestination = 0, floordestination = 0;
result_e res = 0;
#define ORIGFLOORHEIGHT (bridge->vars[0])
#define ORIGCEILINGHEIGHT (bridge->vars[1])
#define BASESPEED (bridge->vars[2])
#define CURSPEED (bridge->vars[3])
#define STARTTAG ((INT16)bridge->vars[4])
#define ENDTAG ((INT16)bridge->vars[5])
#define DIRECTION (bridge->vars[8])
#define SAGAMT (8*FRACUNIT)
fixed_t lowceilheight = ORIGCEILINGHEIGHT - SAGAMT;
fixed_t lowfloorheight = ORIGFLOORHEIGHT - SAGAMT;
#define LOWCEILINGHEIGHT (lowceilheight)
#define LOWFLOORHEIGHT (lowfloorheight)
#define STARTCONTROLTAG (ENDTAG + 1)
#define ENDCONTROLTAG (ENDTAG + (ENDTAG - STARTTAG) + 1)
// Is someone standing on it?
for (j = STARTTAG; j <= ENDTAG; j++)
{
for (i = -1; (i = P_FindSectorFromTag(j, i)) >= 0 ;)
{
sector = &sectors[i];
// Nab the control sector that this sector belongs to.
k = P_FindSectorFromTag((INT16)(j + (ENDTAG-STARTTAG) + 1), -1);
if (k == -1)
break;
controlsec = &sectors[k];
// Is a player standing on me?
for (node = sector->touching_thinglist; node; node = node->m_thinglist_next)
{
thing = node->m_thing;
if (!thing->player)
continue;
if (!(thing->z == controlsec->ceilingheight))
continue;
playeronme = true;
goto wegotit; // Just take the first one?
}
}
}
wegotit:
if (playeronme)
{
// Lower controlsec like a regular T_RaiseSector
// Set the heights of all the other control sectors to
// be a gradient of this height toward the edges
}
else
{
// Raise controlsec like a regular T_RaiseSector
// Set the heights of all the other control sectors to
// be a gradient of this height toward the edges.
}
if (playeronme && controlsec)
{
INT32 dist;
bridge->sector = controlsec;
CURSPEED = BASESPEED;
{
// Translate tags to - 0 + range
/*so you have a number in [min, max].
let range = max - min, subtract min
from your number to get [0, range].
subtract range/2 to get [-range/2, range/2].
take absolute value and get [0, range/2] where
lower number = closer to midpoint. divide by
range/2 to get [0, 1]. subtract that number
from 1 to get [0, 1] with higher number = closer
to midpoint. multiply this by max sag amount*/
INT32 midpoint = STARTCONTROLTAG + ((ENDCONTROLTAG-STARTCONTROLTAG) + 1)/2;
// INT32 tagstart = STARTTAG - midpoint;
// INT32 tagend = ENDTAG - midpoint;
// CONS_Debug(DBG_GAMELOGIC, "tagstart is %d, tagend is %d\n", tagstart, tagend);
// Sag is adjusted by how close you are to the center
dist = ((ENDCONTROLTAG - STARTCONTROLTAG))/2 - abs(bridge->sector->tag - midpoint);
// CONS_Debug(DBG_GAMELOGIC, "Dist is %d\n", dist);
LOWCEILINGHEIGHT -= (SAGAMT) * dist;
LOWFLOORHEIGHT -= (SAGAMT) * dist;
}
// go down
if (bridge->sector->ceilingheight <= LOWCEILINGHEIGHT)
{
bridge->sector->floorheight = LOWCEILINGHEIGHT - (bridge->sector->ceilingheight - bridge->sector->floorheight);
bridge->sector->ceilingheight = LOWCEILINGHEIGHT;
bridge->sector->ceilspeed = 0;
bridge->sector->floorspeed = 0;
goto dorest;
}
DIRECTION = -1;
ceilingdestination = LOWCEILINGHEIGHT;
floordestination = LOWFLOORHEIGHT;
if ((bridge->sector->ceilingheight - LOWCEILINGHEIGHT)
< (ORIGCEILINGHEIGHT - bridge->sector->ceilingheight))
{
fixed_t origspeed = CURSPEED;
// Slow down as you get closer to the bottom
CURSPEED = FixedMul(CURSPEED,FixedDiv(bridge->sector->ceilingheight - LOWCEILINGHEIGHT, (ORIGCEILINGHEIGHT - LOWCEILINGHEIGHT)>>5));
if (CURSPEED <= origspeed/16)
CURSPEED = origspeed/16;
else if (CURSPEED > origspeed)
CURSPEED = origspeed;
}
else
{
fixed_t origspeed = CURSPEED;
// Slow down as you get closer to the top
CURSPEED = FixedMul(CURSPEED,FixedDiv(ORIGCEILINGHEIGHT - bridge->sector->ceilingheight, (ORIGCEILINGHEIGHT - LOWCEILINGHEIGHT)>>5));
if (CURSPEED <= origspeed/16)
CURSPEED = origspeed/16;
else if (CURSPEED > origspeed)
CURSPEED = origspeed;
}
// CONS_Debug(DBG_GAMELOGIC, "Curspeed is %d\n", CURSPEED>>FRACBITS);
res = T_MovePlane
(
bridge->sector, // sector
CURSPEED, // speed
ceilingdestination, // dest
0, // crush
1, // floor or ceiling (1 for ceiling)
DIRECTION // direction
);
if (res == ok || res == pastdest)
T_MovePlane
(
bridge->sector, // sector
CURSPEED, // speed
floordestination, // dest
0, // crush
0, // floor or ceiling (0 for floor)
DIRECTION // direction
);
bridge->sector->ceilspeed = 42;
bridge->sector->floorspeed = CURSPEED*DIRECTION;
dorest:
// Adjust joined sector heights
{
sector_t *sourcesec = bridge->sector;
INT32 divisor = sourcesec->tag - ENDTAG + 1;
fixed_t heightdiff = ORIGCEILINGHEIGHT - sourcesec->ceilingheight;
fixed_t interval;
INT32 plusplusme = 0;
if (divisor > 0)
{
interval = heightdiff/divisor;
// CONS_Debug(DBG_GAMELOGIC, "interval is %d\n", interval>>FRACBITS);
// TODO: Use T_MovePlane
for (j = (INT16)(ENDTAG+1); j <= sourcesec->tag; j++, plusplusme++)
{
for (i = -1; (i = P_FindSectorFromTag(j, i)) >= 0 ;)
{
if (sectors[i].ceilingheight >= sourcesec->ceilingheight)
{
sectors[i].ceilingheight = ORIGCEILINGHEIGHT - (interval*plusplusme);
sectors[i].floorheight = ORIGFLOORHEIGHT - (interval*plusplusme);
}
else // Do the regular rise
{
bridge->sector = &sectors[i];
CURSPEED = BASESPEED/2;
// rise back up
if (bridge->sector->ceilingheight >= ORIGCEILINGHEIGHT)
{
bridge->sector->floorheight = ORIGCEILINGHEIGHT - (bridge->sector->ceilingheight - bridge->sector->floorheight);
bridge->sector->ceilingheight = ORIGCEILINGHEIGHT;
bridge->sector->ceilspeed = 0;
bridge->sector->floorspeed = 0;
continue;
}
DIRECTION = 1;
ceilingdestination = ORIGCEILINGHEIGHT;
floordestination = ORIGFLOORHEIGHT;
// CONS_Debug(DBG_GAMELOGIC, "ceildest: %d, floordest: %d\n", ceilingdestination>>FRACBITS, floordestination>>FRACBITS);
if ((bridge->sector->ceilingheight - LOWCEILINGHEIGHT)
< (ORIGCEILINGHEIGHT - bridge->sector->ceilingheight))
{
fixed_t origspeed = CURSPEED;
// Slow down as you get closer to the bottom
CURSPEED = FixedMul(CURSPEED,FixedDiv(bridge->sector->ceilingheight - LOWCEILINGHEIGHT, (ORIGCEILINGHEIGHT - LOWCEILINGHEIGHT)>>5));
if (CURSPEED <= origspeed/16)
CURSPEED = origspeed/16;
else if (CURSPEED > origspeed)
CURSPEED = origspeed;
}
else
{
fixed_t origspeed = CURSPEED;
// Slow down as you get closer to the top
CURSPEED = FixedMul(CURSPEED,FixedDiv(ORIGCEILINGHEIGHT - bridge->sector->ceilingheight, (ORIGCEILINGHEIGHT - LOWCEILINGHEIGHT)>>5));
if (CURSPEED <= origspeed/16)
CURSPEED = origspeed/16;
else if (CURSPEED > origspeed)
CURSPEED = origspeed;
}
res = T_MovePlane
(
bridge->sector, // sector
CURSPEED, // speed
ceilingdestination, // dest
0, // crush
1, // floor or ceiling (1 for ceiling)
DIRECTION // direction
);
if (res == ok || res == pastdest)
T_MovePlane
(
bridge->sector, // sector
CURSPEED, // speed
floordestination, // dest
0, // crush
0, // floor or ceiling (0 for floor)
DIRECTION // direction
);
bridge->sector->ceilspeed = 42;
bridge->sector->floorspeed = CURSPEED*DIRECTION;
}
}
}
}
// Now the other side
divisor = ENDTAG + (ENDTAG-STARTTAG) + 1;
divisor -= sourcesec->tag;
if (divisor > 0)
{
interval = heightdiff/divisor;
plusplusme = 0;
// CONS_Debug(DBG_GAMELOGIC, "interval2 is %d\n", interval>>FRACBITS);
for (j = (INT16)(sourcesec->tag+1); j <= ENDTAG + (ENDTAG-STARTTAG) + 1; j++, plusplusme++)
{
for (i = -1; (i = P_FindSectorFromTag(j, i)) >= 0 ;)
{
if (sectors[i].ceilingheight >= sourcesec->ceilingheight)
{
sectors[i].ceilingheight = sourcesec->ceilingheight + (interval*plusplusme);
sectors[i].floorheight = sourcesec->floorheight + (interval*plusplusme);
}
else // Do the regular rise
{
bridge->sector = &sectors[i];
CURSPEED = BASESPEED/2;
// rise back up
if (bridge->sector->ceilingheight >= ORIGCEILINGHEIGHT)
{
bridge->sector->floorheight = ORIGCEILINGHEIGHT - (bridge->sector->ceilingheight - bridge->sector->floorheight);
bridge->sector->ceilingheight = ORIGCEILINGHEIGHT;
bridge->sector->ceilspeed = 0;
bridge->sector->floorspeed = 0;
continue;
}
DIRECTION = 1;
ceilingdestination = ORIGCEILINGHEIGHT;
floordestination = ORIGFLOORHEIGHT;
// CONS_Debug(DBG_GAMELOGIC, "ceildest: %d, floordest: %d\n", ceilingdestination>>FRACBITS, floordestination>>FRACBITS);
if ((bridge->sector->ceilingheight - LOWCEILINGHEIGHT)
< (ORIGCEILINGHEIGHT - bridge->sector->ceilingheight))
{
fixed_t origspeed = CURSPEED;
// Slow down as you get closer to the bottom
CURSPEED = FixedMul(CURSPEED,FixedDiv(bridge->sector->ceilingheight - LOWCEILINGHEIGHT, (ORIGCEILINGHEIGHT - LOWCEILINGHEIGHT)>>5));
if (CURSPEED <= origspeed/16)
CURSPEED = origspeed/16;
else if (CURSPEED > origspeed)
CURSPEED = origspeed;
}
else
{
fixed_t origspeed = CURSPEED;
// Slow down as you get closer to the top
CURSPEED = FixedMul(CURSPEED,FixedDiv(ORIGCEILINGHEIGHT - bridge->sector->ceilingheight, (ORIGCEILINGHEIGHT - LOWCEILINGHEIGHT)>>5));
if (CURSPEED <= origspeed/16)
CURSPEED = origspeed/16;
else if (CURSPEED > origspeed)
CURSPEED = origspeed;
}
res = T_MovePlane
(
bridge->sector, // sector
CURSPEED, // speed
ceilingdestination, // dest
0, // crush
1, // floor or ceiling (1 for ceiling)
DIRECTION // direction
);
if (res == ok || res == pastdest)
T_MovePlane
(
bridge->sector, // sector
CURSPEED, // speed
floordestination, // dest
0, // crush
0, // floor or ceiling (0 for floor)
DIRECTION // direction
);
bridge->sector->ceilspeed = 42;
bridge->sector->floorspeed = CURSPEED*DIRECTION;
}
}
}
}
}
// for (i = -1; (i = P_FindSectorFromTag(bridge->sourceline->tag, i)) >= 0 ;)
// P_RecalcPrecipInSector(&sectors[i]);
}
else
{
// Iterate control sectors
for (j = (INT16)(ENDTAG+1); j <= (ENDTAG+(ENDTAG-STARTTAG)+1); j++)
{
for (i = -1; (i = P_FindSectorFromTag(j, i)) >= 0 ;)
{
bridge->sector = &sectors[i];
CURSPEED = BASESPEED/2;
// rise back up
if (bridge->sector->ceilingheight >= ORIGCEILINGHEIGHT)
{
bridge->sector->floorheight = ORIGCEILINGHEIGHT - (bridge->sector->ceilingheight - bridge->sector->floorheight);
bridge->sector->ceilingheight = ORIGCEILINGHEIGHT;
bridge->sector->ceilspeed = 0;
bridge->sector->floorspeed = 0;
continue;
}
DIRECTION = 1;
ceilingdestination = ORIGCEILINGHEIGHT;
floordestination = ORIGFLOORHEIGHT;
// CONS_Debug(DBG_GAMELOGIC, "ceildest: %d, floordest: %d\n", ceilingdestination>>FRACBITS, floordestination>>FRACBITS);
if ((bridge->sector->ceilingheight - LOWCEILINGHEIGHT)
< (ORIGCEILINGHEIGHT - bridge->sector->ceilingheight))
{
fixed_t origspeed = CURSPEED;
// Slow down as you get closer to the bottom
CURSPEED = FixedMul(CURSPEED,FixedDiv(bridge->sector->ceilingheight - LOWCEILINGHEIGHT, (ORIGCEILINGHEIGHT - LOWCEILINGHEIGHT)>>5));
if (CURSPEED <= origspeed/16)
CURSPEED = origspeed/16;
else if (CURSPEED > origspeed)
CURSPEED = origspeed;
}
else
{
fixed_t origspeed = CURSPEED;
// Slow down as you get closer to the top
CURSPEED = FixedMul(CURSPEED,FixedDiv(ORIGCEILINGHEIGHT - bridge->sector->ceilingheight, (ORIGCEILINGHEIGHT - LOWCEILINGHEIGHT)>>5));
if (CURSPEED <= origspeed/16)
CURSPEED = origspeed/16;
else if (CURSPEED > origspeed)
CURSPEED = origspeed;
}
res = T_MovePlane
(
bridge->sector, // sector
CURSPEED, // speed
ceilingdestination, // dest
0, // crush
1, // floor or ceiling (1 for ceiling)
DIRECTION // direction
);
if (res == ok || res == pastdest)
T_MovePlane
(
bridge->sector, // sector
CURSPEED, // speed
floordestination, // dest
0, // crush
0, // floor or ceiling (0 for floor)
DIRECTION // direction
);
bridge->sector->ceilspeed = 42;
bridge->sector->floorspeed = CURSPEED*DIRECTION;
}
}
// Update precip
}
#undef SAGAMT
#undef LOWFLOORHEIGHT
#undef LOWCEILINGHEIGHT
#undef ORIGFLOORHEIGHT
#undef ORIGCEILINGHEIGHT
#undef BASESPEED
#undef CURSPEED
#undef STARTTAG
#undef ENDTAG
#undef DIRECTION
}
static mobj_t *SearchMarioNode(msecnode_t *node)
{
mobj_t *thing = NULL;

View file

@ -3150,7 +3150,7 @@ static boolean P_PlayerHitsPlayer(mobj_t *target, mobj_t *inflictor, mobj_t *sou
return false;
// In COOP/RACE, you can't hurt other players unless cv_friendlyfire is on
if (!(cv_friendlyfire.value || (gametyperules & GTR_FRIENDLYFIRE)) && (G_PlatformGametype()))
if (!(cv_friendlyfire.value || (gametyperules & GTR_FRIENDLYFIRE)) && (gametyperules & GTR_FRIENDLY))
{
if (gametype == GT_COOP && inflictor->type == MT_LHRT && !(player->powers[pw_shield] & SH_NOSTACK)) // co-op only
{

View file

@ -9283,8 +9283,11 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
if (mobj->tracer && mobj->tracer->player && mobj->tracer->health > 0
&& P_AproxDistance(P_AproxDistance(mobj->tracer->x - mobj->x, mobj->tracer->y - mobj->y), mobj->tracer->z - mobj->z) <= mobj->radius*16)
{
var1 = mobj->info->speed;
var2 = 1;
// Home in on the target.
P_HomingAttack(mobj, mobj->tracer);
A_HomingChase(mobj);
if (mobj->z < mobj->floorz)
mobj->z = mobj->floorz;

View file

@ -787,8 +787,13 @@ static boolean P_AreStringArgsEqual(const line_t *li, const line_t *spawnli)
{
UINT8 i;
for (i = 0; i < NUMLINESTRINGARGS; i++)
{
if (!li->stringargs[i])
return !spawnli->stringargs[i];
if (strcmp(li->stringargs[i], spawnli->stringargs[i]))
return false;
}
return true;
}
@ -1356,7 +1361,6 @@ typedef enum
tc_marioblockchecker,
tc_spikesector,
tc_floatsector,
tc_bridgethinker,
tc_crushceiling,
tc_scroll,
tc_friction,
@ -2372,11 +2376,6 @@ static void P_NetArchiveThinkers(void)
SaveSpecialLevelThinker(th, tc_floatsector);
continue;
}
else if (th->function.acp1 == (actionf_p1)T_BridgeThinker)
{
SaveSpecialLevelThinker(th, tc_bridgethinker);
continue;
}
else if (th->function.acp1 == (actionf_p1)T_LaserFlash)
{
SaveLaserThinker(th, tc_laserflash);
@ -3568,10 +3567,6 @@ static void P_NetUnArchiveThinkers(void)
th = LoadSpecialLevelThinker((actionf_p1)T_FloatSector, 0);
break;
case tc_bridgethinker:
th = LoadSpecialLevelThinker((actionf_p1)T_BridgeThinker, 3);
break;
case tc_laserflash:
th = LoadLaserThinker((actionf_p1)T_LaserFlash);
break;

View file

@ -873,7 +873,6 @@ static void P_InitializeSector(sector_t *ss)
ss->linecount = 0;
ss->lines = NULL;
ss->tagline = NULL;
ss->ffloors = NULL;
ss->attached = NULL;
@ -1189,10 +1188,14 @@ static void P_LoadSidedefs(UINT8 *data)
case 9: // Mace parameters
case 14: // Bustable block parameters
case 15: // Fan particle spawner parameters
case 334: // Trigger linedef executor: Object dye - Continuous
case 335: // Trigger linedef executor: Object dye - Each time
case 336: // Trigger linedef executor: Object dye - Once
case 425: // Calls P_SetMobjState on calling mobj
case 434: // Custom Power
case 442: // Calls P_SetMobjState on mobjs of a given type in the tagged sectors
case 461: // Spawns an object on the map based on texture offsets
case 463: // Colorizes an object
{
char process[8*3+1];
memset(process,0,8*3+1);
@ -1822,12 +1825,12 @@ static void P_ProcessLinedefsAfterSidedefs(void)
if (alpha < 0)
{
alpha *= -1;
ld->args[2] |= 16;
ld->args[2] |= TMCF_SUBLIGHTA;
}
if (fadealpha < 0)
{
fadealpha *= -1;
ld->args[2] |= 256;
ld->args[2] |= TMCF_SUBFADEA;
}
exc->rgba = R_GetRgbaRGB(exc->rgba) + R_PutRgbaA(alpha);
@ -3080,13 +3083,13 @@ static void P_ConvertBinaryMap(void)
case 447: //Change colormap
lines[i].args[0] = lines[i].tag;
if (lines[i].flags & ML_EFFECT3)
lines[i].args[2] |= 1;
lines[i].args[2] |= TMCF_RELATIVE;
if (lines[i].flags & ML_EFFECT1)
lines[i].args[2] |= 34;
lines[i].args[2] |= TMCF_SUBLIGHTR|TMCF_SUBFADER;
if (lines[i].flags & ML_NOCLIMB)
lines[i].args[2] |= 68;
lines[i].args[2] |= TMCF_SUBLIGHTG|TMCF_SUBFADEG;
if (lines[i].flags & ML_EFFECT2)
lines[i].args[2] |= 136;
lines[i].args[2] |= TMCF_SUBLIGHTB|TMCF_SUBFADEB;
break;
case 455: //Fade colormap
{
@ -3100,17 +3103,17 @@ static void P_ConvertBinaryMap(void)
else
lines[i].args[2] = (256 + speed - 1)/speed;
if (lines[i].flags & ML_EFFECT3)
lines[i].args[3] |= 1;
lines[i].args[3] |= TMCF_RELATIVE;
if (lines[i].flags & ML_EFFECT1)
lines[i].args[3] |= 34;
lines[i].args[3] |= TMCF_SUBLIGHTR|TMCF_SUBFADER;
if (lines[i].flags & ML_NOCLIMB)
lines[i].args[3] |= 68;
lines[i].args[3] |= TMCF_SUBLIGHTG|TMCF_SUBFADEG;
if (lines[i].flags & ML_EFFECT2)
lines[i].args[3] |= 136;
lines[i].args[3] |= TMCF_SUBLIGHTB|TMCF_SUBFADEB;
if (lines[i].flags & ML_BOUNCY)
lines[i].args[3] |= 4096;
lines[i].args[3] |= TMCF_FROMBLACK;
if (lines[i].flags & ML_EFFECT5)
lines[i].args[3] |= 8192;
lines[i].args[3] |= TMCF_OVERRIDE;
break;
}
case 456: //Stop fading colormap
@ -3133,13 +3136,13 @@ static void P_ConvertBinaryMap(void)
boolean frontceil = (lines[i].special == 701 || lines[i].special == 702 || lines[i].special == 713);
boolean backceil = (lines[i].special == 711 || lines[i].special == 712 || lines[i].special == 703);
lines[i].args[0] = backfloor ? 2 : (frontfloor ? 1 : 0);
lines[i].args[1] = backceil ? 2 : (frontceil ? 1 : 0);
lines[i].args[0] = backfloor ? TMS_BACK : (frontfloor ? TMS_FRONT : TMS_NONE);
lines[i].args[1] = backceil ? TMS_BACK : (frontceil ? TMS_FRONT : TMS_NONE);
if (lines[i].flags & ML_NETONLY)
lines[i].args[2] |= SL_NOPHYSICS;
lines[i].args[2] |= TMSL_NOPHYSICS;
if (lines[i].flags & ML_NONET)
lines[i].args[2] |= SL_DYNAMIC;
lines[i].args[2] |= TMSL_DYNAMIC;
lines[i].special = 700;
break;
@ -3150,13 +3153,13 @@ static void P_ConvertBinaryMap(void)
case 715: //Slope back sector ceiling by 3 tagged vertices
{
if (lines[i].special == 704)
lines[i].args[0] = 0;
lines[i].args[0] = TMSP_FRONTFLOOR;
else if (lines[i].special == 705)
lines[i].args[0] = 1;
lines[i].args[0] = TMSP_FRONTCEILING;
else if (lines[i].special == 714)
lines[i].args[0] = 2;
lines[i].args[0] = TMSP_BACKFLOOR;
else if (lines[i].special == 715)
lines[i].args[0] = 3;
lines[i].args[0] = TMSP_BACKCEILING;
lines[i].args[1] = lines[i].tag;
@ -3179,9 +3182,9 @@ static void P_ConvertBinaryMap(void)
}
if (lines[i].flags & ML_NETONLY)
lines[i].args[4] |= SL_NOPHYSICS;
lines[i].args[4] |= TMSL_NOPHYSICS;
if (lines[i].flags & ML_NONET)
lines[i].args[4] |= SL_DYNAMIC;
lines[i].args[4] |= TMSL_DYNAMIC;
lines[i].special = 704;
break;

View file

@ -495,7 +495,7 @@ boolean P_CheckSight(mobj_t *t1, mobj_t *t2)
if (rover->flags & FF_SOLID)
continue; // shortcut since neither mobj can be inside the 3dfloor
if (!(rover->flags & FF_INVERTPLANES))
if (rover->flags & FF_BOTHPLANES || !(rover->flags & FF_INVERTPLANES))
{
if (los.sightzstart >= topz1 && t2->z + t2->height < topz2)
return false; // blocked by upper outside plane
@ -504,7 +504,7 @@ boolean P_CheckSight(mobj_t *t1, mobj_t *t2)
return false; // blocked by lower outside plane
}
if (rover->flags & FF_INVERTPLANES || rover->flags & FF_BOTHPLANES)
if (rover->flags & FF_BOTHPLANES || rover->flags & FF_INVERTPLANES)
{
if (los.sightzstart < topz1 && t2->z >= topz2)
return false; // blocked by upper inside plane

View file

@ -250,14 +250,14 @@ static void line_SpawnViaLine(const int linenum, const boolean spawnthinker)
vector2_t direction;
fixed_t nx, ny, dz, extent;
boolean frontfloor = line->args[0] == 1;
boolean backfloor = line->args[0] == 2;
boolean frontceil = line->args[1] == 1;
boolean backceil = line->args[1] == 2;
boolean frontfloor = line->args[0] == TMS_FRONT;
boolean backfloor = line->args[0] == TMS_BACK;
boolean frontceil = line->args[1] == TMS_FRONT;
boolean backceil = line->args[1] == TMS_BACK;
UINT8 flags = 0; // Slope flags
if (line->args[2] & 1)
if (line->args[2] & TMSL_NOPHYSICS)
flags |= SL_NOPHYSICS;
if (line->args[2] & 2)
if (line->args[2] & TMSL_DYNAMIC)
flags |= SL_DYNAMIC;
if(!frontfloor && !backfloor && !frontceil && !backceil)
@ -464,26 +464,26 @@ static void line_SpawnViaMapthingVertexes(const int linenum, const boolean spawn
UINT16 tag2 = line->args[2];
UINT16 tag3 = line->args[3];
UINT8 flags = 0; // Slope flags
if (line->args[4] & 1)
if (line->args[4] & TMSL_NOPHYSICS)
flags |= SL_NOPHYSICS;
if (line->args[4] & 2)
if (line->args[4] & TMSL_DYNAMIC)
flags |= SL_DYNAMIC;
switch(line->args[0])
{
case 0:
case TMSP_FRONTFLOOR:
slopetoset = &line->frontsector->f_slope;
side = &sides[line->sidenum[0]];
break;
case 1:
case TMSP_FRONTCEILING:
slopetoset = &line->frontsector->c_slope;
side = &sides[line->sidenum[0]];
break;
case 2:
case TMSP_BACKFLOOR:
slopetoset = &line->backsector->f_slope;
side = &sides[line->sidenum[1]];
break;
case 3:
case TMSP_BACKCEILING:
slopetoset = &line->backsector->c_slope;
side = &sides[line->sidenum[1]];
default:
@ -605,13 +605,13 @@ void P_CopySectorSlope(line_t *line)
setback |= P_SetSlopeFromTag(bsec, line->args[2], false);
setback |= P_SetSlopeFromTag(bsec, line->args[3], true);
if (line->args[4] & 1)
if (line->args[4] & TMSC_FRONTTOBACKFLOOR)
setback |= P_CopySlope(&bsec->f_slope, fsec->f_slope);
if (line->args[4] & 2)
if (line->args[4] & TMSC_BACKTOFRONTFLOOR)
setfront |= P_CopySlope(&fsec->f_slope, bsec->f_slope);
if (line->args[4] & 4)
if (line->args[4] & TMSC_FRONTTOBACKCEILING)
setback |= P_CopySlope(&bsec->c_slope, fsec->c_slope);
if (line->args[4] & 8)
if (line->args[4] & TMSC_BACKTOFRONTCEILING)
setfront |= P_CopySlope(&fsec->c_slope, bsec->c_slope);
}

View file

@ -18,6 +18,35 @@
extern pslope_t *slopelist;
extern UINT16 slopecount;
typedef enum
{
TMSP_FRONTFLOOR,
TMSP_FRONTCEILING,
TMSP_BACKFLOOR,
TMSP_BACKCEILING,
} textmapslopeplane_t;
typedef enum
{
TMSC_FRONTTOBACKFLOOR = 1,
TMSC_BACKTOFRONTFLOOR = 1<<1,
TMSC_FRONTTOBACKCEILING = 1<<2,
TMSC_BACKTOFRONTCEILING = 1<<3,
} textmapslopecopy_t;
typedef enum
{
TMS_NONE,
TMS_FRONT,
TMS_BACK,
} textmapside_t;
typedef enum
{
TMSL_NOPHYSICS = 1,
TMSL_DYNAMIC = 2,
} textmapslopeflags_t;
void P_LinkSlopeThinkers (void);
void P_CalculateSlopeNormal(pslope_t *slope);

View file

@ -2034,6 +2034,17 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller
if (!(actor && actor->player && ((stricmp(triggerline->text, skins[actor->player->skin].name) == 0) ^ ((triggerline->flags & ML_NOCLIMB) == ML_NOCLIMB))))
return false;
break;
case 334: // object dye - continuous
case 335: // object dye - each time
case 336: // object dye - once
{
INT32 triggercolor = (INT32)sides[triggerline->sidenum[0]].toptexture;
UINT8 color = (actor->player ? actor->player->powers[pw_dye] : actor->color);
boolean invert = (triggerline->flags & ML_NOCLIMB ? true : false);
if (invert ^ (triggercolor != color))
return false;
}
default:
break;
}
@ -2167,6 +2178,7 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller
|| specialtype == 328 // Nights lap - Once
|| specialtype == 330 // Nights Bonus Time - Once
|| specialtype == 333 // Skin - Once
|| specialtype == 336 // Dye - Once
|| specialtype == 399) // Level Load
triggerline->special = 0; // Clear it out
@ -2208,7 +2220,8 @@ void P_LinedefExecute(INT16 tag, mobj_t *actor, sector_t *caller)
|| lines[masterline].special == 310 // CTF Red team - Each time
|| lines[masterline].special == 312 // CTF Blue team - Each time
|| lines[masterline].special == 322 // Trigger on X calls - Each Time
|| lines[masterline].special == 332)// Skin - Each time
|| lines[masterline].special == 332 // Skin - Each time
|| lines[masterline].special == 335)// Dye - Each time
continue;
if (lines[masterline].special < 300
@ -3519,7 +3532,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
P_ResetColormapFader(&sectors[secnum]);
if (line->args[2] & 1) // relative calc
if (line->args[2] & TMCF_RELATIVE)
{
extracolormap_t *target = (!udmf && (line->flags & ML_TFERLINE) && line->sidenum[1] != 0xFFFF) ?
sides[line->sidenum[1]].colormap_data : sectors[secnum].extra_colormap; // use back colormap instead of target sector
@ -3527,17 +3540,17 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
extracolormap_t *exc = R_AddColormaps(
target,
source,
line->args[2] & 2, // subtract R
line->args[2] & 4, // subtract G
line->args[2] & 8, // subtract B
line->args[2] & 16, // subtract A
line->args[2] & 32, // subtract FadeR
line->args[2] & 64, // subtract FadeG
line->args[2] & 128, // subtract FadeB
line->args[2] & 256, // subtract FadeA
line->args[2] & 512, // subtract FadeStart
line->args[2] & 1024, // subtract FadeEnd
line->args[2] & 2048, // ignore Flags
line->args[2] & TMCF_SUBLIGHTR,
line->args[2] & TMCF_SUBLIGHTG,
line->args[2] & TMCF_SUBLIGHTB,
line->args[2] & TMCF_SUBLIGHTA,
line->args[2] & TMCF_SUBFADER,
line->args[2] & TMCF_SUBFADEG,
line->args[2] & TMCF_SUBFADEB,
line->args[2] & TMCF_SUBFADEA,
line->args[2] & TMCF_SUBFADESTART,
line->args[2] & TMCF_SUBFADEEND,
line->args[2] & TMCF_IGNOREFLAGS,
false);
if (!(sectors[secnum].extra_colormap = R_GetColormapFromList(exc)))
@ -3855,7 +3868,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
continue;
// Don't interrupt ongoing fade
if (!(line->args[3] & 8192)
if (!(line->args[3] & TMCF_OVERRIDE)
&& sectors[secnum].fadecolormapdata)
//&& ((fadecolormap_t*)sectors[secnum].fadecolormapdata)->timer > (ticbased ? 2 : speed*2))
{
@ -3869,7 +3882,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
exc = sectors[secnum].extra_colormap;
if (!(line->args[3] & 4096) // Override fade from default rgba
if (!(line->args[3] & TMCF_FROMBLACK) // Override fade from default rgba
&& !R_CheckDefaultColormap(dest, true, false, false)
&& R_CheckDefaultColormap(exc, true, false, false))
{
@ -3891,22 +3904,22 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
else
source_exc = exc ? exc : R_GetDefaultColormap();
if (line->args[3] & 1) // relative calc
if (line->args[3] & TMCF_RELATIVE)
{
exc = R_AddColormaps(
source_exc,
dest,
line->args[3] & 2, // subtract R
line->args[3] & 4, // subtract G
line->args[3] & 8, // subtract B
line->args[3] & 16, // subtract A
line->args[3] & 32, // subtract FadeR
line->args[3] & 64, // subtract FadeG
line->args[3] & 128, // subtract FadeB
line->args[3] & 256, // subtract FadeA
line->args[3] & 512, // subtract FadeStart
line->args[3] & 1024, // subtract FadeEnd
line->args[3] & 2048, // ignore Flags
line->args[3] & TMCF_SUBLIGHTR,
line->args[3] & TMCF_SUBLIGHTG,
line->args[3] & TMCF_SUBLIGHTB,
line->args[3] & TMCF_SUBLIGHTA,
line->args[3] & TMCF_SUBFADER,
line->args[3] & TMCF_SUBFADEG,
line->args[3] & TMCF_SUBFADEB,
line->args[3] & TMCF_SUBFADEA,
line->args[3] & TMCF_SUBFADESTART,
line->args[3] & TMCF_SUBFADEEND,
line->args[3] & TMCF_IGNOREFLAGS,
false);
}
else
@ -4056,6 +4069,22 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
}
break;
case 463: // Dye object
{
INT32 color = sides[line->sidenum[0]].toptexture;
if (mo)
{
if (color < 0 || color >= MAXTRANSLATIONS)
return;
var1 = 0;
var2 = color;
A_Dye(mo);
}
}
break;
#ifdef POLYOBJECTS
case 480: // Polyobj_DoorSlide
case 481: // Polyobj_DoorSwing
@ -5761,8 +5790,6 @@ static ffloor_t *P_AddFakeFloor(sector_t *sec, sector_t *sec2, line_t *master, f
sec2->floorheight = tempceiling;
}
sec2->tagline = master;
if (sec2->numattached == 0)
{
sec2->attached = Z_Malloc(sizeof (*sec2->attached) * sec2->maxattached, PU_STATIC, NULL);
@ -5955,39 +5982,6 @@ static void P_AddFloatThinker(sector_t *sec, INT32 tag, line_t *sourceline)
floater->sourceline = sourceline;
}
/** Adds a bridge thinker.
* Bridge thinkers cause a group of FOFs to behave like
* a bridge made up of pieces, that bows under weight.
*
* \param sec Control sector.
* \sa P_SpawnSpecials, T_BridgeThinker
* \author SSNTails <http://www.ssntails.org>
*/
/*
static inline void P_AddBridgeThinker(line_t *sourceline, sector_t *sec)
{
levelspecthink_t *bridge;
// create an initialize new thinker
bridge = Z_Calloc(sizeof (*bridge), PU_LEVSPEC, NULL);
P_AddThinker(THINK_MAIN, &bridge->thinker);
bridge->thinker.function.acp1 = (actionf_p1)T_BridgeThinker;
bridge->sector = sec;
bridge->vars[0] = sourceline->frontsector->floorheight;
bridge->vars[1] = sourceline->frontsector->ceilingheight;
bridge->vars[2] = P_AproxDistance(sourceline->dx, sourceline->dy); // Speed
bridge->vars[2] = FixedDiv(bridge->vars[2], 16*FRACUNIT);
bridge->vars[3] = bridge->vars[2];
// Start tag and end tag are TARGET SECTORS, not CONTROL SECTORS
// Control sector tags should be End_Tag + (End_Tag - Start_Tag)
bridge->vars[4] = sourceline->tag; // Start tag
bridge->vars[5] = (sides[sourceline->sidenum[0]].textureoffset>>FRACBITS); // End tag
}
*/
/**
* Adds a plane displacement thinker.
* Whenever the "control" sector moves,
@ -6725,13 +6719,6 @@ void P_SpawnSpecials(boolean fromnetsave)
}
break;
case 65: // Bridge Thinker
/*
// Disable this until it's working right!
for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;)
P_AddBridgeThinker(&lines[i], &sectors[s]);*/
break;
case 66: // Displace floor by front sector
for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;)
P_AddPlaneDisplaceThinker(pd_floor, P_AproxDistance(lines[i].dx, lines[i].dy)>>8, sides[lines[i].sidenum[0]].sector-sectors, s, !!(lines[i].flags & ML_NOCLIMB));
@ -6919,7 +6906,7 @@ void P_SpawnSpecials(boolean fromnetsave)
break;
case 202: // Fog
ffloorflags = FF_EXISTS|FF_RENDERALL|FF_FOG|FF_BOTHPLANES|FF_INVERTPLANES|FF_ALLSIDES|FF_INVERTSIDES|FF_CUTEXTRA|FF_EXTRA|FF_DOUBLESHADOW|FF_CUTSPRITES;
ffloorflags = FF_EXISTS|FF_RENDERALL|FF_FOG|FF_INVERTPLANES|FF_INVERTSIDES|FF_CUTEXTRA|FF_EXTRA|FF_DOUBLESHADOW|FF_CUTSPRITES;
sec = sides[*lines[i].sidenum].sector - sectors;
// SoM: Because it's fog, check for an extra colormap and set the fog flag...
if (sectors[sec].extra_colormap)
@ -7061,6 +7048,7 @@ void P_SpawnSpecials(boolean fromnetsave)
case 310:
case 312:
case 332:
case 335:
sec = sides[*lines[i].sidenum].sector - sectors;
P_AddEachTimeThinker(&sectors[sec], &lines[i]);
break;
@ -7114,6 +7102,11 @@ void P_SpawnSpecials(boolean fromnetsave)
case 333:
break;
// Object dye executors
case 334:
case 336:
break;
case 399: // Linedef execute on map load
// This is handled in P_RunLevelLoadExecutors.
break;

View file

@ -354,7 +354,6 @@ void T_StartCrumble(elevator_t *elevator);
void T_MarioBlock(levelspecthink_t *block);
void T_SpikeSector(levelspecthink_t *spikes);
void T_FloatSector(levelspecthink_t *floater);
void T_BridgeThinker(levelspecthink_t *bridge);
void T_MarioBlockChecker(levelspecthink_t *block);
void T_ThwompSector(levelspecthink_t *thwomp);
void T_NoEnemiesSector(levelspecthink_t *nobaddies);

View file

@ -1548,6 +1548,10 @@ boolean P_EvaluateMusicStatus(UINT16 status, const char *musname)
int i;
boolean result = false;
#ifndef HAVE_BLUA
(void)musname;
#endif
for (i = 0; i < MAXPLAYERS; i++)
{
if (!P_IsLocalPlayer(&players[i]))
@ -7978,7 +7982,7 @@ static void P_MovePlayer(player_t *player)
&& player->mo->state < &states[S_PLAY_NIGHTS_TRANS6]))) // Note the < instead of <=
{
skin_t *skin = ((skin_t *)(player->mo->skin));
if (skin->flags & SF_SUPER)
if (( skin->flags & (SF_SUPER|SF_NONIGHTSSUPER) ) == SF_SUPER)
{
player->mo->color = skin->supercolor
+ ((player->nightstime == player->startedtime)
@ -9327,7 +9331,7 @@ boolean P_HomingAttack(mobj_t *source, mobj_t *enemy) // Home in on your target
if (enemy->health <= 0) // dead
return false;
if (!((enemy->flags & (MF_ENEMY|MF_BOSS|MF_MONITOR) && (enemy->flags & MF_SHOOTABLE)) || (enemy->flags & MF_SPRING)) == !(enemy->flags2 & MF2_INVERTAIMABLE)) // allows if it has the flags desired XOR it has the invert aimable flag
if (source->player && (!((enemy->flags & (MF_ENEMY|MF_BOSS|MF_MONITOR) && (enemy->flags & MF_SHOOTABLE)) || (enemy->flags & MF_SPRING)) == !(enemy->flags2 & MF2_INVERTAIMABLE))) // allows if it has the flags desired XOR it has the invert aimable flag
return false;
if (enemy->flags2 & MF2_FRET)
@ -12209,7 +12213,7 @@ void P_PlayerThink(player_t *player)
player->powers[pw_nocontrol]--;
else
player->powers[pw_nocontrol] = 0;
//pw_super acts as a timer now
if (player->powers[pw_super]
&& (player->mo->state < &states[S_PLAY_SUPER_TRANS1]
@ -12854,6 +12858,12 @@ void P_PlayerAfterThink(player_t *player)
player->mo->flags |= MF_NOGRAVITY;
}
if (player->powers[pw_dye])
{
player->mo->colorized = true;
player->mo->color = player->powers[pw_dye];
}
if (player->followmobj && (player->spectator || player->mo->health <= 0 || player->followmobj->type != player->followitem))
{
P_RemoveMobj(player->followmobj);

View file

@ -955,8 +955,8 @@ static void R_Subsector(size_t num)
*rover->bottomheight;
if (planecenterz <= ceilingcenterz
&& planecenterz >= floorcenterz
&& ((viewz < heightcheck && !(rover->flags & FF_INVERTPLANES))
|| (viewz > heightcheck && (rover->flags & FF_BOTHPLANES))))
&& ((viewz < heightcheck && (rover->flags & FF_BOTHPLANES || !(rover->flags & FF_INVERTPLANES)))
|| (viewz > heightcheck && (rover->flags & FF_BOTHPLANES || rover->flags & FF_INVERTPLANES))))
{
light = R_GetPlaneLight(frontsector, planecenterz,
viewz < heightcheck);
@ -993,8 +993,8 @@ static void R_Subsector(size_t num)
*rover->topheight;
if (planecenterz >= floorcenterz
&& planecenterz <= ceilingcenterz
&& ((viewz > heightcheck && !(rover->flags & FF_INVERTPLANES))
|| (viewz < heightcheck && (rover->flags & FF_BOTHPLANES))))
&& ((viewz > heightcheck && (rover->flags & FF_BOTHPLANES || !(rover->flags & FF_INVERTPLANES)))
|| (viewz < heightcheck && (rover->flags & FF_BOTHPLANES || rover->flags & FF_INVERTPLANES))))
{
light = R_GetPlaneLight(frontsector, planecenterz, viewz < heightcheck);

View file

@ -721,14 +721,12 @@ Rloadflats (INT32 i, INT32 w)
}
else
{
texstart = W_CheckNumForNamePwad("F_START", (UINT16)w, 0);
texstart = W_CheckNumForMarkerStartPwad("F_START", (UINT16)w, 0);
texend = W_CheckNumForNamePwad("F_END", (UINT16)w, texstart);
}
if (!( texstart == INT16_MAX || texend == INT16_MAX ))
{
texstart++; // Do not count the first marker
// Work through each lump between the markers in the WAD.
for (j = 0; j < (texend - texstart); j++)
{
@ -841,7 +839,7 @@ Rloadtextures (INT32 i, INT32 w)
}
else
{
texstart = W_CheckNumForNamePwad(TX_START, (UINT16)w, 0);
texstart = W_CheckNumForMarkerStartPwad(TX_START, (UINT16)w, 0);
texend = W_CheckNumForNamePwad(TX_END, (UINT16)w, 0);
texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, 0);
if (texturesLumpPos != INT16_MAX)
@ -850,8 +848,6 @@ Rloadtextures (INT32 i, INT32 w)
if (!( texstart == INT16_MAX || texend == INT16_MAX ))
{
texstart++; // Do not count the first marker
// Work through each lump between the markers in the WAD.
for (j = 0; j < (texend - texstart); j++)
{
@ -958,14 +954,12 @@ void R_LoadTextures(void)
}
else
{
texstart = W_CheckNumForNamePwad("F_START", (UINT16)w, 0);
texstart = W_CheckNumForMarkerStartPwad("F_START", (UINT16)w, 0);
texend = W_CheckNumForNamePwad("F_END", (UINT16)w, texstart);
}
if (!( texstart == INT16_MAX || texend == INT16_MAX ))
{
texstart++; // Do not count the first marker
// PK3s have subfolders, so we can't just make a simple sum
if (wadfiles[w]->type == RET_PK3)
{
@ -998,15 +992,13 @@ void R_LoadTextures(void)
}
else
{
texstart = W_CheckNumForNamePwad(TX_START, (UINT16)w, 0);
texstart = W_CheckNumForMarkerStartPwad(TX_START, (UINT16)w, 0);
texend = W_CheckNumForNamePwad(TX_END, (UINT16)w, 0);
}
if (texstart == INT16_MAX || texend == INT16_MAX)
continue;
texstart++; // Do not count the first marker
// PK3s have subfolders, so we can't just make a simple sum
if (wadfiles[w]->type == RET_PK3)
{
@ -1592,9 +1584,9 @@ lumpnum_t R_GetFlatNumForName(const char *name)
switch (wadfiles[i]->type)
{
case RET_WAD:
if ((start = W_CheckNumForNamePwad("F_START", (UINT16)i, 0)) == INT16_MAX)
if ((start = W_CheckNumForMarkerStartPwad("F_START", (UINT16)i, 0)) == INT16_MAX)
{
if ((start = W_CheckNumForNamePwad("FF_START", (UINT16)i, 0)) == INT16_MAX)
if ((start = W_CheckNumForMarkerStartPwad("FF_START", (UINT16)i, 0)) == INT16_MAX)
continue;
else if ((end = W_CheckNumForNamePwad("FF_END", (UINT16)i, start)) == INT16_MAX)
continue;

View file

@ -146,6 +146,24 @@ boolean R_CheckDefaultColormap(extracolormap_t *extra_colormap, boolean checkrgb
boolean R_CheckEqualColormaps(extracolormap_t *exc_a, extracolormap_t *exc_b, boolean checkrgba, boolean checkfadergba, boolean checkparams);
extracolormap_t *R_GetColormapFromList(extracolormap_t *extra_colormap);
typedef enum
{
TMCF_RELATIVE = 1,
TMCF_SUBLIGHTR = 1<<1,
TMCF_SUBLIGHTG = 1<<2,
TMCF_SUBLIGHTB = 1<<3,
TMCF_SUBLIGHTA = 1<<4,
TMCF_SUBFADER = 1<<5,
TMCF_SUBFADEG = 1<<6,
TMCF_SUBFADEB = 1<<7,
TMCF_SUBFADEA = 1<<8,
TMCF_SUBFADESTART = 1<<9,
TMCF_SUBFADEEND = 1<<10,
TMCF_IGNOREFLAGS = 1<<11,
TMCF_FROMBLACK = 1<<12,
TMCF_OVERRIDE = 1<<13,
} textmapcolormapflags_t;
lighttable_t *R_CreateLightTable(extracolormap_t *extra_colormap);
extracolormap_t * R_CreateColormapFromLinedef(char *p1, char *p2, char *p3);
extracolormap_t* R_CreateColormap(INT32 rgba, INT32 fadergba, UINT8 fadestart, UINT8 fadeend, UINT8 flags);

View file

@ -130,11 +130,11 @@ typedef enum
FF_CUTEXTRA = 0x100, ///< Cuts out hidden translucent pixels.
FF_CUTLEVEL = 0x180, ///< Cuts out all hidden pixels.
FF_CUTSPRITES = 0x200, ///< Final step in making 3D water.
FF_BOTHPLANES = 0x400, ///< Renders both planes all the time.
FF_BOTHPLANES = 0x400, ///< Render inside and outside planes.
FF_EXTRA = 0x800, ///< Gets cut by ::FF_CUTEXTRA.
FF_TRANSLUCENT = 0x1000, ///< See through!
FF_FOG = 0x2000, ///< Fog "brush."
FF_INVERTPLANES = 0x4000, ///< Reverse the plane visibility rules.
FF_INVERTPLANES = 0x4000, ///< Only render inside planes.
FF_ALLSIDES = 0x8000, ///< Render inside and outside sides.
FF_INVERTSIDES = 0x10000, ///< Only render inside sides.
FF_DOUBLESHADOW = 0x20000, ///< Make two lightlist entries to reset light?
@ -328,11 +328,6 @@ typedef struct sector_s
size_t linecount;
struct line_s **lines; // [linecount] size
// Hack: store special line tagging to some sectors
// to efficiently help work around bugs by directly
// referencing the specific line that the problem happens in.
// (used in T_MovePlane mobj physics)
struct line_s *tagline;
// Improved fake floor hack
ffloor_t *ffloors;

View file

@ -233,11 +233,11 @@ const UINT8 Color_Index[MAXTRANSLATIONS-1][16] = {
{0x00, 0xd0, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x44, 0x45, 0x46}, // SKINCOLOR_SUPERORANGE4
{0xd0, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x44, 0x45, 0x46, 0x47}, // SKINCOLOR_SUPERORANGE5
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50, 0x51, 0x52, 0x53, 0x48}, // SKINCOLOR_SUPERGOLD1
{0x00, 0x50, 0x51, 0x52, 0x53, 0x53, 0x48, 0x48, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x40, 0x41}, // SKINCOLOR_SUPERGOLD2
{0x51, 0x52, 0x53, 0x53, 0x48, 0x48, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x40, 0x41, 0x42, 0x43}, // SKINCOLOR_SUPERGOLD3
{0x53, 0x48, 0x48, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46}, // SKINCOLOR_SUPERGOLD4
{0x48, 0x48, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47}, // SKINCOLOR_SUPERGOLD5
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50, 0x51, 0x52, 0x53, 0x48, 0x48, 0x48}, // SKINCOLOR_SUPERGOLD1
{0x00, 0x50, 0x51, 0x52, 0x53, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x40, 0x41, 0x41, 0x41}, // SKINCOLOR_SUPERGOLD2
{0x51, 0x52, 0x53, 0x53, 0x48, 0x49, 0x49, 0x49, 0x49, 0x49, 0x40, 0x41, 0x42, 0x43, 0x43, 0x43}, // SKINCOLOR_SUPERGOLD3
{0x53, 0x48, 0x48, 0x49, 0x49, 0x49, 0x49, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x46, 0x46}, // SKINCOLOR_SUPERGOLD4
{0x48, 0x48, 0x49, 0x49, 0x49, 0x40, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x47, 0x47}, // SKINCOLOR_SUPERGOLD5
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x58, 0x58, 0xbc, 0xbc, 0xbc}, // SKINCOLOR_SUPERPERIDOT1
{0x00, 0x58, 0x58, 0x58, 0xbc, 0xbc, 0xbc, 0xbc, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbe, 0xbe}, // SKINCOLOR_SUPERPERIDOT2

View file

@ -2163,7 +2163,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
{
if (!(rover->flags & FF_RENDERSIDES) || !(rover->flags & FF_EXISTS))
continue;
if (rover->flags & FF_INVERTSIDES)
if (!(rover->flags & FF_ALLSIDES) && rover->flags & FF_INVERTSIDES)
continue;
if (rover->norender == leveltime)
@ -2218,7 +2218,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
{
if (!(rover->flags & FF_RENDERSIDES) || !(rover->flags & FF_EXISTS))
continue;
if (!(rover->flags & FF_ALLSIDES))
if (!(rover->flags & FF_ALLSIDES || rover->flags & FF_INVERTSIDES))
continue;
if (rover->norender == leveltime)
@ -2273,7 +2273,9 @@ void R_StoreWallRange(INT32 start, INT32 stop)
{
for (rover = backsector->ffloors, i = 0; rover && i < MAXFFLOORS; rover = rover->next)
{
if (!(rover->flags & FF_RENDERSIDES) || !(rover->flags & FF_EXISTS) || rover->flags & FF_INVERTSIDES)
if (!(rover->flags & FF_RENDERSIDES) || !(rover->flags & FF_EXISTS))
continue;
if (!(rover->flags & FF_ALLSIDES) && rover->flags & FF_INVERTSIDES)
continue;
if (rover->norender == leveltime)
continue;
@ -2293,7 +2295,9 @@ void R_StoreWallRange(INT32 start, INT32 stop)
{
for (rover = frontsector->ffloors, i = 0; rover && i < MAXFFLOORS; rover = rover->next)
{
if (!(rover->flags & FF_RENDERSIDES) || !(rover->flags & FF_EXISTS) || !(rover->flags & FF_ALLSIDES))
if (!(rover->flags & FF_RENDERSIDES) || !(rover->flags & FF_EXISTS))
continue;
if (!(rover->flags & FF_ALLSIDES || rover->flags & FF_INVERTSIDES))
continue;
if (rover->norender == leveltime)
continue;
@ -2618,8 +2622,8 @@ void R_StoreWallRange(INT32 start, INT32 stop)
if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) &&
(roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) &&
((viewz < planevistest && !(rover->flags & FF_INVERTPLANES)) ||
(viewz > planevistest && (rover->flags & FF_BOTHPLANES))))
((viewz < planevistest && (rover->flags & FF_BOTHPLANES || !(rover->flags & FF_INVERTPLANES))) ||
(viewz > planevistest && (rover->flags & FF_BOTHPLANES || rover->flags & FF_INVERTPLANES))))
{
//ffloor[i].slope = *rover->b_slope;
ffloor[i].b_pos = roverleft;
@ -2641,8 +2645,8 @@ void R_StoreWallRange(INT32 start, INT32 stop)
if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) &&
(roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) &&
((viewz > planevistest && !(rover->flags & FF_INVERTPLANES)) ||
(viewz < planevistest && (rover->flags & FF_BOTHPLANES))))
((viewz > planevistest && (rover->flags & FF_BOTHPLANES || !(rover->flags & FF_INVERTPLANES))) ||
(viewz < planevistest && (rover->flags & FF_BOTHPLANES || rover->flags & FF_INVERTPLANES))))
{
//ffloor[i].slope = *rover->t_slope;
ffloor[i].b_pos = roverleft;
@ -2675,8 +2679,8 @@ void R_StoreWallRange(INT32 start, INT32 stop)
if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) &&
(roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) &&
((viewz < planevistest && !(rover->flags & FF_INVERTPLANES)) ||
(viewz > planevistest && (rover->flags & FF_BOTHPLANES))))
((viewz < planevistest && (rover->flags & FF_BOTHPLANES || !(rover->flags & FF_INVERTPLANES))) ||
(viewz > planevistest && (rover->flags & FF_BOTHPLANES || rover->flags & FF_INVERTPLANES))))
{
//ffloor[i].slope = *rover->b_slope;
ffloor[i].b_pos = roverleft;
@ -2698,8 +2702,8 @@ void R_StoreWallRange(INT32 start, INT32 stop)
if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) &&
(roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) &&
((viewz > planevistest && !(rover->flags & FF_INVERTPLANES)) ||
(viewz < planevistest && (rover->flags & FF_BOTHPLANES))))
((viewz > planevistest && (rover->flags & FF_BOTHPLANES || !(rover->flags & FF_INVERTPLANES))) ||
(viewz < planevistest && (rover->flags & FF_BOTHPLANES || rover->flags & FF_INVERTPLANES))))
{
//ffloor[i].slope = *rover->t_slope;
ffloor[i].b_pos = roverleft;

View file

@ -504,6 +504,7 @@ static boolean R_ProcessPatchableFields(skin_t *skin, char *stoken, char *value)
GETFLAG(FASTEDGE)
GETFLAG(MULTIABILITY)
GETFLAG(NONIGHTSROTATION)
GETFLAG(NONIGHTSSUPER)
#undef GETFLAG
else // let's check if it's a sound, otherwise error out

View file

@ -428,9 +428,9 @@ void R_AddSpriteDefs(UINT16 wadnum)
switch (wadfiles[wadnum]->type)
{
case RET_WAD:
start = W_CheckNumForNamePwad("S_START", wadnum, 0);
start = W_CheckNumForMarkerStartPwad("S_START", wadnum, 0);
if (start == INT16_MAX)
start = W_CheckNumForNamePwad("SS_START", wadnum, 0); //deutex compatib.
start = W_CheckNumForMarkerStartPwad("SS_START", wadnum, 0); //deutex compatib.
end = W_CheckNumForNamePwad("S_END",wadnum,start);
if (end == INT16_MAX)
@ -452,8 +452,6 @@ void R_AddSpriteDefs(UINT16 wadnum)
start = 0; //let say S_START is lump 0
}
else
start++; // just after S_START
if (end == INT16_MAX || start >= end)
{

View file

@ -1456,6 +1456,7 @@ musicdef_t soundtestsfx = {
0, // with no conditions
0,
0,
0,
false,
NULL
};
@ -1651,6 +1652,8 @@ ReadMusicDefFields (UINT16 wadnum, int line, boolean fields, char *stoken,
fixed_t bpmf = FLOAT_TO_FIXED(bpm);
if (bpmf > 0)
def->bpm = FixedDiv((60*TICRATE)<<FRACBITS, bpmf);
} else if (!stricmp(stoken, "loopms")) {
def->loop_ms = atoi(textline);
} else {
CONS_Alert(CONS_WARNING,
"MUSICDEF: Invalid field '%s'. (file %s, line %d)\n",
@ -2262,6 +2265,8 @@ static void S_UnloadMusic(void)
static boolean S_PlayMusic(boolean looping, UINT32 fadeinms)
{
musicdef_t *def;
if (S_MusicDisabled())
return false;
@ -2273,6 +2278,17 @@ static boolean S_PlayMusic(boolean looping, UINT32 fadeinms)
return false;
}
/* set loop point from MUSICDEF */
for (def = musicdefstart; def; def = def->next)
{
if (strcasecmp(def->name, music_name) == 0)
{
if (def->loop_ms)
S_SetMusicLoopPoint(def->loop_ms);
break;
}
}
S_InitMusicVolume(); // switch between digi and sequence volume
if (S_MusicNotInFocus())

View file

@ -208,6 +208,7 @@ typedef struct musicdef_s
INT16 soundtestcond; // +ve for map, -ve for conditionset, 0 for already here
tic_t stoppingtics;
fixed_t bpm;
UINT32 loop_ms;/* override LOOPPOINT/LOOPMS */
boolean allowed; // question marks or listenable on sound test?
struct musicdef_s *next;
} musicdef_t;

View file

@ -449,7 +449,7 @@ void SCR_ActuallyChangeRenderer(void)
#ifdef HWRENDER
// Well, it didn't even load anyway.
if ((hwrenderloaded == -1) && (setrenderneeded == render_opengl))
if ((vid_opengl_state == -1) && (setrenderneeded == render_opengl))
{
if (M_CheckParm("-nogl"))
CONS_Alert(CONS_ERROR, "OpenGL rendering was disabled!\n");
@ -474,7 +474,7 @@ void SCR_ChangeRenderer(void)
{
target_renderer = cv_renderer.value;
#ifdef HWRENDER
if (M_CheckParm("-opengl") && (hwrenderloaded == 1))
if (M_CheckParm("-opengl") && (vid_opengl_state == 1))
target_renderer = rendermode = render_opengl;
else
#endif

View file

@ -213,6 +213,7 @@
<ClInclude Include="..\fastcmp.h" />
<ClInclude Include="..\filesrch.h" />
<ClInclude Include="..\f_finale.h" />
<ClInclude Include="..\g_demo.h" />
<ClInclude Include="..\g_game.h" />
<ClInclude Include="..\g_input.h" />
<ClInclude Include="..\g_state.h" />
@ -364,6 +365,7 @@
<ClCompile Include="..\filesrch.c" />
<ClCompile Include="..\f_finale.c" />
<ClCompile Include="..\f_wipe.c" />
<ClCompile Include="..\g_demo.c" />
<ClCompile Include="..\g_game.c" />
<ClCompile Include="..\g_input.c" />
<ClCompile Include="..\hardware\hw3sound.c" />

View file

@ -180,6 +180,9 @@
<ClInclude Include="..\f_finale.h">
<Filter>F_Frame</Filter>
</ClInclude>
<ClInclude Include="..\g_demo.h">
<Filter>G_Game</Filter>
</ClInclude>
<ClInclude Include="..\g_game.h">
<Filter>G_Game</Filter>
</ClInclude>
@ -600,6 +603,9 @@
<ClCompile Include="..\f_wipe.c">
<Filter>F_Frame</Filter>
</ClCompile>
<ClCompile Include="..\g_demo.c">
<Filter>G_Game</Filter>
</ClCompile>
<ClCompile Include="..\g_game.c">
<Filter>G_Game</Filter>
</ClCompile>

View file

@ -104,7 +104,7 @@ static consvar_t cv_stretch = {"stretch", "Off", CV_SAVE|CV_NOSHOWHELP, CV_OnOff
static consvar_t cv_alwaysgrabmouse = {"alwaysgrabmouse", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
UINT8 graphics_started = 0; // Is used in console.c and screen.c
INT32 hwrenderloaded = 0;
INT32 vid_opengl_state = 0;
// To disable fullscreen at startup; is set in VID_PrepareModeList
boolean allow_fullscreen = false;
@ -1440,7 +1440,7 @@ static SDL_bool Impl_CreateContext(void)
{
// Renderer-specific stuff
#ifdef HWRENDER
if ((rendermode == render_opengl) && (hwrenderloaded != -1))
if ((rendermode == render_opengl) && (vid_opengl_state != -1))
{
if (!sdlglcontext)
sdlglcontext = SDL_GL_CreateContext(window);
@ -1473,10 +1473,10 @@ static SDL_bool Impl_CreateContext(void)
return SDL_TRUE;
}
#ifdef HWRENDER
static void VID_CheckGLLoaded(rendermode_t oldrender)
void VID_CheckGLLoaded(rendermode_t oldrender)
{
if (hwrenderloaded == -1) // Well, it didn't work the first time anyway.
#ifdef HWRENDER
if (vid_opengl_state == -1) // Well, it didn't work the first time anyway.
{
rendermode = oldrender;
if (chosenrendermode == render_opengl) // fallback to software
@ -1488,40 +1488,66 @@ static void VID_CheckGLLoaded(rendermode_t oldrender)
setrenderneeded = 0;
}
}
}
#endif
}
void VID_CheckRenderer(void)
{
SDL_bool rendererchanged = SDL_FALSE;
boolean rendererchanged = false;
boolean contextcreated = false;
rendermode_t oldrenderer = rendermode;
if (dedicated)
return;
#ifdef HWRENDER
if (!graphics_started)
VID_CheckGLLoaded(oldrenderer);
#endif
if (setrenderneeded)
{
rendermode = setrenderneeded;
rendererchanged = SDL_TRUE;
rendererchanged = true;
#ifdef HWRENDER
if (rendermode == render_opengl)
{
VID_CheckGLLoaded(oldrenderer);
// Initialise OpenGL before calling SDLSetMode!!!
if (hwrenderloaded != 1)
I_StartupHardwareGraphics();
else if (hwrenderloaded == -1)
rendererchanged = SDL_FALSE;
// This is because SDLSetMode calls OglSdlSurface.
if (vid_opengl_state == 0)
{
VID_StartupOpenGL();
// Loaded successfully!
if (vid_opengl_state == 1)
{
// Destroy the current window, if it exists.
if (window)
{
SDL_DestroyWindow(window);
window = NULL;
}
// Destroy the current window rendering context, if that also exists.
if (renderer)
{
SDL_DestroyRenderer(renderer);
renderer = NULL;
}
// Create a new window.
Impl_CreateWindow(USE_FULLSCREEN);
// From there, the OpenGL context was already created.
contextcreated = true;
}
}
else if (vid_opengl_state == -1)
rendererchanged = false;
}
#endif
Impl_CreateContext();
if (!contextcreated)
Impl_CreateContext();
setrenderneeded = 0;
}
SDLSetMode(vid.width, vid.height, USE_FULLSCREEN, (rendererchanged ? SDL_FALSE : SDL_TRUE));
@ -1534,15 +1560,25 @@ void VID_CheckRenderer(void)
SDL_FreeSurface(bufSurface);
bufSurface = NULL;
}
if (rendererchanged)
{
#ifdef HWRENDER
if (hwrenderloaded == 1) // Only if OpenGL ever loaded!
HWR_FreeTextureCache();
if (vid_opengl_state == 1) // Only if OpenGL ever loaded!
HWR_FreeTextureCache();
#endif
SCR_SetDrawFuncs();
SCR_SetDrawFuncs();
}
}
#ifdef HWRENDER
else if (rendermode == render_opengl)
R_InitHardwareMode();
{
if (rendererchanged)
{
R_InitHardwareMode();
V_SetPalette(0);
}
}
#else
(void)oldrenderer;
#endif
@ -1586,7 +1622,7 @@ static SDL_bool Impl_CreateWindow(SDL_bool fullscreen)
flags |= SDL_WINDOW_BORDERLESS;
#ifdef HWRENDER
if (hwrenderloaded != -1)
if (vid_opengl_state == 1)
flags |= SDL_WINDOW_OPENGL;
#endif
@ -1720,11 +1756,12 @@ void I_StartupGraphics(void)
//SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY>>1,SDL_DEFAULT_REPEAT_INTERVAL<<2);
VID_Command_ModeList_f();
#ifdef HWRENDER
if (M_CheckParm("-nogl"))
hwrenderloaded = -1; // Don't call SDL_GL_LoadLibrary
else
I_StartupHardwareGraphics();
vid_opengl_state = -1; // Don't startup OpenGL
else if (chosenrendermode == render_opengl)
VID_StartupOpenGL();
#endif
// Fury: we do window initialization after GL setup to allow
@ -1779,12 +1816,13 @@ void I_StartupGraphics(void)
graphics_started = true;
}
void I_StartupHardwareGraphics(void)
void VID_StartupOpenGL(void)
{
#ifdef HWRENDER
static boolean glstartup = false;
if (!glstartup)
{
CONS_Printf("VID_StartupOpenGL()...\n");
HWD.pfnInit = hwSym("Init",NULL);
HWD.pfnFinishUpdate = NULL;
HWD.pfnDraw2DLine = hwSym("Draw2DLine",NULL);
@ -1816,13 +1854,13 @@ void I_StartupHardwareGraphics(void)
// check gl renderer lib
if (HWD.pfnGetRenderVersion() != VERSION)
{
CONS_Alert(CONS_ERROR, M_GetText("The version of the renderer doesn't match the version of the executable\nBe sure you have installed SRB2 properly.\n"));
hwrenderloaded = -1;
CONS_Alert(CONS_ERROR, M_GetText("The version of the renderer doesn't match the version of the executable!\nBe sure you have installed SRB2 properly.\n"));
vid_opengl_state = -1;
}
else
hwrenderloaded = HWD.pfnInit(I_Error) ? 1 : -1; // let load the OpenGL library
vid_opengl_state = HWD.pfnInit(I_Error) ? 1 : -1; // let load the OpenGL library
if (hwrenderloaded == -1)
if (vid_opengl_state == -1)
{
rendermode = render_soft;
setrenderneeded = 0;

View file

@ -1331,6 +1331,16 @@ void ST_drawTitleCard(void)
INT32 ttlscroll = FixedInt(lt_scroll);
INT32 zzticker;
patch_t *actpat, *zigzag, *zztext;
UINT8 colornum;
const UINT8 *colormap;
stplyr = &players[consoleplayer];
if (stplyr->skincolor)
colornum = stplyr->skincolor;
else
colornum = cv_playercolor.value;
colormap = R_GetTranslationColormap(TC_DEFAULT, colornum, GTC_CACHE);
if (!G_IsTitleCardAvailable())
return;
@ -1364,16 +1374,16 @@ void ST_drawTitleCard(void)
if (!splitscreen || (splitscreen && stplyr == &players[displayplayer]))
{
zzticker = lt_ticker;
V_DrawScaledPatch(FixedInt(lt_zigzag), (-zzticker) % zigzag->height, V_SNAPTOTOP|V_SNAPTOLEFT, zigzag);
V_DrawScaledPatch(FixedInt(lt_zigzag), (zigzag->height-zzticker) % zigzag->height, V_SNAPTOTOP|V_SNAPTOLEFT, zigzag);
V_DrawScaledPatch(FixedInt(lt_zigzag), (-zigzag->height+zzticker) % zztext->height, V_SNAPTOTOP|V_SNAPTOLEFT, zztext);
V_DrawScaledPatch(FixedInt(lt_zigzag), (zzticker) % zztext->height, V_SNAPTOTOP|V_SNAPTOLEFT, zztext);
V_DrawMappedPatch(FixedInt(lt_zigzag), (-zzticker) % zigzag->height, V_SNAPTOTOP|V_SNAPTOLEFT, zigzag, colormap);
V_DrawMappedPatch(FixedInt(lt_zigzag), (zigzag->height-zzticker) % zigzag->height, V_SNAPTOTOP|V_SNAPTOLEFT, zigzag, colormap);
V_DrawMappedPatch(FixedInt(lt_zigzag), (-zigzag->height+zzticker) % zztext->height, V_SNAPTOTOP|V_SNAPTOLEFT, zztext, colormap);
V_DrawMappedPatch(FixedInt(lt_zigzag), (zzticker) % zztext->height, V_SNAPTOTOP|V_SNAPTOLEFT, zztext, colormap);
}
if (actnum)
{
if (!splitscreen)
V_DrawScaledPatch(ttlnumxpos + ttlscroll, 104 - ttlscroll, 0, actpat);
V_DrawMappedPatch(ttlnumxpos + ttlscroll, 104 - ttlscroll, 0, actpat, colormap);
V_DrawLevelActNum(ttlnumxpos + ttlscroll, 104, V_PERPLAYER, actnum);
}

View file

@ -194,7 +194,6 @@ static inline void W_LoadDehackedLumpsPK3(UINT16 wadnum, boolean mainfile)
if (posStart != INT16_MAX)
{
posEnd = W_CheckNumForFolderEndPK3("Lua/", wadnum, posStart);
posStart++; // first "lump" will be "Lua/" folder itself, so ignore it
for (; posStart < posEnd; posStart++)
LUA_LoadLump(wadnum, posStart);
}
@ -204,7 +203,6 @@ static inline void W_LoadDehackedLumpsPK3(UINT16 wadnum, boolean mainfile)
{
posEnd = W_CheckNumForFolderEndPK3("SOC/", wadnum, posStart);
posStart++; // first "lump" will be "SOC/" folder itself, so ignore it
for(; posStart < posEnd; posStart++)
{
lumpinfo_t *lump_p = &wadfiles[wadnum]->lumpinfo[posStart];
@ -525,8 +523,8 @@ typedef struct zlentry_s
static lumpinfo_t* ResGetLumpsZip (FILE* handle, UINT16* nlmp)
{
zend_t zend;
zentry_t* zentries;
zentry_t* zentry;
zentry_t zentry;
zlentry_t zlentry;
UINT16 numlumps = *nlmp;
lumpinfo_t* lumpinfo;
@ -554,40 +552,36 @@ static lumpinfo_t* ResGetLumpsZip (FILE* handle, UINT16* nlmp)
numlumps = zend.entries;
lump_p = lumpinfo = Z_Malloc(numlumps * sizeof (*lumpinfo), PU_STATIC, NULL);
zentry = zentries = malloc(numlumps * sizeof (*zentries));
fseek(handle, zend.cdiroffset, SEEK_SET);
for (i = 0; i < numlumps; i++, zentry++, lump_p++)
for (i = 0; i < numlumps; i++, lump_p++)
{
char* fullname;
char* trimname;
char* dotpos;
if (fread(zentry, 1, sizeof(zentry_t), handle) < sizeof(zentry_t))
if (fread(&zentry, 1, sizeof(zentry_t), handle) < sizeof(zentry_t))
{
CONS_Alert(CONS_ERROR, "Failed to read central directory (%s)\n", M_FileError(handle));
Z_Free(lumpinfo);
free(zentries);
return NULL;
}
if (memcmp(zentry->signature, pat_central, 4))
if (memcmp(zentry.signature, pat_central, 4))
{
CONS_Alert(CONS_ERROR, "Central directory is corrupt\n");
Z_Free(lumpinfo);
free(zentries);
return NULL;
}
lump_p->position = zentry->offset + zentry->namelen + zentry->xtralen + sizeof(zlentry_t);
lump_p->disksize = zentry->compsize;
lump_p->size = zentry->size;
lump_p->position = zentry.offset; // NOT ACCURATE YET: we still need to read the local entry to find our true position
lump_p->disksize = zentry.compsize;
lump_p->size = zentry.size;
fullname = malloc(zentry->namelen + 1);
if (fgets(fullname, zentry->namelen + 1, handle) != fullname)
fullname = malloc(zentry.namelen + 1);
if (fgets(fullname, zentry.namelen + 1, handle) != fullname)
{
CONS_Alert(CONS_ERROR, "Unable to read lumpname (%s)\n", M_FileError(handle));
Z_Free(lumpinfo);
free(zentries);
free(fullname);
return NULL;
}
@ -604,12 +598,12 @@ static lumpinfo_t* ResGetLumpsZip (FILE* handle, UINT16* nlmp)
memset(lump_p->name, '\0', 9); // Making sure they're initialized to 0. Is it necessary?
strncpy(lump_p->name, trimname, min(8, dotpos - trimname));
lump_p->name2 = Z_Calloc(zentry->namelen + 1, PU_STATIC, NULL);
strncpy(lump_p->name2, fullname, zentry->namelen);
lump_p->name2 = Z_Calloc(zentry.namelen + 1, PU_STATIC, NULL);
strncpy(lump_p->name2, fullname, zentry.namelen);
free(fullname);
switch(zentry->compression)
switch(zentry.compression)
{
case 0:
lump_p->compression = CM_NOCOMPRESSION;
@ -627,9 +621,29 @@ static lumpinfo_t* ResGetLumpsZip (FILE* handle, UINT16* nlmp)
lump_p->compression = CM_UNSUPPORTED;
break;
}
// skip and ignore comments/extra fields
if (fseek(handle, zentry.xtralen + zentry.commlen, SEEK_CUR) != 0)
{
CONS_Alert(CONS_ERROR, "Central directory is corrupt\n");
Z_Free(lumpinfo);
return NULL;
}
}
free(zentries);
// Adjust lump position values properly
for (i = 0, lump_p = lumpinfo; i < numlumps; i++, lump_p++)
{
// skip and ignore comments/extra fields
if ((fseek(handle, lump_p->position, SEEK_SET) != 0) || (fread(&zlentry, 1, sizeof(zlentry_t), handle) < sizeof(zlentry_t)))
{
CONS_Alert(CONS_ERROR, "Local headers for lump %s are corrupt\n", lump_p->name2);
Z_Free(lumpinfo);
return NULL;
}
lump_p->position += sizeof(zlentry_t) + zlentry.namelen + zlentry.xtralen;
}
*nlmp = numlumps;
return lumpinfo;
@ -914,15 +928,32 @@ UINT16 W_CheckNumForNamePwad(const char *name, UINT16 wad, UINT16 startlump)
return INT16_MAX;
}
UINT16
W_CheckNumForMarkerStartPwad (const char *name, UINT16 wad, UINT16 startlump)
{
UINT16 marker;
marker = W_CheckNumForNamePwad(name, wad, startlump);
if (marker != INT16_MAX)
marker++; // Do not count the first marker
return marker;
}
// Look for the first lump from a folder.
UINT16 W_CheckNumForFolderStartPK3(const char *name, UINT16 wad, UINT16 startlump)
{
size_t name_length;
INT32 i;
lumpinfo_t *lump_p = wadfiles[wad]->lumpinfo + startlump;
name_length = strlen(name);
for (i = startlump; i < wadfiles[wad]->numlumps; i++, lump_p++)
{
if (strnicmp(name, lump_p->name2, strlen(name)) == 0)
if (strnicmp(name, lump_p->name2, name_length) == 0)
{
/* SLADE is special and puts a single directory entry. Skip that. */
if (strlen(lump_p->name2) == name_length)
i++;
break;
}
}
return i;
}
@ -1025,7 +1056,7 @@ lumpnum_t W_CheckNumForMap(const char *name)
else
continue;
// Now look for the specified map.
for (++lumpNum; lumpNum < end; lumpNum++)
for (; lumpNum < end; lumpNum++)
if (!strnicmp(name, (wadfiles[i]->lumpinfo + lumpNum)->name, 8))
return (i<<16) + lumpNum;
}
@ -1505,6 +1536,57 @@ void *W_CacheLumpName(const char *name, INT32 tag)
// Cache a patch into heap memory, convert the patch format as necessary
//
void *W_CacheSoftwarePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag)
{
lumpcache_t *lumpcache = NULL;
if (needpatchflush)
W_FlushCachedPatches();
if (!TestValidLump(wad, lump))
return NULL;
lumpcache = wadfiles[wad]->patchcache;
if (!lumpcache[lump])
{
size_t len = W_LumpLengthPwad(wad, lump);
void *ptr, *lumpdata;
#ifndef NO_PNG_LUMPS
void *srcdata = NULL;
#endif
ptr = Z_Malloc(len, tag, &lumpcache[lump]);
lumpdata = Z_Malloc(len, tag, NULL);
// read the lump in full
W_ReadLumpHeaderPwad(wad, lump, lumpdata, 0, 0);
#ifndef NO_PNG_LUMPS
// lump is a png so convert it
if (R_IsLumpPNG((UINT8 *)lumpdata, len))
{
size_t newlen;
srcdata = R_PNGToPatch((UINT8 *)lumpdata, len, &newlen);
ptr = Z_Realloc(ptr, newlen, tag, &lumpcache[lump]);
M_Memcpy(ptr, srcdata, newlen);
Z_Free(srcdata);
}
else // just copy it into the patch cache
#endif
M_Memcpy(ptr, lumpdata, len);
}
else
Z_ChangeTag(lumpcache[lump], tag);
return lumpcache[lump];
}
void *W_CacheSoftwarePatchNum(lumpnum_t lumpnum, INT32 tag)
{
return W_CacheSoftwarePatchNumPwad(WADFILENUM(lumpnum),LUMPNUM(lumpnum),tag);
}
void *W_CachePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag)
{
#ifdef HWRENDER
@ -1522,39 +1604,7 @@ void *W_CachePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag)
if (rendermode == render_soft || rendermode == render_none)
#endif
{
lumpcache_t *lumpcache = wadfiles[wad]->patchcache;
if (!lumpcache[lump])
{
size_t len = W_LumpLengthPwad(wad, lump);
void *ptr, *lumpdata;
#ifndef NO_PNG_LUMPS
void *srcdata = NULL;
#endif
ptr = Z_Malloc(len, tag, &lumpcache[lump]);
lumpdata = Z_Malloc(len, tag, NULL);
// read the lump in full
W_ReadLumpHeaderPwad(wad, lump, lumpdata, 0, 0);
#ifndef NO_PNG_LUMPS
// lump is a png so convert it
if (R_IsLumpPNG((UINT8 *)lumpdata, len))
{
size_t newlen;
srcdata = R_PNGToPatch((UINT8 *)lumpdata, len, &newlen);
ptr = Z_Realloc(ptr, newlen, tag, &lumpcache[lump]);
M_Memcpy(ptr, srcdata, newlen);
Z_Free(srcdata);
}
else // just copy it into the patch cache
#endif
M_Memcpy(ptr, lumpdata, len);
}
else
Z_ChangeTag(lumpcache[lump], tag);
return lumpcache[lump];
return W_CacheSoftwarePatchNumPwad(wad, lump, tag);
}
#ifdef HWRENDER
@ -1829,6 +1879,10 @@ W_VerifyPK3 (FILE *fp, lumpchecklist_t *checklist, boolean status)
}
free(fullname);
// skip and ignore comments/extra fields
if (fseek(fp, zentry.xtralen + zentry.commlen, SEEK_CUR) != 0)
return true;
}
return true;

View file

@ -156,6 +156,9 @@ const char *W_CheckNameForNum(lumpnum_t lumpnum);
UINT16 W_CheckNumForNamePwad(const char *name, UINT16 wad, UINT16 startlump); // checks only in one pwad
/* Find the first lump after F_START for instance. */
UINT16 W_CheckNumForMarkerStartPwad(const char *name, UINT16 wad, UINT16 startlump);
UINT16 W_CheckNumForFullNamePK3(const char *name, UINT16 wad, UINT16 startlump);
UINT16 W_CheckNumForFolderStartPK3(const char *name, UINT16 wad, UINT16 startlump);
UINT16 W_CheckNumForFolderEndPK3(const char *name, UINT16 wad, UINT16 startlump);
@ -191,8 +194,15 @@ boolean W_IsPatchCached(lumpnum_t lump, void *ptr);
void *W_CacheLumpName(const char *name, INT32 tag);
void *W_CachePatchName(const char *name, INT32 tag);
void *W_CachePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag); // return a patch_t
void *W_CachePatchNum(lumpnum_t lumpnum, INT32 tag); // return a patch_t
// Returns either a Software patch, or an OpenGL patch.
// Performs any necessary conversions from PNG images.
void *W_CachePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag);
void *W_CachePatchNum(lumpnum_t lumpnum, INT32 tag);
// Returns a Software patch.
// Performs any necessary conversions from PNG images.
void *W_CacheSoftwarePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag);
void *W_CacheSoftwarePatchNum(lumpnum_t lumpnum, INT32 tag);
void W_UnlockCachedPatch(void *patch);
void W_FlushCachedPatches(void);

View file

@ -239,10 +239,7 @@ void I_StartupGraphics(void)
if (!dedicated) graphics_started = true;
}
void I_StartupHardwareGraphics(void)
{
// oh yeah woo yeah oh yeah woo yeah oh yeah woo yeah oh yeah woo yeah oh yeah woo yeah oh yeah woo yeah oh yeah woo y
}
void VID_StartupOpenGL(void){}
// ------------------
// I_ShutdownGraphics
@ -951,10 +948,8 @@ INT32 VID_SetMode(INT32 modenum)
return 1;
}
void VID_CheckRenderer(void)
{
// ..............
}
void VID_CheckRenderer(void) {}
void VID_CheckGLLoaded(rendermode_t oldrender) {}
// ========================================================================
// Free the video buffer of the last video mode,