Compare commits
37
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
677e381a2c | ||
|
|
01b24e5417 | ||
|
|
f86a99cd1b | ||
|
|
85cac497ea | ||
|
|
92d6c2b7b0 | ||
|
|
f67f8e7dbf | ||
|
|
6adf39b460 | ||
|
|
e160427108 | ||
|
|
275d28c9c6 | ||
|
|
2a848e32e4 | ||
|
|
6af09bd215 | ||
|
|
015d9208e3 | ||
|
|
94d01d1ee9 | ||
|
|
7e5acd72c1 | ||
|
|
6017543666 | ||
|
|
3af0009453 | ||
|
|
145eecf8a4 | ||
|
|
684a43a95c | ||
|
|
4fcb41f659 | ||
|
|
8d1ef1721f | ||
|
|
02ffceb300 | ||
|
|
44fe156751 | ||
|
|
aca48d69cd | ||
|
|
294ce055cd | ||
|
|
4117eb5b40 | ||
|
|
a9068ee162 | ||
|
|
9549a204a5 | ||
|
|
c276736002 | ||
|
|
b5dfe74cfe | ||
|
|
6c891f1146 | ||
|
|
7d06f59da5 | ||
|
|
9dee0f0ea8 | ||
|
|
9338b5b10f | ||
|
|
b7ecffedcd | ||
|
|
7deeb4486f | ||
|
|
602bd1a010 | ||
|
|
f57b8092fc |
No files matched your search
@@ -30,6 +30,24 @@ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
0-Clause BSD License
|
||||
applies to:
|
||||
- qs22k
|
||||
Copyright (c) 2022, Raymond Gardner
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
|
||||
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
curl License
|
||||
applies to:
|
||||
|
||||
+18
-5
@@ -131,9 +131,19 @@ endif
|
||||
include Makefile.d/util.mk
|
||||
|
||||
ifdef PREFIX
|
||||
ifdef USECLANG
|
||||
CC:=$(PREFIX)-clang
|
||||
CXX:=$(PREFIX)-clang++
|
||||
else
|
||||
CC:=$(PREFIX)-gcc
|
||||
CXX:=$(PREFIX)-g++
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef USECLANG
|
||||
CC=clang
|
||||
CXX=clang++
|
||||
endif
|
||||
|
||||
OBJDUMP_OPTS?=--wide --source --line-numbers
|
||||
|
||||
@@ -236,7 +246,7 @@ endif
|
||||
# build with profiling information
|
||||
ifdef PROFILEMODE
|
||||
opts+=-pg
|
||||
libs+=-pg
|
||||
LDFLAGS+=-pg
|
||||
endif
|
||||
|
||||
ifdef DEBUGMODE
|
||||
@@ -248,10 +258,10 @@ ifdef USELTO
|
||||
# compile with LTO
|
||||
ifdef MINGW
|
||||
opts+=-flto=auto -g
|
||||
libs+=-flto=auto -g
|
||||
LDFLAGS+=-flto=auto -g
|
||||
else
|
||||
opts+=-flto=auto
|
||||
libs+=-flto=auto
|
||||
LDFLAGS+=-flto=auto
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
@@ -265,8 +275,10 @@ else
|
||||
opts+=-fsanitize=address
|
||||
libs+=-fsanitize=address
|
||||
endif
|
||||
opts+=-fsanitize=address
|
||||
libs+=-fsanitize=address
|
||||
endif
|
||||
|
||||
ifeq ($(CC),clang)
|
||||
LDFLAGS+= -fuse-ld=lld
|
||||
endif
|
||||
|
||||
# debug_opts also get passed to windres
|
||||
@@ -281,6 +293,7 @@ cxxopts:=$(opts) $(CXXFLAGS)
|
||||
opts+=$(CWFLAGS) # warning flags that shouldnt be passed to c++ compiler
|
||||
|
||||
libs+=$(LDFLAGS) -lstdc++ -lpthread
|
||||
|
||||
asflags:=$(ASFLAGS) -x assembler-with-cpp
|
||||
|
||||
cc=$(CC)
|
||||
|
||||
@@ -144,6 +144,10 @@ ifdef GCC81
|
||||
WFLAGS+=-Wno-error=multistatement-macros
|
||||
endif
|
||||
|
||||
ifeq ($(CC),clang)
|
||||
WFLAGS+= -Wno-unknown-pragmas -Wno-cast-align
|
||||
endif
|
||||
|
||||
ifdef NONX86
|
||||
ifdef X86_64 # yeah that SEEMS contradictory
|
||||
opts+=-march=nocona
|
||||
|
||||
+1
-1
@@ -61,7 +61,7 @@ struct SourceLocation {
|
||||
|
||||
class IErrorAssertHandler {
|
||||
public:
|
||||
static void handle(const SourceLocation& source_location, const char* expression) {
|
||||
[[ noreturn ]] static void handle(const SourceLocation& source_location, const char* expression) {
|
||||
I_Error("Assertion failed at %s:%u: %s != true",
|
||||
source_location.file_name,
|
||||
source_location.line_number,
|
||||
|
||||
+320
-65
@@ -16,6 +16,8 @@
|
||||
#include <unistd.h> //for unlink
|
||||
#endif
|
||||
|
||||
#include <zlib.h>
|
||||
|
||||
#include "i_time.h"
|
||||
#include "i_net.h"
|
||||
#include "i_system.h"
|
||||
@@ -87,6 +89,17 @@ boolean serverrunning = false;
|
||||
INT32 serverplayer = 0;
|
||||
char motd[254], server_context[8]; // Message of the Day, Unique Context (even without Mumble support)
|
||||
|
||||
#define MAP_ICON_REQUEST_FREQUENCY 8
|
||||
|
||||
static UINT8 map_icon_index; // amount of fragments we have retrieved
|
||||
static UINT8 map_icon_needed; // amount of fragments we need to get the full data set
|
||||
static INT32 map_icon_read; // amount of bytes we have read
|
||||
static UINT32 map_icon_missing; // bitmask of fragments we haven't received yet
|
||||
static tic_t map_icon_last_request; // last time we sent an icon request, to avoid flood
|
||||
static int map_icon_request_count; // current count of icon requests sent
|
||||
static UINT8 *map_icon_data;
|
||||
static patch_t *map_icon;
|
||||
|
||||
plrinfo playerinfo[MAXPLAYERS];
|
||||
SINT8 joinnode = 0; // used for CL_VIEWSERVER
|
||||
|
||||
@@ -1211,6 +1224,10 @@ static inline void CL_DrawConnectionStatus(void)
|
||||
if (!menuactive) // menu already draws its own fade
|
||||
V_DrawFadeScreen(0xFF00, 16); // force default
|
||||
|
||||
// reset the counter for mapicon
|
||||
if (cl_mode != CL_VIEWSERVER)
|
||||
map_icon_request_count = 0;
|
||||
|
||||
if (cl_mode != CL_DOWNLOADFILES && cl_mode != CL_LOADFILES && cl_mode != CL_CHECKFILES && cl_mode != CL_VIEWSERVER
|
||||
#ifdef HAVE_CURL
|
||||
&& cl_mode != CL_DOWNLOADHTTPFILES
|
||||
@@ -1337,11 +1354,48 @@ static inline void CL_DrawConnectionStatus(void)
|
||||
|
||||
V_DrawThinString(12 + 80, 18, V_ALLOWLOWERCASE, va("%s", serverlist[joinnode].info.servername));
|
||||
|
||||
const char *map = va("%sP", serverlist[joinnode].info.mapname);
|
||||
patch_t *current_map = W_LumpExists(map) ? W_CachePatchName(map, PU_CACHE) : W_CachePatchName("BLANKLVL", PU_CACHE);
|
||||
V_DrawSmallScaledPatch(10, 18, 0, current_map);
|
||||
if (map_icon == NULL)
|
||||
{
|
||||
const char *map = va("%sP", serverlist[joinnode].info.mapname);
|
||||
patch_t *current_map = W_LumpExists(map) ? W_CachePatchName(map, PU_CACHE) : NULL;
|
||||
|
||||
// check first if we may have the map icon loaded already
|
||||
if (current_map != NULL)
|
||||
V_DrawSmallScaledPatch(10, 18, 0, current_map);
|
||||
else if (map_icon_data != NULL && map_icon_request_count <= 5)
|
||||
{
|
||||
if (I_GetTime() - map_icon_last_request > MAP_ICON_REQUEST_FREQUENCY)
|
||||
{
|
||||
doomdata_t *netbuffer = DOOMCOM_DATA(doomcom);
|
||||
netbuffer->packettype = PT_NEEDMAPICON;
|
||||
|
||||
// failed to retrieve map icon, request it again
|
||||
HSendPacket(servernode, false, 0, 0);
|
||||
map_icon_last_request = I_GetTime();
|
||||
map_icon_request_count++;
|
||||
}
|
||||
|
||||
V_DrawFill(10, 18, MAP_ICON_WIDTH / 2, MAP_ICON_HEIGHT / 2, 31);
|
||||
char dots[4] = "...";
|
||||
if ((I_GetTime() & 0xf) < 4)
|
||||
dots[0] = '\0';
|
||||
else if ((I_GetTime() & 0xf) < 8)
|
||||
dots[1] = '\0';
|
||||
else if ((I_GetTime() & 0xf) < 12)
|
||||
dots[2] = '\0';
|
||||
V_DrawString(10 + MAP_ICON_WIDTH / 4 - V_StringWidth("...", 0) / 2, 18 + MAP_ICON_HEIGHT / 4 - 3, 0, dots);
|
||||
}
|
||||
else
|
||||
V_DrawSmallScaledPatch(10, 18, 0, W_CachePatchName("BLANKLVL", PU_CACHE));
|
||||
}
|
||||
else
|
||||
V_DrawSmallScaledPatch(10, 18, 0, map_icon);
|
||||
|
||||
if (serverlist[joinnode].info.iszone)
|
||||
V_DrawThinString(12 + 80, 38, V_ALLOWLOWERCASE, va("%s Zone", serverlist[joinnode].info.maptitle));
|
||||
else
|
||||
V_DrawThinString(12 + 80, 38, V_ALLOWLOWERCASE, va("%s", serverlist[joinnode].info.maptitle));
|
||||
|
||||
V_DrawThinString(12 + 80, 38, V_ALLOWLOWERCASE, va("%s", serverlist[joinnode].info.maptitle));
|
||||
V_DrawThinString(12 + 80, 48, V_ALLOWLOWERCASE, va("%s", Gametype_Names[serverlist[joinnode].info.gametype]));
|
||||
|
||||
if (fileneedednum > 0)
|
||||
@@ -1535,12 +1589,12 @@ static boolean CL_SendJoin(void)
|
||||
netbuffer->u.clientcfg.version = VERSION;
|
||||
netbuffer->u.clientcfg.subversion = SUBVERSION;
|
||||
strncpy(netbuffer->u.clientcfg.application, SRB2APPLICATION,
|
||||
sizeof netbuffer->u.clientcfg.application);
|
||||
sizeof(netbuffer->u.clientcfg.application));
|
||||
#ifdef SATURNJOIN
|
||||
netbuffer->u.clientcfg.issaturn = ISSATURN;
|
||||
#endif
|
||||
|
||||
return HSendPacket(servernode, false, 0, sizeof (clientconfig_pak));
|
||||
return HSendPacket(servernode, false, 0, sizeof(clientconfig_pak));
|
||||
}
|
||||
|
||||
static void SV_SendServerInfo(INT32 node, tic_t servertime)
|
||||
@@ -1581,59 +1635,38 @@ static void SV_SendServerInfo(INT32 node, tic_t servertime)
|
||||
|
||||
CopyCaretColors(netbuffer->u.serverinfo.servername, cv_servername.string,
|
||||
MAXSERVERNAME);
|
||||
strncpy(netbuffer->u.serverinfo.mapname, G_BuildMapName(gamemap), 7);
|
||||
strncpy(netbuffer->u.serverinfo.mapname, G_BuildMapName(gamemap), sizeof(netbuffer->u.serverinfo.mapname)-1);
|
||||
|
||||
M_Memcpy(netbuffer->u.serverinfo.mapmd5, mapmd5, 16);
|
||||
M_Memcpy(netbuffer->u.serverinfo.mapmd5, mapmd5, sizeof(netbuffer->u.serverinfo.mapmd5));
|
||||
|
||||
if (!(mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE) && !(mapheaderinfo[prevmap]->zonttl[0]))
|
||||
netbuffer->u.serverinfo.iszone = 1;
|
||||
else
|
||||
netbuffer->u.serverinfo.iszone = 0;
|
||||
netbuffer->u.serverinfo.iszone = 0;
|
||||
|
||||
memset(netbuffer->u.serverinfo.maptitle, 0, 33);
|
||||
memset(netbuffer->u.serverinfo.maptitle, 0, sizeof(netbuffer->u.serverinfo.maptitle));
|
||||
memset(netbuffer->u.serverinfo.httpsource, 0, MAX_MIRROR_LENGTH);
|
||||
|
||||
if (!(mapheaderinfo[gamemap-1]->menuflags & LF2_HIDEINMENU) && mapheaderinfo[gamemap-1]->lvlttl[0])
|
||||
{
|
||||
//strncpy(netbuffer->u.serverinfo.maptitle, (char *)mapheaderinfo[gamemap-1]->lvlttl, 33);
|
||||
// set up the levelstring
|
||||
if (netbuffer->u.serverinfo.iszone || (mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE))
|
||||
strncpy(netbuffer->u.serverinfo.maptitle, mapheaderinfo[gamemap-1]->lvlttl, sizeof(netbuffer->u.serverinfo.maptitle)-1);
|
||||
|
||||
if (!(mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE))
|
||||
{
|
||||
if (mapheaderinfo[gamemap-1]->actnum[0])
|
||||
snprintf(netbuffer->u.serverinfo.maptitle,
|
||||
33,
|
||||
"%s %s",
|
||||
mapheaderinfo[gamemap-1]->lvlttl, mapheaderinfo[gamemap-1]->actnum);
|
||||
if (mapheaderinfo[gamemap-1]->zonttl[0])
|
||||
{
|
||||
strncat(netbuffer->u.serverinfo.maptitle, " ", sizeof(netbuffer->u.serverinfo.maptitle)-1);
|
||||
strncat(netbuffer->u.serverinfo.maptitle, mapheaderinfo[gamemap-1]->zonttl,
|
||||
sizeof(netbuffer->u.serverinfo.maptitle)-1);
|
||||
}
|
||||
else
|
||||
snprintf(netbuffer->u.serverinfo.maptitle,
|
||||
33,
|
||||
"%s",
|
||||
mapheaderinfo[gamemap-1]->lvlttl);
|
||||
{
|
||||
netbuffer->u.serverinfo.iszone = 1; // ms and clients will append this themselves
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
if (mapheaderinfo[gamemap-1]->actnum[0])
|
||||
{
|
||||
if (mapheaderinfo[gamemap-1]->actnum[0])
|
||||
{
|
||||
if (snprintf(netbuffer->u.serverinfo.maptitle,
|
||||
33,
|
||||
"%s %s %s",
|
||||
mapheaderinfo[gamemap-1]->lvlttl, mapheaderinfo[gamemap-1]->zonttl, mapheaderinfo[gamemap-1]->actnum) < 0)
|
||||
{
|
||||
// If there's an encoding error, send UNKNOWN, we accept that the above may be truncated
|
||||
strncpy(netbuffer->u.serverinfo.maptitle, "Unknown", 33);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (snprintf(netbuffer->u.serverinfo.maptitle,
|
||||
33,
|
||||
"%s %s",
|
||||
mapheaderinfo[gamemap-1]->lvlttl, mapheaderinfo[gamemap-1]->zonttl) < 0)
|
||||
{
|
||||
// If there's an encoding error, send UNKNOWN, we accept that the above may be truncated
|
||||
strncpy(netbuffer->u.serverinfo.maptitle, "Unknown", 33);
|
||||
}
|
||||
}
|
||||
strncat(netbuffer->u.serverinfo.maptitle, " ", sizeof(netbuffer->u.serverinfo.maptitle)-1);
|
||||
strncat(netbuffer->u.serverinfo.maptitle, mapheaderinfo[gamemap-1]->actnum,
|
||||
sizeof(netbuffer->u.serverinfo.maptitle)-1);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1722,6 +1755,83 @@ static void SV_SendPlayerInfo(INT32 node)
|
||||
HSendPacket(node, false, 0, sizeof(plrinfo) * MSCOMPAT_MAXPLAYERS);
|
||||
}
|
||||
|
||||
static void SV_SendMapIcon(INT32 node)
|
||||
{
|
||||
doomdata_t *netbuffer = DOOMCOM_DATA(doomcom);
|
||||
|
||||
const char *map = va("%sP", G_BuildMapName(gamemap));
|
||||
if (!W_LumpExists(map) || (mapheaderinfo[gamemap-1]->menuflags & LF2_HIDEINMENU))
|
||||
{
|
||||
// send an empty icon to tell the client there is no map icon
|
||||
netbuffer->packettype = PT_MAPICON;
|
||||
UINT8 *icondata = netbuffer->u.mapicondata;
|
||||
WRITEUINT8(icondata, 0x80);
|
||||
HSendPacket(node, false, 0, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
patch_t *current_map = W_CachePatchName(map, PU_CACHE);
|
||||
if (current_map->width != MAP_ICON_WIDTH || current_map->height != MAP_ICON_HEIGHT)
|
||||
{
|
||||
// we only support 160x100 for now
|
||||
netbuffer->packettype = PT_MAPICON;
|
||||
UINT8 *icondata = netbuffer->u.mapicondata;
|
||||
WRITEUINT8(icondata, 0x80);
|
||||
HSendPacket(node, false, 0, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
UINT8 *data = Z_Malloc(2 * current_map->width * current_map->height, PU_STATIC, NULL);
|
||||
UINT8 *pixeldata = data + current_map->width * current_map->height;
|
||||
|
||||
R_PatchToPixels(current_map, pixeldata);
|
||||
|
||||
z_stream stream;
|
||||
stream.zalloc = NULL;
|
||||
stream.zfree = NULL;
|
||||
stream.opaque = NULL;
|
||||
if (deflateInit(&stream, Z_DEFAULT_COMPRESSION) != Z_OK)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, "Cannot compress map icon, not enough memory\n");
|
||||
Z_Free(data);
|
||||
return;
|
||||
}
|
||||
|
||||
stream.next_in = pixeldata;
|
||||
stream.avail_in = current_map->width * current_map->height;
|
||||
stream.next_out = data;
|
||||
stream.avail_out = current_map->width * current_map->height;
|
||||
if (deflate(&stream, Z_FINISH) != Z_STREAM_END)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, "Cannot compress map icon, error occured during compression\n");
|
||||
deflateEnd(&stream);
|
||||
Z_Free(data);
|
||||
return;
|
||||
}
|
||||
size_t count = stream.total_out;
|
||||
deflateEnd(&stream);
|
||||
|
||||
size_t index = 0;
|
||||
|
||||
for (size_t i = 0; i < count; i += MAXPACKETLENGTH-BASEPACKETSIZE-1)
|
||||
{
|
||||
size_t size = min(MAXPACKETLENGTH-BASEPACKETSIZE-1, count-i);
|
||||
|
||||
UINT8 *icondata = netbuffer->u.mapicondata;
|
||||
netbuffer->packettype = PT_MAPICON;
|
||||
|
||||
if (count-i <= MAXPACKETLENGTH-BASEPACKETSIZE-1)
|
||||
WRITEUINT8(icondata, 0x80 | index);
|
||||
else
|
||||
WRITEUINT8(icondata, index);
|
||||
index++;
|
||||
|
||||
WRITEMEM(icondata, &data[i], size);
|
||||
HSendPacket(node, false, 0, size + 1);
|
||||
}
|
||||
Z_Free(data);
|
||||
}
|
||||
|
||||
/** Sends a PT_SERVERCFG packet
|
||||
*
|
||||
* \param node The destination
|
||||
@@ -2704,9 +2814,26 @@ static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic
|
||||
if (cl_mode == CL_VIEWSERVER)
|
||||
{
|
||||
if (key == KEY_ENTER || key == KEY_JOY1)
|
||||
{
|
||||
cl_mode = CL_CHECKFILES;
|
||||
if (map_icon != NULL)
|
||||
Patch_Free(map_icon);
|
||||
map_icon = NULL;
|
||||
if (map_icon_data != NULL)
|
||||
Z_Free(map_icon_data);
|
||||
map_icon_data = NULL;
|
||||
}
|
||||
else if (key == KEY_ESCAPE || key == KEY_JOY1+1)
|
||||
{
|
||||
cl_mode = CL_ABORTED;
|
||||
if (map_icon != NULL)
|
||||
Patch_Free(map_icon);
|
||||
map_icon = NULL;
|
||||
if (map_icon_data != NULL)
|
||||
Z_Free(map_icon_data);
|
||||
map_icon_data = NULL;
|
||||
map_icon_request_count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Only ESC and non-keyboard keys abort connection
|
||||
@@ -2822,6 +2949,17 @@ static void CL_ConnectToServer(void)
|
||||
serverlist[i].info.version, serverlist[i].info.subversion);
|
||||
}
|
||||
SL_ClearServerList(servernode);
|
||||
|
||||
if (map_icon_data != NULL)
|
||||
Z_Free(map_icon_data);
|
||||
if (map_icon != NULL)
|
||||
Patch_Free(map_icon);
|
||||
map_icon_data = Z_Malloc(MAP_ICON_WIDTH * MAP_ICON_HEIGHT, PU_CACHE, NULL);
|
||||
map_icon_index = 0;
|
||||
map_icon_needed = 0xff;
|
||||
map_icon_read = 0;
|
||||
map_icon_missing = 0xffffffff;
|
||||
map_icon_last_request = I_GetTime();
|
||||
#endif
|
||||
|
||||
do
|
||||
@@ -4706,6 +4844,10 @@ static void HandleConnect(SINT8 node)
|
||||
if (playernode[i] != UINT8_MAX) // We use this to count players because it is affected by SV_AddWaitingPlayers when more than one client joins on the same tic, unlike playeringame and D_NumPlayers. UINT8_MAX denotes no node for that player
|
||||
connectedplayers++;
|
||||
|
||||
#ifdef SATURNJOIN
|
||||
const boolean issaturn = (((doomcom->datalength) == sizeof(clientconfig_pak)) && netbuffer->u.clientcfg.issaturn == ISSATURN); // Check the packet lenght to skip potential garbo data!
|
||||
#endif
|
||||
|
||||
if (bannednode && bannednode[node].banid != SIZE_MAX)
|
||||
{
|
||||
const char *reason = NULL;
|
||||
@@ -4759,7 +4901,7 @@ static void HandleConnect(SINT8 node)
|
||||
SV_SendRefuse(node, va(M_GetText("Different SRB2Kart versions cannot\nplay a netgame!\n(server version %d.%d)"), VERSION, SUBVERSION));
|
||||
}
|
||||
#ifdef SATURNJOIN
|
||||
else if ((!cv_allownewplayer.value && node && netbuffer->u.clientcfg.issaturn != ISSATURN) || (!cv_allownewsaturnplayer.value && node && netbuffer->u.clientcfg.issaturn == ISSATURN))
|
||||
else if (((!cv_allownewplayer.value && !issaturn) || (!cv_allownewsaturnplayer.value && issaturn)) && node)
|
||||
#else
|
||||
else if (!cv_allownewplayer.value && node)
|
||||
#endif
|
||||
@@ -4787,16 +4929,15 @@ static void HandleConnect(SINT8 node)
|
||||
#ifndef NONET
|
||||
boolean newnode = false;
|
||||
#endif
|
||||
|
||||
// client authorised to join
|
||||
nodewaiting[node] = (UINT8)(netbuffer->u.clientcfg.localplayers - playerpernode[node]);
|
||||
|
||||
if (!nodeingame[node])
|
||||
{
|
||||
gamestate_t backupstate = gamestate;
|
||||
#ifndef NONET
|
||||
newnode = true;
|
||||
#endif
|
||||
|
||||
SV_AddNode(node);
|
||||
|
||||
/// \note Wait what???
|
||||
@@ -4818,12 +4959,14 @@ static void HandleConnect(SINT8 node)
|
||||
/// \todo fix this !!!
|
||||
return; // restart the while
|
||||
}
|
||||
|
||||
SV_SendServerInfo(node, 0); // Dunno if 0 time is good idea
|
||||
//if (gamestate != GS_LEVEL) // GS_INTERMISSION, etc?
|
||||
// SV_SendPlayerConfigs(node); // send bare minimum player info
|
||||
G_SetGamestate(backupstate);
|
||||
DEBFILE("new node joined\n");
|
||||
}
|
||||
|
||||
#ifdef JOININGAME
|
||||
if (nodewaiting[node])
|
||||
{
|
||||
@@ -4832,6 +4975,7 @@ static void HandleConnect(SINT8 node)
|
||||
SV_SendSaveGame(node, false); // send a complete game state
|
||||
DEBFILE("send savegame\n");
|
||||
}
|
||||
|
||||
SV_AddWaitingPlayers();
|
||||
}
|
||||
#else
|
||||
@@ -4871,17 +5015,6 @@ static void HandleTimeout(SINT8 node)
|
||||
M_StartMessage(M_GetText("Server Timeout\n\nPress Esc\n"), NULL, MM_NOTHING);
|
||||
}
|
||||
|
||||
// Helper function for packets that should only be sent by the server
|
||||
// If it is NOT from the server, bail out and close the connection!
|
||||
static boolean ServerOnly(SINT8 node)
|
||||
{
|
||||
if (node == servernode)
|
||||
return false;
|
||||
|
||||
Net_CloseConnection(node);
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifndef NONET
|
||||
/** Called when a PT_SERVERINFO packet is received
|
||||
*
|
||||
@@ -4921,6 +5054,115 @@ static void HandlePlayerInfo(void)
|
||||
playerinfo[i] = netbuffer->u.playerinfo[i];
|
||||
}
|
||||
|
||||
// Helper function for packets that should only be sent by the server
|
||||
// If it is NOT from the server, bail out and close the connection!
|
||||
static boolean ServerOnly(SINT8 node)
|
||||
{
|
||||
if (node == servernode)
|
||||
return false;
|
||||
|
||||
Net_CloseConnection(node);
|
||||
return true;
|
||||
}
|
||||
|
||||
static void PT_MapIcon(void)
|
||||
{
|
||||
if (map_icon_data == NULL)
|
||||
return;
|
||||
|
||||
if (ServerOnly(doomcom->remotenode))
|
||||
return;
|
||||
|
||||
doomdata_t *netbuffer = DOOMCOM_DATA(doomcom);
|
||||
|
||||
UINT8 *icondata = netbuffer->u.mapicondata;
|
||||
|
||||
map_icon_last_request = I_GetTime();
|
||||
map_icon_request_count = 0;
|
||||
|
||||
UINT8 index = READUINT8(icondata);
|
||||
if (index & 0x80)
|
||||
map_icon_needed = (index & 0x7f) + 1;
|
||||
index &= 0x7f;
|
||||
|
||||
// check if we already got this fragment
|
||||
if (map_icon_missing & ((UINT32)1 << index))
|
||||
{
|
||||
map_icon_missing &= ~((UINT32)1 << index);
|
||||
INT32 offset = index * (MAXPACKETLENGTH-BASEPACKETSIZE-1);
|
||||
if (offset + doomcom->datalength-1 > MAP_ICON_WIDTH * MAP_ICON_HEIGHT)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, "Excess amount of data for map icon (expected %d, got %d)\n", MAP_ICON_WIDTH * MAP_ICON_HEIGHT, offset + doomcom->datalength-1);
|
||||
Z_Free(map_icon_data);
|
||||
map_icon_data = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
READMEM(icondata, &map_icon_data[offset], doomcom->datalength-1);
|
||||
map_icon_read += doomcom->datalength-1;
|
||||
map_icon_index++;
|
||||
}
|
||||
|
||||
if (map_icon_index >= map_icon_needed)
|
||||
{
|
||||
if (map_icon_read == 0)
|
||||
{
|
||||
// map has no icon
|
||||
Z_Free(map_icon_data);
|
||||
map_icon_data = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
UINT8 *data = Z_Malloc(MAP_ICON_WIDTH * MAP_ICON_HEIGHT, PU_STATIC, NULL);
|
||||
z_stream stream;
|
||||
stream.zalloc = NULL;
|
||||
stream.zfree = NULL;
|
||||
stream.opaque = NULL;
|
||||
stream.next_in = map_icon_data;
|
||||
stream.avail_in = map_icon_read;
|
||||
if (inflateInit(&stream) != Z_OK)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, "Cannot decompress map icon, not enough memory\n");
|
||||
Z_Free(data);
|
||||
Z_Free(map_icon_data);
|
||||
map_icon_data = NULL;
|
||||
return;
|
||||
}
|
||||
stream.next_out = data;
|
||||
stream.avail_out = MAP_ICON_WIDTH * MAP_ICON_HEIGHT;
|
||||
if (inflate(&stream, Z_FINISH) != Z_STREAM_END)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, "Failed to decompress map icon, map icon is invalid or corrupted\n");
|
||||
deflateEnd(&stream);
|
||||
Z_Free(data);
|
||||
Z_Free(map_icon_data);
|
||||
map_icon_data = NULL;
|
||||
return;
|
||||
}
|
||||
inflateEnd(&stream);
|
||||
Z_Free(map_icon_data);
|
||||
map_icon_data = NULL;
|
||||
|
||||
if (stream.total_out > MAP_ICON_WIDTH * MAP_ICON_HEIGHT)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, "Excess amount of data for map icon (expected %d, got %ld)\n", MAP_ICON_WIDTH * MAP_ICON_HEIGHT, stream.total_out);
|
||||
Z_Free(data);
|
||||
return;
|
||||
}
|
||||
else if (stream.total_out < MAP_ICON_WIDTH * MAP_ICON_HEIGHT)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, "Insufficient amount of data for map icon (expected %d, got %ld)\n", MAP_ICON_WIDTH * MAP_ICON_HEIGHT, stream.total_out);
|
||||
Z_Free(data);
|
||||
return;
|
||||
}
|
||||
|
||||
//map_icon = Patch_CreateFromData(MAP_ICON_WIDTH, MAP_ICON_HEIGHT, data);
|
||||
map_icon = (patch_t *)R_PixelsToPatch(data, MAP_ICON_WIDTH, MAP_ICON_HEIGHT, 0, 0, NULL);
|
||||
|
||||
Z_Free(data);
|
||||
}
|
||||
}
|
||||
|
||||
static void PT_TellFilesNeeded(SINT8 node)
|
||||
{
|
||||
if (server && serverrunning)
|
||||
@@ -4969,11 +5211,18 @@ static void PT_AskInfo(SINT8 node)
|
||||
doomdata_t *netbuffer = DOOMCOM_DATA(doomcom);
|
||||
SV_SendServerInfo(node, (tic_t)LONG(netbuffer->u.askinfo.time));
|
||||
SV_SendPlayerInfo(node); // Send extra info
|
||||
//SV_SendMapIcon(node); // idk i dont think we need this here
|
||||
}
|
||||
|
||||
Net_CloseConnection(node);
|
||||
}
|
||||
|
||||
static void PT_NeedMapIcon(SINT8 node)
|
||||
{
|
||||
SV_SendMapIcon(node);
|
||||
Net_CloseConnection(node);
|
||||
}
|
||||
|
||||
// Negative response of client join request
|
||||
static void PT_ServerRefuse(SINT8 node)
|
||||
{
|
||||
@@ -5234,6 +5483,12 @@ static void HandlePacketFromAwayNode(SINT8 node)
|
||||
case PT_PLAYERINFO:
|
||||
HandlePlayerInfo();
|
||||
break;
|
||||
case PT_MAPICON:
|
||||
PT_MapIcon();
|
||||
break;
|
||||
case PT_NEEDMAPICON:
|
||||
PT_NeedMapIcon(node);
|
||||
break;
|
||||
case PT_SERVERTICS:
|
||||
// Do not remove my own server (we have just get a out of order packet)
|
||||
if (node == servernode)
|
||||
@@ -5522,10 +5777,10 @@ static void PT_TextCmd(INT32 netconsole, SINT8 node)
|
||||
|
||||
// ignore if the textcmd size var is actually larger than it should be
|
||||
// BASEPACKETSIZE + 1 (for size) + textcmd[0] should == datalength
|
||||
if (netbuffer->u.textcmd[0] > (size_t)doomcom->datalength-BASEPACKETSIZE-1)
|
||||
if (netbuffer->u.textcmd[0] > (size_t)doomcom->datalength-1)
|
||||
{
|
||||
DEBFILE(va("GetPacket: Bad Textcmd packet size! (expected %d, actual %s, node %u, player %d)\n",
|
||||
netbuffer->u.textcmd[0], sizeu1((size_t)doomcom->datalength-BASEPACKETSIZE-1),
|
||||
netbuffer->u.textcmd[0], sizeu1((size_t)doomcom->datalength-1),
|
||||
node, netconsole));
|
||||
Net_UnAcknowledgePacket(node);
|
||||
return;
|
||||
@@ -5566,7 +5821,6 @@ static void PT_TextCmd(INT32 netconsole, SINT8 node)
|
||||
|
||||
static void PT_ClientQuit(INT32 netconsole, SINT8 node)
|
||||
{
|
||||
|
||||
if (client)
|
||||
return;
|
||||
|
||||
@@ -6982,6 +7236,7 @@ void NetUpdate(void)
|
||||
#endif
|
||||
CON_Ticker();
|
||||
}
|
||||
|
||||
SV_FileSendTicker();
|
||||
}
|
||||
|
||||
|
||||
+3
-1
@@ -120,6 +120,8 @@ typedef enum
|
||||
PT_ISSATURN, // Saturn specific identifier packet
|
||||
#endif
|
||||
|
||||
PT_MAPICON, // Send map image icon (gamespy).
|
||||
PT_NEEDMAPICON, // Request missed map icon (gamespy).
|
||||
NUMPACKETTYPE
|
||||
} packettype_t;
|
||||
|
||||
@@ -513,6 +515,7 @@ typedef struct
|
||||
INT32 filesneedednum; // 4 bytes
|
||||
filesneededconfig_pak filesneededcfg; // ??? bytes
|
||||
UINT32 pingtable[MAXPLAYERS+1]; // 68 bytes
|
||||
UINT8 mapicondata[0];
|
||||
} u; // This is needed to pack diff packet types data together
|
||||
} ATTRPACK doomdata_t;
|
||||
|
||||
@@ -564,7 +567,6 @@ typedef enum
|
||||
KR_TIMEOUT, //Connection Timeout
|
||||
KR_BAN, //Banned by server
|
||||
KR_LEAVE, //Quit the game
|
||||
|
||||
} kickreason_t;
|
||||
|
||||
/* the max number of name changes in some time period */
|
||||
|
||||
+1
-1
@@ -933,7 +933,6 @@ void D_SRB2Loop(void)
|
||||
Discord_RunCallbacks();
|
||||
}
|
||||
#endif
|
||||
|
||||
// Fully completed frame made.
|
||||
finishprecise = I_GetPreciseTime();
|
||||
|
||||
@@ -971,6 +970,7 @@ void D_SRB2Loop(void)
|
||||
I_SleepDuration(capbudget - elapsed);
|
||||
}
|
||||
}
|
||||
|
||||
// Capture the time once more to get the real delta time.
|
||||
finishprecise = I_GetPreciseTime();
|
||||
deltasecs = (double)((INT64)(finishprecise - enterprecise)) / I_GetPrecisePrecision();
|
||||
|
||||
@@ -1201,6 +1201,7 @@ boolean HGetPacket(void)
|
||||
GotAcks();
|
||||
continue;
|
||||
}
|
||||
doomcom->datalength -= BASEPACKETSIZE;
|
||||
break;
|
||||
}
|
||||
#endif // ifndef NONET
|
||||
|
||||
@@ -937,6 +937,7 @@ void D_RegisterClientCommands(void)
|
||||
CV_RegisterVar(&cv_consolechat);
|
||||
CV_RegisterVar(&cv_chatnotifications);
|
||||
CV_RegisterVar(&cv_chatbacktint);
|
||||
CV_RegisterVar(&cv_chatcentertext);
|
||||
CV_RegisterVar(&cv_songcredits);
|
||||
CV_RegisterVar(&cv_showfreeplay);
|
||||
CV_RegisterVar(&cv_skinselectspin);
|
||||
|
||||
+13
-35
@@ -1173,41 +1173,7 @@ filestatus_t findfile(char *filename, const UINT8 *wantedmd5sum, boolean complet
|
||||
filestatus_t homecheck; // store result of last file search
|
||||
boolean badmd5 = false; // store whether md5 was bad from either of the first two searches (if nothing was found in the third)
|
||||
|
||||
// skip for startup, our mainwads wont be in there
|
||||
if (loaded_config)
|
||||
{
|
||||
if (cv_addons_option.value == 3 && *cv_addons_folder.string != '\0')
|
||||
{
|
||||
// first, check any custom directory if specified
|
||||
homecheck = filesearch(filename, cv_addons_folder.string, wantedmd5sum, completepath, 10);
|
||||
|
||||
if (homecheck == FS_FOUND) // we found the file, so return that we have :)
|
||||
return FS_FOUND;
|
||||
else if (homecheck == FS_MD5SUMBAD) // file has a bad md5; move on and look for a file with the right md5
|
||||
badmd5 = true;
|
||||
// if not found at all, just move on without doing anything
|
||||
}
|
||||
|
||||
// next, check "DOWNLOAD" directory
|
||||
homecheck = filesearch(filename, "DOWNLOAD", wantedmd5sum, completepath, 10);
|
||||
|
||||
if (homecheck == FS_FOUND) // we found the file, so return that we have :)
|
||||
return FS_FOUND;
|
||||
else if (homecheck == FS_MD5SUMBAD) // file has a bad md5; move on and look for a file with the right md5
|
||||
badmd5 = true;
|
||||
// if not found at all, just move on without doing anything
|
||||
|
||||
// next, check "addons" directory
|
||||
homecheck = filesearch(filename, "addons", wantedmd5sum, completepath, 10);
|
||||
|
||||
if (homecheck == FS_FOUND) // we found the file, so return that we have :)
|
||||
return FS_FOUND;
|
||||
else if (homecheck == FS_MD5SUMBAD) // file has a bad md5; move on and look for a file with the right md5
|
||||
badmd5 = true;
|
||||
// if not found at all, just move on without doing anything
|
||||
}
|
||||
|
||||
// next, check SRB2's "home" directory
|
||||
// first, check SRB2's "home" directory
|
||||
homecheck = filesearch(filename, srb2home, wantedmd5sum, completepath, 10);
|
||||
|
||||
if (homecheck == FS_FOUND) // we found the file, so return that we have :)
|
||||
@@ -1225,6 +1191,18 @@ filestatus_t findfile(char *filename, const UINT8 *wantedmd5sum, boolean complet
|
||||
badmd5 = true;
|
||||
// if not found at all, just move on without doing anything
|
||||
|
||||
if (cv_addons_option.value == 3 && *cv_addons_folder.string != '\0')
|
||||
{
|
||||
// next, check any custom directory if specified
|
||||
homecheck = filesearch(filename, cv_addons_folder.string, wantedmd5sum, completepath, 10);
|
||||
|
||||
if (homecheck == FS_FOUND) // we found the file, so return that we have :)
|
||||
return FS_FOUND;
|
||||
else if (homecheck == FS_MD5SUMBAD) // file has a bad md5; move on and look for a file with the right md5
|
||||
badmd5 = true;
|
||||
// if not found at all, just move on without doing anything
|
||||
}
|
||||
|
||||
// finally check "." directory
|
||||
homecheck = filesearch(filename, ".", wantedmd5sum, completepath, 10);
|
||||
|
||||
|
||||
@@ -1899,7 +1899,7 @@ static const char *searchWad(const char *searchDir)
|
||||
filestatus_t fstemp;
|
||||
|
||||
strcpy(tempsw, WADKEYWORD1);
|
||||
fstemp = filesearch(tempsw, searchDir, NULL, true, 20);
|
||||
fstemp = filesearch(tempsw,searchDir,NULL,true,20);
|
||||
if (fstemp == FS_FOUND)
|
||||
{
|
||||
pathonly(tempsw);
|
||||
|
||||
+72
-163
@@ -341,7 +341,6 @@ char *refreshdirname = NULL;
|
||||
// direrror is set if there was an error.
|
||||
INT32 pathisdirectory(const char *path)
|
||||
{
|
||||
#ifndef _WIN32
|
||||
struct stat fsstat;
|
||||
|
||||
if (stat(path, &fsstat) < 0)
|
||||
@@ -349,67 +348,39 @@ INT32 pathisdirectory(const char *path)
|
||||
return -1;
|
||||
}
|
||||
else if (S_ISDIR(fsstat.st_mode))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
#else
|
||||
DWORD fileattr = GetFileAttributes(path);
|
||||
if (fileattr == INVALID_FILE_ATTRIBUTES)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else if (fileattr & FILE_ATTRIBUTE_DIRECTORY)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// skip those folders, they will not have any addons
|
||||
static const char *exclude_paths[] = {
|
||||
"logs",
|
||||
"luafiles",
|
||||
"replay",
|
||||
"mdls",
|
||||
"gifs",
|
||||
"screenshots",
|
||||
NULL
|
||||
};
|
||||
|
||||
filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *wantedmd5sum, boolean completepath, int maxsearchdepth)
|
||||
{
|
||||
filestatus_t retval = FS_NOTFOUND;
|
||||
DIR **dirhandle;
|
||||
struct dirent *dent;
|
||||
#ifndef _WIN32
|
||||
struct stat fsstat;
|
||||
#endif
|
||||
int found = 0;
|
||||
char *searchname;
|
||||
char *searchname = strdup(filename);
|
||||
int depthleft = maxsearchdepth;
|
||||
char searchpath[1024];
|
||||
size_t *searchpathindex;
|
||||
|
||||
dirhandle = (DIR**)malloc(maxsearchdepth * sizeof(DIR*));
|
||||
searchpathindex = (size_t *)malloc(maxsearchdepth * sizeof(size_t));
|
||||
dirhandle = (DIR**) malloc(maxsearchdepth * sizeof(DIR*));
|
||||
searchpathindex = (size_t *) malloc(maxsearchdepth * sizeof(size_t));
|
||||
|
||||
strcpy(searchpath, startpath);
|
||||
strcpy(searchpath,startpath);
|
||||
searchpathindex[--depthleft] = strlen(searchpath) + 1;
|
||||
|
||||
dirhandle[depthleft] = opendir(searchpath);
|
||||
|
||||
if (dirhandle[depthleft] == NULL)
|
||||
{
|
||||
free(searchname);
|
||||
free(dirhandle);
|
||||
free(searchpathindex);
|
||||
return FS_NOTFOUND;
|
||||
}
|
||||
|
||||
searchname = strdup(filename);
|
||||
|
||||
if (searchpath[searchpathindex[depthleft]-2] != PATHSEP[0])
|
||||
{
|
||||
searchpath[searchpathindex[depthleft]-1] = PATHSEP[0];
|
||||
@@ -441,88 +412,62 @@ filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *want
|
||||
// okay, now we actually want searchpath to incorporate d_name
|
||||
strcpy(&searchpath[searchpathindex[depthleft]], dent->d_name);
|
||||
|
||||
#if defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__)
|
||||
if (dent->d_type == DT_UNKNOWN || dent->d_type == DT_LNK)
|
||||
if (stat(searchpath, &fsstat) == 0 && S_ISDIR(fsstat.st_mode))
|
||||
dent->d_type = DT_DIR;
|
||||
|
||||
// Linux and FreeBSD has a special field for file type on dirent, so use that to speed up lookups.
|
||||
if (dent->d_type == DT_DIR)
|
||||
#elif defined (_WIN32)
|
||||
// if we wanna follow symlinks we can check with FILE_ATTRIBUTE_REPARSE_POINT
|
||||
DWORD fileattr = GetFileAttributes(searchpath);
|
||||
if (fileattr == INVALID_FILE_ATTRIBUTES)
|
||||
continue; // was the file (re)moved? can't stat it
|
||||
|
||||
if (fileattr & FILE_ATTRIBUTE_DIRECTORY)
|
||||
#else
|
||||
if (stat(searchpath,&fsstat) < 0) // do we want to follow symlinks? if not: change it to lstat
|
||||
continue; // was the file (re)moved? can't stat it
|
||||
|
||||
if (S_ISDIR(fsstat.st_mode))
|
||||
#endif
|
||||
#if defined(__linux__) || defined(__FreeBSD__)
|
||||
if (dent->d_type == DT_UNKNOWN && lstat(searchpath, &fsstat) == 0)
|
||||
{
|
||||
// I am a folder!
|
||||
|
||||
if (!depthleft)
|
||||
continue; // No additional folder delving permitted...
|
||||
|
||||
const char **path = exclude_paths;
|
||||
|
||||
if (depthleft == maxsearchdepth-1)
|
||||
{
|
||||
// When we're at the root of the search, we exclude certain folders.
|
||||
|
||||
boolean skipfolder = false;
|
||||
|
||||
for (; *path != NULL; path++)
|
||||
{
|
||||
if (strcasecmp(*path, dent->d_name) == 0)
|
||||
{
|
||||
skipfolder = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (skipfolder)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (strcasecmp(".git", dent->d_name) // sanity if you're weird like me
|
||||
&& (dirhandle[depthleft-1] = opendir(searchpath)) != NULL)
|
||||
{
|
||||
// Got read permissions!
|
||||
searchpathindex[--depthleft] = strlen(searchpath) + 1;
|
||||
|
||||
searchpath[searchpathindex[depthleft]-1] = PATHSEP[0];
|
||||
searchpath[searchpathindex[depthleft]] = 0;
|
||||
}
|
||||
|
||||
continue;
|
||||
if (S_ISDIR(fsstat.st_mode))
|
||||
dent->d_type = DT_DIR;
|
||||
else if (S_ISLNK(fsstat.st_mode))
|
||||
dent->d_type = DT_LNK;
|
||||
}
|
||||
|
||||
// I am a file!
|
||||
|
||||
if (strcasecmp(searchname, dent->d_name))
|
||||
continue; // Not what we're looking for!
|
||||
|
||||
switch (checkfilemd5(searchpath, wantedmd5sum))
|
||||
// Symlinks aren't always directory symlinks. Dunno if this would resolve recursive
|
||||
// symlinks, but i think stat already does that
|
||||
if (dent->d_type == DT_LNK && stat(searchpath,&fsstat) == 0 && !S_ISDIR(fsstat.st_mode))
|
||||
{
|
||||
case FS_FOUND:
|
||||
if (completepath)
|
||||
strcpy(filename, searchpath);
|
||||
else
|
||||
strcpy(filename, dent->d_name);
|
||||
retval = FS_FOUND;
|
||||
found = 1;
|
||||
break;
|
||||
case FS_MD5SUMBAD:
|
||||
retval = FS_MD5SUMBAD;
|
||||
break;
|
||||
default: // prevent some compiler warnings
|
||||
break;
|
||||
dent->d_type = DT_UNKNOWN;
|
||||
}
|
||||
|
||||
// Linux and FreeBSD has a special field for file type on dirent, so use that to speed up lookups.
|
||||
// FIXME: should we also follow symlinks?
|
||||
if ((dent->d_type == DT_DIR && depthleft) || (dent->d_type == DT_LNK && depthleft))
|
||||
#else
|
||||
if (stat(searchpath,&fsstat) < 0) // do we want to follow symlinks? if not: change it to lstat
|
||||
; // was the file (re)moved? can't stat it
|
||||
else if (S_ISDIR(fsstat.st_mode) && depthleft)
|
||||
#endif
|
||||
{
|
||||
searchpathindex[--depthleft] = strlen(searchpath) + 1;
|
||||
dirhandle[depthleft] = opendir(searchpath);
|
||||
|
||||
if (!dirhandle[depthleft])
|
||||
{
|
||||
// can't open it... maybe no read-permissions
|
||||
// go back to previous dir
|
||||
depthleft++;
|
||||
}
|
||||
|
||||
searchpath[searchpathindex[depthleft]-1] = PATHSEP[0];
|
||||
searchpath[searchpathindex[depthleft]] = 0;
|
||||
}
|
||||
else if (!strcasecmp(searchname, dent->d_name))
|
||||
{
|
||||
switch (checkfilemd5(searchpath, wantedmd5sum))
|
||||
{
|
||||
case FS_FOUND:
|
||||
if (completepath)
|
||||
strcpy(filename, searchpath);
|
||||
else
|
||||
strcpy(filename, dent->d_name);
|
||||
retval = FS_FOUND;
|
||||
found = 1;
|
||||
break;
|
||||
case FS_MD5SUMBAD:
|
||||
retval = FS_MD5SUMBAD;
|
||||
break;
|
||||
default: // prevent some compiler warnings
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -699,9 +644,7 @@ boolean preparefilemenu(boolean samedepth, boolean replayhut)
|
||||
{
|
||||
DIR *dirhandle;
|
||||
struct dirent *dent;
|
||||
#ifndef _WIN32
|
||||
struct stat fsstat;
|
||||
#endif
|
||||
size_t pos = 0, folderpos = 0, numfolders = 0;
|
||||
char *tempname = NULL;
|
||||
|
||||
@@ -737,44 +680,30 @@ boolean preparefilemenu(boolean samedepth, boolean replayhut)
|
||||
if (!dent)
|
||||
break;
|
||||
else if (dent->d_name[0]=='.' &&
|
||||
(dent->d_name[1]=='\0' ||
|
||||
(dent->d_name[1]=='.' &&
|
||||
dent->d_name[2]=='\0')))
|
||||
(dent->d_name[1]=='\0' ||
|
||||
(dent->d_name[1]=='.' &&
|
||||
dent->d_name[2]=='\0')))
|
||||
continue; // we don't want to scan uptree
|
||||
|
||||
strcpy(&menupath[menupathindex[menudepthleft]],dent->d_name);
|
||||
|
||||
#ifndef _WIN32
|
||||
if (stat(menupath, &fsstat) < 0)
|
||||
#else
|
||||
// if we wanna follow symlinks we can check with FILE_ATTRIBUTE_REPARSE_POINT
|
||||
DWORD fileattr = GetFileAttributes(menupath);
|
||||
if (fileattr == INVALID_FILE_ATTRIBUTES)
|
||||
#endif
|
||||
if (stat(menupath,&fsstat) < 0) // do we want to follow symlinks? if not: change it to lstat
|
||||
; // was the file (re)moved? can't stat it
|
||||
else // is a file or directory
|
||||
{
|
||||
#ifndef _WIN32
|
||||
if (!S_ISDIR(fsstat.st_mode)) // file
|
||||
#else
|
||||
if (!(fileattr & FILE_ATTRIBUTE_DIRECTORY))
|
||||
#endif
|
||||
{
|
||||
size_t len = strlen(dent->d_name)+1;
|
||||
if (replayhut)
|
||||
{
|
||||
if (strcasecmp(".lmp", dent->d_name+len-5))
|
||||
continue; // Not a replay
|
||||
if (strcasecmp(".lmp", dent->d_name+len-5)) continue; // Not a replay
|
||||
}
|
||||
else if (!cv_addons_showall.value)
|
||||
{
|
||||
UINT8 ext;
|
||||
for (ext = 0; ext < NUM_EXT_TABLE; ext++)
|
||||
if (!strcasecmp(exttable[ext]+1, dent->d_name+len-(exttable[ext][0])))
|
||||
break; // extension comparison
|
||||
|
||||
if (ext == NUM_EXT_TABLE)
|
||||
continue; // not an addfile-able (or exec-able) file
|
||||
if (!strcasecmp(exttable[ext]+1, dent->d_name+len-(exttable[ext][0]))) break; // extension comparison
|
||||
if (ext == NUM_EXT_TABLE) continue; // not an addfile-able (or exec-able) file
|
||||
}
|
||||
}
|
||||
else // directory
|
||||
@@ -819,20 +748,14 @@ boolean preparefilemenu(boolean samedepth, boolean replayhut)
|
||||
if (!dent)
|
||||
break;
|
||||
else if (dent->d_name[0]=='.' &&
|
||||
(dent->d_name[1]=='\0' ||
|
||||
(dent->d_name[1]=='.' &&
|
||||
dent->d_name[2]=='\0')))
|
||||
(dent->d_name[1]=='\0' ||
|
||||
(dent->d_name[1]=='.' &&
|
||||
dent->d_name[2]=='\0')))
|
||||
continue; // we don't want to scan uptree
|
||||
|
||||
strcpy(&menupath[menupathindex[menudepthleft]],dent->d_name);
|
||||
|
||||
#ifndef _WIN32
|
||||
if (stat(menupath, &fsstat) < 0)
|
||||
#else
|
||||
// if we wanna follow symlinks we can check with FILE_ATTRIBUTE_REPARSE_POINT
|
||||
DWORD fileattr = GetFileAttributes(menupath);
|
||||
if (fileattr == INVALID_FILE_ATTRIBUTES)
|
||||
#endif
|
||||
if (stat(menupath,&fsstat) < 0) // do we want to follow symlinks? if not: change it to lstat
|
||||
; // was the file (re)moved? can't stat it
|
||||
else // is a file or directory
|
||||
{
|
||||
@@ -841,31 +764,20 @@ boolean preparefilemenu(boolean samedepth, boolean replayhut)
|
||||
UINT8 ext = EXT_FOLDER;
|
||||
UINT8 folder;
|
||||
|
||||
#ifndef _WIN32
|
||||
if (!S_ISDIR(fsstat.st_mode)) // file
|
||||
#else
|
||||
if (!(fileattr & FILE_ATTRIBUTE_DIRECTORY))
|
||||
#endif
|
||||
{
|
||||
if (!((numfolders+pos) < sizecoredirmenu))
|
||||
continue; // crash prevention
|
||||
if (!((numfolders+pos) < sizecoredirmenu)) continue; // crash prevention
|
||||
|
||||
if (replayhut)
|
||||
{
|
||||
if (strcasecmp(".lmp", dent->d_name+len-5))
|
||||
continue; // Not a replay
|
||||
|
||||
if (strcasecmp(".lmp", dent->d_name+len-5)) continue; // Not a replay
|
||||
ext = EXT_TXT; // This isn't used anywhere but better safe than sorry for messing with this...
|
||||
}
|
||||
else
|
||||
{
|
||||
for (; ext < NUM_EXT_TABLE; ext++)
|
||||
if (!strcasecmp(exttable[ext]+1, dent->d_name+len-(exttable[ext][0])))
|
||||
break; // extension comparison
|
||||
|
||||
if (ext == NUM_EXT_TABLE && !cv_addons_showall.value)
|
||||
continue; // not an addfile-able (or exec-able) file
|
||||
|
||||
if (!strcasecmp(exttable[ext]+1, dent->d_name+len-(exttable[ext][0]))) break; // extension comparison
|
||||
if (ext == NUM_EXT_TABLE && !cv_addons_showall.value) continue; // not an addfile-able (or exec-able) file
|
||||
ext += EXT_START; // moving to be appropriate position
|
||||
|
||||
if (ext >= EXT_LOADSTART)
|
||||
@@ -882,7 +794,6 @@ boolean preparefilemenu(boolean samedepth, boolean replayhut)
|
||||
|
||||
if (strcmp(dent->d_name, filenamebuf[i]))
|
||||
continue;
|
||||
|
||||
if (cv_addons_md5.value && !checkfilemd5(menupath, wadfiles[i]->md5sum))
|
||||
continue;
|
||||
|
||||
@@ -909,11 +820,9 @@ boolean preparefilemenu(boolean samedepth, boolean replayhut)
|
||||
|
||||
if (!(temp = Z_Malloc((len+DIR_STRING+folder) * sizeof (char), PU_STATIC, NULL)))
|
||||
I_Error("preparefilemenu(): could not create file entry.");
|
||||
|
||||
temp[DIR_TYPE] = ext;
|
||||
temp[DIR_LEN] = (UINT8)(len);
|
||||
strlcpy(temp+DIR_STRING, dent->d_name, len);
|
||||
|
||||
if (folder)
|
||||
{
|
||||
strcpy(temp+len, PATHSEP);
|
||||
|
||||
+2
-1
@@ -30,7 +30,8 @@ extern consvar_t cv_addons_option, cv_addons_folder, cv_addons_md5, cv_addons_sh
|
||||
|
||||
*/
|
||||
|
||||
filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *wantedmd5sum, boolean completepath, int maxsearchdepth);
|
||||
filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *wantedmd5sum,
|
||||
boolean completepath, int maxsearchdepth);
|
||||
|
||||
#define menudepth 20
|
||||
|
||||
|
||||
+4
-2
@@ -310,6 +310,8 @@ consvar_t cv_chatbacktint = {"chatbacktint", "On", CV_SAVE, CV_OnOff, NULL, 0, N
|
||||
static CV_PossibleValue_t consolechat_cons_t[] = {{0, "Window"}, {1, "Console"}, {2, "Window (Hidden)"}, {0, NULL}};
|
||||
consvar_t cv_consolechat = {"chatmode", "Window", CV_SAVE, consolechat_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
consvar_t cv_chatcentertext = {"chatcentertext", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
// Pause game upon window losing focus
|
||||
consvar_t cv_pauseifunfocused = {"pauseifunfocused", "Yes", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
@@ -1793,11 +1795,11 @@ void G_Ticker(boolean run)
|
||||
{
|
||||
for (i = 0; i < MAXPLAYERS; i++) // read/write demo and check turbo cheat
|
||||
{
|
||||
cmd = &players[i].cmd;
|
||||
|
||||
if (!playeringame[i])
|
||||
continue;
|
||||
|
||||
cmd = &players[i].cmd;
|
||||
|
||||
//@TODO all this throwdir stuff shouldn't be here! But it stays for now to maintain 1.0.4 compat...
|
||||
// Remove for 1.1!
|
||||
|
||||
|
||||
+1
-1
@@ -49,7 +49,7 @@ extern tic_t timeinmap; // Ticker for time spent in level (used for levelcard di
|
||||
extern INT16 rw_maximums[NUM_WEAPONS];
|
||||
|
||||
// used in game menu
|
||||
extern consvar_t cv_chatwidth, cv_chatnotifications, cv_chatheight, cv_chattime, cv_consolechat, cv_chatbacktint, cv_chatspamprotection/*, cv_compactscoreboard*/;
|
||||
extern consvar_t cv_chatwidth, cv_chatnotifications, cv_chatheight, cv_chattime, cv_consolechat, cv_chatbacktint, cv_chatspamprotection, cv_chatcentertext/*, cv_compactscoreboard*/;
|
||||
extern consvar_t cv_songcredits;
|
||||
extern consvar_t cv_showfreeplay;
|
||||
extern consvar_t cv_growmusic, cv_supermusic;
|
||||
|
||||
@@ -99,7 +99,8 @@ void HWR_ProcessPolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPt
|
||||
polygonArrayAllocSize *= 2;
|
||||
polygonArray = realloc(polygonArray, polygonArrayAllocSize * sizeof(PolygonArrayEntry));
|
||||
// also need to redo the index array, dont need to copy it though
|
||||
polygonArraySorted = realloc(polygonArraySorted, polygonArrayAllocSize * sizeof(PolygonArrayEntry*));
|
||||
free(polygonArraySorted);
|
||||
polygonArraySorted = malloc(polygonArrayAllocSize * sizeof(PolygonArrayEntry *));
|
||||
}
|
||||
|
||||
while (unsortedVertexArraySize + (int)iNumPts > unsortedVertexArrayAllocSize)
|
||||
|
||||
+27
-30
@@ -378,7 +378,7 @@ void HWR_ObjectLightLevelPost(gl_vissprite_t *spr, const sector_t *sector, INT32
|
||||
fixed_t extralight = R_GetSpriteDirectionalLighting(R_PointToAngle(spr->mobj->x, spr->mobj->y));
|
||||
|
||||
// Less change in contrast in dark sectors
|
||||
extralight = FixedMul(extralight, CLAMP(*lightlevel, 0, 255) * FRACUNIT / 255);
|
||||
extralight = FixedMul(extralight, std::min(std::max(0, *lightlevel), 255) * FRACUNIT / 255);
|
||||
|
||||
// simple OGL approximation
|
||||
fixed_t tr = R_QuickCamDist(spr->mobj->x, spr->mobj->y) << FRACBITS;
|
||||
@@ -459,6 +459,7 @@ void HWR_Lighting(FSurfaceInfo *Surface, INT32 light_level, extracolormap_t *col
|
||||
V_CubeApply(&tint_color.s.red, &tint_color.s.green, &tint_color.s.blue);
|
||||
V_CubeApply(&fade_color.s.red, &fade_color.s.green, &fade_color.s.blue);
|
||||
}
|
||||
|
||||
Surface->PolyColor.rgba = poly_color.rgba;
|
||||
Surface->TintColor.rgba = tint_color.rgba;
|
||||
Surface->FadeColor.rgba = fade_color.rgba;
|
||||
@@ -548,9 +549,9 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool
|
||||
INT32 i;
|
||||
|
||||
float height; // constant y for all points on the convex flat polygon
|
||||
float flatxref, flatyref = 0.0f;
|
||||
float fflatsize = 64.0f;
|
||||
INT32 flatflag = 63;
|
||||
static float flatxref = 0.0f, flatyref = 0.0f;
|
||||
static float fflatsize = 64.0f;
|
||||
static INT32 flatflag = 63;
|
||||
size_t len;
|
||||
|
||||
float tempxsow, tempytow;
|
||||
@@ -1013,10 +1014,10 @@ static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum,
|
||||
|
||||
float diff;
|
||||
|
||||
fixed_t v1x = FloatToFixed(wallVerts[0].x);
|
||||
fixed_t v1y = FloatToFixed(wallVerts[0].z);
|
||||
fixed_t v2x = FloatToFixed(wallVerts[1].x);
|
||||
fixed_t v2y = FloatToFixed(wallVerts[1].z);
|
||||
const fixed_t v1x = FloatToFixed(wallVerts[0].x);
|
||||
const fixed_t v1y = FloatToFixed(wallVerts[0].z);
|
||||
const fixed_t v2x = FloatToFixed(wallVerts[1].x);
|
||||
const fixed_t v2y = FloatToFixed(wallVerts[1].z);
|
||||
|
||||
const UINT8 alpha = Surf->PolyColor.s.alpha;
|
||||
FUINT lightnum = HWR_CalcWallLight(sector->lightlevel, gl_curline, NULL);
|
||||
@@ -1222,6 +1223,7 @@ static void HWR_DrawSkyWallList(void)
|
||||
|
||||
HWR_SetCurrentTexture(NULL);
|
||||
GL_UnSetShader();
|
||||
|
||||
for (i = 0; i < skyWallVertexArraySize; i++)
|
||||
{
|
||||
GL_DrawPolygon(&surf, skyWallVertexArray + i * 4, 4, PF_Occlude|PF_Invisible|PF_NoTexture|PF_Skydecal);
|
||||
@@ -5304,19 +5306,14 @@ static void HWR_DrawSkyBackground(void)
|
||||
{
|
||||
FTransform dometransform;
|
||||
|
||||
if (drewsky)
|
||||
return;
|
||||
|
||||
if (HWR_IsWireframeMode())
|
||||
if (drewsky || HWR_IsWireframeMode())
|
||||
return;
|
||||
|
||||
GL_SetBlend(PF_Translucent|PF_NoDepthTest|PF_Modulated);
|
||||
|
||||
memcpy(&dometransform, &atransform, sizeof(FTransform));
|
||||
|
||||
dometransform.x = 0.0;
|
||||
dometransform.y = 0.0;
|
||||
dometransform.z = 0.0;
|
||||
dometransform.x = dometransform.y = dometransform.z = 0.0;
|
||||
|
||||
//04/01/2000: Hurdler: added for T&L
|
||||
// It should replace all other gl_viewxxx when finished
|
||||
@@ -5333,6 +5330,7 @@ static void HWR_DrawSkyBackground(void)
|
||||
|
||||
if (HWR_UseShader())
|
||||
GL_SetShader(HWR_GetShaderFromTarget(SHADER_SKY));
|
||||
|
||||
GL_SetTransform(&dometransform);
|
||||
GL_RenderSkyDome(&gl_sky);
|
||||
}
|
||||
@@ -5350,7 +5348,6 @@ static inline void HWR_ClearView(void)
|
||||
GL_ClearBuffer(false, true, true, NULL);
|
||||
}
|
||||
|
||||
|
||||
// -----------------+
|
||||
// HWR_SetViewSize : set projection and scaling values
|
||||
// -----------------+
|
||||
@@ -5581,7 +5578,7 @@ void HWR_RenderViewpoint(gl_portal_t *rootportal, player_t *player, int stencil_
|
||||
drewsky = false;
|
||||
HWR_DrawSkyBackground();
|
||||
HWR_SetStencilState(HWR_STENCIL_NORMAL, 0);
|
||||
GL_ClearBuffer(false, false, true, 0);// clear skywall markings from the stencil buffer
|
||||
GL_ClearBuffer(false, false, true, NULL);// clear skywall markings from the stencil buffer
|
||||
HWR_SetTransform(fpov);// restore transform
|
||||
}
|
||||
}
|
||||
@@ -5700,13 +5697,7 @@ void HWR_RenderPlayerView(void)
|
||||
// Clear the color buffer, stops HOMs. Also seems to fix the skybox issue on Intel GPUs.
|
||||
if (viewssnum == 0) // Only do it if it's the first screen being rendered
|
||||
{
|
||||
FRGBAFloat ClearColor;
|
||||
|
||||
ClearColor.red = 0.0f;
|
||||
ClearColor.green = 0.0f;
|
||||
ClearColor.blue = 0.0f;
|
||||
ClearColor.alpha = 1.0f;
|
||||
|
||||
static FRGBAFloat ClearColor = {0.0f, 0.0f, 0.0f, 1.0f};
|
||||
GL_ClearBuffer(true, false, false, &ClearColor);
|
||||
}
|
||||
|
||||
@@ -5715,13 +5706,19 @@ void HWR_RenderPlayerView(void)
|
||||
if (cv_ripplewater.value)
|
||||
GL_SetShaderInfo(HWD_SHADERINFO_LEVELTIME, (INT32)leveltime); // The water surface shader needs the leveltime.
|
||||
|
||||
const angle_t light_angle = maplighting.angle - viewangle + ANGLE_90; // I fucking hate OGL's coordinate system
|
||||
GL_SetShaderInfo(HWD_SHADERINFO_LIGHT_X, FINECOSINE(light_angle >> ANGLETOFINESHIFT));
|
||||
GL_SetShaderInfo(HWD_SHADERINFO_LIGHT_Y, 0);
|
||||
GL_SetShaderInfo(HWD_SHADERINFO_LIGHT_Z, -FINESINE(light_angle >> ANGLETOFINESHIFT));
|
||||
if (cv_glmdls.value)
|
||||
{
|
||||
if (maplighting.directional)
|
||||
{
|
||||
const angle_t light_angle = maplighting.angle - viewangle + ANGLE_90; // I fucking hate OGL's coordinate system
|
||||
GL_SetShaderInfo(HWD_SHADERINFO_LIGHT_X, FINECOSINE(light_angle >> ANGLETOFINESHIFT));
|
||||
GL_SetShaderInfo(HWD_SHADERINFO_LIGHT_Y, 0);
|
||||
GL_SetShaderInfo(HWD_SHADERINFO_LIGHT_Z, -FINESINE(light_angle >> ANGLETOFINESHIFT));
|
||||
}
|
||||
|
||||
GL_SetShaderInfo(HWD_SHADERINFO_LIGHT_CONTRAST, maplighting.contrast);
|
||||
GL_SetShaderInfo(HWD_SHADERINFO_LIGHT_BACKLIGHT, maplighting.backlight);
|
||||
GL_SetShaderInfo(HWD_SHADERINFO_LIGHT_CONTRAST, maplighting.contrast);
|
||||
GL_SetShaderInfo(HWD_SHADERINFO_LIGHT_BACKLIGHT, maplighting.backlight);
|
||||
}
|
||||
}
|
||||
|
||||
if (viewssnum > 3)
|
||||
|
||||
@@ -35,7 +35,7 @@ static struct {
|
||||
// Sprite shader
|
||||
{GLSL_DEFAULT_VERTEX_SHADER, GLSL_WALL_FRAGMENT_SHADER},
|
||||
|
||||
// Model shader
|
||||
// Model shader + diffuse lighting from above
|
||||
{GLSL_MODEL_LIGHTING_VERTEX_SHADER, GLSL_WALL_FRAGMENT_SHADER},
|
||||
|
||||
// Water shader
|
||||
|
||||
@@ -2112,7 +2112,7 @@ static void GL_Shader_SetUniforms(FSurfaceInfo *Surface, GLRGBAFloat *poly, GLRG
|
||||
UNIFORM_1(shader->uniforms[gluniform_lighting], (GLfloat)Surface->LightInfo.light_level, pglUniform1f);
|
||||
UNIFORM_1(shader->uniforms[gluniform_fade_start], (GLfloat)Surface->LightInfo.fade_start, pglUniform1f);
|
||||
UNIFORM_1(shader->uniforms[gluniform_fade_end], (GLfloat)Surface->LightInfo.fade_end, pglUniform1f);
|
||||
directional = Surface->LightInfo.directional;
|
||||
directional = cv_glmdls.value && Surface->LightInfo.directional;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
+1
-1
@@ -1658,7 +1658,7 @@ static void HU_drawMiniChat(void)
|
||||
if (cv_chatbacktint.value) // on request of wolfy
|
||||
V_DrawFillConsoleMap(x + dx + 2, y+dy, charwidth, charheight, 239|V_SNAPTOBOTTOM|V_SNAPTOLEFT);
|
||||
|
||||
V_DrawChatCharacter(x + dx + 2, y+dy, msg[j++] |V_SNAPTOBOTTOM|V_SNAPTOLEFT|transflag, !cv_allcaps.value, colormap);
|
||||
V_DrawChatCharacter(x + dx + 2, y+dy+cv_chatcentertext.value, msg[j++] |V_SNAPTOBOTTOM|V_SNAPTOLEFT|transflag, !cv_allcaps.value, colormap);
|
||||
}
|
||||
|
||||
dx += charwidth;
|
||||
|
||||
@@ -3074,6 +3074,12 @@ static void K_drawNameTags(void)
|
||||
else
|
||||
flipped = players[i].mo->eflags & MFE_VERTICALFLIP;
|
||||
|
||||
#ifdef HWRENDER
|
||||
// Needs extra offset. Not perfect but this will do for now
|
||||
if (rendermode == render_opengl && !cv_glshearing.value && cv_smallnametags.value)
|
||||
namey -= dup*6;
|
||||
#endif
|
||||
|
||||
if (cv_smallnametags.value || !nametaggfx)
|
||||
{
|
||||
if (flipped)
|
||||
|
||||
+3
-3
@@ -3752,7 +3752,7 @@ I_mutex replayquerymutex;
|
||||
#endif/*HAVE_THREADS*/
|
||||
|
||||
|
||||
#define MAXREPLAYQUERY 40
|
||||
#define MAXREPLAYQUERY 37
|
||||
static char replayqueryinput_buffer[MAXREPLAYQUERY+1]; // The input typed
|
||||
static textinput_t replayqueryinput;
|
||||
|
||||
@@ -4454,7 +4454,7 @@ static void M_DrawReplayHut(void)
|
||||
DrawReplayHutReplayInfo();
|
||||
}
|
||||
|
||||
x -= 40;
|
||||
x = 4;
|
||||
|
||||
// Draw search query
|
||||
M_DrawTextBoxFlags(x, 200 - 22, MAXREPLAYQUERY, 1, V_SNAPTOBOTTOM);
|
||||
@@ -7046,7 +7046,7 @@ static INT32 M_FindFirstMap(INT32 gtype)
|
||||
{
|
||||
INT32 i;
|
||||
|
||||
if (mapheaderinfo[gamemap] && (mapheaderinfo[gamemap]->typeoflevel & gtype))
|
||||
if (mapheaderinfo[gamemap-1] && (mapheaderinfo[gamemap-1]->typeoflevel & gtype))
|
||||
return gamemap;
|
||||
|
||||
for (i = 0; i < NUMMAPS; i++)
|
||||
|
||||
+21
-17
@@ -1346,14 +1346,15 @@ static const char* OP_CamOptionsTooltips[] =
|
||||
};
|
||||
|
||||
#define OP_CAMMENU(pnum) \
|
||||
{IT_STRING | IT_CVAR, NULL, "Flipcam", &cv_flipcam[pnum], 30}, \
|
||||
{IT_STRING | IT_CVAR | IT_CV_BIGFLOAT, NULL, "Camera Distance", &cv_cam_dist[pnum], 50}, \
|
||||
{IT_STRING | IT_CVAR | IT_CV_BIGFLOAT, NULL, "Camera Height", &cv_cam_height[pnum], 60}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Camera Speed", &cv_cam_speed[pnum], 70}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Camera Lookback Momentum", &cv_lookbackmom[pnum], 90}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Camera Vertical Look", &cv_verticallook[pnum], 100}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Freecam Speed", &cv_freecam_speed[pnum], 120}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Third Person Camera", &cv_chasecam[pnum], 135}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Flipcam", &cv_flipcam[pnum], 30}, \
|
||||
{IT_STRING | IT_CVAR | IT_CV_BIGFLOAT, NULL, "Camera Distance", &cv_cam_dist[pnum], 50}, \
|
||||
{IT_STRING | IT_CVAR | IT_CV_BIGFLOAT, NULL, "Camera Height", &cv_cam_height[pnum], 60}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Camera Slope Pitch", &cv_cam_pitch[pnum], 70}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Camera Speed", &cv_cam_speed[pnum], 80}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Camera Lookback Momentum", &cv_cam_lookbackmom[pnum], 100}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Camera Vertical Look", &cv_verticallook[pnum], 110}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Freecam Speed", &cv_freecam_speed[pnum], 130}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Third Person Camera", &cv_chasecam[pnum], 145}, \
|
||||
|
||||
static menuitem_t OP_Player1CamOptionsMenu[] =
|
||||
{
|
||||
@@ -1385,6 +1386,7 @@ static const char* OP_PlayerCamOptionsTooltips[] =
|
||||
"Should the Camera flip on gravity flipped sections?.",
|
||||
"Camera distance relative to the Player.",
|
||||
"Height of the Camera",
|
||||
"Pitch Camera on Upwards or Downhill Slopes",
|
||||
"Speed of the Camera",
|
||||
"Should looking back inherit the Players Momentum?\nEither inherit Player Momentum or double of it\nmay make looking back while boosting or going in high speed less jarring",
|
||||
"Allows looking up/down by holding\naim forward/backward while standing still.",
|
||||
@@ -1402,18 +1404,19 @@ static menuitem_t OP_ChatOptionsMenu[] =
|
||||
NULL, "Chat Box Width", &cv_chatwidth, 20},
|
||||
{IT_STRING | IT_CVAR | IT_CV_SLIDER,
|
||||
NULL, "Chat Box Height", &cv_chatheight, 30},
|
||||
{IT_STRING | IT_CVAR, NULL, "Center Text in Chat", &cv_chatcentertext, 40},
|
||||
|
||||
{IT_STRING | IT_CVAR, NULL, "Chat Background Tint", &cv_chatbacktint, 45},
|
||||
{IT_STRING | IT_CVAR, NULL, "Message Fadeout Time", &cv_chattime, 55},
|
||||
{IT_STRING | IT_CVAR, NULL, "Spam Protection", &cv_chatspamprotection, 65},
|
||||
{IT_STRING | IT_CVAR, NULL, "Max Chat Messages", &cv_chatlogsize, 75},
|
||||
{IT_STRING | IT_CVAR, NULL, "Chat Background Tint", &cv_chatbacktint, 55},
|
||||
{IT_STRING | IT_CVAR, NULL, "Message Fadeout Time", &cv_chattime, 65},
|
||||
{IT_STRING | IT_CVAR, NULL, "Spam Protection", &cv_chatspamprotection, 75},
|
||||
{IT_STRING | IT_CVAR, NULL, "Max Chat Messages", &cv_chatlogsize, 85},
|
||||
|
||||
{IT_STRING | IT_CVAR, NULL, "Local ping display", &cv_showping, 95}, // shows ping above the framerate if we want to.
|
||||
{IT_STRING | IT_CVAR, NULL, "Ping display style", &cv_pingstyle, 105},
|
||||
{IT_STRING | IT_CVAR, NULL, "Ping measurement", &cv_pingmeasurement, 115},
|
||||
{IT_STRING | IT_CVAR, NULL, "Ping icon", &cv_pingicon, 125},
|
||||
{IT_STRING | IT_CVAR, NULL, "Local ping display", &cv_showping, 105}, // shows ping above the framerate if we want to.
|
||||
{IT_STRING | IT_CVAR, NULL, "Ping display style", &cv_pingstyle, 115},
|
||||
{IT_STRING | IT_CVAR, NULL, "Ping measurement", &cv_pingmeasurement, 125},
|
||||
{IT_STRING | IT_CVAR, NULL, "Ping icon", &cv_pingicon, 135},
|
||||
|
||||
{IT_STRING | IT_CVAR, NULL, "Show IP address in playerlist", &cv_shownodeip, 135},
|
||||
{IT_STRING | IT_CVAR, NULL, "Show IP address in playerlist", &cv_shownodeip, 145},
|
||||
};
|
||||
|
||||
static const char* OP_ChatOptionsTooltips[] =
|
||||
@@ -1421,6 +1424,7 @@ static const char* OP_ChatOptionsTooltips[] =
|
||||
"Chat mode used for in-game chat.",
|
||||
"Width of chat box.",
|
||||
"Height of chat box.",
|
||||
"Center text in the chat message pop ups.",
|
||||
"Chatbox background.",
|
||||
"Fadeout time for new chat message.",
|
||||
"Spam protection for in-game chat.",
|
||||
|
||||
+1
-1
@@ -96,7 +96,7 @@ ATTRINLINE static fixed_t FUNCINLINE __internal_prng__(void)
|
||||
randomseed ^= randomseed >> 13;
|
||||
randomseed ^= randomseed >> 11;
|
||||
randomseed ^= randomseed << 21;
|
||||
return ( (randomseed*36548569) >> 4) & (FRACUNIT-1);
|
||||
return ((randomseed*36548569) >> 4) & (FRACUNIT-1);
|
||||
}
|
||||
|
||||
/** Provides a random fixed point number. Distribution is uniform.
|
||||
|
||||
+6
-3
@@ -128,6 +128,9 @@ typedef struct camera_s
|
||||
// SRB2Kart: camera pans while drifting
|
||||
fixed_t pan;
|
||||
|
||||
// SRB2Kart: camera pitches on slopes
|
||||
angle_t pitch;
|
||||
|
||||
// postproccess effects
|
||||
UINT8 postimg;
|
||||
} camera_t;
|
||||
@@ -144,9 +147,11 @@ enum
|
||||
|
||||
extern camera_t camera[MAXSPLITSCREENPLAYERS];
|
||||
extern consvar_t cv_cam_dist[MAXSPLITSCREENPLAYERS];
|
||||
extern consvar_t cv_cam_still[MAXSPLITSCREENPLAYERS];
|
||||
extern consvar_t cv_cam_height[MAXSPLITSCREENPLAYERS];
|
||||
extern consvar_t cv_cam_pitch[MAXSPLITSCREENPLAYERS];
|
||||
extern consvar_t cv_cam_speed[MAXSPLITSCREENPLAYERS];
|
||||
extern consvar_t cv_cam_lookbackmom[MAXSPLITSCREENPLAYERS];
|
||||
extern consvar_t cv_cam_still[MAXSPLITSCREENPLAYERS];
|
||||
extern consvar_t cv_cam_rotate[MAXSPLITSCREENPLAYERS];
|
||||
extern consvar_t cv_cam_timeover[MAXSPLITSCREENPLAYERS];
|
||||
|
||||
@@ -160,8 +165,6 @@ extern consvar_t cv_actionmovie;
|
||||
|
||||
extern consvar_t cv_screenquake;
|
||||
|
||||
extern consvar_t cv_lookbackmom[MAXSPLITSCREENPLAYERS];
|
||||
|
||||
extern consvar_t cv_verticallook[MAXSPLITSCREENPLAYERS];
|
||||
|
||||
extern fixed_t t_cam_rotate[MAXSPLITSCREENPLAYERS];
|
||||
|
||||
+4
-2
@@ -9854,7 +9854,6 @@ mobj_t *P_SpawnShadowMobj(mobj_t * caster)
|
||||
mobj->radius = info->radius;
|
||||
mobj->height = info->height;
|
||||
mobj->flags = info->flags;
|
||||
mobj->blendmode = AST_TRANSLUCENT;
|
||||
|
||||
mobj->health = info->spawnhealth;
|
||||
|
||||
@@ -9890,7 +9889,10 @@ mobj_t *P_SpawnShadowMobj(mobj_t * caster)
|
||||
}
|
||||
|
||||
// Sprite rendering
|
||||
mobj->spritexscale = mobj->spriteyscale = mobj->scale;
|
||||
mobj->blendmode = AST_TRANSLUCENT;
|
||||
mobj->realxscale = mobj->realyscale = mobj->scale;
|
||||
mobj->spritexscale = mobj->realxscale;
|
||||
mobj->spriteyscale = mobj->realyscale;
|
||||
|
||||
// set subsector and/or block links
|
||||
P_SetThingPosition(mobj);
|
||||
|
||||
+26
-27
@@ -442,7 +442,7 @@ void P_UpdateSegLightOffset(seg_t *li)
|
||||
|
||||
extralight = -contrastFixed + FixedMul(light, contrastFixed * 2);
|
||||
|
||||
// Between -2 and 2 for software, -8 and 8 for hardware
|
||||
// Between -1 and 1 for software, -8 and 8 for hardware
|
||||
li->lightOffset = FixedFloor((extralight / 8) + (FRACUNIT / 2)) / FRACUNIT;
|
||||
#ifdef HWRENDER
|
||||
li->hwLightOffset = FixedFloor(extralight + (FRACUNIT / 2)) / FRACUNIT;
|
||||
@@ -537,7 +537,6 @@ static void P_SetupDirectionalLight(void)
|
||||
|
||||
oldmap = gamemap;
|
||||
oldencore = encoremode;
|
||||
return;
|
||||
}
|
||||
|
||||
maplighting.contrast = lighting->light_contrast;
|
||||
@@ -1748,33 +1747,33 @@ static void P_CreateBlockMap(void)
|
||||
|
||||
// Now we simply iterate block-by-block until we reach the end block.
|
||||
for (curblockx = bxstart; curblockx <= bxend; curblockx++)
|
||||
for (curblocky = bystart; curblocky <= byend; curblocky++)
|
||||
{
|
||||
size_t b = curblocky * bmapwidth + curblockx;
|
||||
|
||||
if (b >= tot)
|
||||
continue;
|
||||
|
||||
if (!straight && !(LineInBlock((fixed_t)x, (fixed_t)y, (fixed_t)v2x, (fixed_t)v2y, (fixed_t)(curblockx << MAPBTOFRAC), (fixed_t)(curblocky << MAPBTOFRAC))))
|
||||
continue;
|
||||
|
||||
// Increase size of allocated list if necessary
|
||||
if (bmap[b].n >= bmap[b].nalloc)
|
||||
for (curblocky = bystart; curblocky <= byend; curblocky++)
|
||||
{
|
||||
// Graue 02-29-2004: make code more readable, don't realloc a null pointer
|
||||
// (because it crashes for me, and because the comp.lang.c FAQ says so)
|
||||
if (bmap[b].nalloc == 0)
|
||||
bmap[b].nalloc = 8;
|
||||
else
|
||||
bmap[b].nalloc *= 2;
|
||||
bmap[b].list = Z_Realloc(bmap[b].list, bmap[b].nalloc * sizeof (*bmap->list), PU_CACHE, &bmap[b].list);
|
||||
if (!bmap[b].list)
|
||||
I_Error("Out of Memory in P_CreateBlockMap");
|
||||
}
|
||||
size_t b = curblocky * bmapwidth + curblockx;
|
||||
|
||||
// Add linedef to end of list
|
||||
bmap[b].list[bmap[b].n++] = (INT32)i;
|
||||
}
|
||||
if (b >= tot)
|
||||
continue;
|
||||
|
||||
if (!straight && !(LineInBlock((fixed_t)x, (fixed_t)y, (fixed_t)v2x, (fixed_t)v2y, (fixed_t)(curblockx << MAPBTOFRAC), (fixed_t)(curblocky << MAPBTOFRAC))))
|
||||
continue;
|
||||
|
||||
// Increase size of allocated list if necessary
|
||||
if (bmap[b].n >= bmap[b].nalloc)
|
||||
{
|
||||
// Graue 02-29-2004: make code more readable, don't realloc a null pointer
|
||||
// (because it crashes for me, and because the comp.lang.c FAQ says so)
|
||||
if (bmap[b].nalloc == 0)
|
||||
bmap[b].nalloc = 8;
|
||||
else
|
||||
bmap[b].nalloc *= 2;
|
||||
bmap[b].list = Z_Realloc(bmap[b].list, bmap[b].nalloc * sizeof (*bmap->list), PU_CACHE, &bmap[b].list);
|
||||
if (!bmap[b].list)
|
||||
I_Error("Out of Memory in P_CreateBlockMap");
|
||||
}
|
||||
|
||||
// Add linedef to end of list
|
||||
bmap[b].list[bmap[b].n++] = (INT32)i;
|
||||
}
|
||||
}
|
||||
|
||||
// Compute the total size of the blockmap.
|
||||
|
||||
+2
-34
@@ -16,6 +16,7 @@
|
||||
#endif
|
||||
|
||||
#include "doomstat.h"
|
||||
#include "dehacked.h"
|
||||
#include "g_game.h"
|
||||
#include "g_input.h"
|
||||
#include "p_local.h"
|
||||
@@ -613,37 +614,6 @@ static void P_RunQuakes(void)
|
||||
--quake.time;
|
||||
}
|
||||
|
||||
// Reset our Sprite scales and offsets
|
||||
// at the start of our tic
|
||||
// this is just to make things simpler
|
||||
// as we dont have to reset it ourselves after use
|
||||
// done at the start so lua can still overwrite everything
|
||||
static inline void P_ResetSpriteStuff(void)
|
||||
{
|
||||
thinker_t *th;
|
||||
|
||||
if (rendermode == render_none)
|
||||
return;
|
||||
|
||||
for (th = thinkercap.next; th != &thinkercap; th = th->next)
|
||||
{
|
||||
mobj_t *mo;
|
||||
|
||||
if (th->function != (actionf_p1)P_MobjThinker) // not a mobj
|
||||
continue;
|
||||
|
||||
mo = (mobj_t *)th;
|
||||
|
||||
if (!mo || (mo->sprite == SPR_NULL) || (mo->flags2 & MF2_DONTDRAW) || (mo->type == MT_SHADOW))
|
||||
continue;
|
||||
|
||||
mo->spritexscale = mo->realxscale;
|
||||
mo->spriteyscale = mo->realyscale;
|
||||
mo->spritexoffset = mo->realxoffset;
|
||||
mo->spriteyoffset = mo->realyoffset;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// P_Ticker
|
||||
//
|
||||
@@ -711,9 +681,9 @@ void P_Ticker(boolean run)
|
||||
if (playeringame[i])
|
||||
G_WriteDemoTiccmd(&players[i].cmd, i);
|
||||
}
|
||||
|
||||
if (demo.playback)
|
||||
{
|
||||
|
||||
#ifdef DEMO_COMPAT_100
|
||||
if (demo.version == 0x0001)
|
||||
{
|
||||
@@ -745,8 +715,6 @@ void P_Ticker(boolean run)
|
||||
ps_lua_mobjhooks.value.i = 0;
|
||||
ps_checkposition_calls.value.i = 0;
|
||||
|
||||
P_ResetSpriteStuff();
|
||||
|
||||
PS_START_TIMING(ps_lua_prethinkframe_time);
|
||||
LUA_HookPreThinkFrame();
|
||||
PS_STOP_TIMING(ps_lua_prethinkframe_time);
|
||||
|
||||
+90
-25
@@ -3003,21 +3003,28 @@ static void CV_PlayerCam4_OnChange(void)
|
||||
}
|
||||
|
||||
consvar_t cv_cam_dist[MAXSPLITSCREENPLAYERS] = {
|
||||
{"cam_dist", "160", CV_FLOAT|CV_SAVE|CV_CALL|CV_NOINIT, NULL, CV_PlayerCam1_OnChange, 0, NULL, NULL, 0, 0, NULL},
|
||||
{"cam_dist", "160", CV_FLOAT|CV_SAVE|CV_CALL|CV_NOINIT, NULL, CV_PlayerCam1_OnChange, 0, NULL, NULL, 0, 0, NULL},
|
||||
{"cam2_dist", "160", CV_FLOAT|CV_SAVE|CV_CALL|CV_NOINIT, NULL, CV_PlayerCam2_OnChange, 0, NULL, NULL, 0, 0, NULL},
|
||||
{"cam3_dist", "160", CV_FLOAT|CV_SAVE|CV_CALL|CV_NOINIT, NULL, CV_PlayerCam3_OnChange, 0, NULL, NULL, 0, 0, NULL},
|
||||
{"cam4_dist", "160", CV_FLOAT|CV_SAVE|CV_CALL|CV_NOINIT, NULL, CV_PlayerCam4_OnChange, 0, NULL, NULL, 0, 0, NULL}
|
||||
};
|
||||
|
||||
consvar_t cv_cam_height[MAXSPLITSCREENPLAYERS] = {
|
||||
{"cam_height", "50", CV_FLOAT|CV_SAVE|CV_CALL|CV_NOINIT, NULL, CV_PlayerCam1_OnChange, 0, NULL, NULL, 0, 0, NULL},
|
||||
{"cam_height", "50", CV_FLOAT|CV_SAVE|CV_CALL|CV_NOINIT, NULL, CV_PlayerCam1_OnChange, 0, NULL, NULL, 0, 0, NULL},
|
||||
{"cam2_height", "50", CV_FLOAT|CV_SAVE|CV_CALL|CV_NOINIT, NULL, CV_PlayerCam2_OnChange, 0, NULL, NULL, 0, 0, NULL},
|
||||
{"cam3_height", "50", CV_FLOAT|CV_SAVE|CV_CALL|CV_NOINIT, NULL, CV_PlayerCam3_OnChange, 0, NULL, NULL, 0, 0, NULL},
|
||||
{"cam4_height", "50", CV_FLOAT|CV_SAVE|CV_CALL|CV_NOINIT, NULL, CV_PlayerCam4_OnChange, 0, NULL, NULL, 0, 0, NULL},
|
||||
};
|
||||
|
||||
consvar_t cv_cam_pitch[MAXSPLITSCREENPLAYERS] = {
|
||||
{"cam_pitch", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL},
|
||||
{"cam2_pitch", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL},
|
||||
{"cam3_pitch", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL},
|
||||
{"cam4_pitch", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}
|
||||
};
|
||||
|
||||
consvar_t cv_cam_still[MAXSPLITSCREENPLAYERS] = {
|
||||
{"cam_still", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL},
|
||||
{"cam_still", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL},
|
||||
{"cam2_still", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL},
|
||||
{"cam3_still", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL},
|
||||
{"cam4_still", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}
|
||||
@@ -3025,7 +3032,7 @@ consvar_t cv_cam_still[MAXSPLITSCREENPLAYERS] = {
|
||||
|
||||
static CV_PossibleValue_t cam_speed_cons_t[] = {{0, "MIN"}, {1*FRACUNIT, "MAX"}, {0, NULL}};
|
||||
consvar_t cv_cam_speed[MAXSPLITSCREENPLAYERS] = {
|
||||
{"cam_speed", "0.4", CV_FLOAT|CV_SAVE, cam_speed_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL},
|
||||
{"cam_speed", "0.4", CV_FLOAT|CV_SAVE, cam_speed_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL},
|
||||
{"cam2_speed", "0.4", CV_FLOAT|CV_SAVE, cam_speed_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL},
|
||||
{"cam3_speed", "0.4", CV_FLOAT|CV_SAVE, cam_speed_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL},
|
||||
{"cam4_speed", "0.4", CV_FLOAT|CV_SAVE, cam_speed_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}
|
||||
@@ -3034,14 +3041,14 @@ consvar_t cv_cam_speed[MAXSPLITSCREENPLAYERS] = {
|
||||
|
||||
static CV_PossibleValue_t cam_rotate_cons_t[] = {{-720, "MIN"}, {720, "MAX"}, {0, NULL}};
|
||||
consvar_t cv_cam_rotate[MAXSPLITSCREENPLAYERS] = {
|
||||
{"cam_rotate", "0", CV_CALL|CV_NOINIT, cam_rotate_cons_t, CV_CamRotate_OnChange, 0, NULL, NULL, 0, 0, NULL},
|
||||
{"cam_rotate", "0", CV_CALL|CV_NOINIT, cam_rotate_cons_t, CV_CamRotate_OnChange, 0, NULL, NULL, 0, 0, NULL},
|
||||
{"cam2_rotate", "0", CV_CALL|CV_NOINIT, cam_rotate_cons_t, CV_CamRotate2_OnChange, 0, NULL, NULL, 0, 0, NULL},
|
||||
{"cam3_rotate", "0", CV_CALL|CV_NOINIT, cam_rotate_cons_t, CV_CamRotate3_OnChange, 0, NULL, NULL, 0, 0, NULL},
|
||||
{"cam4_rotate", "0", CV_CALL|CV_NOINIT, cam_rotate_cons_t, CV_CamRotate4_OnChange, 0, NULL, NULL, 0, 0, NULL}
|
||||
};
|
||||
|
||||
consvar_t cv_cam_timeover[MAXSPLITSCREENPLAYERS] = {
|
||||
{"cam_timeover", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL},
|
||||
{"cam_timeover", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL},
|
||||
{"cam2_timeover", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL},
|
||||
{"cam3_timeover", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL},
|
||||
{"cam4_timeover", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}
|
||||
@@ -3049,7 +3056,7 @@ consvar_t cv_cam_timeover[MAXSPLITSCREENPLAYERS] = {
|
||||
|
||||
static CV_PossibleValue_t freecam_speed_cons_t[] = {{0, "MIN"}, {10, "MAX"}, {0, NULL}};
|
||||
consvar_t cv_freecam_speed[MAXSPLITSCREENPLAYERS] = {
|
||||
{"freecam_speed", "1", CV_SAVE, freecam_speed_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL},
|
||||
{"freecam_speed", "1", CV_SAVE, freecam_speed_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL},
|
||||
{"freecam2_speed", "1", CV_SAVE, freecam_speed_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL},
|
||||
{"freecam3_speed", "1", CV_SAVE, freecam_speed_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL},
|
||||
{"freecam4_speed", "1", CV_SAVE, freecam_speed_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}
|
||||
@@ -3063,13 +3070,13 @@ consvar_t cv_actionmovie = {"actionmovie", "Off", CV_SAVE, CV_OnOff, NULL, 0, NU
|
||||
|
||||
consvar_t cv_screenquake = {"quakescreenshake", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
static CV_PossibleValue_t lookbackmom_cons_t[] = {{0, "Off"}, {1, "On"}, {2, "Double"}, {0, NULL}};
|
||||
static CV_PossibleValue_t cam_lookbackmom_cons_t[] = {{0, "Off"}, {1, "On"}, {2, "Double"}, {0, NULL}};
|
||||
|
||||
consvar_t cv_lookbackmom[MAXSPLITSCREENPLAYERS] = {
|
||||
{"cameralookbackmom", "Off", CV_SAVE, lookbackmom_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL},
|
||||
{"cameralookbackmom2", "Off", CV_SAVE, lookbackmom_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL},
|
||||
{"cameralookbackmom3", "Off", CV_SAVE, lookbackmom_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL},
|
||||
{"cameralookbackmom4", "Off", CV_SAVE, lookbackmom_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}
|
||||
consvar_t cv_cam_lookbackmom[MAXSPLITSCREENPLAYERS] = {
|
||||
{"cameralookbackmom", "Off", CV_SAVE, cam_lookbackmom_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL},
|
||||
{"cameralookbackmom2", "Off", CV_SAVE, cam_lookbackmom_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL},
|
||||
{"cameralookbackmom3", "Off", CV_SAVE, cam_lookbackmom_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL},
|
||||
{"cameralookbackmom4", "Off", CV_SAVE, cam_lookbackmom_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}
|
||||
};
|
||||
|
||||
fixed_t t_cam_rotate[MAXSPLITSCREENPLAYERS] = {-42, -42, -42, -42};
|
||||
@@ -3713,8 +3720,8 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
||||
static boolean lookbackactive[MAXSPLITSCREENPLAYERS];
|
||||
static UINT8 lookbackdelay[MAXSPLITSCREENPLAYERS];
|
||||
UINT8 num = 0;
|
||||
angle_t angle = 0, focusangle = 0, focusaiming = 0;
|
||||
fixed_t x, y, z, dist, viewpointx, viewpointy, camspeed, camdist, camheight, pviewheight;
|
||||
angle_t angle = 0, focusangle = 0, focusaiming = 0, pitch = 0;
|
||||
fixed_t x, y, z, dist, distxy, distz, viewpointx, viewpointy, camspeed, camdist, camheight, pviewheight;
|
||||
fixed_t pan, xpan, ypan;
|
||||
INT32 camrotate;
|
||||
boolean camstill, lookback, lookbackdown;
|
||||
@@ -3758,8 +3765,6 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
||||
|
||||
mo = player->mo;
|
||||
|
||||
const boolean vflip = (mo->eflags & MFE_VERTICALFLIP);
|
||||
|
||||
if (cv_cam_timeover[num].value && (player->pflags & PF_TIMEOVER))
|
||||
timeover = (player->kartstuff[k_timeovercam] > 2*TICRATE ? 2 : 1); // 1 for momentum keep, 2 for turnaround
|
||||
else
|
||||
@@ -3817,6 +3822,8 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
||||
if (P_CameraThinker(player, thiscam, resetcalled))
|
||||
return true;
|
||||
|
||||
const boolean vflip = (mo->eflags & MFE_VERTICALFLIP);
|
||||
|
||||
camspeed = cv_cam_speed[num].value;
|
||||
camstill = cv_cam_still[num].value;
|
||||
camrotate = cv_cam_rotate[num].value;
|
||||
@@ -3913,8 +3920,41 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
||||
if (player->kartstuff[k_boostcam])
|
||||
dist -= FixedMul(11*dist/16, player->kartstuff[k_boostcam]);
|
||||
|
||||
x = mo->x - FixedMul(FINECOSINE((angle>>ANGLETOFINESHIFT) & FINEMASK), dist);
|
||||
y = mo->y - FixedMul(FINESINE((angle>>ANGLETOFINESHIFT) & FINEMASK), dist);
|
||||
if (cv_cam_pitch[num].value)
|
||||
{
|
||||
if (mo->standingslope)
|
||||
{
|
||||
pitch = (angle_t)FixedMul(P_ReturnThrustX(mo, thiscam->angle - mo->standingslope->xydirection, FRACUNIT), (fixed_t)mo->standingslope->zangle);
|
||||
|
||||
if (vflip)
|
||||
{
|
||||
if (pitch >= ANGLE_180)
|
||||
pitch = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pitch < ANGLE_180)
|
||||
pitch = 0;
|
||||
}
|
||||
}
|
||||
pitch = thiscam->pitch + (angle_t)FixedMul(pitch - thiscam->pitch, camspeed/4);
|
||||
|
||||
#ifdef HWRENDER
|
||||
if (rendermode == render_opengl)
|
||||
distxy = FixedMul(dist, FINECOSINE((pitch>>ANGLETOFINESHIFT) & FINEMASK));
|
||||
else
|
||||
#endif
|
||||
distxy = dist;
|
||||
distz = -FixedMul(dist, FINESINE((pitch>>ANGLETOFINESHIFT) & FINEMASK));
|
||||
}
|
||||
else
|
||||
{
|
||||
distxy = dist;
|
||||
distz = 0;
|
||||
}
|
||||
|
||||
x = mo->x - FixedMul(FINECOSINE((angle>>ANGLETOFINESHIFT) & FINEMASK), distxy);
|
||||
y = mo->y - FixedMul(FINESINE((angle>>ANGLETOFINESHIFT) & FINEMASK), distxy);
|
||||
|
||||
// SRB2Kart: set camera panning
|
||||
if (camstill || resetcalled || player->playerstate == PST_DEAD)
|
||||
@@ -3946,10 +3986,26 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
||||
|
||||
pviewheight = FixedMul(32<<FRACBITS, mo->scale);
|
||||
|
||||
if (vflip)
|
||||
z = mo->z + mo->height - pviewheight - camheight;
|
||||
if (cv_cam_pitch[num].value)
|
||||
{
|
||||
if (vflip)
|
||||
{
|
||||
distz = min(-camheight, distz);
|
||||
z = mo->z + mo->height - pviewheight + distz;
|
||||
}
|
||||
else
|
||||
{
|
||||
distz = max(camheight, distz);
|
||||
z = mo->z + pviewheight + distz;
|
||||
}
|
||||
}
|
||||
else
|
||||
z = mo->z + pviewheight + camheight;
|
||||
{
|
||||
if (vflip)
|
||||
z = mo->z + mo->height - pviewheight - camheight;
|
||||
else
|
||||
z = mo->z + pviewheight + camheight;
|
||||
}
|
||||
|
||||
#ifndef NOCLIPCAM // Disable all z-clipping for noclip cam
|
||||
if (P_CheckNoclipCameraPosition(player, thiscam, x, y, z, resetcalled))
|
||||
@@ -3991,16 +4047,17 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
||||
// when looking back, camera's momentum
|
||||
// should inherit the momentum of the player
|
||||
// if value is 2, add extra
|
||||
if (cv_lookbackmom[num].value && lookback && lookbackdelay[num])
|
||||
if (cv_cam_lookbackmom[num].value && lookback && lookbackdelay[num])
|
||||
{
|
||||
thiscam->momx += cv_lookbackmom[num].value*mo->momx;
|
||||
thiscam->momy += cv_lookbackmom[num].value*mo->momy;
|
||||
thiscam->momx += cv_cam_lookbackmom[num].value*mo->momx;
|
||||
thiscam->momy += cv_cam_lookbackmom[num].value*mo->momy;
|
||||
}
|
||||
|
||||
thiscam->momz = FixedMul(z - thiscam->z, camspeed/2);
|
||||
}
|
||||
|
||||
thiscam->pan = pan;
|
||||
thiscam->pitch = pitch;
|
||||
|
||||
// compute aming to look the viewed point
|
||||
f1 = viewpointx-thiscam->x;
|
||||
@@ -4008,9 +4065,17 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
||||
dist = FixedHypot(f1, f2);
|
||||
|
||||
if (vflip)
|
||||
{
|
||||
angle = R_PointToAngle2(0, thiscam->z + thiscam->height, dist, mo->z + mo->height - P_GetPlayerHeight(player));
|
||||
if (thiscam->pitch < ANGLE_180 && thiscam->pitch > angle)
|
||||
angle += (thiscam->pitch - angle)/2;
|
||||
}
|
||||
else
|
||||
{
|
||||
angle = R_PointToAngle2(0, thiscam->z, dist, mo->z + P_GetPlayerHeight(player));
|
||||
if (thiscam->pitch >= ANGLE_180 && thiscam->pitch < angle)
|
||||
angle -= (angle - thiscam->pitch)/2;
|
||||
}
|
||||
|
||||
if (player->playerstate != PST_DEAD && !((player->pflags & PF_NIGHTSMODE) && player->exiting))
|
||||
angle += (focusaiming < ANGLE_180 ? focusaiming/2 : InvAngle(InvAngle(focusaiming)/2)); // overcomplicated version of '((signed)focusaiming)/2;'
|
||||
|
||||
@@ -25,6 +25,9 @@
|
||||
|
||||
#include "screen.h" // MAXVIDWIDTH, MAXVIDHEIGHT
|
||||
|
||||
#define MAP_ICON_WIDTH 160
|
||||
#define MAP_ICON_HEIGHT 100
|
||||
|
||||
//
|
||||
// ClipWallSegment
|
||||
// Clips the given range of columns
|
||||
|
||||
@@ -57,7 +57,7 @@ static constexpr UINT8 R_GetColumnTranslucent(drawcolumndata_t* dc, UINT8 * rest
|
||||
}
|
||||
|
||||
template<DrawColumnType Type>
|
||||
static constexpr UINT8 R_DrawColumnPixel(drawcolumndata_t* dc, UINT8 * restrict dest, UINT32 bit, const restrict UINT8 *source, const restrict UINT8 *colormap)
|
||||
static constexpr UINT8 R_DrawColumnPixel(drawcolumndata_t* dc, UINT8 * restrict dest, UINT32 bit, const UINT8 * restrict source, const UINT8 * restrict colormap)
|
||||
{
|
||||
UINT8 col = source[bit];
|
||||
|
||||
@@ -217,7 +217,7 @@ static void R_DrawColumnTemplate(drawcolumndata_t *dc)
|
||||
{
|
||||
if (frac < 0)
|
||||
// adjust in case we underread
|
||||
frac += FRACUNIT;
|
||||
frac += fracstep;
|
||||
|
||||
// texture has no height, so just go
|
||||
while (--count >= 0)
|
||||
|
||||
+33
@@ -492,6 +492,7 @@ void R_CreateInterpolator_Polyobj(thinker_t *thinker, polyobj_t *polyobj)
|
||||
|
||||
interp->polyobj.oldcx = interp->polyobj.bakcx = polyobj->centerPt.x;
|
||||
interp->polyobj.oldcy = interp->polyobj.bakcy = polyobj->centerPt.y;
|
||||
interp->polyobj.oldangle = interp->polyobj.bakangle = polyobj->angle;
|
||||
}
|
||||
|
||||
/*void R_CreateInterpolator_DynSlope(thinker_t *thinker, pslope_t *slope)
|
||||
@@ -515,6 +516,15 @@ void R_InitializeLevelInterpolators(void)
|
||||
levelinterpolators = NULL;
|
||||
}
|
||||
|
||||
static void RecalculatePolyobjectSegAngles(polyobj_t *polyobj)
|
||||
{
|
||||
for (size_t i = 0; i < polyobj->segCount; i++)
|
||||
{
|
||||
seg_t *seg = polyobj->segs[i];
|
||||
seg->angle = R_PointToAngle2(seg->v1->x, seg->v1->y, seg->v2->x, seg->v2->y);
|
||||
}
|
||||
}
|
||||
|
||||
static void UpdateLevelInterpolatorState(levelinterpolator_t *interp)
|
||||
{
|
||||
size_t i;
|
||||
@@ -545,10 +555,14 @@ static void UpdateLevelInterpolatorState(levelinterpolator_t *interp)
|
||||
interp->polyobj.bakvertices[i * 2 ] = interp->polyobj.polyobj->vertices[i]->x;
|
||||
interp->polyobj.bakvertices[i * 2 + 1] = interp->polyobj.polyobj->vertices[i]->y;
|
||||
}
|
||||
|
||||
RecalculatePolyobjectSegAngles(interp->polyobj.polyobj);
|
||||
interp->polyobj.oldcx = interp->polyobj.bakcx;
|
||||
interp->polyobj.oldcy = interp->polyobj.bakcy;
|
||||
interp->polyobj.oldangle = interp->polyobj.bakangle;
|
||||
interp->polyobj.bakcx = interp->polyobj.polyobj->centerPt.x;
|
||||
interp->polyobj.bakcy = interp->polyobj.polyobj->centerPt.y;
|
||||
interp->polyobj.bakangle = interp->polyobj.polyobj->angle;
|
||||
break;
|
||||
/*case LVLINTERP_DynSlope:
|
||||
FV3_Copy(&interp->dynslope.oldo, &interp->dynslope.bako);
|
||||
@@ -630,8 +644,11 @@ void R_ApplyLevelInterpolators(fixed_t frac)
|
||||
interp->polyobj.polyobj->vertices[ii]->x = R_LerpFixed(interp->polyobj.oldvertices[ii * 2 ], interp->polyobj.bakvertices[ii * 2 ], frac);
|
||||
interp->polyobj.polyobj->vertices[ii]->y = R_LerpFixed(interp->polyobj.oldvertices[ii * 2 + 1], interp->polyobj.bakvertices[ii * 2 + 1], frac);
|
||||
}
|
||||
|
||||
RecalculatePolyobjectSegAngles(interp->polyobj.polyobj);
|
||||
interp->polyobj.polyobj->centerPt.x = R_LerpFixed(interp->polyobj.oldcx, interp->polyobj.bakcx, frac);
|
||||
interp->polyobj.polyobj->centerPt.y = R_LerpFixed(interp->polyobj.oldcy, interp->polyobj.bakcy, frac);
|
||||
interp->polyobj.polyobj->angle = R_LerpAngle(interp->polyobj.oldangle, interp->polyobj.bakangle, frac);
|
||||
break;
|
||||
/*case LVLINTERP_DynSlope:
|
||||
R_LerpVector3(&interp->dynslope.oldo, &interp->dynslope.bako, frac, &interp->dynslope.slope->o);
|
||||
@@ -685,8 +702,11 @@ void R_RestoreLevelInterpolators(void)
|
||||
interp->polyobj.polyobj->vertices[ii]->x = interp->polyobj.bakvertices[ii * 2 ];
|
||||
interp->polyobj.polyobj->vertices[ii]->y = interp->polyobj.bakvertices[ii * 2 + 1];
|
||||
}
|
||||
|
||||
RecalculatePolyobjectSegAngles(interp->polyobj.polyobj);
|
||||
interp->polyobj.polyobj->centerPt.x = interp->polyobj.bakcx;
|
||||
interp->polyobj.polyobj->centerPt.y = interp->polyobj.bakcy;
|
||||
interp->polyobj.polyobj->angle = interp->polyobj.bakangle;
|
||||
break;
|
||||
/*case LVLINTERP_DynSlope:
|
||||
FV3_Copy(&interp->dynslope.slope->o, &interp->dynslope.bako);
|
||||
@@ -840,6 +860,19 @@ void R_ResetMobjInterpolationState(mobj_t *mobj)
|
||||
mobj->player->old_frameangle = mobj->player->frameangle;
|
||||
}
|
||||
|
||||
// Reset our Sprite scales and offsets
|
||||
// at the start of the tic
|
||||
// this is just to make things simpler
|
||||
// as we dont have to reset it ourselves after use
|
||||
// done at the start so lua can still overwrite everything
|
||||
|
||||
// technically not interpolation related
|
||||
// but this saves us another thinkerloop and multiple checks lel
|
||||
mobj->spritexscale = mobj->realxscale;
|
||||
mobj->spriteyscale = mobj->realyscale;
|
||||
mobj->spritexoffset = mobj->realxoffset;
|
||||
mobj->spriteyoffset = mobj->realyoffset;
|
||||
|
||||
mobj->resetinterp = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -119,6 +119,7 @@ typedef struct levelinterpolator_s {
|
||||
fixed_t *bakvertices;
|
||||
size_t vertices_size;
|
||||
fixed_t oldcx, oldcy, bakcx, bakcy;
|
||||
angle_t oldangle, bakangle;
|
||||
} polyobj;
|
||||
struct {
|
||||
pslope_t *slope;
|
||||
|
||||
+5
-4
@@ -1569,14 +1569,15 @@ void R_RegisterEngineStuff(void)
|
||||
CV_RegisterVar(&cv_chasecam[i]);
|
||||
|
||||
CV_RegisterVar(&cv_cam_dist[i]);
|
||||
CV_RegisterVar(&cv_cam_still[i]);
|
||||
CV_RegisterVar(&cv_cam_height[i]);
|
||||
CV_RegisterVar(&cv_cam_pitch[i]);
|
||||
CV_RegisterVar(&cv_cam_speed[i]);
|
||||
CV_RegisterVar(&cv_cam_rotate[i]);
|
||||
CV_RegisterVar(&cv_cam_timeover[i]);
|
||||
CV_RegisterVar(&cv_freecam_speed[i]);
|
||||
CV_RegisterVar(&cv_cam_lookbackmom[i]);
|
||||
CV_RegisterVar(&cv_cam_still[i]);
|
||||
CV_RegisterVar(&cv_cam_rotate[i]);
|
||||
|
||||
CV_RegisterVar(&cv_lookbackmom[i]);
|
||||
CV_RegisterVar(&cv_freecam_speed[i]);
|
||||
}
|
||||
|
||||
CV_RegisterVar(&cv_tilting);
|
||||
|
||||
+2
-2
@@ -108,7 +108,7 @@ FUNCINLINE static ATTRINLINE PUREFUNC INT32 R_PointOnSide(fixed_t x, fixed_t y,
|
||||
|
||||
// This is not as accurate
|
||||
// SHOULD NOT BE USED FOR ANYTHING GAMEPLAY RELATED!!
|
||||
FUNCINLINE static ATTRINLINE PUREFUNC INT32 R_PointOnSideFast(fixed_t x, fixed_t y, const node_t *node)
|
||||
FUNCINLINE static ATTRINLINE PUREFUNC INT32 R_PointOnSideFast(fixed_t x, fixed_t y, const node_t* restrict node)
|
||||
{
|
||||
// use cross product to determine side quickly
|
||||
INT64 v = ((INT64)y - node->y) * node->dx - ((INT64)x - node->x) * node->dy;
|
||||
@@ -201,7 +201,7 @@ extern consvar_t cv_secbright;
|
||||
|
||||
extern consvar_t cv_randomdirlight;
|
||||
|
||||
static inline INT32 R_GetSoftLightlevel(INT32 llevel)
|
||||
FUNCINLINE static ATTRINLINE INT32 R_GetSoftLightlevel(INT32 llevel)
|
||||
{
|
||||
return CLAMP(llevel, cv_secbright.value, 255) >> LIGHTSEGSHIFT;
|
||||
}
|
||||
|
||||
+159
@@ -451,6 +451,124 @@ void *Patch_CreateGL(patch_t *patch)
|
||||
}
|
||||
#endif // HWRENDER
|
||||
|
||||
//
|
||||
// R_MaskedFlatToPatch
|
||||
//
|
||||
// Convert raw pixels to a patch.
|
||||
//
|
||||
void *R_PixelsToPatch(UINT8 *raw, INT16 width, INT16 height, INT16 leftoffset, INT16 topoffset, size_t *destsize)
|
||||
{
|
||||
INT16 x, y;
|
||||
UINT8 *img;
|
||||
UINT8 *imgptr = imgbuf;
|
||||
UINT8 *colpointers, *startofspan;
|
||||
size_t size = 0;
|
||||
|
||||
if (!raw)
|
||||
return NULL;
|
||||
|
||||
// Write image size and offset
|
||||
WRITEINT16(imgptr, width);
|
||||
WRITEINT16(imgptr, height);
|
||||
WRITEINT16(imgptr, leftoffset);
|
||||
WRITEINT16(imgptr, topoffset);
|
||||
|
||||
// Leave placeholder to column pointers
|
||||
colpointers = imgptr;
|
||||
imgptr += width*4;
|
||||
|
||||
// Write columns
|
||||
for (x = 0; x < width; x++)
|
||||
{
|
||||
int lastStartY = 0;
|
||||
int spanSize = 0;
|
||||
startofspan = NULL;
|
||||
|
||||
// Write column pointer
|
||||
WRITEINT32(colpointers, imgptr - imgbuf);
|
||||
|
||||
// Write pixels
|
||||
for (y = 0; y < height; y++)
|
||||
{
|
||||
UINT8 pixel = raw[((y * width) + x)];
|
||||
UINT8 opaque = (pixel != 0xf7); // If not 247 (0xf7), we have a pixel
|
||||
|
||||
// End span if we have a transparent pixel
|
||||
if (!opaque)
|
||||
{
|
||||
if (startofspan)
|
||||
WRITEUINT8(imgptr, 0);
|
||||
startofspan = NULL;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Start new column if we need to
|
||||
if (!startofspan || spanSize == 255)
|
||||
{
|
||||
int writeY = y;
|
||||
|
||||
// If we reached the span size limit, finish the previous span
|
||||
if (startofspan)
|
||||
WRITEUINT8(imgptr, 0);
|
||||
|
||||
if (y > 254)
|
||||
{
|
||||
// Make sure we're aligned to 254
|
||||
if (lastStartY < 254)
|
||||
{
|
||||
WRITEUINT8(imgptr, 254);
|
||||
WRITEUINT8(imgptr, 0);
|
||||
imgptr += 2;
|
||||
lastStartY = 254;
|
||||
}
|
||||
|
||||
// Write stopgap empty spans if needed
|
||||
writeY = y - lastStartY;
|
||||
|
||||
while (writeY > 254)
|
||||
{
|
||||
WRITEUINT8(imgptr, 254);
|
||||
WRITEUINT8(imgptr, 0);
|
||||
imgptr += 2;
|
||||
writeY -= 254;
|
||||
}
|
||||
}
|
||||
|
||||
startofspan = imgptr;
|
||||
WRITEUINT8(imgptr, writeY);
|
||||
imgptr += 2;
|
||||
spanSize = 0;
|
||||
|
||||
lastStartY = y;
|
||||
}
|
||||
|
||||
// Write the pixel
|
||||
WRITEUINT8(imgptr, pixel);
|
||||
spanSize++;
|
||||
startofspan[1] = spanSize;
|
||||
}
|
||||
|
||||
if (startofspan)
|
||||
WRITEUINT8(imgptr, 0);
|
||||
|
||||
WRITEUINT8(imgptr, 0xFF);
|
||||
}
|
||||
|
||||
size = imgptr-imgbuf;
|
||||
img = Z_Malloc(size, PU_STATIC, NULL);
|
||||
memcpy(img, imgbuf, size);
|
||||
|
||||
if (destsize != NULL)
|
||||
*destsize = size;
|
||||
|
||||
patch_t *converted = Patch_Create((softwarepatch_t *)img, size, NULL);
|
||||
#ifdef HWRENDER
|
||||
Patch_CreateGL(converted);
|
||||
#endif
|
||||
Z_Free(img);
|
||||
|
||||
return converted;
|
||||
}
|
||||
|
||||
//
|
||||
// R_MaskedFlatToPatch
|
||||
@@ -615,3 +733,44 @@ UINT16 R_GetPatchPixel(patch_t *patch, INT32 x, INT32 y, boolean flip)
|
||||
|
||||
return 0xFF00;
|
||||
}
|
||||
|
||||
void R_PatchToPixels(patch_t *patch, UINT8 *dst)
|
||||
{
|
||||
const INT16 width = patch->width;
|
||||
|
||||
// init out destination to cyan so we can easily check for it when we convert it back to a patch
|
||||
memset(dst, 0xf7, (width * patch->height)); // should this be here or should this be taken care of before passing it?
|
||||
|
||||
for (INT32 x = 0; x < width; ++x)
|
||||
{
|
||||
INT32 y = 0;
|
||||
INT32 prevdelta = -1;
|
||||
|
||||
column_t *column = (column_t *)((UINT8 *)patch->columns + (patch->columnofs[x]));
|
||||
|
||||
while (column->topdelta != 0xff)
|
||||
{
|
||||
INT32 topdelta = column->topdelta;
|
||||
|
||||
if (topdelta <= prevdelta)
|
||||
topdelta += prevdelta;
|
||||
|
||||
prevdelta = topdelta;
|
||||
|
||||
for (; y-topdelta < column->length; ++y)
|
||||
{
|
||||
UINT8 pixel = 0;
|
||||
|
||||
if (y >= topdelta)
|
||||
{
|
||||
UINT8 *source = (UINT8*)(column) + 3;
|
||||
pixel = source[y-topdelta];
|
||||
}
|
||||
|
||||
dst[(y*width) + x] = pixel;
|
||||
}
|
||||
|
||||
column = (column_t *)((UINT8 *)column + column->length + 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
+64
-62
@@ -1,62 +1,64 @@
|
||||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||
// Copyright (C) 2018-2019 by Jaime "Lactozilla" Passos.
|
||||
// Copyright (C) 2019 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file r_patch.h
|
||||
/// \brief Patch generation.
|
||||
|
||||
#ifndef __R_PATCH__
|
||||
#define __R_PATCH__
|
||||
|
||||
#include "r_defs.h"
|
||||
|
||||
// Structs
|
||||
typedef enum
|
||||
{
|
||||
ROTAXIS_X, // Roll (the default)
|
||||
ROTAXIS_Y, // Pitch
|
||||
ROTAXIS_Z // Yaw
|
||||
} rotaxis_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
INT32 x, y;
|
||||
rotaxis_t rotaxis;
|
||||
} spriteframepivot_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
spriteframepivot_t pivot[64];
|
||||
boolean available;
|
||||
} spriteinfo_t;
|
||||
|
||||
// Patch functions
|
||||
patch_t *Patch_Create(softwarepatch_t *source, size_t srcsize, void *dest);
|
||||
void Patch_Free(patch_t *patch);
|
||||
|
||||
#define Patch_FreeTag(tagnum) Patch_FreeTags(tagnum, tagnum)
|
||||
void Patch_FreeTags(INT32 lowtag, INT32 hightag);
|
||||
|
||||
#ifdef HWRENDER
|
||||
void *Patch_AllocateHardwarePatch(patch_t *patch);
|
||||
void *Patch_CreateGL(patch_t *patch);
|
||||
#endif
|
||||
|
||||
// Conversions between patches / flats / textures...
|
||||
boolean R_CheckIfPatch(lumpnum_t lump);
|
||||
|
||||
// SpriteInfo
|
||||
extern spriteinfo_t spriteinfo[NUMSPRITES];
|
||||
void R_LoadSpriteInfoLumps(UINT16 wadnum, UINT16 numlumps);
|
||||
void R_ParseSPRTINFOLump(UINT16 wadNum, UINT16 lumpNum);
|
||||
|
||||
void *R_MaskedFlatToPatch(UINT16 *raw, INT16 width, INT16 height, INT16 leftoffset, INT16 topoffset, size_t *destsize);
|
||||
UINT16 R_GetPatchPixel(patch_t *patch, INT32 x, INT32 y, boolean flip);
|
||||
|
||||
#endif // __R_PATCH__
|
||||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||
// Copyright (C) 2018-2019 by Jaime "Lactozilla" Passos.
|
||||
// Copyright (C) 2019 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file r_patch.h
|
||||
/// \brief Patch generation.
|
||||
|
||||
#ifndef __R_PATCH__
|
||||
#define __R_PATCH__
|
||||
|
||||
#include "r_defs.h"
|
||||
|
||||
// Structs
|
||||
typedef enum
|
||||
{
|
||||
ROTAXIS_X, // Roll (the default)
|
||||
ROTAXIS_Y, // Pitch
|
||||
ROTAXIS_Z // Yaw
|
||||
} rotaxis_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
INT32 x, y;
|
||||
rotaxis_t rotaxis;
|
||||
} spriteframepivot_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
spriteframepivot_t pivot[64];
|
||||
boolean available;
|
||||
} spriteinfo_t;
|
||||
|
||||
// Patch functions
|
||||
patch_t *Patch_Create(softwarepatch_t *source, size_t srcsize, void *dest);
|
||||
void Patch_Free(patch_t *patch);
|
||||
|
||||
#define Patch_FreeTag(tagnum) Patch_FreeTags(tagnum, tagnum)
|
||||
void Patch_FreeTags(INT32 lowtag, INT32 hightag);
|
||||
|
||||
#ifdef HWRENDER
|
||||
void *Patch_AllocateHardwarePatch(patch_t *patch);
|
||||
void *Patch_CreateGL(patch_t *patch);
|
||||
#endif
|
||||
|
||||
// Conversions between patches / flats / textures...
|
||||
boolean R_CheckIfPatch(lumpnum_t lump);
|
||||
|
||||
// SpriteInfo
|
||||
extern spriteinfo_t spriteinfo[NUMSPRITES];
|
||||
void R_LoadSpriteInfoLumps(UINT16 wadnum, UINT16 numlumps);
|
||||
void R_ParseSPRTINFOLump(UINT16 wadNum, UINT16 lumpNum);
|
||||
|
||||
void *R_MaskedFlatToPatch(UINT16 *raw, INT16 width, INT16 height, INT16 leftoffset, INT16 topoffset, size_t *destsize);
|
||||
void *R_PixelsToPatch(UINT8 *raw, INT16 width, INT16 height, INT16 leftoffset, INT16 topoffset, size_t *destsize);
|
||||
UINT16 R_GetPatchPixel(patch_t *patch, INT32 x, INT32 y, boolean flip);
|
||||
void R_PatchToPixels(patch_t *patch, UINT8 *dst); // Important: dst must have enough space for patch->width*patch->height pixels!
|
||||
|
||||
#endif // __R_PATCH__
|
||||
+9
-9
@@ -1072,15 +1072,15 @@ void R_DrawSinglePlane(drawspandata_t* ds, visplane_t *pl, boolean allow_paralle
|
||||
{
|
||||
if ((pl->ffloor->flags & FF_CUTEXTRA) && (rover->flags & FF_EXTRA))
|
||||
{
|
||||
if (!(rover->flags & FF_EXTRA))
|
||||
continue;
|
||||
|
||||
// The plane is from an extra 3D floor... Check the flags so
|
||||
// there are no undesired cuts.
|
||||
if (((pl->ffloor->flags & (FF_FOG|FF_SWIMMABLE)) == (rover->flags & (FF_FOG|FF_SWIMMABLE)))
|
||||
&& pl->height < *rover->topheight
|
||||
&& pl->height > *rover->bottomheight)
|
||||
return;
|
||||
if (pl->ffloor->flags & FF_EXTRA)
|
||||
{
|
||||
// The plane is from an extra 3D floor... Check the flags so
|
||||
// there are no undesired cuts.
|
||||
if (((pl->ffloor->flags & (FF_FOG|FF_SWIMMABLE)) == (rover->flags & (FF_FOG|FF_SWIMMABLE)))
|
||||
&& pl->height < *rover->topheight
|
||||
&& pl->height > *rover->bottomheight)
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2486,7 +2486,7 @@ static const char *searchWad(const char *searchDir)
|
||||
filestatus_t fstemp;
|
||||
|
||||
strcpy(tempsw, WADKEYWORD1);
|
||||
fstemp = filesearch(tempsw, searchDir, NULL, true, 20);
|
||||
fstemp = filesearch(tempsw,searchDir,NULL,true,20);
|
||||
if (fstemp == FS_FOUND)
|
||||
{
|
||||
pathonly(tempsw);
|
||||
|
||||
+23
-122
@@ -163,20 +163,13 @@ static INT32 firstEntry = 0;
|
||||
static INT32 mousemovex = 0, mousemovey = 0;
|
||||
|
||||
// SDL vars
|
||||
static SDL_Surface *vidSurface = NULL;
|
||||
static SDL_Surface *bufSurface = NULL;
|
||||
static SDL_Surface *icoSurface = NULL;
|
||||
static SDL_Color localPalette[256];
|
||||
#if 0
|
||||
static SDL_Rect **modeList = NULL;
|
||||
static Uint8 BitsPerPixel = 16;
|
||||
#endif
|
||||
static UINT32 localPalette[256];
|
||||
Uint16 realwidth = BASEVIDWIDTH;
|
||||
Uint16 realheight = BASEVIDHEIGHT;
|
||||
static SDL_bool mousegrabok = SDL_TRUE;
|
||||
static SDL_bool wrapmouseok = SDL_FALSE;
|
||||
#define HalfWarpMouse(x,y) if (wrapmouseok) SDL_WarpMouseInWindow(window, (Uint16)(x/2),(Uint16)(y/2))
|
||||
static SDL_bool videoblitok = SDL_FALSE;
|
||||
static SDL_bool exposevideo = SDL_FALSE;
|
||||
static SDL_bool usesdl2soft = SDL_FALSE;
|
||||
static SDL_bool borderlesswindow = SDL_FALSE;
|
||||
@@ -219,7 +212,6 @@ static INT32 windowedModes[MAXWINMODES][2] =
|
||||
static INT32 custom_width = 0;
|
||||
static INT32 custom_height = 0;
|
||||
|
||||
static void Impl_VideoSetupSDLBuffer(void);
|
||||
static void Impl_VideoSetupBuffer(void);
|
||||
static SDL_bool Impl_CreateWindow(SDL_bool fullscreen);
|
||||
static void Impl_SetWindowIcon(void);
|
||||
@@ -485,39 +477,6 @@ static void VID_Command_NumModes_f (void)
|
||||
CONS_Printf(M_GetText("%d video mode(s) available(s)\n"), VID_NumModes());
|
||||
}
|
||||
|
||||
// SDL2 doesn't have SDL_GetVideoSurface or a lot of the SDL_Surface flags that SDL 1.2 had
|
||||
static void SurfaceInfo(const SDL_Surface *infoSurface, const char *SurfaceText)
|
||||
{
|
||||
INT32 vfBPP;
|
||||
|
||||
if (!infoSurface)
|
||||
return;
|
||||
|
||||
if (!SurfaceText)
|
||||
SurfaceText = M_GetText("Unknown Surface");
|
||||
|
||||
vfBPP = infoSurface->format?infoSurface->format->BitsPerPixel:0;
|
||||
|
||||
CONS_Printf("\x82" "%s\n", SurfaceText);
|
||||
CONS_Printf(M_GetText(" %ix%i at %i bit color\n"), infoSurface->w, infoSurface->h, vfBPP);
|
||||
|
||||
if (infoSurface->flags&SDL_PREALLOC)
|
||||
CONS_Printf("%s", M_GetText(" Uses preallocated memory\n"));
|
||||
else
|
||||
CONS_Printf("%s", M_GetText(" Stored in system memory\n"));
|
||||
if (infoSurface->flags&SDL_RLEACCEL)
|
||||
CONS_Printf("%s", M_GetText(" Colorkey RLE acceleration blit\n"));
|
||||
}
|
||||
|
||||
static void VID_Command_Info_f (void)
|
||||
{
|
||||
if (!M_CheckParm("-noblit"))
|
||||
videoblitok = SDL_TRUE;
|
||||
|
||||
SurfaceInfo(bufSurface, M_GetText("Current Engine Mode"));
|
||||
SurfaceInfo(vidSurface, M_GetText("Current Video Mode"));
|
||||
}
|
||||
|
||||
static void VID_Command_ModeList_f(void)
|
||||
{
|
||||
// List windowed modes
|
||||
@@ -1340,8 +1299,6 @@ void I_OsPolling(void)
|
||||
static void SDLSetMode(INT32 width, INT32 height, SDL_bool fullscreen)
|
||||
{
|
||||
static SDL_bool wasfullscreen = SDL_FALSE;
|
||||
Uint32 rmask, gmask, bmask, amask;
|
||||
int bpp = 16;
|
||||
int sw_texture_format = SDL_PIXELFORMAT_ABGR8888;
|
||||
|
||||
realwidth = vid.width;
|
||||
@@ -1410,32 +1367,13 @@ static void SDLSetMode(INT32 width, INT32 height, SDL_bool fullscreen)
|
||||
SDL_DestroyTexture(texture);
|
||||
}
|
||||
|
||||
if (!usesdl2soft)
|
||||
{
|
||||
sw_texture_format = SDL_PIXELFORMAT_RGB565;
|
||||
}
|
||||
else
|
||||
{
|
||||
bpp = 32;
|
||||
sw_texture_format = SDL_PIXELFORMAT_RGBA8888;
|
||||
}
|
||||
|
||||
texture = SDL_CreateTexture(renderer, sw_texture_format, SDL_TEXTUREACCESS_STREAMING, width, height);
|
||||
|
||||
// Set up SW surface
|
||||
if (vidSurface != NULL)
|
||||
{
|
||||
SDL_FreeSurface(vidSurface);
|
||||
}
|
||||
|
||||
if (vid.buffer)
|
||||
{
|
||||
free(vid.buffer);
|
||||
vid.buffer = NULL;
|
||||
}
|
||||
|
||||
SDL_PixelFormatEnumToMasks(sw_texture_format, &bpp, &rmask, &gmask, &bmask, &amask);
|
||||
vidSurface = SDL_CreateRGBSurface(0, width, height, bpp, rmask, gmask, bmask, amask);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1494,19 +1432,21 @@ void I_FinishUpdate(void)
|
||||
|
||||
if (rendermode == render_soft && vid.screens[0])
|
||||
{
|
||||
if (!bufSurface) //Double-Check
|
||||
void *pixels;
|
||||
int pitch;
|
||||
SDL_LockTexture(texture, NULL, &pixels, &pitch);
|
||||
int step = pitch / 4 - vid.width;
|
||||
UINT32 *restrict dst = pixels;
|
||||
UINT8 *restrict src = vid.screens[0];
|
||||
UINT32 *restrict palette = localPalette;
|
||||
for (INT32 y = 0; y < vid.height; y++)
|
||||
{
|
||||
Impl_VideoSetupSDLBuffer();
|
||||
}
|
||||
|
||||
if (bufSurface)
|
||||
{
|
||||
SDL_BlitSurface(bufSurface, &src_rect, vidSurface, &src_rect);
|
||||
// Fury -- there's no way around UpdateTexture, the GL backend uses it anyway
|
||||
SDL_LockSurface(vidSurface);
|
||||
SDL_UpdateTexture(texture, &src_rect, vidSurface->pixels, vidSurface->pitch);
|
||||
SDL_UnlockSurface(vidSurface);
|
||||
UINT8 *restrict end = src + vid.width;
|
||||
do *dst++ = palette[*src++];
|
||||
while (src < end);
|
||||
dst += step;
|
||||
}
|
||||
SDL_UnlockTexture(texture);
|
||||
|
||||
SDL_RenderClear(renderer);
|
||||
SDL_RenderCopy(renderer, texture, &src_rect, NULL);
|
||||
@@ -1553,14 +1493,11 @@ void I_SetPalette(RGBA_t *palette)
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
localPalette[i].r = palette[i].s.red;
|
||||
localPalette[i].g = palette[i].s.green;
|
||||
localPalette[i].b = palette[i].s.blue;
|
||||
localPalette[i] = 0xff000000;
|
||||
localPalette[i] |= palette[i].s.red << 0;
|
||||
localPalette[i] |= palette[i].s.green << 8;
|
||||
localPalette[i] |= palette[i].s.blue << 16;
|
||||
}
|
||||
|
||||
//if (vidSurface) SDL_SetPaletteColors(vidSurface->format->palette, localPalette, 0, 256);
|
||||
// Fury -- SDL2 vidSurface is a 32-bit surface buffer copied to the texture. It's not palletized, like bufSurface.
|
||||
if (bufSurface) SDL_SetPaletteColors(bufSurface->format->palette, localPalette, 0, 256);
|
||||
}
|
||||
|
||||
// return number of fullscreen + X11 modes
|
||||
@@ -1682,15 +1619,6 @@ INT32 VID_SetMode(INT32 modeNum)
|
||||
SDLSetMode(vid.width, vid.height, USE_FULLSCREEN);
|
||||
Impl_VideoSetupBuffer();
|
||||
|
||||
if (rendermode == render_soft)
|
||||
{
|
||||
if (bufSurface)
|
||||
{
|
||||
SDL_FreeSurface(bufSurface);
|
||||
bufSurface = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
src_rect.w = vid.width;
|
||||
src_rect.h = vid.height;
|
||||
|
||||
@@ -1818,36 +1746,19 @@ static void Impl_SetWindowIcon(void)
|
||||
SDL_SetWindowIcon(window, icoSurface);
|
||||
}
|
||||
|
||||
static void Impl_VideoSetupSDLBuffer(void)
|
||||
{
|
||||
if (bufSurface != NULL)
|
||||
{
|
||||
SDL_FreeSurface(bufSurface);
|
||||
bufSurface = NULL;
|
||||
}
|
||||
// Set up the SDL palletized buffer (copied to vidbuffer before being rendered to texture)
|
||||
bufSurface = SDL_CreateRGBSurfaceFrom(vid.screens[0], vid.width, vid.height, 8,
|
||||
(int)vid.rowbytes, 0x00000000, 0x00000000, 0x00000000, 0x00000000); // 256 mode
|
||||
|
||||
if (bufSurface)
|
||||
{
|
||||
SDL_SetPaletteColors(bufSurface->format->palette, localPalette, 0, 256);
|
||||
}
|
||||
else
|
||||
{
|
||||
I_Error("%s", M_GetText("No system memory for SDL buffer surface\n"));
|
||||
}
|
||||
}
|
||||
|
||||
static void Impl_VideoSetupBuffer(void)
|
||||
{
|
||||
// Set up game's software render buffer
|
||||
size_t size;
|
||||
|
||||
vid.rowbytes = vid.width;
|
||||
|
||||
if (vid.buffer)
|
||||
free(vid.buffer);
|
||||
|
||||
vid.buffer = calloc(vid.rowbytes*vid.height, NUMSCREENS);
|
||||
size = vid.rowbytes*vid.height * NUMSCREENS;
|
||||
|
||||
vid.buffer = calloc(size, NUMSCREENS);
|
||||
|
||||
if (!vid.buffer)
|
||||
{
|
||||
@@ -1874,7 +1785,6 @@ void I_StartupGraphics(void)
|
||||
return;
|
||||
|
||||
COM_AddCommand ("vid_nummodes", VID_Command_NumModes_f);
|
||||
COM_AddCommand ("vid_info", VID_Command_Info_f);
|
||||
COM_AddCommand ("vid_modelist", VID_Command_ModeList_f);
|
||||
COM_AddCommand ("vid_mode", VID_Command_Mode_f);
|
||||
CV_RegisterVar (&cv_vidwait);
|
||||
@@ -2076,7 +1986,6 @@ void I_StartupGraphics(void)
|
||||
realwidth = (Uint16)vid.width;
|
||||
realheight = (Uint16)vid.height;
|
||||
|
||||
VID_Command_Info_f();
|
||||
SDLdoUngrabMouse();
|
||||
|
||||
SDL_RaiseWindow(window);
|
||||
@@ -2101,17 +2010,9 @@ void I_ShutdownGraphics(void)
|
||||
|
||||
if (oldrendermode == render_soft)
|
||||
{
|
||||
if (vidSurface)
|
||||
SDL_FreeSurface(vidSurface);
|
||||
vidSurface = NULL;
|
||||
|
||||
if (vid.buffer)
|
||||
free(vid.buffer);
|
||||
vid.buffer = NULL;
|
||||
|
||||
if (bufSurface)
|
||||
SDL_FreeSurface(bufSurface);
|
||||
bufSurface = NULL;
|
||||
}
|
||||
|
||||
I_OutputMsg("I_ShutdownGraphics(): ");
|
||||
|
||||
+33
-5
@@ -615,8 +615,21 @@ static void CV_constextsize_OnChange(void)
|
||||
void VID_BlitLinearScreen(const UINT8 *srcptr, UINT8 *destptr, INT32 width, INT32 height, size_t srcrowbytes,
|
||||
size_t destrowbytes)
|
||||
{
|
||||
if ((srcrowbytes == destrowbytes) && (srcrowbytes == (size_t)width))
|
||||
M_Memcpy(destptr, srcptr, srcrowbytes * height);
|
||||
if (srcrowbytes == destrowbytes)
|
||||
{
|
||||
size_t i = srcrowbytes * height;
|
||||
#if defined(__SSE__)
|
||||
while (i >= 16)
|
||||
{
|
||||
// TODO: find where the buffer is misaligned at times and align it
|
||||
_mm_storeu_ps((float *)destptr, _mm_loadu_ps((const float *)srcptr));
|
||||
srcptr += 16;
|
||||
destptr += 16;
|
||||
i -= 16;
|
||||
}
|
||||
#endif
|
||||
M_Memcpy(destptr, srcptr, i);
|
||||
}
|
||||
else
|
||||
{
|
||||
while (height--)
|
||||
@@ -3775,17 +3788,32 @@ UINT8 GetColorLUTDirect(colorlookup_t *lut, UINT8 r, UINT8 g, UINT8 b)
|
||||
void V_Init(void)
|
||||
{
|
||||
INT32 i;
|
||||
UINT8 *base = vid.buffer;
|
||||
const INT32 screensize = vid.rowbytes * vid.height;
|
||||
|
||||
for (i = 0; i < NUMSCREENS; i++)
|
||||
{
|
||||
#if defined(__SSE__)
|
||||
aligned_free(vid.screens[i]);
|
||||
#else
|
||||
free(vid.screens[i]);
|
||||
#endif
|
||||
vid.screens[i] = NULL;
|
||||
}
|
||||
|
||||
// start address of NUMSCREENS * width*height vidbuffers
|
||||
if (base)
|
||||
if (screensize > 0)
|
||||
{
|
||||
for (i = 0; i < NUMSCREENS; i++)
|
||||
vid.screens[i] = base + i*screensize;
|
||||
{
|
||||
// we need to allocate these relative to their cpu restrictions to not trigger segfaults
|
||||
// TODO: add support for sve and neon
|
||||
#if defined(__SSE__)
|
||||
vid.screens[i] = aligned_alloc(128, screensize);
|
||||
#else
|
||||
vid.screens[i] = malloc(screensize);
|
||||
#endif
|
||||
memset(vid.screens[i], 0, screensize);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
@@ -23,6 +23,18 @@ extern "C" {
|
||||
#include "r_defs.h"
|
||||
#include "r_main.h"
|
||||
|
||||
#if defined(__SSE__)
|
||||
#ifdef _WIN32
|
||||
#include <malloc.h>
|
||||
#define aligned_alloc(align, size) _aligned_malloc(size, align)
|
||||
#define aligned_free(ptr) _aligned_free(ptr)
|
||||
#else
|
||||
#define aligned_free(ptr) free(ptr)
|
||||
#endif
|
||||
|
||||
#include <immintrin.h>
|
||||
#endif
|
||||
|
||||
//
|
||||
// VIDEO
|
||||
//
|
||||
|
||||
+1
-1
@@ -1819,7 +1819,7 @@ void *W_CachePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag)
|
||||
|
||||
#ifdef HWRENDER
|
||||
// Software-only compile cache the data without conversion
|
||||
if (rendermode == render_opengl)
|
||||
if (patch != NULL && rendermode == render_opengl)
|
||||
Patch_CreateGL(patch);
|
||||
#endif
|
||||
|
||||
|
||||
Reference in new issue
Block a user