Merge remote-tracking branch 'public/next' into conenction-screen-improvements

This commit is contained in:
Ashnal 2020-08-19 19:08:33 -04:00
commit 648a950ac8
47 changed files with 2330 additions and 1159 deletions

View file

@ -439,6 +439,30 @@ matrix:
# List Ubuntu LTS, newest to oldest
# Then list non-LTS, newest to oldest
################################
- os: linux
addons:
apt:
packages:
- libsdl2-mixer-dev
- libpng-dev
- libgl1-mesa-dev
- libgme-dev
- libcurl4-openssl-dev
- p7zip-full
- gcc-4.8
compiler: gcc-4.8
dist: xenial
if: env(DPL_ENABLED) = "1" AND (env(_DPL_JOB_ENABLED) = "1" OR env(DPL_JOB_ENABLE_ALL) = "1")
AND (branch =~ /^.*deployer.*$/ OR (tag IS present AND env(DPL_TAG_ENABLED) = "1"))
AND env(DPL_TERMINATE_MAIN) != "1"
env:
- _DPL_JOB_ENABLED=1
- _DPL_JOB_NAME=focal
- _DPL_DPUT_TARGET=1
- _DPL_PACKAGE_SOURCE=1
- PACKAGE_DISTRO=focal
- PACKAGE_SUBVERSION=~20.04focal
#gcc-4.8 (Ubuntu 4.8.5-2ubuntu1~14.04.1) 4.8.5
- os: linux
addons:
apt:
@ -463,6 +487,30 @@ matrix:
- PACKAGE_DISTRO=bionic
- PACKAGE_SUBVERSION=~18.04bionic
#gcc-4.8 (Ubuntu 4.8.5-2ubuntu1~14.04.1) 4.8.5
- os: linux
addons:
apt:
packages:
- libsdl2-mixer-dev
- libpng-dev
- libgl1-mesa-dev
- libgme-dev
- libcurl4-openssl-dev
- p7zip-full
- gcc-4.8
compiler: gcc-4.8
dist: xenial
if: env(DPL_ENABLED) = "1" AND (env(_DPL_JOB_ENABLED) = "1" OR env(DPL_JOB_ENABLE_ALL) = "1")
AND (branch =~ /^.*deployer.*$/ OR (tag IS present AND env(DPL_TAG_ENABLED) = "1"))
AND env(DPL_TERMINATE_MAIN) != "1"
env:
- _DPL_JOB_ENABLED=1
- _DPL_JOB_NAME=xenial
- _DPL_DPUT_TARGET=1
- _DPL_PACKAGE_SOURCE=1
- PACKAGE_DISTRO=xenial
- PACKAGE_SUBVERSION=~16.04xenial
#gcc-4.8 (Ubuntu 4.8.5-2ubuntu1~14.04.1) 4.8.5
- os: linux
addons:
apt:
@ -505,59 +553,11 @@ matrix:
AND env(DPL_TERMINATE_MAIN) != "1"
env:
- _DPL_JOB_ENABLED=1
- _DPL_JOB_NAME=disco
- _DPL_JOB_NAME=eoan
- _DPL_DPUT_TARGET=1
- _DPL_PACKAGE_SOURCE=1
- PACKAGE_DISTRO=disco
- PACKAGE_SUBVERSION=~19.04disco
#gcc-4.8 (Ubuntu 4.8.5-2ubuntu1~14.04.1) 4.8.5
- os: linux
addons:
apt:
packages:
- libsdl2-mixer-dev
- libpng-dev
- libgl1-mesa-dev
- libgme-dev
- libcurl4-openssl-dev
- p7zip-full
- gcc-4.8
compiler: gcc-4.8
dist: xenial
if: env(DPL_ENABLED) = "1" AND (env(_DPL_JOB_ENABLED) = "1" OR env(DPL_JOB_ENABLE_ALL) = "1")
AND (branch =~ /^.*deployer.*$/ OR (tag IS present AND env(DPL_TAG_ENABLED) = "1"))
AND env(DPL_TERMINATE_MAIN) != "1"
env:
- _DPL_JOB_ENABLED=1
- _DPL_JOB_NAME=cosmic
- _DPL_DPUT_TARGET=1
- _DPL_PACKAGE_SOURCE=1
- PACKAGE_DISTRO=cosmic
- PACKAGE_SUBVERSION=~18.10cosmic
#gcc-4.8 (Ubuntu 4.8.5-2ubuntu1~14.04.1) 4.8.5
- os: linux
addons:
apt:
packages:
- libsdl2-mixer-dev
- libpng-dev
- libgl1-mesa-dev
- libgme-dev
- libcurl4-openssl-dev
- p7zip-full
- gcc-4.8
compiler: gcc-4.8
dist: xenial
if: env(DPL_ENABLED) = "1" AND (env(_DPL_JOB_ENABLED) = "1" OR env(DPL_JOB_ENABLE_ALL) = "1")
AND (branch =~ /^.*deployer.*$/ OR (tag IS present AND env(DPL_TAG_ENABLED) = "1"))
AND env(DPL_TERMINATE_MAIN) != "1"
env:
- _DPL_JOB_ENABLED=1
- _DPL_JOB_NAME=xenial
- _DPL_DPUT_TARGET=1
- _DPL_PACKAGE_SOURCE=1
- PACKAGE_DISTRO=xenial
- PACKAGE_SUBVERSION=~16.04xenial
- PACKAGE_DISTRO=eoan
- PACKAGE_SUBVERSION=~19.10eoan
#gcc-4.8 (Ubuntu 4.8.5-2ubuntu1~14.04.1) 4.8.5
allow_failures:
- compiler: clang-3.5

View file

@ -35,6 +35,7 @@ set(SRB2_CORE_SOURCES
m_random.c
md5.c
mserv.c
http-mserv.c
s_sound.c
screen.c
sounds.c

View file

@ -548,6 +548,7 @@ OBJS:=$(i_main_o) \
$(OBJDIR)/w_wad.o \
$(OBJDIR)/filesrch.o \
$(OBJDIR)/mserv.o \
$(OBJDIR)/http-mserv.o\
$(OBJDIR)/i_tcp.o \
$(OBJDIR)/lzf.o \
$(OBJDIR)/vid_copy.o \

View file

@ -543,10 +543,7 @@ static void COM_ExecuteString(char *ptext)
if (!stricmp(com_argv[0], a->name))
{
if (recursion > MAX_ALIAS_RECURSION)
{
CONS_Alert(CONS_WARNING, M_GetText("Alias recursion cycle detected!\n"));
recursion = 0;
}
else
{
char buf[1024];
@ -578,8 +575,10 @@ static void COM_ExecuteString(char *ptext)
}
WRITESTRING(write, read);
// Monster Iestyn: keep track of how many levels of recursion we're in
recursion++;
COM_BufInsertText(buf);
recursion--;
}
return;
}

View file

@ -31,6 +31,7 @@
#include "i_video.h"
#include "z_zone.h"
#include "i_system.h"
#include "i_threads.h"
#include "d_main.h"
#include "m_menu.h"
#include "filesrch.h"
@ -45,6 +46,16 @@
#define MAXHUDLINES 20
#ifdef HAVE_THREADS
I_mutex con_mutex;
# define Lock_state() I_lock_mutex(&con_mutex)
# define Unlock_state() I_unlock_mutex(con_mutex)
#else/*HAVE_THREADS*/
# define Lock_state()
# define Unlock_state()
#endif/*HAVE_THREADS*/
static boolean con_started = false; // console has been initialised
boolean con_startup = false; // true at game startup, screen need refreshing
static boolean con_forcepic = true; // at startup toggle console translucency when first off
@ -170,6 +181,8 @@ static void CONS_hudlines_Change(void)
{
INT32 i;
Lock_state();
// Clear the currently displayed lines
for (i = 0; i < con_hudlines; i++)
con_hudtime[i] = 0;
@ -181,6 +194,8 @@ static void CONS_hudlines_Change(void)
con_hudlines = cons_hudlines.value;
Unlock_state();
CONS_Printf(M_GetText("Number of console HUD lines is now %d\n"), con_hudlines);
}
@ -188,12 +203,16 @@ static void CONS_hudlines_Change(void)
//
static void CONS_Clear_f(void)
{
Lock_state();
memset(con_buffer, 0, CON_BUFFERSIZE);
con_cx = 0;
con_cy = con_totallines-1;
con_line = &con_buffer[con_cy*con_width];
con_scrollup = 0;
Unlock_state();
}
// Choose english keymap
@ -369,20 +388,29 @@ void CON_Init(void)
for (i = 0; i < NUMINPUTS; i++)
bindtable[i] = NULL;
Lock_state();
// clear all lines
memset(con_buffer, 0, CON_BUFFERSIZE);
// make sure it is ready for the loading screen
con_width = 0;
Unlock_state();
CON_RecalcSize();
CON_SetupColormaps();
Lock_state();
//note: CON_Ticker should always execute at least once before D_Display()
con_clipviewtop = -1; // -1 does not clip
con_hudlines = atoi(cons_hudlines.defaultvalue);
Unlock_state();
// setup console input filtering
CON_InputInit();
@ -391,15 +419,23 @@ void CON_Init(void)
COM_AddCommand("cls", CONS_Clear_f);
//COM_AddCommand("english", CONS_English_f);
// set console full screen for game startup MAKE SURE VID_Init() done !!!
Lock_state();
con_destlines = vid.height;
con_curlines = vid.height;
Unlock_state();
if (!dedicated)
{
Lock_state();
con_started = true;
con_startup = true; // need explicit screen refresh until we are in Doom loop
consoletoggle = false;
Unlock_state();
CV_RegisterVar(&cons_msgtimeout);
CV_RegisterVar(&cons_hudlines);
CV_RegisterVar(&cons_speed);
@ -411,19 +447,27 @@ void CON_Init(void)
}
else
{
Lock_state();
con_started = true;
con_startup = false; // need explicit screen refresh until we are in Doom loop
consoletoggle = true;
Unlock_state();
}
}
// Console input initialization
//
static void CON_InputInit(void)
{
Lock_state();
// prepare the first prompt line
memset(inputlines, 0, sizeof (inputlines));
inputline = 0;
input_cur = input_sel = input_len = 0;
Unlock_state();
}
//======================================================================
@ -439,6 +483,8 @@ static void CON_RecalcSize(void)
char *tmp_buffer;
char *string;
Lock_state();
switch (cv_constextsize.value)
{
case V_NOSCALEPATCH:
@ -476,11 +522,18 @@ static void CON_RecalcSize(void)
// check for change of video width
if (conw == con_width)
{
Unlock_state();
return; // didn't change
}
Unlock_state();
tmp_buffer = Z_Malloc(CON_BUFFERSIZE, PU_STATIC, NULL);
string = Z_Malloc(CON_BUFFERSIZE, PU_STATIC, NULL); // BP: it is a line but who know
Lock_state();
oldcon_width = con_width;
oldnumlines = con_totallines;
oldcon_cy = con_cy;
@ -501,6 +554,8 @@ static void CON_RecalcSize(void)
con_line = &con_buffer[con_cy*con_width];
con_scrollup = 0;
Unlock_state();
// re-arrange console text buffer to keep text
if (oldcon_width) // not the first time
{
@ -525,7 +580,11 @@ static void CON_RecalcSize(void)
static void CON_ChangeHeight(void)
{
INT32 minheight = 20 * con_scalefactor; // 20 = 8+8+4
INT32 minheight;
Lock_state();
minheight = 20 * con_scalefactor; // 20 = 8+8+4
// toggle console in
con_destlines = (cons_height.value*vid.height)/100;
@ -535,13 +594,19 @@ static void CON_ChangeHeight(void)
con_destlines = vid.height;
con_destlines &= ~0x3; // multiple of text row height
Unlock_state();
}
// Handles Console moves in/out of screen (per frame)
//
static void CON_MoveConsole(void)
{
const fixed_t conspeed = FixedDiv(cons_speed.value*vid.fdupy, FRACUNIT);
fixed_t conspeed;
Lock_state();
conspeed = FixedDiv(cons_speed.value*vid.fdupy, FRACUNIT);
// instant
if (!cons_speed.value)
@ -563,6 +628,8 @@ static void CON_MoveConsole(void)
if (con_curlines < con_destlines)
con_curlines = con_destlines;
}
Unlock_state();
}
INT32 CON_ShiftChar(INT32 ch)
@ -587,27 +654,44 @@ void CON_ClearHUD(void)
{
INT32 i;
Lock_state();
for (i = 0; i < con_hudlines; i++)
con_hudtime[i] = 0;
Unlock_state();
}
// Force console to move out immediately
// note: con_ticker will set consoleready false
void CON_ToggleOff(void)
{
Lock_state();
if (!con_destlines)
{
Unlock_state();
return;
}
con_destlines = 0;
con_curlines = 0;
CON_ClearHUD();
con_forcepic = 0;
con_clipviewtop = -1; // remove console clipping of view
Unlock_state();
}
boolean CON_Ready(void)
{
return consoleready;
boolean ready;
Lock_state();
{
ready = consoleready;
}
Unlock_state();
return ready;
}
// Console ticker: handles console move in/out, cursor blinking
@ -615,7 +699,11 @@ boolean CON_Ready(void)
void CON_Ticker(void)
{
INT32 i;
INT32 minheight = 20 * con_scalefactor; // 20 = 8+8+4
INT32 minheight;
Lock_state();
minheight = 20 * con_scalefactor; // 20 = 8+8+4
// cursor blinking
con_tick++;
@ -673,6 +761,8 @@ void CON_Ticker(void)
if (con_hudtime[i] < 0)
con_hudtime[i] = 0;
}
Unlock_state();
}
//
@ -684,32 +774,51 @@ void CON_Ticker(void)
static void CON_InputClear(void)
{
Lock_state();
memset(inputlines[inputline], 0, CON_MAXPROMPTCHARS);
input_cur = input_sel = input_len = 0;
Unlock_state();
}
static void CON_InputSetString(const char *c)
{
Lock_state();
memset(inputlines[inputline], 0, CON_MAXPROMPTCHARS);
strcpy(inputlines[inputline], c);
input_cur = input_sel = input_len = strlen(c);
Unlock_state();
}
static void CON_InputAddString(const char *c)
{
size_t csize = strlen(c);
Lock_state();
if (input_len + csize > CON_MAXPROMPTCHARS-1)
{
Unlock_state();
return;
}
if (input_cur != input_len)
memmove(&inputlines[inputline][input_cur+csize], &inputlines[inputline][input_cur], input_len-input_cur);
memcpy(&inputlines[inputline][input_cur], c, csize);
input_len += csize;
input_sel = (input_cur += csize);
Unlock_state();
}
static void CON_InputDelSelection(void)
{
size_t start, end, len;
Lock_state();
if (input_cur > input_sel)
{
start = input_sel;
@ -728,27 +837,39 @@ static void CON_InputDelSelection(void)
input_len -= len;
input_sel = input_cur = start;
Unlock_state();
}
static void CON_InputAddChar(char c)
{
if (input_len >= CON_MAXPROMPTCHARS-1)
return;
Lock_state();
if (input_cur != input_len)
memmove(&inputlines[inputline][input_cur+1], &inputlines[inputline][input_cur], input_len-input_cur);
inputlines[inputline][input_cur++] = c;
inputlines[inputline][++input_len] = 0;
input_sel = input_cur;
Unlock_state();
}
static void CON_InputDelChar(void)
{
if (!input_cur)
return;
Lock_state();
if (input_cur != input_len)
memmove(&inputlines[inputline][input_cur-1], &inputlines[inputline][input_cur], input_len-input_cur);
inputlines[inputline][--input_len] = 0;
input_sel = --input_cur;
Unlock_state();
}
//
@ -1174,6 +1295,8 @@ static void CON_Print(char *msg)
S_StartSound(NULL, sfx_radio);
}
Lock_state();
if (!(*msg & 0x80))
{
con_line[con_cx++] = '\x80';
@ -1234,7 +1357,10 @@ static void CON_Print(char *msg)
}
if (*msg == '\0')
{
Unlock_state();
return;
}
// printable character
for (l = 0; l < (con_width-11) && msg[l] > ' '; l++)
@ -1252,6 +1378,8 @@ static void CON_Print(char *msg)
for (; l > 0; l--)
con_line[con_cx++] = *(msg++);
}
Unlock_state();
}
void CON_LogMessage(const char *msg)
@ -1283,6 +1411,7 @@ void CONS_Printf(const char *fmt, ...)
{
va_list argptr;
static char *txt = NULL;
boolean startup;
if (txt == NULL)
txt = malloc(8192);
@ -1315,11 +1444,16 @@ void CONS_Printf(const char *fmt, ...)
CON_LogMessage(txt);
#endif
Lock_state();
// make sure new text is visible
con_scrollup = 0;
startup = con_startup;
Unlock_state();
// if not in display loop, force screen update
if (con_startup)
if (startup)
{
#if (defined (_WINDOWS)) || (defined (__OS2__) && !defined (HAVE_SDL))
patch_t *con_backpic = W_CachePatchName("KARTKREW", PU_CACHE);
@ -1633,8 +1767,13 @@ static void CON_DrawConsole(void)
//
void CON_Drawer(void)
{
Lock_state();
if (!con_started || !graphics_started)
{
Unlock_state();
return;
}
if (con_recalc)
CON_RecalcSize();
@ -1644,4 +1783,6 @@ void CON_Drawer(void)
else if (gamestate == GS_LEVEL || gamestate == GS_INTERMISSION || gamestate == GS_CUTSCENE || gamestate == GS_CREDITS
|| gamestate == GS_VOTING || gamestate == GS_EVALUATION || gamestate == GS_WAITINGPLAYERS)
CON_DrawHudlines();
Unlock_state();
}

View file

@ -12,6 +12,7 @@
#include "d_event.h"
#include "command.h"
#include "i_threads.h"
#ifdef _WII
void CON_InitWii(void);
@ -21,6 +22,10 @@ void CON_Init(void);
boolean CON_Responder(event_t *ev);
#ifdef HAVE_THREADS
extern I_mutex con_mutex;
#endif
// set true when screen size has changed, to adapt console
extern boolean con_recalc;

View file

@ -76,7 +76,7 @@
boolean server = true; // true or false but !server == client
#define client (!server)
boolean nodownload = false;
static boolean serverrunning = false;
boolean serverrunning = false;
INT32 serverplayer = 0;
char motd[254], server_context[8]; // Message of the Day, Unique Context (even without Mumble support)
@ -1351,7 +1351,7 @@ static boolean CL_AskFileList(INT32 firstfile)
netbuffer->packettype = PT_TELLFILESNEEDED;
netbuffer->u.filesneedednum = firstfile;
return HSendPacket(servernode, true, 0, sizeof (INT32));
return HSendPacket(servernode, false, 0, sizeof (INT32));
}
/** Sends a special packet to declare how many players in local
@ -1829,7 +1829,7 @@ static void CL_LoadReceivedSavegame(void)
#endif
#ifndef NONET
static void SendAskInfo(INT32 node, boolean viams)
static void SendAskInfo(INT32 node)
{
const tic_t asktime = I_GetTime();
netbuffer->packettype = PT_ASKINFO;
@ -1840,10 +1840,6 @@ static void SendAskInfo(INT32 node, boolean viams)
// now allowed traffic from the host to us in, so once the MS relays
// our address to the host, it'll be able to speak to us.
HSendPacket(node, false, 0, sizeof (askinfo_pak));
// Also speak to the MS.
if (viams && node != 0 && node != BROADCASTADDR)
SendAskInfoViaMS(node, asktime);
}
serverelem_t serverlist[MAXSERVERLIST];
@ -1909,13 +1905,96 @@ static void SL_InsertServer(serverinfo_pak* info, SINT8 node)
M_SortServerList();
}
#ifdef HAVE_THREADS
struct Fetch_servers_ctx
{
int room;
int id;
};
static void
Fetch_servers_thread (struct Fetch_servers_ctx *ctx)
{
msg_server_t *server_list;
server_list = GetShortServersList(ctx->room, ctx->id);
if (server_list)
{
I_lock_mutex(&ms_QueryId_mutex);
{
if (ctx->id != ms_QueryId)
{
free(server_list);
server_list = NULL;
}
}
I_unlock_mutex(ms_QueryId_mutex);
if (server_list)
{
I_lock_mutex(&m_menu_mutex);
{
if (m_waiting_mode == M_WAITING_SERVERS)
m_waiting_mode = M_NOT_WAITING;
}
I_unlock_mutex(m_menu_mutex);
I_lock_mutex(&ms_ServerList_mutex);
{
ms_ServerList = server_list;
}
I_unlock_mutex(ms_ServerList_mutex);
}
}
free(ctx);
}
#endif/*HAVE_THREADS*/
void CL_QueryServerList (msg_server_t *server_list)
{
INT32 i;
for (i = 0; server_list[i].header.buffer[0]; i++)
{
// Make sure MS version matches our own, to
// thwart nefarious servers who lie to the MS.
/* lol bruh, that version COMES from the servers */
//if (strcmp(version, server_list[i].version) == 0)
{
INT32 node = I_NetMakeNodewPort(server_list[i].ip, server_list[i].port);
if (node == -1)
break; // no more node free
SendAskInfo(node);
// Force close the connection so that servers can't eat
// up nodes forever if we never get a reply back from them
// (usually when they've not forwarded their ports).
//
// Don't worry, we'll get in contact with the working
// servers again when they send SERVERINFO to us later!
//
// (Note: as a side effect this probably means every
// server in the list will probably be using the same node (e.g. node 1),
// not that it matters which nodes they use when
// the connections are closed afterwards anyway)
// -- Monster Iestyn 12/11/18
Net_CloseConnection(node|FORCECLOSE);
}
}
}
void CL_UpdateServerList(boolean internetsearch, INT32 room)
{
#ifdef HAVE_THREADS
struct Fetch_servers_ctx *ctx;
#endif
SL_ClearServerList(0);
if (!netgame && I_NetOpenSocket)
{
MSCloseUDPSocket(); // Tidy up before wiping the slate.
if (I_NetOpenSocket())
{
netgame = true;
@ -1925,56 +2004,36 @@ void CL_UpdateServerList(boolean internetsearch, INT32 room)
// search for local servers
if (netgame)
SendAskInfo(BROADCASTADDR, false);
SendAskInfo(BROADCASTADDR);
if (internetsearch)
{
const msg_server_t *server_list;
INT32 i = -1;
server_list = GetShortServersList(room);
#ifdef HAVE_THREADS
ctx = malloc(sizeof *ctx);
/* This called from M_Refresh so I don't use a mutex */
m_waiting_mode = M_WAITING_SERVERS;
I_lock_mutex(&ms_QueryId_mutex);
{
ctx->id = ms_QueryId;
}
I_unlock_mutex(ms_QueryId_mutex);
ctx->room = room;
I_spawn_thread("fetch-servers", (I_thread_fn)Fetch_servers_thread, ctx);
#else
msg_server_t *server_list;
server_list = GetShortServersList(room, 0);
if (server_list)
{
char version[8] = "";
#if VERSION > 0 || SUBVERSION > 0
snprintf(version, sizeof (version), "%d.%d", VERSION, SUBVERSION);
#else
strcpy(version, GetRevisionString());
CL_QueryServerList(server_list);
free(server_list);
}
#endif
version[sizeof (version) - 1] = '\0';
for (i = 0; server_list[i].header.buffer[0]; i++)
{
// Make sure MS version matches our own, to
// thwart nefarious servers who lie to the MS.
if (strcmp(version, server_list[i].version) == 0)
{
INT32 node = I_NetMakeNodewPort(server_list[i].ip, server_list[i].port);
if (node == -1)
break; // no more node free
SendAskInfo(node, true);
// Force close the connection so that servers can't eat
// up nodes forever if we never get a reply back from them
// (usually when they've not forwarded their ports).
//
// Don't worry, we'll get in contact with the working
// servers again when they send SERVERINFO to us later!
//
// (Note: as a side effect this probably means every
// server in the list will probably be using the same node (e.g. node 1),
// not that it matters which nodes they use when
// the connections are closed afterwards anyway)
// -- Monster Iestyn 12/11/18
Net_CloseConnection(node|FORCECLOSE);
}
}
}
//no server list?(-1) or no servers?(0)
if (!i)
{
; /// TODO: display error or warning?
}
}
}
@ -2044,11 +2103,11 @@ static boolean CL_FinishedFileList(void)
CL_Reset();
D_StartTitle();
M_StartMessage(M_GetText(
"You have WAD files loaded or have\n"
"modified the game in some way, and\n"
"your file list does not match\n"
"the server's file list.\n"
"Please restart SRB2Kart before connecting.\n\n"
"You have the wrong addons loaded.\n\n"
"To play on this server, restart\n"
"the game and don't load any addons.\n"
"SRB2Kart will automatically add\n"
"everything you need when you join.\n\n"
"Press ESC\n"
), NULL, MM_NOTHING);
return false;
@ -2083,11 +2142,12 @@ static boolean CL_FinishedFileList(void)
CL_Reset();
D_StartTitle();
M_StartMessage(M_GetText(
"You cannot connect to this server\n"
"because you cannot download the files\n"
"that you are missing from the server.\n\n"
"See the console or log file for\n"
"more details.\n\n"
"An error occured when trying to\n"
"download missing addons.\n"
"(This is almost always a problem\n"
"with the server, not your game.)\n\n"
"See the console or log file\n"
"for additional details.\n\n"
"Press ESC\n"
), NULL, MM_NOTHING);
return false;
@ -2149,14 +2209,13 @@ static boolean CL_FinishedFileList(void)
/** Called by CL_ServerConnectionTicker
*
* \param viams ???
* \param asksent The last time we asked the server to join. We re-ask every second in case our request got lost in transmit.
* \return False if the connection was aborted
* \sa CL_ServerConnectionTicker
* \sa CL_ConnectToServer
*
*/
static boolean CL_ServerConnectionSearchTicker(boolean viams, tic_t *asksent)
static boolean CL_ServerConnectionSearchTicker(tic_t *asksent)
{
#ifndef NONET
INT32 i;
@ -2214,7 +2273,7 @@ static boolean CL_ServerConnectionSearchTicker(boolean viams, tic_t *asksent)
// Ask the info to the server (askinfo packet)
if (*asksent + NEWTICRATE < I_GetTime())
{
SendAskInfo(servernode, viams);
SendAskInfo(servernode);
*asksent = I_GetTime();
}
#else
@ -2229,7 +2288,6 @@ static boolean CL_ServerConnectionSearchTicker(boolean viams, tic_t *asksent)
/** Called by CL_ConnectToServer
*
* \param viams ???
* \param tmpsave The name of the gamestate file???
* \param oldtic Used for knowing when to poll events and redraw
* \param asksent The last time we asked the server to join. We re-ask every second in case our request got lost in transmit.
@ -2238,7 +2296,7 @@ static boolean CL_ServerConnectionSearchTicker(boolean viams, tic_t *asksent)
* \sa CL_ConnectToServer
*
*/
static boolean CL_ServerConnectionTicker(boolean viams, const char *tmpsave, tic_t *oldtic, tic_t *asksent)
static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic_t *asksent)
{
boolean waitmore;
INT32 i;
@ -2250,7 +2308,7 @@ static boolean CL_ServerConnectionTicker(boolean viams, const char *tmpsave, tic
switch (cl_mode)
{
case CL_SEARCHING:
if (!CL_ServerConnectionSearchTicker(viams, asksent))
if (!CL_ServerConnectionSearchTicker(asksent))
return false;
break;
@ -2444,11 +2502,10 @@ static boolean CL_ServerConnectionTicker(boolean viams, const char *tmpsave, tic
/** Use adaptive send using net_bandwidth and stat.sendbytes
*
* \param viams ???
* \todo Better description...
*
*/
static void CL_ConnectToServer(boolean viams)
static void CL_ConnectToServer(void)
{
INT32 pnumnodes, nodewaited = doomcom->numnodes, i;
tic_t oldtic;
@ -2520,9 +2577,9 @@ static void CL_ConnectToServer(boolean viams)
{
// If the connection was aborted for some reason, leave
#ifndef NONET
if (!CL_ServerConnectionTicker(viams, tmpsave, &oldtic, &asksent))
if (!CL_ServerConnectionTicker(tmpsave, &oldtic, &asksent))
#else
if (!CL_ServerConnectionTicker(viams, (char*)NULL, &oldtic, (tic_t *)NULL))
if (!CL_ServerConnectionTicker((char*)NULL, &oldtic, (tic_t *)NULL))
#endif
return;
@ -2648,6 +2705,7 @@ static void Command_ClearBans(void)
return;
I_ClearBans();
D_SaveBan();
reasontail = NULL;
while (reasonhead)
{
@ -2702,9 +2760,6 @@ static void Command_ReloadBan(void) //recheck ban.txt
static void Command_connect(void)
{
// Assume we connect directly.
boolean viams = false;
if (COM_Argc() < 2 || *COM_Argv(1) == 0)
{
CONS_Printf(M_GetText(
@ -2738,9 +2793,6 @@ static void Command_connect(void)
if (netgame && !stricmp(COM_Argv(1), "node"))
{
servernode = (SINT8)atoi(COM_Argv(2));
// Use MS to traverse NAT firewalls.
viams = true;
}
else if (netgame)
{
@ -2749,7 +2801,6 @@ static void Command_connect(void)
}
else if (I_NetOpenSocket)
{
MSCloseUDPSocket(); // Tidy up before wiping the slate.
I_NetOpenSocket();
netgame = true;
multiplayer = true;
@ -2778,7 +2829,7 @@ static void Command_connect(void)
}
botingame = false;
botskin = 0;
CL_ConnectToServer(viams);
CL_ConnectToServer();
}
#endif
@ -3829,7 +3880,6 @@ boolean SV_SpawnServer(void)
SV_GenContext();
if (netgame && I_NetOpenSocket)
{
MSCloseUDPSocket(); // Tidy up before wiping the slate.
I_NetOpenSocket();
if (ms_RoomId > 0)
RegisterServer();
@ -3837,7 +3887,7 @@ boolean SV_SpawnServer(void)
// non dedicated server just connect to itself
if (!dedicated)
CL_ConnectToServer(false);
CL_ConnectToServer();
else doomcom->numslots = 1;
}
@ -5674,7 +5724,13 @@ FILESTAMP
if (nowtime > resptime)
{
resptime = nowtime;
#ifdef HAVE_THREADS
I_lock_mutex(&m_menu_mutex);
#endif
M_Ticker();
#ifdef HAVE_THREADS
I_unlock_mutex(m_menu_mutex);
#endif
CON_Ticker();
}
SV_FileSendTicker();

View file

@ -18,6 +18,7 @@
#include "d_netcmd.h"
#include "tables.h"
#include "d_player.h"
#include "mserv.h"
/*
The 'packet version' is used to distinguish packet formats.
@ -531,6 +532,7 @@ typedef enum
} kickreason_t;
extern boolean server;
extern boolean serverrunning;
#define client (!server)
extern boolean dedicated; // For dedicated server
extern UINT16 software_MAXPACKETLENGTH;
@ -577,6 +579,7 @@ void CL_RemoveSplitscreenPlayer(UINT8 p);
void CL_Reset(void);
void CL_ClearPlayer(INT32 playernum);
void CL_RemovePlayer(INT32 playernum, INT32 reason);
void CL_QueryServerList(msg_server_t *list);
void CL_UpdateServerList(boolean internetsearch, INT32 room);
// Is there a game running
boolean Playing(void);

View file

@ -50,6 +50,7 @@ int snprintf(char *str, size_t n, const char *fmt, ...);
#include "hu_stuff.h"
#include "i_sound.h"
#include "i_system.h"
#include "i_threads.h"
#include "i_video.h"
#include "m_argv.h"
#include "m_menu.h"
@ -143,6 +144,8 @@ boolean advancedemo;
INT32 debugload = 0;
#endif
char savegamename[256];
#ifdef _arch_dreamcast
char srb2home[256] = "/cd";
char srb2path[256] = "/cd";
@ -185,35 +188,6 @@ UINT8 shiftdown = 0; // 0x1 left, 0x2 right
UINT8 ctrldown = 0; // 0x1 left, 0x2 right
UINT8 altdown = 0; // 0x1 left, 0x2 right
boolean capslock = 0; // gee i wonder what this does.
//
// D_ModifierKeyResponder
// Sets global shift/ctrl/alt variables, never actually eats events
//
static inline void D_ModifierKeyResponder(event_t *ev)
{
if (ev->type == ev_keydown || ev->type == ev_console) switch (ev->data1)
{
case KEY_LSHIFT: shiftdown |= 0x1; return;
case KEY_RSHIFT: shiftdown |= 0x2; return;
case KEY_LCTRL: ctrldown |= 0x1; return;
case KEY_RCTRL: ctrldown |= 0x2; return;
case KEY_LALT: altdown |= 0x1; return;
case KEY_RALT: altdown |= 0x2; return;
case KEY_CAPSLOCK: capslock = !capslock; return;
default: return;
}
else if (ev->type == ev_keyup) switch (ev->data1)
{
case KEY_LSHIFT: shiftdown &= ~0x1; return;
case KEY_RSHIFT: shiftdown &= ~0x2; return;
case KEY_LCTRL: ctrldown &= ~0x1; return;
case KEY_RCTRL: ctrldown &= ~0x2; return;
case KEY_LALT: altdown &= ~0x1; return;
case KEY_RALT: altdown &= ~0x2; return;
default: return;
}
}
//
// D_ProcessEvents
@ -223,6 +197,8 @@ void D_ProcessEvents(void)
{
event_t *ev;
boolean eaten;
for (; eventtail != eventhead; eventtail = (eventtail+1) & (MAXEVENTS-1))
{
ev = &events[eventtail];
@ -244,7 +220,17 @@ void D_ProcessEvents(void)
}
// Menu input
if (M_Responder(ev))
#ifdef HAVE_THREADS
I_lock_mutex(&m_menu_mutex);
#endif
{
eaten = M_Responder(ev);
}
#ifdef HAVE_THREADS
I_unlock_mutex(m_menu_mutex);
#endif
if (eaten)
continue; // menu ate the event
// Demo input:
@ -253,7 +239,17 @@ void D_ProcessEvents(void)
continue; // demo ate the event
// console input
if (CON_Responder(ev))
#ifdef HAVE_THREADS
I_lock_mutex(&con_mutex);
#endif
{
eaten = CON_Responder(ev);
}
#ifdef HAVE_THREADS
I_unlock_mutex(con_mutex);
#endif
if (eaten)
continue; // ate the event
G_Responder(ev);
@ -280,7 +276,7 @@ static void D_Display(void)
{
if (nodrawers)
return; // for comparative timing/profiling
// check for change of screen size (video mode)
if (setmodeneeded && !wipe)
SCR_SetMode(); // change video mode
@ -549,7 +545,13 @@ static void D_Display(void)
if (gamestate != GS_TIMEATTACK)
CON_Drawer();
#ifdef HAVE_THREADS
I_lock_mutex(&m_menu_mutex);
#endif
M_Drawer(); // menu is drawn even on top of everything
#ifdef HAVE_THREADS
I_unlock_mutex(m_menu_mutex);
#endif
// focus lost moved to M_Drawer
//

View file

@ -19,7 +19,9 @@
#define __D_NET__
// Max computers in a game
#define MAXNETNODES 64
// 127 is probably as high as this can go, because
// SINT8 is used for nodes sometimes >:(
#define MAXNETNODES 127
#define BROADCASTADDR MAXNETNODES
#define NETSPLITSCREEN // Kart's splitscreen netgame feature

View file

@ -784,7 +784,7 @@ void SV_FileSendTicker(void)
if (ram)
M_Memcpy(p->data, &f->id.ram[transfer[i].position], size);
else if (fread(p->data, 1, size, transfer[i].currentfile) != size)
I_Error("SV_FileSendTicker: can't read %s byte on %s at %d because %s", sizeu1(size), f->id.filename, transfer[i].position, strerror(ferror(transfer[i].currentfile)));
I_Error("SV_FileSendTicker: can't read %s byte on %s at %d because %s", sizeu1(size), f->id.filename, transfer[i].position, M_FileError(transfer[i].currentfile));
p->position = LONG(transfer[i].position);
// Put flag so receiver knows the total size
if (transfer[i].position + size == f->size)
@ -863,7 +863,7 @@ void Got_Filetxpak(void)
// We can receive packet in the wrong order, anyway all os support gaped file
fseek(file->file, pos, SEEK_SET);
if (fwrite(netbuffer->u.filetxpak.data,size,1,file->file) != 1)
I_Error("Can't write to %s: %s\n",filename, strerror(ferror(file->file)));
I_Error("Can't write to %s: %s\n",filename, M_FileError(file->file));
file->currentsize += size;
// Finished?
@ -1106,7 +1106,7 @@ void CURLPrepareFile(const char* url, int dfilenum)
// Only allow HTTP and HTTPS
curl_easy_setopt(http_handle, CURLOPT_PROTOCOLS, CURLPROTO_HTTP|CURLPROTO_HTTPS);
curl_easy_setopt(http_handle, CURLOPT_USERAGENT, va("SRB2Kart/v%d.%d.%d", VERSION/100, VERSION%100, SUBVERSION)); // Set user agent as some servers won't accept invalid user agents.
curl_easy_setopt(http_handle, CURLOPT_USERAGENT, va("SRB2Kart/v%d.%d", VERSION, SUBVERSION)); // Set user agent as some servers won't accept invalid user agents.
// Follow a redirect request, if sent by the server.
curl_easy_setopt(http_handle, CURLOPT_FOLLOWLOCATION, 1L);

View file

@ -155,8 +155,8 @@ extern char logfilename[1024];
#else
#define VERSION 1 // Game version
#define SUBVERSION 2 // more precise version number
#define VERSIONSTRING "v1.2"
#define VERSIONSTRINGW L"v1.2"
#define VERSIONSTRING "v1.2 (HTTP MS)"
#define VERSIONSTRINGW L"v1.2 (HTTP MS)"
// Hey! If you change this, add 1 to the MODVERSION below! Otherwise we can't force updates!
// And change CMakeLists.txt, for CMake users!
// AND appveyor.yml, for the build bots!
@ -506,7 +506,7 @@ void CONS_Debug(INT32 debugflags, const char *fmt, ...) FUNCDEBUG;
// Things that used to be in dstrings.h
#define SAVEGAMENAME "srb2sav"
char savegamename[256];
extern char savegamename[256];
// m_misc.h
#ifdef GETTEXT

View file

@ -24,6 +24,7 @@
#include "w_wad.h"
#include "z_zone.h"
#include "i_system.h"
#include "i_threads.h"
#include "m_menu.h"
#include "dehacked.h"
#include "g_input.h"
@ -317,7 +318,13 @@ void F_IntroDrawer(void)
{
I_OsPolling();
I_UpdateNoBlit();
#ifdef HAVE_THREADS
I_lock_mutex(&m_menu_mutex);
#endif
M_Drawer(); // menu is drawn even on top of wipes
#ifdef HAVE_THREADS
I_unlock_mutex(m_menu_mutex);
#endif
I_FinishUpdate(); // Update the screen with the image Tails 06-19-2001
}
}

View file

@ -22,6 +22,7 @@
#include "z_zone.h"
#include "i_system.h"
#include "i_threads.h"
#include "m_menu.h"
#include "console.h"
#include "d_main.h"
@ -379,7 +380,15 @@ void F_RunWipe(UINT8 wipetype, boolean drawMenu)
I_UpdateNoBlit();
if (drawMenu)
{
#ifdef HAVE_THREADS
I_lock_mutex(&m_menu_mutex);
#endif
M_Drawer(); // menu is drawn even on top of wipes
#ifdef HAVE_THREADS
I_unlock_mutex(m_menu_mutex);
#endif
}
I_FinishUpdate(); // page flip or blit buffer

View file

@ -6368,7 +6368,9 @@ void G_BeginRecording(void)
demoflags |= DF_ENCORE;
#ifdef HAVE_BLUA
demoflags |= DF_LUAVARS;
if (!modeattacking) // Ghosts don't read luavars, and you shouldn't ever need to save Lua in replays, you doof!
// SERIOUSLY THOUGH WHY WOULD YOU LOAD HOSTMOD AND RECORD A GHOST WITH IT !????
demoflags |= DF_LUAVARS;
#endif
// Setup header.
@ -6474,8 +6476,9 @@ void G_BeginRecording(void)
WRITEUINT8(demo_p, 0xFF); // Denote the end of the player listing
#ifdef HAVE_BLUA
// player lua vars, always saved even if empty
LUA_ArchiveDemo();
// player lua vars, always saved even if empty... Unless it's record attack.
if (!modeattacking)
LUA_ArchiveDemo();
#endif
memset(&oldcmd,0,sizeof(oldcmd));
@ -7543,6 +7546,7 @@ void G_DoPlayDemo(char *defdemoname)
if (!gL) // No Lua state! ...I guess we'll just start one...
LUA_ClearState();
// No modeattacking check, DF_LUAVARS won't be present here.
LUA_UnArchiveDemo();
}
#endif

View file

@ -407,7 +407,7 @@ void HWR_RenderPlane(extrasubsector_t *xsub, boolean isceiling, fixed_t fixedhei
if (angle) // Only needs to be done if there's an altered angle
{
angle = (InvAngle(angle)+ANGLE_180)>>ANGLETOFINESHIFT;
angle = InvAngle(angle)>>ANGLETOFINESHIFT;
// This needs to be done so that it scrolls in a different direction after rotation like software
/*tempxsow = FLOAT_TO_FIXED(scrollx);
@ -439,7 +439,7 @@ void HWR_RenderPlane(extrasubsector_t *xsub, boolean isceiling, fixed_t fixedhei
tempxsow = FLOAT_TO_FIXED(v3d->s);
tempytow = FLOAT_TO_FIXED(v3d->t);
v3d->s = (FIXED_TO_FLOAT(FixedMul(tempxsow, FINECOSINE(angle)) - FixedMul(tempytow, FINESINE(angle))));
v3d->t = (FIXED_TO_FLOAT(-FixedMul(tempxsow, FINESINE(angle)) - FixedMul(tempytow, FINECOSINE(angle))));
v3d->t = (FIXED_TO_FLOAT(FixedMul(tempxsow, FINESINE(angle)) + FixedMul(tempytow, FINECOSINE(angle))));
}
//v3d->s = (float)(v3d->s - flatxref + scrollx);

View file

@ -143,7 +143,7 @@ static const GLfloat byte2float[256] = {
// -----------------+
#ifdef DEBUG_TO_FILE
FILE *gllogstream;
FILE *gllogstream = NULL;
#endif
FUNCPRINTF void GL_DBG_Printf(const char *format, ...)
@ -152,14 +152,14 @@ FUNCPRINTF void GL_DBG_Printf(const char *format, ...)
char str[4096] = "";
va_list arglist;
if (!gllogstream)
gllogstream = fopen("ogllog.txt", "w");
if (gllogstream)
{
va_start(arglist, format);
vsnprintf(str, 4096, format, arglist);
va_end(arglist);
va_start(arglist, format);
vsnprintf(str, 4096, format, arglist);
va_end(arglist);
fwrite(str, strlen(str), 1, gllogstream);
fwrite(str, strlen(str), 1, gllogstream);
}
#else
(void)format;
#endif
@ -823,7 +823,7 @@ EXPORT boolean HWRAPI(LoadShaders) (void)
#ifdef GL_SHADERS
GLuint gl_vertShader, gl_fragShader;
GLint i, result;
if (!pglUseProgram) return false;
gl_customvertexshaders[0] = NULL;
@ -2002,11 +2002,11 @@ EXPORT void HWRAPI(RenderBatches) (int *sNumPolys, int *sNumVerts, int *sNumCall
boolean stopFlag = false;
boolean changeState = false;
boolean changeShader = false;
GLuint nextShader;
GLuint nextShader = 0U;
boolean changeTexture = false;
GLuint nextTexture;
GLuint nextTexture = 0U;
boolean changePolyFlags = false;
FBITFIELD nextPolyFlags;
FBITFIELD nextPolyFlags = 0U;
boolean changeSurfaceInfo = false;
FSurfaceInfo nextSurfaceInfo;
@ -2307,7 +2307,7 @@ EXPORT void HWRAPI(DrawPolygon) (FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUI
pglColor4ubv((GLubyte*)&pSurf->PolyColor.s);
}
// Tint color
tint.red = byte2float[pSurf->TintColor.s.red];
tint.green = byte2float[pSurf->TintColor.s.green];

675
src/http-mserv.c Normal file
View file

@ -0,0 +1,675 @@
// SONIC ROBO BLAST 2 KART
//-----------------------------------------------------------------------------
// Copyright (C) 2020 by James R.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
// \brief HTTP based master server
/*
Documentation available here.
<http://mb.srb2.org/MS/tools/api/v1/>
*/
#include <curl/curl.h>
#include "doomdef.h"
#include "d_clisrv.h"
#include "command.h"
#include "m_argv.h"
#include "m_menu.h"
#include "mserv.h"
#include "i_tcp.h"/* for current_port */
#include "i_threads.h"
/* reasonable default I guess?? */
#define DEFAULT_BUFFER_SIZE (4096)
/* I just stop myself from making macros anymore. */
#define Blame( ... ) \
CONS_Printf("\x85" __VA_ARGS__)
static void MasterServer_Debug_OnChange (void);
consvar_t cv_masterserver_timeout = {
"masterserver_timeout", "5", CV_SAVE, CV_Unsigned,
NULL, 0, NULL, NULL, 0, 0, NULL/* C90 moment */
};
consvar_t cv_masterserver_debug = {
"masterserver_debug", "Off", CV_SAVE|CV_CALL, CV_OnOff,
MasterServer_Debug_OnChange, 0, NULL, NULL, 0, 0, NULL/* C90 moment */
};
consvar_t cv_masterserver_token = {
"masterserver_token", "", CV_SAVE, NULL,
NULL, 0, NULL, NULL, 0, 0, NULL/* C90 moment */
};
static int hms_started;
static char *hms_api;
#ifdef HAVE_THREADS
static I_mutex hms_api_mutex;
#endif
static char *hms_server_token;
struct HMS_buffer
{
CURL *curl;
char *buffer;
int needle;
int end;
};
static void
Contact_error (void)
{
CONS_Alert(CONS_ERROR,
"There was a problem contacting the master server...\n"
);
}
static size_t
HMS_on_read (char *s, size_t _1, size_t n, void *userdata)
{
struct HMS_buffer *buffer;
size_t blocks;
(void)_1;
buffer = userdata;
if (n >= (size_t)( buffer->end - buffer->needle ))
{
/* resize to next multiple of buffer size */
blocks = ( n / DEFAULT_BUFFER_SIZE + 1 );
buffer->end += ( blocks * DEFAULT_BUFFER_SIZE );
buffer->buffer = realloc(buffer->buffer, buffer->end);
}
memcpy(&buffer->buffer[buffer->needle], s, n);
buffer->needle += n;
return n;
}
static struct HMS_buffer *
HMS_connect (const char *format, ...)
{
va_list ap;
CURL *curl;
char *url;
char *quack_token;
size_t seek;
size_t token_length;
struct HMS_buffer *buffer;
if (! hms_started)
{
if (curl_global_init(CURL_GLOBAL_ALL) != 0)
{
Contact_error();
Blame("From curl_global_init.\n");
return NULL;
}
else
{
atexit(curl_global_cleanup);
hms_started = 1;
}
}
curl = curl_easy_init();
if (! curl)
{
Contact_error();
Blame("From curl_easy_init.\n");
return NULL;
}
if (cv_masterserver_token.string[0])
{
quack_token = curl_easy_escape(curl, cv_masterserver_token.string, 0);
token_length = ( sizeof "?token="-1 )+ strlen(quack_token);
}
else
{
quack_token = NULL;
token_length = 0;
}
#ifdef HAVE_THREADS
I_lock_mutex(&hms_api_mutex);
#endif
seek = strlen(hms_api) + 1;/* + '/' */
va_start (ap, format);
url = malloc(seek + vsnprintf(0, 0, format, ap) + token_length + 1);
va_end (ap);
sprintf(url, "%s/", hms_api);
#ifdef HAVE_THREADS
I_unlock_mutex(hms_api_mutex);
#endif
va_start (ap, format);
seek += vsprintf(&url[seek], format, ap);
va_end (ap);
if (quack_token)
sprintf(&url[seek], "?token=%s", quack_token);
CONS_Printf("HMS: connecting '%s'...\n", url);
buffer = malloc(sizeof *buffer);
buffer->curl = curl;
buffer->end = DEFAULT_BUFFER_SIZE;
buffer->buffer = malloc(buffer->end);
buffer->needle = 0;
if (cv_masterserver_debug.value)
{
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
curl_easy_setopt(curl, CURLOPT_STDERR, logstream);
}
if (M_CheckParm("-bindaddr") && M_IsNextParm())
{
curl_easy_setopt(curl, CURLOPT_INTERFACE, M_GetNextParm());
}
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, cv_masterserver_timeout.value);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, HMS_on_read);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, buffer);
curl_free(quack_token);
free(url);
return buffer;
}
static int
HMS_do (struct HMS_buffer *buffer)
{
CURLcode cc;
long status;
char *p;
cc = curl_easy_perform(buffer->curl);
if (cc != CURLE_OK)
{
Contact_error();
Blame(
"From curl_easy_perform: %s\n",
curl_easy_strerror(cc)
);
return 0;
}
buffer->buffer[buffer->needle] = '\0';
curl_easy_getinfo(buffer->curl, CURLINFO_RESPONSE_CODE, &status);
if (status != 200)
{
p = strchr(buffer->buffer, '\n');
if (p)
*p = '\0';
Contact_error();
Blame(
"Master server error %ld: %s%s\n",
status,
buffer->buffer,
( (p) ? "" : " (malformed)" )
);
return 0;
}
else
return 1;
}
static void
HMS_end (struct HMS_buffer *buffer)
{
curl_easy_cleanup(buffer->curl);
free(buffer->buffer);
free(buffer);
}
int
HMS_fetch_rooms (int joining, int query_id)
{
struct HMS_buffer *hms;
int ok;
int doing_shit;
char *id;
char *title;
char *room_motd;
int id_no;
char *p;
char *end;
int i;
(void)query_id;
hms = HMS_connect("rooms");
if (! hms)
return 0;
if (HMS_do(hms))
{
doing_shit = 1;
p = hms->buffer;
for (i = 0; i < NUM_LIST_ROOMS && ( end = strstr(p, "\n\n\n") );)
{
*end = '\0';
id = strtok(p, "\n");
title = strtok(0, "\n");
room_motd = strtok(0, "");
if (id && title && room_motd)
{
id_no = atoi(id);
/*
Don't show the 'All' room if hosting. And it's a hack like this
because I'm way too lazy to add another feature to the MS.
*/
if (joining || id_no != 0)
{
#ifdef HAVE_THREADS
I_lock_mutex(&ms_QueryId_mutex);
{
if (query_id != ms_QueryId)
doing_shit = 0;
}
I_unlock_mutex(ms_QueryId_mutex);
if (! doing_shit)
break;
#endif
room_list[i].header.buffer[0] = 1;
room_list[i].id = id_no;
strlcpy(room_list[i].name, title, sizeof room_list[i].name);
strlcpy(room_list[i].motd, room_motd, sizeof room_list[i].motd);
i++;
}
p = ( end + 3 );/* skip the three linefeeds */
}
else
break;
}
if (doing_shit)
room_list[i].header.buffer[0] = 0;
ok = 1;
if (doing_shit)
{
#ifdef HAVE_THREADS
I_lock_mutex(&m_menu_mutex);
#endif
{
for (i = 0; room_list[i].header.buffer[0]; i++)
{
if(*room_list[i].name != '\0')
{
MP_RoomMenu[i+1].text = room_list[i].name;
roomIds[i] = room_list[i].id;
MP_RoomMenu[i+1].status = IT_STRING|IT_CALL;
}
}
}
#ifdef HAVE_THREADS
I_unlock_mutex(m_menu_mutex);
#endif
}
}
else
ok = 0;
HMS_end(hms);
return ok;
}
int
HMS_register (void)
{
struct HMS_buffer *hms;
int ok;
char post[256];
char *title;
hms = HMS_connect("rooms/%d/register", ms_RoomId);
if (! hms)
return 0;
title = curl_easy_escape(hms->curl, cv_servername.string, 0);
snprintf(post, sizeof post,
"port=%d&"
"title=%s&"
"version=%d.%d",
current_port,
title,
VERSION,
SUBVERSION
);
curl_free(title);
curl_easy_setopt(hms->curl, CURLOPT_POSTFIELDS, post);
ok = HMS_do(hms);
if (ok)
{
hms_server_token = strdup(strtok(hms->buffer, "\n"));
}
HMS_end(hms);
return ok;
}
int
HMS_unlist (void)
{
struct HMS_buffer *hms;
int ok;
hms = HMS_connect("servers/%s/unlist", hms_server_token);
if (! hms)
return 0;
curl_easy_setopt(hms->curl, CURLOPT_CUSTOMREQUEST, "POST");
ok = HMS_do(hms);
HMS_end(hms);
free(hms_server_token);
return ok;
}
int
HMS_update (void)
{
struct HMS_buffer *hms;
int ok;
char post[256];
char *title;
hms = HMS_connect("servers/%s/update", hms_server_token);
if (! hms)
return 0;
title = curl_easy_escape(hms->curl, cv_servername.string, 0);
snprintf(post, sizeof post,
"title=%s",
title
);
curl_free(title);
curl_easy_setopt(hms->curl, CURLOPT_POSTFIELDS, post);
ok = HMS_do(hms);
HMS_end(hms);
return ok;
}
void
HMS_list_servers (void)
{
struct HMS_buffer *hms;
char *p;
hms = HMS_connect("servers");
if (! hms)
return;
if (HMS_do(hms))
{
p = &hms->buffer[strlen(hms->buffer)];
while (*--p == '\n')
;
CONS_Printf("%s\n", hms->buffer);
}
HMS_end(hms);
}
msg_server_t *
HMS_fetch_servers (msg_server_t *list, int room_number, int query_id)
{
struct HMS_buffer *hms;
int doing_shit;
char local_version[9];
char *room;
char *address;
char *port;
char *title;
char *version;
char *end;
char *section_end;
char *p;
int i;
(void)query_id;
if (room_number > 0)
{
hms = HMS_connect("rooms/%d/servers", room_number);
}
else
hms = HMS_connect("servers");
if (! hms)
return NULL;
if (HMS_do(hms))
{
doing_shit = 1;
snprintf(local_version, sizeof local_version,
"%d.%d",
VERSION,
SUBVERSION
);
p = hms->buffer;
i = 0;
do
{
section_end = strstr(p, "\n\n");
room = strtok(p, "\n");
p = strtok(0, "");
if (! p)
break;
while (i < MAXSERVERLIST && ( end = strchr(p, '\n') ))
{
*end = '\0';
address = strtok(p, " ");
port = strtok(0, " ");
title = strtok(0, " ");
version = strtok(0, "");
if (address && port && title && version)
{
#ifdef HAVE_THREADS
I_lock_mutex(&ms_QueryId_mutex);
{
if (query_id != ms_QueryId)
doing_shit = 0;
}
I_unlock_mutex(ms_QueryId_mutex);
if (! doing_shit)
break;
#endif
if (strcmp(version, local_version) == 0)
{
strlcpy(list[i].ip, address, sizeof list[i].ip);
strlcpy(list[i].port, port, sizeof list[i].port);
strlcpy(list[i].name, title, sizeof list[i].name);
strlcpy(list[i].version, version, sizeof list[i].version);
list[i].room = atoi(room);
list[i].header.buffer[0] = 1;
i++;
}
if (end == section_end)/* end of list for this room */
break;
else
p = ( end + 1 );/* skip server delimiter */
}
else
{
section_end = 0;/* malformed so quit the parsing */
break;
}
}
if (! doing_shit)
break;
p = ( section_end + 2 );
}
while (section_end) ;
if (doing_shit)
list[i].header.buffer[0] = 0;
}
else
list = NULL;
HMS_end(hms);
return list;
}
int
HMS_compare_mod_version (char *buffer, size_t buffer_size)
{
struct HMS_buffer *hms;
int ok;
char *version;
char *version_name;
hms = HMS_connect("versions/%d", MODID);
if (! hms)
return 0;
ok = 0;
if (HMS_do(hms))
{
version = strtok(hms->buffer, " ");
version_name = strtok(0, "\n");
if (version && version_name)
{
if (atoi(version) != MODVERSION)
{
strlcpy(buffer, version_name, buffer_size);
ok = 1;
}
else
ok = -1;
}
}
HMS_end(hms);
return ok;
}
void
HMS_set_api (char *api)
{
#ifdef HAVE_THREADS
I_lock_mutex(&hms_api_mutex);
#endif
{
free(hms_api);
hms_api = api;
}
#ifdef HAVE_THREADS
I_unlock_mutex(hms_api_mutex);
#endif
}
static void
MasterServer_Debug_OnChange (void)
{
/* TODO: change to 'latest-log.txt' for log files revision. */
if (cv_masterserver_debug.value)
CONS_Printf("Master server debug messages will appear in log.txt\n");
}

39
src/i_threads.h Normal file
View file

@ -0,0 +1,39 @@
// SONIC ROBO BLAST 2 KART
//-----------------------------------------------------------------------------
// Copyright (C) 2020 by James R.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file i_threads.h
/// \brief Multithreading abstraction
#ifdef HAVE_THREADS
#ifndef I_THREADS_H
#define I_THREADS_H
typedef void (*I_thread_fn)(void *userdata);
typedef void * I_mutex;
typedef void * I_cond;
void I_start_threads (void);
void I_stop_threads (void);
void I_spawn_thread (const char *name, I_thread_fn, void *userdata);
/* check in your thread whether to return early */
int I_thread_is_stopped (void);
void I_lock_mutex (I_mutex *);
void I_unlock_mutex (I_mutex);
void I_hold_cond (I_cond *, I_mutex);
void I_wake_one_cond (I_cond *);
void I_wake_all_cond (I_cond *);
#endif/*I_THREADS_H*/
#endif/*HAVE_THREADS*/

View file

@ -898,6 +898,7 @@ static INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, fixed_t mashed, boolean sp
newodds = 0;
else
POWERITEMODDS(newodds);
break;
case KITEM_HYUDORO:
if ((hyubgone > 0) || COOLDOWNONSTART)
newodds = 0;
@ -1061,6 +1062,10 @@ static void K_KartItemRoulette(player_t *player, ticcmd_t *cmd)
bestbumper = players[i].kartstuff[k_bumper];
}
// No forced SPB in 1v1s, it has to be randomly rolled
if (pingame <= 2)
dontforcespb = true;
// This makes the roulette produce the random noises.
if ((player->kartstuff[k_itemroulette] % 3) == 1 && P_IsDisplayPlayer(player) && !demo.freecam)
{
@ -3312,7 +3317,8 @@ void K_PuntMine(mobj_t *thismine, mobj_t *punter)
if (!thismine || P_MobjWasRemoved(thismine))
return;
if (thismine->type == MT_SSMINE_SHIELD) // Create a new mine
//This guarantees you hit a mine being dragged
if (thismine->type == MT_SSMINE_SHIELD) // Create a new mine, and clean up the old one
{
mine = P_SpawnMobj(thismine->x, thismine->y, thismine->z, MT_SSMINE);
P_SetTarget(&mine->target, thismine->target);
@ -3320,7 +3326,19 @@ void K_PuntMine(mobj_t *thismine, mobj_t *punter)
mine->flags2 = thismine->flags2;
mine->floorz = thismine->floorz;
mine->ceilingz = thismine->ceilingz;
//Since we aren't using P_KillMobj, we need to clean up the hnext reference
{
P_SetTarget(&thismine->target->hnext, NULL); //target is the player who owns the mine
thismine->target->player->kartstuff[k_bananadrag] = 0;
thismine->target->player->kartstuff[k_itemheld] = 0;
if (--thismine->target->player->kartstuff[k_itemamount] <= 0)
thismine->target->player->kartstuff[k_itemtype] = KITEM_NONE;
}
P_RemoveMobj(thismine);
}
else
mine = thismine;
@ -3870,6 +3888,62 @@ void K_DropItems(player_t *player)
K_StripItems(player);
}
void K_DropRocketSneaker(player_t *player)
{
mobj_t *shoe = player->mo;
fixed_t flingangle;
boolean leftshoe = true; //left shoe is first
if (!(player->mo && !P_MobjWasRemoved(player->mo) && player->mo->hnext && !P_MobjWasRemoved(player->mo->hnext)))
return;
while ((shoe = shoe->hnext) && !P_MobjWasRemoved(shoe))
{
if (shoe->type != MT_ROCKETSNEAKER)
return; //woah, not a rocketsneaker, bail! safeguard in case this gets used when you're holding non-rocketsneakers
shoe->flags2 &= ~MF2_DONTDRAW;
shoe->flags &= ~MF_NOGRAVITY;
shoe->angle += ANGLE_45;
if (shoe->eflags & MFE_VERTICALFLIP)
shoe->z -= shoe->height;
else
shoe->z += shoe->height;
//left shoe goes off tot eh left, right shoe off to the right
if (leftshoe)
flingangle = -(ANG60);
else
flingangle = ANG60;
S_StartSound(shoe, shoe->info->deathsound);
P_SetObjectMomZ(shoe, 8*FRACUNIT, false);
P_InstaThrust(shoe, R_PointToAngle2(shoe->target->x, shoe->target->y, shoe->x, shoe->y)+flingangle, 16*FRACUNIT);
shoe->momx += shoe->target->momx;
shoe->momy += shoe->target->momy;
shoe->momz += shoe->target->momz;
shoe->extravalue2 = 1;
leftshoe = false;
}
P_SetTarget(&player->mo->hnext, NULL);
player->kartstuff[k_rocketsneakertimer] = 0;
}
void K_DropKitchenSink(player_t *player)
{
if (!(player->mo && !P_MobjWasRemoved(player->mo) && player->mo->hnext && !P_MobjWasRemoved(player->mo->hnext)))
return;
if (player->mo->hnext->type != MT_SINK_SHIELD)
return; //so we can just call this function regardless of what is being held
P_KillMobj(player->mo->hnext, NULL, NULL);
P_SetTarget(&player->mo->hnext, NULL);
}
// When an item in the hnext chain dies.
void K_RepairOrbitChain(mobj_t *orbit)
{
@ -4490,6 +4564,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
fast->momx = 3*player->mo->momx/4;
fast->momy = 3*player->mo->momy/4;
fast->momz = 3*player->mo->momz/4;
P_SetTarget(&fast->target, player->mo); // easier lua access
K_MatchGenericExtraFlags(fast, player->mo);
}
@ -5195,12 +5270,12 @@ void K_KartUpdatePosition(player_t *player)
//
void K_StripItems(player_t *player)
{
K_DropRocketSneaker(player);
K_DropKitchenSink(player);
player->kartstuff[k_itemtype] = KITEM_NONE;
player->kartstuff[k_itemamount] = 0;
player->kartstuff[k_itemheld] = 0;
player->kartstuff[k_rocketsneakertimer] = 0;
if (!player->kartstuff[k_itemroulette] || player->kartstuff[k_roulettetype] != 2)
{
player->kartstuff[k_itemroulette] = 0;
@ -8634,7 +8709,7 @@ void K_drawKartFreePlay(UINT32 flashtime)
return;
V_DrawKartString((BASEVIDWIDTH - (LAPS_X+1)) - (12*9), // mirror the laps thingy
LAPS_Y+3, V_SNAPTOBOTTOM|V_SNAPTORIGHT, "FREE PLAY");
LAPS_Y+3, V_SNAPTOBOTTOM|V_SNAPTORIGHT|V_HUDTRANS, "FREE PLAY");
}
static void K_drawDistributionDebugger(void)

View file

@ -11,7 +11,7 @@
#define KART_FULLTURN 800
UINT8 colortranslations[MAXTRANSLATIONS][16];
extern UINT8 colortranslations[MAXTRANSLATIONS][16];
extern const char *KartColor_Names[MAXSKINCOLORS];
extern const UINT8 KartColor_Opposite[MAXSKINCOLORS*2];
void K_RainbowColormap(UINT8 *dest_colormap, UINT8 skincolor);
@ -55,6 +55,8 @@ INT16 K_GetKartTurnValue(player_t *player, INT16 turnvalue);
INT32 K_GetKartDriftSparkValue(player_t *player);
void K_KartUpdatePosition(player_t *player);
void K_DropItems(player_t *player);
void K_DropRocketSneaker(player_t *player);
void K_DropKitchenSink(player_t *player);
void K_StripItems(player_t *player);
void K_StripOther(player_t *player);
void K_MomentumToFacing(player_t *player);

View file

@ -17,6 +17,7 @@
#include "d_player.h"
#include "g_game.h"
#include "p_local.h"
#include "d_clisrv.h"
#include "lua_script.h"
#include "lua_libs.h"
@ -118,7 +119,7 @@ static int lib_iterateDisplayplayers(lua_State *L)
for (i++; i < MAXSPLITSCREENPLAYERS; i++)
{
if (!playeringame[displayplayers[i]] || i > splitscreen)
if (i > splitscreen || !playeringame[displayplayers[i]])
return 0; // Stop! There are no more players for us to go through. There will never be a player gap in displayplayers.
if (!players[displayplayers[i]].mo)
@ -139,6 +140,8 @@ static int lib_getDisplayplayers(lua_State *L)
lua_Integer i = luaL_checkinteger(L, 2);
if (i < 0 || i >= MAXSPLITSCREENPLAYERS)
return luaL_error(L, "displayplayers[] index %d out of range (0 - %d)", i, MAXSPLITSCREENPLAYERS-1);
if (i > splitscreen)
return 0;
if (!playeringame[displayplayers[i]])
return 0;
if (!players[displayplayers[i]].mo)
@ -385,6 +388,8 @@ static int player_get(lua_State *L)
else if (fastcmp(field,"fovadd"))
lua_pushfixed(L, plr->fovadd);
#endif
else if (fastcmp(field,"ping"))
lua_pushinteger(L, playerpingtable[( plr - players )]);
else {
lua_getfield(L, LUA_REGISTRYINDEX, LREG_EXTVARS);
I_Assert(lua_istable(L, -1));

View file

@ -16,6 +16,7 @@
#include "doomdef.h"
#include "command.h"
#include "m_argv.h"
#include "m_misc.h"
/** \brief number of arg
*/
@ -166,7 +167,7 @@ void M_FindResponseFile(void)
if (!file)
I_Error("No more free memory for the response file");
if (fread(file, size, 1, handle) != 1)
I_Error("Couldn't read response file because %s", strerror(ferror(handle)));
I_Error("Couldn't read response file because %s", M_FileError(handle));
fclose(handle);
// keep all the command line arguments following @responsefile

View file

@ -32,6 +32,7 @@
#include "sounds.h"
#include "s_sound.h"
#include "i_system.h"
#include "i_threads.h"
// Addfile
#include "filesrch.h"
@ -118,6 +119,12 @@ typedef enum
NUM_QUITMESSAGES
} text_enum;
#ifdef HAVE_THREADS
I_mutex m_menu_mutex;
#endif
M_waiting_mode_t m_waiting_mode = M_NOT_WAITING;
const char *quitmsg[NUM_QUITMESSAGES];
// Stuff for customizing the player select screen Tails 09-22-2003
@ -1039,7 +1046,7 @@ enum
FIRSTSERVERLINE
};
static menuitem_t MP_RoomMenu[] =
menuitem_t MP_RoomMenu[] =
{
{IT_STRING | IT_CALL, NULL, "<Offline Mode>", M_ChooseRoom, 9},
{IT_DISABLED, NULL, "", M_ChooseRoom, 18},
@ -2896,7 +2903,6 @@ boolean M_Responder(event_t *ev)
//make sure the game doesn't still think we're in a netgame.
if (!Playing() && netgame && multiplayer)
{
MSCloseUDPSocket(); // Clean up so we can re-open the connection later.
netgame = false;
multiplayer = false;
}
@ -3304,6 +3310,30 @@ void M_SetupNextMenu(menu_t *menudef)
{
INT16 i;
#ifdef HAVE_THREADS
if (currentMenu == &MP_RoomDef || currentMenu == &MP_ConnectDef)
{
I_lock_mutex(&ms_QueryId_mutex);
{
ms_QueryId++;
}
I_unlock_mutex(ms_QueryId_mutex);
}
if (currentMenu == &MP_ConnectDef)
{
I_lock_mutex(&ms_ServerList_mutex);
{
if (ms_ServerList)
{
free(ms_ServerList);
ms_ServerList = NULL;
}
}
I_unlock_mutex(ms_ServerList_mutex);
}
#endif/*HAVE_THREADS*/
if (currentMenu->quitroutine)
{
// If you're going from a menu to itself, why are you running the quitroutine? You're not quitting it! -SH
@ -3361,6 +3391,19 @@ void M_Ticker(void)
if (--vidm_testingmode == 0)
setmodeneeded = vidm_previousmode + 1;
}
#ifdef HAVE_THREADS
I_lock_mutex(&ms_ServerList_mutex);
{
if (ms_ServerList)
{
CL_QueryServerList(ms_ServerList);
free(ms_ServerList);
ms_ServerList = NULL;
}
}
I_unlock_mutex(ms_ServerList_mutex);
#endif
}
//
@ -4833,7 +4876,7 @@ static boolean M_AddonsRefresh(void)
else if (majormods && !prevmajormods)
{
S_StartSound(NULL, sfx_s221);
message = va("%c%s\x80\nGameplay has now been modified.\nIf you wish to play Record Attack mode, restart the game to clear existing addons.\n\n(Press a key)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), refreshdirname);
message = va("%c%s\x80\nYou've loaded a gameplay-modifying addon.\n\nRecord Attack has been disabled, but you\ncan still play alone in local Multiplayer.\n\nIf you wish to play Record Attack mode, restart the game to disable loaded addons.\n\n(Press a key)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), refreshdirname);
prevmajormods = majormods;
}
@ -8327,22 +8370,65 @@ static INT32 menuRoomIndex = 0;
static void M_DrawRoomMenu(void)
{
static int frame = -12;
int dot_frame;
char text[4];
const char *rmotd;
const char *waiting_message;
int dots;
if (m_waiting_mode)
{
dot_frame = frame / 4;
dots = dot_frame + 3;
strcpy(text, " ");
if (dots > 0)
{
if (dot_frame < 0)
dot_frame = 0;
strncpy(&text[dot_frame], "...", min(dots, 3 - dot_frame));
}
if (++frame == 12)
frame = -12;
currentMenu->menuitems[0].text = text;
}
// use generic drawer for cursor, items and title
M_DrawGenericMenu();
V_DrawString(currentMenu->x - 16, currentMenu->y, highlightflags, M_GetText("Select a room"));
M_DrawTextBox(144, 24, 20, 20);
if (m_waiting_mode == M_NOT_WAITING)
{
M_DrawTextBox(144, 24, 20, 20);
if (itemOn == 0)
rmotd = M_GetText("Don't connect to the Master Server.");
else
rmotd = room_list[itemOn-1].motd;
if (itemOn == 0)
rmotd = M_GetText("Don't connect to the Master Server.");
else
rmotd = room_list[itemOn-1].motd;
rmotd = V_WordWrap(0, 20*8, 0, rmotd);
V_DrawString(144+8, 32, V_ALLOWLOWERCASE|V_RETURN8, rmotd);
rmotd = V_WordWrap(0, 20*8, 0, rmotd);
V_DrawString(144+8, 32, V_ALLOWLOWERCASE|V_RETURN8, rmotd);
}
if (m_waiting_mode)
{
// Display a little "please wait" message.
M_DrawTextBox(52, BASEVIDHEIGHT/2-10, 25, 3);
if (m_waiting_mode == M_WAITING_VERSION)
waiting_message = "Checking for updates...";
else
waiting_message = "Fetching room info...";
V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT/2, 0, waiting_message);
V_DrawCenteredString(BASEVIDWIDTH/2, (BASEVIDHEIGHT/2)+12, 0, "Please wait.");
}
}
static void M_DrawConnectMenu(void)
@ -8416,6 +8502,14 @@ static void M_DrawConnectMenu(void)
localservercount = serverlistcount;
M_DrawGenericMenu();
if (m_waiting_mode)
{
// Display a little "please wait" message.
M_DrawTextBox(52, BASEVIDHEIGHT/2-10, 25, 3);
V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT/2, 0, "Searching for servers...");
V_DrawCenteredString(BASEVIDWIDTH/2, (BASEVIDHEIGHT/2)+12, 0, "Please wait.");
}
}
static boolean M_CancelConnect(void)
@ -8497,10 +8591,10 @@ void M_SortServerList(void)
#ifndef NONET
#ifdef UPDATE_ALERT
static boolean M_CheckMODVersion(void)
static boolean M_CheckMODVersion(int id)
{
char updatestring[500];
const char *updatecheck = GetMODVersion();
const char *updatecheck = GetMODVersion(id);
if(updatecheck)
{
sprintf(updatestring, UPDATE_ALERT_STRING, VERSIONSTRING, updatecheck);
@ -8509,7 +8603,62 @@ static boolean M_CheckMODVersion(void)
} else
return true;
}
#endif
#ifdef HAVE_THREADS
static void
Check_new_version_thread (int *id)
{
int hosting;
int okay;
okay = 0;
if (M_CheckMODVersion(*id))
{
I_lock_mutex(&ms_QueryId_mutex);
{
okay = ( *id == ms_QueryId );
}
I_unlock_mutex(ms_QueryId_mutex);
if (okay)
{
I_lock_mutex(&m_menu_mutex);
{
m_waiting_mode = M_WAITING_ROOMS;
hosting = ( currentMenu->prevMenu == &MP_ServerDef );
}
I_unlock_mutex(m_menu_mutex);
GetRoomsList(hosting, *id);
}
}
else
{
I_lock_mutex(&ms_QueryId_mutex);
{
okay = ( *id == ms_QueryId );
}
I_unlock_mutex(ms_QueryId_mutex);
}
if (okay)
{
I_lock_mutex(&m_menu_mutex);
{
if (m_waiting_mode)
{
m_waiting_mode = M_NOT_WAITING;
MP_RoomMenu[0].text = "<Offline Mode>";
}
}
I_unlock_mutex(m_menu_mutex);
}
free(id);
}
#endif/*HAVE_THREADS*/
#endif/*UPDATE_ALERT*/
static void M_ConnectMenu(INT32 choice)
{
@ -8538,18 +8687,21 @@ static void M_ConnectMenuModChecks(INT32 choice)
if (modifiedgame)
{
M_StartMessage(M_GetText("Addons are currently loaded.\n\nYou will only be able to join a server if\nit has the same ones loaded in the same order, which may be unlikely.\n\nIf you wish to play on other servers,\nrestart the game to clear existing addons.\n\n(Press a key)\n"),M_ConnectMenu,MM_EVENTHANDLER);
M_StartMessage(M_GetText("You have addons loaded.\nYou won't be able to join netgames!\n\nTo play online, restart the game\nand don't load any addons.\nSRB2Kart will automatically add\neverything you need when you join.\n\n(Press a key)\n"),M_ConnectMenu,MM_EVENTHANDLER);
return;
}
M_ConnectMenu(-1);
}
static UINT32 roomIds[NUM_LIST_ROOMS];
UINT32 roomIds[NUM_LIST_ROOMS];
static void M_RoomMenu(INT32 choice)
{
INT32 i;
#ifdef HAVE_THREADS
int *id;
#endif
(void)choice;
@ -8562,34 +8714,47 @@ static void M_RoomMenu(INT32 choice)
if (rendermode == render_soft)
I_FinishUpdate(); // page flip or blit buffer
if (GetRoomsList(currentMenu == &MP_ServerDef) < 0)
return;
#ifdef UPDATE_ALERT
if (!M_CheckMODVersion())
return;
#endif
for (i = 1; i < NUM_LIST_ROOMS+1; ++i)
MP_RoomMenu[i].status = IT_DISABLED;
memset(roomIds, 0, sizeof(roomIds));
for (i = 0; room_list[i].header.buffer[0]; i++)
{
if(*room_list[i].name != '\0')
{
MP_RoomMenu[i+1].text = room_list[i].name;
roomIds[i] = room_list[i].id;
MP_RoomMenu[i+1].status = IT_STRING|IT_CALL;
}
}
MP_RoomDef.prevMenu = currentMenu;
M_SetupNextMenu(&MP_RoomDef);
#ifdef UPDATE_ALERT
#ifdef HAVE_THREADS
m_waiting_mode = M_WAITING_VERSION;
MP_RoomMenu[0].text = "";
id = malloc(sizeof *id);
I_lock_mutex(&ms_QueryId_mutex);
{
*id = ms_QueryId;
}
I_unlock_mutex(ms_QueryId_mutex);
I_spawn_thread("check-new-version",
(I_thread_fn)Check_new_version_thread, id);
#else/*HAVE_THREADS*/
if (M_CheckMODVersion(0))
{
GetRoomsList(currentMenu->prevMenu == &MP_ServerDef, 0);
}
#endif/*HAVE_THREADS*/
#endif/*UPDATE_ALERT*/
}
static void M_ChooseRoom(INT32 choice)
{
#ifdef HAVE_THREADS
I_lock_mutex(&ms_QueryId_mutex);
{
ms_QueryId++;
}
I_unlock_mutex(ms_QueryId_mutex);
#endif
if (choice == 0)
ms_RoomId = -1;
else

View file

@ -17,6 +17,8 @@
#include "d_event.h"
#include "command.h"
#include "i_threads.h"
#include "mserv.h"
#include "r_things.h" // for SKINNAMESIZE
//
@ -72,6 +74,18 @@ typedef enum
} menumessagetype_t;
void M_StartMessage(const char *string, void *routine, menumessagetype_t itemtype);
typedef enum
{
M_NOT_WAITING,
M_WAITING_VERSION,
M_WAITING_ROOMS,
M_WAITING_SERVERS,
}
M_waiting_mode_t;
extern M_waiting_mode_t m_waiting_mode;
// Called by linux_x/i_video_xshm.c
void M_QuitResponse(INT32 ch);
@ -161,6 +175,9 @@ typedef struct menuitem_s
extern menuitem_t PlayerMenu[MAXSKINS];
extern menuitem_t MP_RoomMenu[];
extern UINT32 roomIds[NUM_LIST_ROOMS];
typedef struct menu_s
{
const char *menutitlepic;
@ -176,6 +193,10 @@ typedef struct menu_s
void M_SetupNextMenu(menu_t *menudef);
void M_ClearMenus(boolean callexitmenufunc);
#ifdef HAVE_THREADS
extern I_mutex m_menu_mutex;
#endif
extern menu_t *currentMenu;
extern menu_t MainDef;

View file

@ -23,6 +23,8 @@
#include <unistd.h>
#endif
#include <errno.h>
// Extended map support.
#include <ctype.h>
@ -2363,3 +2365,13 @@ void M_SetupMemcpy(void)
M_Memcpy = cpu_cpy;
#endif
}
/** Return the appropriate message for a file error or end of file.
*/
const char *M_FileError(FILE *fp)
{
if (ferror(fp))
return strerror(errno);
else
return "end-of-file";
}

View file

@ -100,6 +100,8 @@ void strcatbf(char *s1, const char *s2, const char *s3);
void M_SetupMemcpy(void);
const char *M_FileError(FILE *handle);
// counting bits, for weapon ammo code, usually
FUNCMATH UINT8 M_CountBits(UINT32 num, UINT8 size);

File diff suppressed because it is too large Load diff

View file

@ -2,6 +2,7 @@
//-----------------------------------------------------------------------------
// Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2018 by Sonic Team Junior.
// Copyright (C) 2020 by James R.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
@ -13,7 +14,7 @@
#ifndef _MSERV_H_
#define _MSERV_H_
#define MASTERSERVERS21 // MasterServer v2.1
#include "i_threads.h"
// lowered from 32 due to menu changes
#define NUM_LIST_ROOMS 16
@ -64,33 +65,47 @@ typedef struct
// ================================ GLOBALS ===============================
extern consvar_t cv_masterserver, cv_servername;
extern consvar_t cv_masterserver_update_rate;
extern consvar_t cv_masterserver_timeout;
extern consvar_t cv_masterserver_debug;
extern consvar_t cv_masterserver_token;
// < 0 to not connect (usually -1) (offline mode)
// == 0 to show all rooms, not a valid hosting room
// anything else is whatever room the MS assigns to that number (online mode)
INT16 ms_RoomId;
extern INT16 ms_RoomId;
const char *GetMasterServerPort(void);
const char *GetMasterServerIP(void);
#ifdef HAVE_THREADS
extern int ms_QueryId;
extern I_mutex ms_QueryId_mutex;
void MSOpenUDPSocket(void);
void MSCloseUDPSocket(void);
void SendAskInfoViaMS(INT32 node, tic_t asktime);
extern msg_server_t *ms_ServerList;
extern I_mutex ms_ServerList_mutex;
#endif
void RegisterServer(void);
void UnregisterServer(void);
void MasterClient_Ticker(void);
const msg_server_t *GetShortServersList(INT32 room);
INT32 GetRoomsList(boolean hosting);
msg_server_t *GetShortServersList(INT32 room, int id);
INT32 GetRoomsList(boolean hosting, int id);
#ifdef UPDATE_ALERT
const char *GetMODVersion(void);
char *GetMODVersion(int id);
void GetMODVersion_Console(void);
#endif
extern msg_rooms_t room_list[NUM_LIST_ROOMS+1];
void AddMServCommands(void);
/* HTTP */
void HMS_set_api (char *api);
int HMS_fetch_rooms (int joining, int id);
int HMS_register (void);
int HMS_unlist (void);
int HMS_update (void);
void HMS_list_servers (void);
msg_server_t * HMS_fetch_servers (msg_server_t *list, int room, int id);
int HMS_compare_mod_version (char *buffer, size_t size_of_buffer);
#endif

View file

@ -8517,6 +8517,7 @@ void A_SPBChase(mobj_t *actor)
//fast->momz = (3*actor->momz)/4;
fast->color = SKINCOLOR_RED;
fast->colorized = true;
P_SetTarget(&fast->target, actor); // easier lua access
K_MatchGenericExtraFlags(fast, actor);
}

View file

@ -8312,18 +8312,7 @@ void P_MobjThinker(mobj_t *mobj)
if (!mobj->extravalue2)
{
if (mobj->eflags & MFE_VERTICALFLIP)
mobj->z -= mobj->height;
else
mobj->z += mobj->height;
S_StartSound(mobj, mobj->info->deathsound);
P_SetObjectMomZ(mobj, 8*FRACUNIT, false);
P_InstaThrust(mobj, R_PointToAngle2(mobj->target->x, mobj->target->y, mobj->x, mobj->y)+ANGLE_90, 16*FRACUNIT);
mobj->momx += mobj->target->momx;
mobj->momy += mobj->target->momy;
mobj->momz += mobj->target->momz;
mobj->extravalue2 = 1;
K_DropRocketSneaker(mobj->target->player);
}
else if (P_IsObjectOnGround(mobj))
{

View file

@ -1408,7 +1408,7 @@ static void P_LoadRawSideDefs2(void *data)
UINT16 i;
INT32 num;
size_t j;
UINT32 cr, cg, cb;
RGBA_t color;
for (i = 0; i < numsides; i++)
{
@ -1490,23 +1490,21 @@ static void P_LoadRawSideDefs2(void *data)
// encore mode colormaps!
// do it like software by aproximating a color to a palette index, and then convert it to its encore variant and then back to a color code.
// do this for both the start and fade colormaps.
cr = (HEX2INT(col[1]) << 4) + (HEX2INT(col[2]) << 0);
cg = (HEX2INT(col[3]) << 12) + (HEX2INT(col[4]) << 8);
cb = (HEX2INT(col[5]) << 20) + (HEX2INT(col[6]) << 16);
color.s.red = (HEX2INT(col[1]) << 4) + HEX2INT(col[2]);
color.s.green = (HEX2INT(col[3]) << 4) + HEX2INT(col[4]);
color.s.blue = (HEX2INT(col[5]) << 4) + HEX2INT(col[6]);
#ifdef GLENCORE
if (encoremap)
{
j = encoremap[NearestColor((UINT8)cr, (UINT8)cg, (UINT8)cb)];
j = encoremap[NearestColor(color.s.red, color.s.green, color.s.blue)];
//CONS_Printf("R_CreateColormap: encoremap[%d] = %d\n", j, encoremap[j]); -- moved encoremap upwards for optimisation
cr = pLocalPalette[j].s.red;
cg = pLocalPalette[j].s.green;
cb = pLocalPalette[j].s.blue;
color = pLocalPalette[j]; // note: this sets alpha to 255, we will reset it below
}
#endif
sec->extra_colormap->rgba = cr + cg + cb;
color.s.alpha = 0; // reset/init the alpha, so the addition below will work correctly
sec->extra_colormap->rgba = color.rgba;
// alpha
if (msd->toptexture[7])
@ -1533,23 +1531,21 @@ static void P_LoadRawSideDefs2(void *data)
col = msd->bottomtexture;
// do the exact same thing as above here.
cr = (HEX2INT(col[1]) << 4) + (HEX2INT(col[2]) << 0);
cg = (HEX2INT(col[3]) << 12) + (HEX2INT(col[4]) << 8);
cb = (HEX2INT(col[5]) << 20) + (HEX2INT(col[6]) << 16);
color.s.red = (HEX2INT(col[1]) << 4) + HEX2INT(col[2]);
color.s.green = (HEX2INT(col[3]) << 4) + HEX2INT(col[4]);
color.s.blue = (HEX2INT(col[5]) << 4) + HEX2INT(col[6]);
#ifdef GLENCORE
if (encoremap)
{
j = encoremap[NearestColor((UINT8)cr, (UINT8)cg, (UINT8)cb)];
j = encoremap[NearestColor(color.s.red, color.s.green, color.s.blue)];
//CONS_Printf("R_CreateColormap: encoremap[%d] = %d\n", j, encoremap[j]); -- moved encoremap upwards for optimisation
cr = pLocalPalette[j].s.red;
cg = pLocalPalette[j].s.green;
cb = pLocalPalette[j].s.blue;
color = pLocalPalette[j]; // note: this sets alpha to 255, we will reset it below
}
#endif
sec->extra_colormap->fadergba = cr + cg + cb;
color.s.alpha = 0; // reset/init the alpha, so the addition below will work correctly
sec->extra_colormap->fadergba = color.rgba;
// alpha
if (msd->bottomtexture[7])

View file

@ -726,9 +726,9 @@ void P_Ticker(boolean run)
if (exitcountdown > 1)
exitcountdown--;
if (indirectitemcooldown > 1)
if (indirectitemcooldown > 0)
indirectitemcooldown--;
if (hyubgone > 1)
if (hyubgone > 0)
hyubgone--;
if (G_BattleGametype())

View file

@ -1142,7 +1142,7 @@ void R_SetupFrame(player_t *player, boolean skybox)
aimingangle = player->aiming;
viewangle = viewmobj->angle;
if (/*!demo.playback && */player->playerstate != PST_DEAD)
if (!demo.playback && player->playerstate != PST_DEAD)
{
if (player == &players[consoleplayer])
{

View file

@ -402,7 +402,7 @@ static visplane_t *new_visplane(unsigned hash)
visplane_t *check = freetail;
if (!check)
{
check = calloc(2, sizeof (*check));
check = calloc(1, sizeof (*check));
if (check == NULL) I_Error("%s: Out of memory", "new_visplane"); // FIXME: ugly
}
else

View file

@ -236,7 +236,7 @@ void S_StopSoundByNum(sfxenum_t sfxnum);
#ifdef MUSICSLOT_COMPATIBILITY
// For compatibility with code/scripts relying on older versions
// This is a list of all the "special" slot names and their associated numbers
const char *compat_special_music_slots[16];
extern const char *compat_special_music_slots[16];
#endif
#endif

View file

@ -83,6 +83,11 @@ else
SDL_LDFLAGS+=-lSDL2_mixer
endif
ifndef NOTHREADS
OPTS+=-DHAVE_THREADS
OBJS+=$(OBJDIR)/i_threads.o
endif
ifdef SDL_TTF
OPTS+=-DHAVE_TTF
SDL_LDFLAGS+=-lSDL2_ttf -lfreetype -lz

View file

@ -249,6 +249,7 @@
<ClInclude Include="..\lzf.h" />
<ClInclude Include="..\md5.h" />
<ClInclude Include="..\mserv.h" />
<ClInclude Include="..\http-mserv.h" />
<ClInclude Include="..\m_aatree.h" />
<ClInclude Include="..\m_anigif.h" />
<ClInclude Include="..\m_argv.h" />
@ -399,6 +400,7 @@
<ClCompile Include="..\lzf.c" />
<ClCompile Include="..\md5.c" />
<ClCompile Include="..\mserv.c" />
<ClCompile Include="..\http-mserv.c" />
<ClCompile Include="..\m_aatree.c" />
<ClCompile Include="..\m_anigif.c" />
<ClCompile Include="..\m_argv.c" />

View file

@ -291,6 +291,9 @@
<ClInclude Include="..\mserv.h">
<Filter>I_Interface</Filter>
</ClInclude>
<ClInclude Include="..\http-mserv.h">
<Filter>I_Interface</Filter>
</ClInclude>
<ClInclude Include="..\lua_hook.h">
<Filter>LUA</Filter>
</ClInclude>
@ -663,6 +666,9 @@
<ClCompile Include="..\mserv.c">
<Filter>I_Interface</Filter>
</ClCompile>
<ClCompile Include="..\http-mserv.c">
<Filter>I_Interface</Filter>
</ClCompile>
<ClCompile Include="..\lua_baselib.c">
<Filter>LUA</Filter>
</ClCompile>

View file

@ -2782,6 +2782,50 @@
RelativePath="..\mserv.h"
>
</File>
<File
RelativePath="..\http-mserv.c"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|x64"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|x64"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\http-mserv.h"
>
</File>
</Filter>
<Filter
Name="M_Misc"

View file

@ -168,6 +168,7 @@ static char returnWadPath[256];
#include "../i_video.h"
#include "../i_sound.h"
#include "../i_system.h"
#include "../i_threads.h"
#include "../screen.h" //vid.WndParent
#include "../d_net.h"
#include "../g_game.h"
@ -3134,6 +3135,10 @@ INT32 I_StartupSystem(void)
SDL_version SDLlinked;
SDL_VERSION(&SDLcompiled)
SDL_GetVersion(&SDLlinked);
#ifdef HAVE_THREADS
I_start_threads();
I_AddExitFunc(I_stop_threads);
#endif
I_StartupConsole();
#ifdef NEWSIGNALHANDLER
I_Fork();

356
src/sdl/i_threads.c Normal file
View file

@ -0,0 +1,356 @@
// SONIC ROBO BLAST 2 KART
//-----------------------------------------------------------------------------
// Copyright (C) 2020 by James R.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file i_threads.c
/// \brief Multithreading abstraction
#include "../doomdef.h"
#include "../i_threads.h"
#include <SDL.h>
typedef void * (*Create_fn)(void);
struct Link;
struct Thread;
typedef struct Link * Link;
typedef struct Thread * Thread;
struct Link
{
void * data;
Link next;
Link prev;
};
struct Thread
{
I_thread_fn entry;
void * userdata;
SDL_Thread * thread;
};
static Link i_thread_pool;
static Link i_mutex_pool;
static Link i_cond_pool;
static I_mutex i_thread_pool_mutex;
static I_mutex i_mutex_pool_mutex;
static I_mutex i_cond_pool_mutex;
static SDL_atomic_t i_threads_running = {1};
static Link
Insert_link (
Link * head,
Link link
){
link->prev = NULL;
link->next = (*head);
if ((*head))
(*head)->prev = link;
(*head) = link;
return link;
}
static void
Free_link (
Link * head,
Link link
){
if (link->prev)
link->prev->next = link->next;
else
(*head) = link->next;
if (link->next)
link->next->prev = link->prev;
free(link->data);
free(link);
}
static Link
New_link (void *data)
{
Link link;
link = malloc(sizeof *link);
if (! link)
abort();
link->data = data;
return link;
}
static void *
Identity (
Link * pool_anchor,
I_mutex pool_mutex,
void ** anchor,
Create_fn create_fn
){
void * id;
id = SDL_AtomicGetPtr(anchor);
if (! id)
{
I_lock_mutex(&pool_mutex);
{
id = SDL_AtomicGetPtr(anchor);
if (! id)
{
id = (*create_fn)();
if (! id)
abort();
Insert_link(pool_anchor, New_link(id));
SDL_AtomicSetPtr(anchor, id);
}
}
I_unlock_mutex(pool_mutex);
}
return id;
}
static int
Worker (
Link link
){
Thread th;
th = link->data;
(*th->entry)(th->userdata);
if (SDL_AtomicGet(&i_threads_running))
{
I_lock_mutex(&i_thread_pool_mutex);
{
if (SDL_AtomicGet(&i_threads_running))
{
SDL_DetachThread(th->thread);
Free_link(&i_thread_pool, link);
}
}
I_unlock_mutex(i_thread_pool_mutex);
}
return 0;
}
void
I_spawn_thread (
const char * name,
I_thread_fn entry,
void * userdata
){
Link link;
Thread th;
th = malloc(sizeof *th);
if (! th)
abort();/* this is pretty GNU of me */
th->entry = entry;
th->userdata = userdata;
I_lock_mutex(&i_thread_pool_mutex);
{
link = Insert_link(&i_thread_pool, New_link(th));
if (SDL_AtomicGet(&i_threads_running))
{
th->thread = SDL_CreateThread(
(SDL_ThreadFunction)Worker,
name,
link
);
if (! th->thread)
abort();
}
}
I_unlock_mutex(i_thread_pool_mutex);
}
int
I_thread_is_stopped (void)
{
return ( ! SDL_AtomicGet(&i_threads_running) );
}
void
I_start_threads (void)
{
i_thread_pool_mutex = SDL_CreateMutex();
i_mutex_pool_mutex = SDL_CreateMutex();
i_cond_pool_mutex = SDL_CreateMutex();
if (!(
i_thread_pool_mutex &&
i_mutex_pool_mutex &&
i_cond_pool_mutex
)){
abort();
}
}
void
I_stop_threads (void)
{
Link link;
Link next;
Thread th;
SDL_mutex * mutex;
SDL_cond * cond;
if (i_threads_running.value)
{
/* rely on the good will of thread-san */
SDL_AtomicSet(&i_threads_running, 0);
I_lock_mutex(&i_thread_pool_mutex);
{
for (
link = i_thread_pool;
link;
link = next
){
next = link->next;
th = link->data;
SDL_WaitThread(th->thread, NULL);
free(th);
free(link);
}
}
I_unlock_mutex(i_thread_pool_mutex);
for (
link = i_mutex_pool;
link;
link = next
){
next = link->next;
mutex = link->data;
SDL_DestroyMutex(mutex);
free(link);
}
for (
link = i_cond_pool;
link;
link = next
){
next = link->next;
cond = link->data;
SDL_DestroyCond(cond);
free(link);
}
SDL_DestroyMutex(i_thread_pool_mutex);
SDL_DestroyMutex(i_mutex_pool_mutex);
SDL_DestroyMutex(i_cond_pool_mutex);
}
}
void
I_lock_mutex (
I_mutex * anchor
){
SDL_mutex * mutex;
mutex = Identity(
&i_mutex_pool,
i_mutex_pool_mutex,
anchor,
(Create_fn)SDL_CreateMutex
);
if (SDL_LockMutex(mutex) == -1)
abort();
}
void
I_unlock_mutex (
I_mutex id
){
if (SDL_UnlockMutex(id) == -1)
abort();
}
void
I_hold_cond (
I_cond * cond_anchor,
I_mutex mutex_id
){
SDL_cond * cond;
cond = Identity(
&i_cond_pool,
i_cond_pool_mutex,
cond_anchor,
(Create_fn)SDL_CreateCond
);
if (SDL_CondWait(cond, mutex_id) == -1)
abort();
}
void
I_wake_one_cond (
I_cond * anchor
){
SDL_cond * cond;
cond = Identity(
&i_cond_pool,
i_cond_pool_mutex,
anchor,
(Create_fn)SDL_CreateCond
);
if (SDL_CondSignal(cond) == -1)
abort();
}
void
I_wake_all_cond (
I_cond * anchor
){
SDL_cond * cond;
cond = Identity(
&i_cond_pool,
i_cond_pool_mutex,
anchor,
(Create_fn)SDL_CreateCond
);
if (SDL_CondBroadcast(cond) == -1)
abort();
}

View file

@ -33,6 +33,7 @@
#endif
#include "../doomdef.h"
#include "../d_main.h"
#ifdef HWRENDER
#include "../hardware/r_opengl/r_opengl.h"
@ -154,11 +155,26 @@ boolean OglSdlSurface(INT32 w, INT32 h)
{
INT32 cbpp = cv_scr_depth.value < 16 ? 16 : cv_scr_depth.value;
static boolean first_init = false;
const char *gllogdir = NULL;
oglflags = 0;
if (!first_init)
{
if (!gllogstream)
{
gllogdir = D_Home();
#ifdef DEBUG_TO_FILE
#ifdef DEFAULTDIR
if (gllogdir)
gllogstream = fopen(va("%s/"DEFAULTDIR"/ogllog.txt",gllogdir), "wt");
else
#endif
gllogstream = fopen("./ogllog.txt", "wt");
#endif
}
gl_version = pglGetString(GL_VERSION);
gl_renderer = pglGetString(GL_RENDERER);
gl_extensions = pglGetString(GL_EXTENSIONS);

View file

@ -1173,7 +1173,10 @@ void I_StartupSound(void)
const char *sdrv_name = NULL;
#endif
#ifndef HAVE_MIXER
midi_disabled = digital_disabled = true;
#ifndef NO_MIDI
midi_disabled =
#endif
digital_disabled = true;
#endif
memset(channels, 0, sizeof (channels)); //Alam: Clean it

View file

@ -1435,7 +1435,7 @@ static boolean LoadSong(void *data, size_t lumplength, size_t selectpos)
if (fwrite(data, lumplength, 1, midfile) == 0)
{
CONS_Printf(M_GetText("Couldn't write music into file %s because %s\n"), tempname, strerror(ferror(midfile)));
CONS_Printf(M_GetText("Couldn't write music into file %s because %s\n"), tempname, M_FileError(midfile));
Z_Free(data);
fclose(midfile);
return false;

View file

@ -1797,10 +1797,12 @@ static void ST_doItemFinderIconsAndSound(void) // SRB2kart - unused.
//
static void ST_overlayDrawer(void)
{
/* SRB2kart doesn't need this stuff
//hu_showscores = auto hide score/time/rings when tab rankings are shown
if (!(hu_showscores && (netgame || multiplayer)))
{
K_drawKartHUD();
/* SRB2kart doesn't need this stuff
if (maptol & TOL_NIGHTS)
ST_drawNiGHTSHUD();
else
@ -1824,8 +1826,8 @@ static void ST_overlayDrawer(void)
)
ST_drawLives();
}
}
*/
}
// GAME OVER pic
/*if (G_GametypeUsesLives() && stplyr->lives <= 0 && !(hu_showscores && (netgame || multiplayer)))
@ -1845,8 +1847,6 @@ static void ST_overlayDrawer(void)
// Countdown timer for Race Mode
// ...moved to k_kart.c so we can take advantage of the LAPS_Y value
K_drawKartHUD();
/* SRB2kart doesn't need this stuff, I think
// If you are in overtime, put a big honkin' flashin' message on the screen.
if (G_BattleGametype() && cv_overtime.value

View file

@ -366,7 +366,7 @@ static lumpinfo_t* ResGetLumpsWad (FILE* handle, UINT16* nlmp, const char* filen
// read the header
if (fread(&header, 1, sizeof header, handle) < sizeof header)
{
CONS_Alert(CONS_ERROR, M_GetText("Can't read wad header because %s\n"), strerror(ferror(handle)));
CONS_Alert(CONS_ERROR, M_GetText("Can't read wad header because %s\n"), M_FileError(handle));
return NULL;
}
@ -389,7 +389,7 @@ static lumpinfo_t* ResGetLumpsWad (FILE* handle, UINT16* nlmp, const char* filen
if (fseek(handle, header.infotableofs, SEEK_SET) == -1
|| fread(fileinfo, 1, i, handle) < i)
{
CONS_Alert(CONS_ERROR, M_GetText("Corrupt wadfile directory (%s)\n"), strerror(ferror(handle)));
CONS_Alert(CONS_ERROR, M_GetText("Corrupt wadfile directory (%s)\n"), M_FileError(handle));
free(fileinfov);
return NULL;
}
@ -410,7 +410,7 @@ static lumpinfo_t* ResGetLumpsWad (FILE* handle, UINT16* nlmp, const char* filen
handle) < sizeof realsize)
{
I_Error("corrupt compressed file: %s; maybe %s", /// \todo Avoid the bailout?
filename, strerror(ferror(handle)));
filename, M_FileError(handle));
}
realsize = LONG(realsize);
if (realsize != 0)
@ -548,7 +548,7 @@ static lumpinfo_t* ResGetLumpsZip (FILE* handle, UINT16* nlmp)
fseek(handle, -4, SEEK_CUR);
if (fread(&zend, 1, sizeof zend, handle) < sizeof zend)
{
CONS_Alert(CONS_ERROR, "Corrupt central directory (%s)\n", strerror(ferror(handle)));
CONS_Alert(CONS_ERROR, "Corrupt central directory (%s)\n", M_FileError(handle));
return NULL;
}
numlumps = zend.entries;
@ -565,7 +565,7 @@ static lumpinfo_t* ResGetLumpsZip (FILE* handle, UINT16* nlmp)
if (fread(zentry, 1, sizeof(zentry_t), handle) < sizeof(zentry_t))
{
CONS_Alert(CONS_ERROR, "Failed to read central directory (%s)\n", strerror(ferror(handle)));
CONS_Alert(CONS_ERROR, "Failed to read central directory (%s)\n", M_FileError(handle));
Z_Free(lumpinfo);
free(zentry);
return NULL;
@ -585,7 +585,7 @@ static lumpinfo_t* ResGetLumpsZip (FILE* handle, UINT16* nlmp)
fullname = malloc(zentry->namelen + 1);
if (fgets(fullname, zentry->namelen + 1, handle) != fullname)
{
CONS_Alert(CONS_ERROR, "Unable to read lumpname (%s)\n", strerror(ferror(handle)));
CONS_Alert(CONS_ERROR, "Unable to read lumpname (%s)\n", M_FileError(handle));
Z_Free(lumpinfo);
free(zentry);
free(fullname);
@ -1319,8 +1319,8 @@ size_t W_ReadLumpHeaderPwad(UINT16 wad, UINT16 lump, void *dest, size_t size, si
{
size = 0;
zerr(zErr);
(void)inflateEnd(&strm);
}
(void)inflateEnd(&strm);
}
else
{