Compare commits

...
Author SHA1 Message Date
alufolie91 3f68b0f8c1 OpenGL: prefer GL_RGBA for water screen copy
as per recommended https://wikis.khronos.org/opengl/Common_Mistakes
2026-10-01 19:30:35 +02:00
alufolie91 938c95c80d Merge branch 'Saturn-Next' into waterrefract 2026-08-23 03:30:14 +02:00
alufolie91 1552b1808f "about" 2026-08-21 16:51:04 +02:00
alufolie91 fd349e2b37 netsync mobj pmomz in non vanilla compat builds
may help with some join desynchs
2026-08-18 17:39:19 +02:00
alufolie91 0cf1cabcc2 basic 32 player support
can just be enabled per MAXPLAYERS define in doomdef
this will also auto undefine COMPAT_VANILLA
no support for tab rankings or intermission rankings at all yet
will port those over eventually from saturn 32p or blankart and clean stuff up
please note this may have bugs since not everything is ported over yet
2026-08-18 17:39:19 +02:00
alufolie91 bcbe765b9d fix potential buffer underflow in portal handling
P_FindSpecialLineFromTag may return -1 in some cases
2026-08-17 19:19:51 +02:00
alufolie91 eca3effb3b raise version to v10
was originally be 9.3 but this update is too massive to be a minor version update
2026-08-17 18:47:42 +02:00
Gustaf Alhäll f1380a276e Fix buffer overflow when running map scripts 2026-08-17 18:43:08 +02:00
James R 8ffeab1646 Reset wait period for COM_BufInsertText 2026-08-17 16:39:27 +02:00
alufolie91 2eb175c356 few more smaller code cleanups 2026-08-17 16:39:23 +02:00
alufolie91 4e606fc7de fix indentation 2026-08-10 15:50:35 +02:00
Gustaf Alhäll c5116dea1a Add support for OpenBSD 2026-08-10 15:50:32 +02:00
alufolie91 924f9c2151 put directory changing and getting stuff into functions
from https://gitlab.com/kart-krew-dev/ring-racers/-/commit/7ef40f5d743bf6bf251e2edc89cda23e8fb36ee5

changed a bit so windows also can print the "warning" on failure
2026-08-10 15:38:31 +02:00
alufolie91 e0fa53e4df demonames apparently should write one less character
better keep it like this
2026-08-10 15:33:40 +02:00
alufolie91 eeb7d48a6f one more snprintf replacement for next branch 2026-08-09 17:51:39 +02:00
alufolie91 df291710d8 replace a few more length magic numbers with sizeof
just to be sure really
2026-08-09 17:49:34 +02:00
alufolie91 16577877d3 replace all sprintf with snprintf
some of this was taken from https://gitlab.com/kart-krew-dev/ring-racers/-/commit/59f23dfa181327ed5c00f55688840d39e3583569 so thx!
should fix apple clang warnings and is alot safer to have all this crap be bounded
theres prob alot more other stuff, and id love to eventually replace all the strcpy family functions with snprintf and equivalent
2026-08-09 17:49:31 +02:00
alufolie91 dfc7b5482e Merge branch 'Saturn-Next' into waterrefract 2026-07-20 16:45:18 +02:00
alufolie91 d258c920de Merge remote-tracking branch 'origin/Saturn-Next' into waterrefract 2026-07-20 11:47:31 +02:00
alufolie91 b3eac23977 dont draw refraction planes in wireframe mode
idk but this prob just fucks shit up
2026-07-17 22:43:31 +02:00
alufolie91 a114dd840b Merge branch 'Saturn-Next' into waterrefract 2026-07-17 22:43:28 +02:00
alufolie91 87fa339c8d tweak ripple and refraction shaders
this much much more closely resembles the software effect
i manually tweaked this until it looked very similar
its still not quite perfect probably, but in many cases its a close match
2026-07-17 08:39:26 +02:00
alufolie91 afb5b717fe smol change to GL_DrawWaterPolygon
this doesent need anything, its basically just a blank polygon, so can save some work and also pass less stuff to this
2026-07-16 20:20:45 +02:00
alufolie91 1a7dc425d2 remove horizonline handling for refraction planes
forgot those wont work with fofs anyways
still need to look into that sometime
but thisll save some perf
2026-07-16 18:31:45 +02:00
alufolie91 038e8f0864 clean up the refraction shader a bit
most stuff wasnt needed, forgot to remove it earlier
2026-07-16 18:18:36 +02:00
alufolie91 8ac506bf35 change how water refraction is handled
split it into its own pass
we will draw "refraction planes" before drawing anything translucent
this way we wont cause any draw order issues or anything like that
this is also a bit faster and more sane than the other approach
only caveat: translucent stuff behind water planes is unaffected by refraction
but better than it was before, and sure better than trying to copy the screen per plane or shit like that lol
like this, this should be mostly feasible to actually use, the skybox water stuff kinda was a non issue since i noticed even just normal water does not draw over the map geometry (must have misremembered that part since software does do that), but still might be worth looking into at some point
2026-07-16 17:57:55 +02:00
alufolie91 6cf2561dd3 dedupe GL_DrawWaterPolygon 2026-07-16 17:57:52 +02:00
alufolie91 3e459d4a21 WIP: OpenGL water refraction
tries to replicate the effect from software renderer
this is quite a mess, but finally feel like pushing this since i finally figured out the depth testing stuff
this still has some issues:
-map geometry in front of skybox water will just draw over it completely (not super sure how to fix this other than deferring water rendering after rendering both skybox and normal scene)
-translucent geometry is not included in refraction (and may draw in front of it?), software also suffers from this in certain cases, i just hope its not that visible

this really needs a cleanup at some point
and due to how this is setup for floor and ceiling planes this also costs quite a lot of gpu time (atleast on the cpu side this costs barely anything)
2026-07-16 17:57:46 +02:00
61 changed files with 926 additions and 486 deletions

No files matched your search

+1 -1
View File
@@ -143,7 +143,7 @@ const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
}
case 'p': {
char buff[4*sizeof(void *) + 8]; /* should be enough space for a `%p' */
sprintf(buff, "%p", va_arg(argp, void *));
snprintf(buff, sizeof(buff), "%p", va_arg(argp, void *));
pushstr(L, buff);
break;
}
+6 -6
View File
@@ -776,23 +776,23 @@ static int str_format (lua_State *L) {
strfrmt = scanformat(L, strfrmt, form);
switch (*strfrmt++) {
case 'c': {
sprintf(buff, form, (int)luaL_checknumber(L, arg));
snprintf(buff, sizeof(buff), form, (int)luaL_checknumber(L, arg));
break;
}
case 'd': case 'i': {
addintlen(form);
sprintf(buff, form, (LUA_INTFRM_T)luaL_checknumber(L, arg));
snprintf(buff, sizeof(buff), form, (LUA_INTFRM_T)luaL_checknumber(L, arg));
break;
}
case 'o': case 'u': case 'x': case 'X': {
addintlen(form);
sprintf(buff, form, (unsigned LUA_INTFRM_T)luaL_checknumber(L, arg));
snprintf(buff, sizeof(buff), form, (unsigned LUA_INTFRM_T)luaL_checknumber(L, arg));
break;
}
case 'e': case 'E': case 'f':
case 'g': case 'G': {
lua_Number n = luaL_checknumber(L, arg);
sprintf(buff, form, (double)n);
lua_Number n = luaL_checknumber(L, arg);
snprintf(buff, sizeof(buff), form, (double)n);
break;
}
case 'q': {
@@ -810,7 +810,7 @@ static int str_format (lua_State *L) {
continue; /* skip the `addsize' at the end */
}
else {
sprintf(buff, form, s);
snprintf(buff, sizeof(buff), form, s);
break;
}
}
+1 -1
View File
@@ -536,7 +536,7 @@
#define LUA_NUMBER_SCAN "%d"
#define LUA_NUMBER_FMT "%d"
#endif
#define lua_number2str(s,n) sprintf((s), LUA_NUMBER_FMT, (n))
#define lua_number2str(s,n) snprintf((s), LUAI_MAXNUMBER2STR, LUA_NUMBER_FMT, (n))
#define LUAI_MAXNUMBER2STR 12 /* 10 digits, sign, and \0 */
#define lua_str2number(s,p) ({ \
long nmr = strtol((s), (p), 10); \
+42 -15
View File
@@ -113,18 +113,29 @@ static vsbuf_t com_text; // variable sized buffer
* \param ptext The text to add.
* \sa COM_BufInsertText
*/
void COM_BufAddText(const char *ptext)
void COM_BufAddTextEx(const char *ptext, size_t plen)
{
size_t l;
char *text;
l = strlen(ptext);
if (plen == 0)
plen = strlen(ptext);
text = Z_Malloc(sizeof(char) * (plen+1), PU_STATIC, NULL);
memcpy(text, ptext, plen);
text[plen] = '\0';
l = strlen(text);
if (com_text.cursize + l >= com_text.maxsize)
{
CONS_Alert(CONS_WARNING, M_GetText("Command buffer full!\n"));
return;
}
VS_Write(&com_text, ptext, l);
VS_Write(&com_text, text, l);
Z_Free(text);
}
/** Adds command text and executes it immediately.
@@ -132,8 +143,10 @@ void COM_BufAddText(const char *ptext)
* \param ptext The text to execute. A newline is automatically added.
* \sa COM_BufAddText
*/
void COM_BufInsertText(const char *ptext)
void COM_BufInsertTextEx(const char *ptext, size_t plen)
{
const INT32 old_wait = com_wait;
char *temp = NULL;
size_t templen;
@@ -145,10 +158,14 @@ void COM_BufInsertText(const char *ptext)
VS_Clear(&com_text);
}
com_wait = 0;
// add the entire text of the file (or alias)
COM_BufAddText(ptext);
COM_BufAddTextEx(ptext, plen);
COM_BufExecute(); // do it right away
com_wait += old_wait;
// add the copied off data
if (templen)
{
@@ -159,8 +176,7 @@ void COM_BufInsertText(const char *ptext)
/** Progress the wait timer and flush waiting console commands when ready.
*/
void
COM_BufTicker(void)
void COM_BufTicker(void)
{
if (com_wait)
{
@@ -1596,7 +1612,9 @@ void CV_SaveNetVars(UINT8 **p, boolean isdemorecording)
// send only changed cvars ...
// the client will reset all netvars to default before loading
WRITEUINT16(*p, 0x0000);
for (cvar = consvar_vars; cvar; cvar = cvar->next)
{
if (((cvar->flags & CV_NETVAR) && !CV_IsSetToDefault(cvar)) || (isdemorecording && cvar->netid == cv_numlaps.netid))
{
WRITEUINT16(*p, cvar->netid);
@@ -1614,7 +1632,7 @@ void CV_SaveNetVars(UINT8 **p, boolean isdemorecording)
else
{
char buf[9];
sprintf(buf, "%d", mapheaderinfo[gamemap - 1]->numlaps);
snprintf(buf, sizeof(buf), "%d", mapheaderinfo[gamemap - 1]->numlaps);
WRITESTRING(*p, buf);
}
}
@@ -1626,6 +1644,8 @@ void CV_SaveNetVars(UINT8 **p, boolean isdemorecording)
WRITEUINT8(*p, false);
++count;
}
}
WRITEUINT16(count_p, count);
}
@@ -1782,8 +1802,7 @@ void CV_StealthSet(consvar_t *var, const char *value)
void CV_StealthSetValue(consvar_t *var, INT32 value)
{
char val[32];
sprintf(val, "%d", value);
snprintf(val, sizeof(val), "%d", value);
CV_SetCVar(var, val, true);
}
@@ -1803,8 +1822,7 @@ void CV_Set(consvar_t *var, const char *value)
void CV_SetValue(consvar_t *var, INT32 value)
{
char val[32];
sprintf(val, "%d", value);
snprintf(val, sizeof(val), "%d", value);
CV_SetCVar(var, val, false);
}
@@ -2202,6 +2220,7 @@ void CV_SaveVariables(FILE *f)
consvar_t *cvar;
for (cvar = consvar_vars; cvar; cvar = cvar->next)
{
if (cvar->flags & CV_SAVE)
{
char stringtowrite[MAXTEXTCMD+1];
@@ -2210,15 +2229,23 @@ void CV_SaveVariables(FILE *f)
if (fastcmp(cvar->string, "MAX") || fastcmp(cvar->string, "MIN"))
{
if (cvar->flags & CV_FLOAT)
sprintf(stringtowrite, "%f", FixedToFloat(cvar->value));
{
snprintf(stringtowrite, sizeof(stringtowrite), "%f", FixedToFloat(cvar->value));
}
else
sprintf(stringtowrite, "%d", cvar->value);
{
snprintf(stringtowrite, sizeof(stringtowrite), "%d", cvar->value);
}
}
else
strcpy(stringtowrite, cvar->string);
{
strncpy(stringtowrite, cvar->string, sizeof(stringtowrite)-1);
stringtowrite[sizeof(stringtowrite)-1] = '\0';
}
fprintf(f, "%s \"%s\"\n", cvar->name, stringtowrite);
}
}
}
//============================================================================
+4 -2
View File
@@ -52,10 +52,12 @@ size_t COM_FirstOption(void);
const char *COM_CompleteCommand(const char *partial, INT32 skips);
// insert at queu (at end of other command)
void COM_BufAddText(const char *btext);
#define COM_BufAddText(s) COM_BufAddTextEx(s, 0)
void COM_BufAddTextEx(const char *ptext, size_t plen);
// insert in head (before other command)
void COM_BufInsertText(const char *btext);
#define COM_BufInsertText(s) COM_BufInsertTextEx(s, 0)
void COM_BufInsertTextEx(const char *ptext, size_t plen);
// don't bother inserting, just do immediately
void COM_ImmedExecute(const char *ptext);
+7 -7
View File
@@ -2097,7 +2097,7 @@ static void SV_SavedGame(void)
if (!cv_dumpconsistency.value)
return;
sprintf(tmpsave, "%s" PATHSEP TMPSAVENAME, srb2home);
snprintf(tmpsave, sizeof(tmpsave), "%s" PATHSEP TMPSAVENAME, srb2home);
// first save it in a malloced buffer
save.p = save.buffer = (UINT8 *)Z_Malloc(SAVEGAMESIZE, PU_STATIC, NULL);
@@ -2135,7 +2135,7 @@ static void CL_LoadReceivedSavegame(boolean reloading)
size_t length, decompressedlen;
char tmpsave[264];
sprintf(tmpsave, "%s" PATHSEP TMPSAVENAME, srb2home);
snprintf(tmpsave, sizeof(tmpsave), "%s" PATHSEP TMPSAVENAME, srb2home);
length = FIL_ReadFile(tmpsave, &save.buffer);
@@ -2214,7 +2214,7 @@ static void CL_ReloadReceivedSavegame(void)
for (i = 0; i < MAXPLAYERS; i++)
{
LUA_InvalidatePlayer(&players[i]);
sprintf(player_names[i], "Player %d", i + 1);
snprintf(player_names[i], MAXPLAYERNAME+1, "Player %d", i + 1);
}
CL_LoadReceivedSavegame(true);
@@ -2950,7 +2950,7 @@ static void CL_ConnectToServer(void)
tic_t asksent;
char tmpsave[264];
sprintf(tmpsave, "%s" PATHSEP TMPSAVENAME, srb2home);
snprintf(tmpsave, sizeof(tmpsave), "%s" PATHSEP TMPSAVENAME, srb2home);
filedownload.current = -1;
cl_mode = CL_SEARCHING;
@@ -3513,7 +3513,7 @@ void CL_RemovePlayer(INT32 playernum, INT32 reason)
player_muted[playernum] = false;
// Reset the name
sprintf(player_names[playernum], "Player %d", playernum+1);
snprintf(player_names[playernum], MAXPLAYERNAME+1, "Player %d", playernum+1);
player_name_changes[playernum] = 0;
@@ -4475,7 +4475,7 @@ void SV_ResetServer(void)
for (i = 0; i < MAXPLAYERS; i++)
{
LUA_InvalidatePlayer(&players[i]);
sprintf(player_names[i], "Player %d", i + 1);
snprintf(player_names[i], MAXPLAYERNAME+1, "Player %d", i + 1);
}
memset(player_name_changes, 0, sizeof(player_name_changes));
@@ -5534,7 +5534,7 @@ static void PT_WillResendGamestate(void)
CONS_Printf(M_GetText("Reloading game state...\n"));
sprintf(tmpsave, "%s" PATHSEP TMPSAVENAME, srb2home);
snprintf(tmpsave, sizeof(tmpsave), "%s" PATHSEP TMPSAVENAME, srb2home);
// Don't get a corrupt savegame error because tmpsave already exists
if (FIL_FileExists(tmpsave) && unlink(tmpsave) == -1)
+1 -1
View File
@@ -1245,7 +1245,7 @@ static void IdentifyVersion(void)
#endif
char tempsrb2path[256] = ".";
if (getcwd(tempsrb2path, 256) == NULL)
if (I_GetCwd(tempsrb2path, 256) == NULL)
strcpy(tempsrb2path, ".");
// get the current directory (possible problem on NT with "." as current dir)
+3 -1
View File
@@ -1315,7 +1315,9 @@ boolean D_CheckNetGame(void)
while (!debugfile && k < MAXPLAYERS)
{
k++;
sprintf(filename, "debug%d.txt", k);
snprintf(filename, sizeof(filename), "debug%d.txt", k);
debugfile = fopen(va("%s" PATHSEP "%s", srb2home, filename), "w");
}
+15 -11
View File
@@ -608,7 +608,7 @@ void D_RegisterServerCommands(void)
// Set default player names
// Monster Iestyn (12/08/19): not sure where else I could have actually put this, but oh well
for (i = 0; i < MAXPLAYERS; i++)
sprintf(player_names[i], "Player %d", 1 + i);
snprintf(player_names[i], sizeof(player_names[i]), "Player %d", 1 + i);
RegisterNetXCmd(XD_NAMEANDCOLOR, Got_NameAndColor);
RegisterNetXCmd(XD_WEAPONPREF, Got_WeaponPref);
@@ -1288,7 +1288,8 @@ static boolean EnsurePlayerNameIsGood(char *name, INT32 playernum)
else if (len == 1) // Agh!
{
// Last ditch effort...
sprintf(name, "%d", M_RandomKey(10));
snprintf(name, MAXPLAYERNAME+1, "%d", M_RandomKey(10));
if (!EnsurePlayerNameIsGood(name, playernum))
return false;
}
@@ -2342,11 +2343,12 @@ static char *ConcatCommandArgv(int start, int end)
if (!p)
I_Error("ConcatCommandArgv: Out of memory!\n");
--end;/* handle the final argument separately */
--end; /* handle the final argument separately */
for (i = start; i < end; ++i)
{
p += sprintf(p, "%s ", COM_Argv(i));
if (size - (p - final) > 0)
p += snprintf(p, size - (p - final), "%s ", COM_Argv(i));
}
/* at this point "end" is actually the last argument's position */
@@ -2760,11 +2762,11 @@ static void Command_ReplayMarker(void)
if (title)
{
snprintf(demo.titlename, 64, "%s [%i:%02d/%.5s]", title, G_TicsToMinutes(adjustedleveltime, false), G_TicsToSeconds(adjustedleveltime), modeattacking ? "Record Attack" : connectedservername);
snprintf(demo.titlename, sizeof(demo.titlename)-1, "%s [%i:%02d/%.5s]", title, G_TicsToMinutes(adjustedleveltime, false), G_TicsToSeconds(adjustedleveltime), modeattacking ? "Record Attack" : connectedservername);
Z_Free(title);
}
else
snprintf(demo.titlename, 64, "[%i:%02d/%.5s]", G_TicsToMinutes(adjustedleveltime, false), G_TicsToSeconds(adjustedleveltime), modeattacking ? "Record Attack" : connectedservername);
snprintf(demo.titlename, sizeof(demo.titlename)-1, "[%i:%02d/%.5s]", G_TicsToMinutes(adjustedleveltime, false), G_TicsToSeconds(adjustedleveltime), modeattacking ? "Record Attack" : connectedservername);
CONS_Printf("Replay will be saved!\n");
}
@@ -4361,13 +4363,13 @@ static void Got_RequestAddfilecmd(const UINT8 **cp, INT32 playernum)
char message[275];
if (toomany)
sprintf(message, M_GetText("Too many files loaded to add %s\n"), filename);
snprintf(message, sizeof(message), M_GetText("Too many files loaded to add %s\n"), filename);
else if (ncs == FS_NOTFOUND)
sprintf(message, M_GetText("The server doesn't have %s\n"), filename);
snprintf(message, sizeof(message), M_GetText("The server doesn't have %s\n"), filename);
else if (ncs == FS_MD5SUMBAD)
sprintf(message, M_GetText("Checksum mismatch on %s\n"), filename);
snprintf(message, sizeof(message), M_GetText("Checksum mismatch on %s\n"), filename);
else
sprintf(message, M_GetText("Unknown error finding wad file (%s)\n"), filename);
snprintf(message, sizeof(message), M_GetText("Unknown error finding wad file (%s)\n"), filename);
CONS_Printf("%s",message);
@@ -5201,8 +5203,10 @@ static void Command_Mapmd5_f(void)
{
INT32 i;
char md5tmp[33];
for (i = 0; i < 16; ++i)
sprintf(&md5tmp[i*2], "%02x", mapmd5[i]);
snprintf(&md5tmp[i*2], 3, "%02x", mapmd5[i]);
CONS_Printf("%s: %s\n", G_BuildMapName(gamemap), md5tmp);
}
else
+4 -1
View File
@@ -299,10 +299,13 @@ boolean CL_CheckDownloadable(void)
{
INT32 j;
char md5tmp[33];
for (j = 0; j < 16; j++)
sprintf(&md5tmp[j*2], "%02x", fileneeded[i].md5sum[j]);
snprintf(&md5tmp[j*2], 3, "%02x", fileneeded[i].md5sum[j]);
CONS_Printf("%s", md5tmp);
}
CONS_Printf("\n");
}
}
+49 -27
View File
@@ -542,7 +542,7 @@ void I_OutputMsg(const char *fmt, ...)
I_Error("I_OutputMsg: Out of memory!\n");
va_start(argptr, fmt);
vsprintf(txt, fmt, argptr);
vsnprintf(txt, len+1, fmt, argptr);
va_end(argptr);
#ifdef HAVE_TTF
@@ -550,7 +550,7 @@ void I_OutputMsg(const char *fmt, ...)
DEFAULTFONTBGR, DEFAULTFONTBGG, DEFAULTFONTBGB, DEFAULTFONTBGA, txt);
#endif
len = strlen(txt);
len = strnlen(txt, len+1);
#ifdef LOGMESSAGES
if (logstream)
@@ -968,14 +968,18 @@ void I_Sleep(UINT32 ms)
void I_SleepDuration(precise_t duration)
{
#if defined(__linux__) || defined(__FreeBSD__) || defined(__HAIKU__)
#if defined(__linux__) || defined(__FreeBSD__) || defined(__HAIKU__) || defined(__OpenBSD__)
UINT64 precision = I_GetPrecisePrecision();
struct timespec ts = {
.tv_sec = duration / precision,
.tv_nsec = duration * 1000000000 / precision % 1000000000,
};
int status;
#ifdef __OpenBSD__
do status = nanosleep(&ts, &ts);
#else
do status = clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, &ts);
#endif
while (status == EINTR);
#elif defined (MIN_SLEEP_DURATION_MS)
UINT64 precision = I_GetPrecisePrecision();
@@ -1053,7 +1057,7 @@ static void I_PrintSignal(INT32 signal_num, boolean core_dumped, char *signal_ms
sigmsg = ("SIGABRT - SRB2Kart-Saturn was terminated by an abort signal.");
break;
default:
sprintf(signal_msg, "Signal number %d", signal_num);
snprintf(signal_msg, 512, "Signal number %d", signal_num);
sigmsg = (core_dumped ? "Unknown signal" : signal_msg);
break;
}
@@ -1061,13 +1065,17 @@ static void I_PrintSignal(INT32 signal_num, boolean core_dumped, char *signal_ms
if (core_dumped)
{
if (sigmsg)
sprintf(signal_msg, "%s (core dumped)", sigmsg);
{
snprintf(signal_msg, 512, "%s (core dumped)", sigmsg);
}
else
{
strcat(signal_msg, " (core dumped)");
}
}
else
{
sprintf(signal_msg, "%s", sigmsg);
snprintf(signal_msg, 512, "%s", sigmsg);
}
}
@@ -1344,7 +1352,7 @@ FUNCNORETURN static ATTRNORETURN void newsignalhandler_Warn(const char *pr)
{
char text[128];
snprintf(text, sizeof text,
snprintf(text, sizeof(text),
"Error while setting up signal reporting: %s: %s",
pr,
strerror(errno)
@@ -1530,7 +1538,7 @@ FUNCIERROR void ATTRNORETURN I_Error(const char *error, ...)
if (errorcount > 20)
{
va_start(argptr, error);
vsnprintf(buffer, 8192, error, argptr);
vsnprintf(buffer, sizeof(buffer), error, argptr);
va_end(argptr);
I_OutputMsg("SRB2Kart %s Recursive Error", buffer);
@@ -1543,7 +1551,7 @@ FUNCIERROR void ATTRNORETURN I_Error(const char *error, ...)
// Display error message in the console before we start shutting it down
va_start(argptr, error);
vsnprintf(buffer, 8192, error, argptr);
vsnprintf(buffer, sizeof(buffer), error, argptr);
va_end(argptr);
I_OutputMsg("\nI_Error(): %s\n", buffer);
@@ -1764,7 +1772,8 @@ char *I_GetUserName(void)
}
}
}
strncpy(username, p, MAXPLAYERNAME);
snprintf(username, sizeof(username), "%s", p);
}
if (!fastcmp(username, ""))
@@ -1788,6 +1797,24 @@ INT32 I_mkdir(const char *dirname, INT32 unixright)
#endif
}
INT32 I_ChDir(const char *path)
{
#ifdef _WIN32
return (SetCurrentDirectoryA(path) ? 0 : -1);
#else
return chdir(path);
#endif
}
char *I_GetCwd(char *buf, size_t size)
{
#ifdef _WIN32
return (GetCurrentDirectoryA((DWORD)size, buf) ? buf : NULL);
#else
return getcwd(buf, size);
#endif
}
char *I_GetEnv(const char *name)
{
return getenv(name);
@@ -1820,28 +1847,23 @@ const char *I_ClipboardPaste(void)
*/
static boolean isWadPathOk(const char *path)
{
char *wad3path = (char*)(malloc(256));
char wad3path[256];
if (!wad3path)
return false;
sprintf(wad3path, pandf, path, WADKEYWORD);
snprintf(wad3path, sizeof(wad3path), pandf, path, WADKEYWORD);
if (FIL_ReadFileOK(wad3path))
{
free(wad3path);
return true;
}
free(wad3path);
return false;
}
static void pathonly(char *s)
static void pathonly(char *s, size_t size)
{
size_t j;
for (j = strlen(s); j != (size_t)-1; j--)
for (j = strnlen(s, size); j != (size_t)-1; j--)
{
if ((s[j] == '\\') || (s[j] == ':') || (s[j] == '/'))
{
@@ -1868,11 +1890,12 @@ static const char *searchWad(const char *searchDir)
static char tempsw[256] = "";
filestatus_t fstemp;
strcpy(tempsw, WADKEYWORD);
snprintf(tempsw, sizeof(tempsw), "%s", WADKEYWORD);
fstemp = filesearch(tempsw, searchDir, NULL, true, 20);
if (fstemp == FS_FOUND)
{
pathonly(tempsw);
pathonly(tempsw, sizeof(tempsw));
return tempsw;
}
@@ -1910,7 +1933,7 @@ static const char *locateWad(void)
#ifndef NOCWD
// examine current dir
strcpy(returnWadPath, ".");
snprintf(returnWadPath, sizeof(returnWadPath), "%s", ".");
I_OutputMsg(",%s", returnWadPath);
if (isWadPathOk(returnWadPath))
return NULL;
@@ -1922,7 +1945,7 @@ static const char *locateWad(void)
// examine user jart directory
if ((envstr = I_GetEnv("HOME")) != NULL)
{
sprintf(returnWadPath, "%s" PATHSEP DEFAULTDIR, envstr);
snprintf(returnWadPath, sizeof(returnWadPath), "%s" PATHSEP DEFAULTDIR, envstr);
CHECKWADPATH(returnWadPath);
}
#endif
@@ -1936,7 +1959,7 @@ static const char *locateWad(void)
// examine default dirs
for (i = 0; wadDefaultPaths[i]; i++)
{
strcpy(returnWadPath, wadDefaultPaths[i]);
snprintf(returnWadPath, sizeof(returnWadPath), "%s", wadDefaultPaths[i]);
CHECKWADPATH(returnWadPath);
}
@@ -1964,12 +1987,11 @@ const char *I_LocateWad(void)
// change to the directory where we found srb2.srb
#if defined (_WIN32)
waddir = _fullpath(NULL, waddir, MAX_PATH);
SetCurrentDirectoryA(waddir);
#else
waddir = realpath(waddir, NULL);
if (waddir == NULL || chdir(waddir) == -1)
I_OutputMsg("Couldn't change working directory\n");
#endif
if (waddir == NULL || I_ChDir(waddir) == -1)
I_OutputMsg("Couldn't change working directory\n");
}
return waddir;
+1 -1
View File
@@ -402,7 +402,7 @@ static void Discordrp_OnChange(void)
static void DRPC_GotServerIP(UINT32 address)
{
const unsigned char * p = (const unsigned char *)&address;
sprintf(self_ip, "%u.%u.%u.%u:%u", p[0], p[1], p[2], p[3], current_port);
snprintf(self_ip, IP_SIZE+1, "%u.%u.%u.%u:%u", p[0], p[1], p[2], p[3], current_port);
}
/*--------------------------------------------------
+4 -4
View File
@@ -130,8 +130,8 @@ extern char logfilename[1024];
#else
#define VERSION 1 // Game version
#define SUBVERSION 6 // more precise version number
#define VERSIONSTRING "Saturn v9.3"
#define VERSIONSTRINGW L"Saturn v9.3"
#define VERSIONSTRING "Saturn v10"
#define VERSIONSTRINGW L"Saturn v10"
#define SATURN_TESTING // comment out for saturn release builds!
@@ -604,8 +604,8 @@ extern const char *compdate, *comptime, *comprevision, *compbranch;
// undefine to enable fixes and features that are not vanilla compatible
#define COMPAT_VANILLA
// if we build with 32 player (or more!) support we dont need to care vanilla compat
#if MAXPLAYERS > 16
// if we build with 32 player (or more or less!) support we dont need to care about vanilla compat
#if MAXPLAYERS != 16
#undef COMPAT_VANILLA
#endif
+2 -1
View File
@@ -111,7 +111,8 @@ static fademask_t *F_GetFadeMask(UINT8 masknum, UINT8 scrnnum)
goto freemask;
// SRB2Kart: This suddenly triggers ERRORMODE now
//sprintf(&lumpname[4], "%.2hu%.2hu", (UINT16)masknum, (UINT16)scrnnum);
//snprintf(&lumpname[4], 3, "%.2hu%.2hu", (UINT16)masknum, (UINT16)scrnnum);
//lumpname[8] = 0;
lumpname[4] = '0'+(masknum/10);
lumpname[5] = '0'+(masknum%10);
+30 -30
View File
@@ -1723,11 +1723,11 @@ void G_BeginRecording(void)
// Print to a separate temp buffer instead of demo.titlename, so we can use it in M_TextInputSetString
if (title)
{
snprintf(demotitlename, 64, "%s - %s", title, modeattacking ? "Time Attack" : connectedservername);
snprintf(demotitlename, sizeof(demotitlename)-1, "%s - %s", title, modeattacking ? "Time Attack" : connectedservername);
Z_Free(title);
}
else
snprintf(demotitlename, 64, "%s", modeattacking ? "Time Attack" : connectedservername);
snprintf(demotitlename, sizeof(demotitlename)-1, "%s", modeattacking ? "Time Attack" : connectedservername);
// Init just in case it isn't initialized already
M_TextInputInit(&demo.titlenameinput, demo.titlename, sizeof(demo.titlename));
@@ -2212,7 +2212,7 @@ void G_LoadDemoInfo(menudemo_t *pdemo)
{
CONS_Alert(CONS_ERROR, M_GetText("Failed to read file '%s'.\n"), pdemo->filepath);
pdemo->type = MD_INVALID;
sprintf(pdemo->title, "INVALID REPLAY");
snprintf(pdemo->title, sizeof(pdemo->title), "INVALID REPLAY");
return;
}
@@ -2222,7 +2222,7 @@ void G_LoadDemoInfo(menudemo_t *pdemo)
{
CONS_Alert(CONS_ERROR, M_GetText("%s is not a SRB2Kart replay file.\n"), pdemo->filepath);
pdemo->type = MD_INVALID;
sprintf(pdemo->title, "INVALID REPLAY");
snprintf(pdemo->title, sizeof(pdemo->title), "INVALID REPLAY");
return;
}
@@ -2247,14 +2247,14 @@ void G_LoadDemoInfo(menudemo_t *pdemo)
#ifdef DEMO_COMPAT_100
case 0x0001:
pdemo->type = MD_OUTDATED;
sprintf(pdemo->title, "Legacy Replay");
snprintf(pdemo->title, sizeof(pdemo->title), "Legacy Replay");
break;
#endif
// too old, cannot support.
default:
CONS_Alert(CONS_ERROR, M_GetText("%s is an incompatible replay format and cannot be played.\n"), pdemo->filepath);
pdemo->type = MD_INVALID;
sprintf(pdemo->title, "INVALID REPLAY");
snprintf(pdemo->title, sizeof(pdemo->title), "INVALID REPLAY");
return;
}
@@ -2267,7 +2267,7 @@ void G_LoadDemoInfo(menudemo_t *pdemo)
{
CONS_Alert(CONS_ERROR, M_GetText("%s is the wrong type of recording and cannot be played.\n"), pdemo->filepath);
pdemo->type = MD_INVALID;
sprintf(pdemo->title, "INVALID REPLAY");
snprintf(pdemo->title, sizeof(pdemo->title), "INVALID REPLAY");
return;
}
@@ -2288,7 +2288,7 @@ void G_LoadDemoInfo(menudemo_t *pdemo)
{
CONS_Alert(CONS_ERROR, M_GetText("%s is a legacy multiplayer replay and cannot be played.\n"), pdemo->filepath);
pdemo->type = MD_INVALID;
sprintf(pdemo->title, "INVALID REPLAY");
snprintf(pdemo->title, sizeof(pdemo->title), "INVALID REPLAY");
return;
}
#endif
@@ -2522,7 +2522,7 @@ void G_LoadDemoTitle(menudemo_t *pdemo)
if (!handle)
{
CONS_Alert(CONS_ERROR, M_GetText("Failed to read file '%s'.\n"), pdemo->filepath);
sprintf(pdemo->title, "INVALID REPLAY");
snprintf(pdemo->title, sizeof(pdemo->title), "INVALID REPLAY");
return;
}
@@ -2534,7 +2534,7 @@ void G_LoadDemoTitle(menudemo_t *pdemo)
if (count < 96 || memcmp(info_p, DEMOHEADER, 12))
{
CONS_Alert(CONS_ERROR, M_GetText("%s is not a SRB2Kart replay file.\n"), pdemo->filepath);
sprintf(pdemo->title, "INVALID REPLAY");
snprintf(pdemo->title, sizeof(pdemo->title), "INVALID REPLAY");
return;
}
@@ -2563,13 +2563,13 @@ void G_LoadDemoTitle(menudemo_t *pdemo)
break;
#ifdef DEMO_COMPAT_100
case 0x0001:
sprintf(pdemo->title, "Legacy Replay");
snprintf(pdemo->title, sizeof(pdemo->title), "Legacy Replay");
break;
#endif
// too old, cannot support.
default:
CONS_Alert(CONS_ERROR, M_GetText("%s is an incompatible replay format and cannot be played.\n"), pdemo->filepath);
sprintf(pdemo->title, "INVALID REPLAY");
snprintf(pdemo->title, sizeof(pdemo->title), "INVALID REPLAY");
}
}
@@ -2633,7 +2633,7 @@ void G_DoPlayDemo(char *defdemoname)
//FIL_DefaultExtension(defdemoname, ".lmp");
if (!FIL_ReadFile(defdemoname, &demobuf.buffer))
{
snprintf(msg, 1024, M_GetText("Failed to read file '%s'.\n"), defdemoname);
snprintf(msg, sizeof(msg), M_GetText("Failed to read file '%s'.\n"), defdemoname);
CONS_Alert(CONS_ERROR, "%s", msg);
gameaction = ga_nothing;
M_StartMessage(msg, M_ReturnToTitleFromError, MM_EVENTHANDLER);
@@ -2645,7 +2645,7 @@ void G_DoPlayDemo(char *defdemoname)
// load demo resource from WAD
else if ((l = W_CheckNumForName(defdemoname)) == LUMPERROR)
{
snprintf(msg, 1024, M_GetText("Failed to read lump '%s'.\n"), defdemoname);
snprintf(msg, sizeof(msg), M_GetText("Failed to read lump '%s'.\n"), defdemoname);
CONS_Alert(CONS_ERROR, "%s", msg);
gameaction = ga_nothing;
M_StartMessage(msg, M_ReturnToTitleFromError, MM_EVENTHANDLER);
@@ -2666,7 +2666,7 @@ void G_DoPlayDemo(char *defdemoname)
if (memcmp(demobuf.p, DEMOHEADER, 12))
{
snprintf(msg, 1024, M_GetText("%s is not a SRB2Kart replay file.\n"), pdemoname);
snprintf(msg, sizeof(msg), M_GetText("%s is not a SRB2Kart replay file.\n"), pdemoname);
CONS_Alert(CONS_ERROR, "%s", msg);
M_StartMessage(msg, M_ReturnToTitleFromError, MM_EVENTHANDLER);
G_ResetDemoPlayback();
@@ -2692,7 +2692,7 @@ void G_DoPlayDemo(char *defdemoname)
#endif
// too old, cannot support.
default:
snprintf(msg, 1024, M_GetText("%s is an incompatible replay format and cannot be played.\n"), pdemoname);
snprintf(msg, sizeof(msg), M_GetText("%s is an incompatible replay format and cannot be played.\n"), pdemoname);
CONS_Alert(CONS_ERROR, "%s", msg);
M_StartMessage(msg, M_ReturnToTitleFromError, MM_EVENTHANDLER);
G_ResetDemoPlayback();
@@ -2703,7 +2703,7 @@ void G_DoPlayDemo(char *defdemoname)
if (memcmp(demobuf.p, "PLAY", 4))
{
snprintf(msg, 1024, M_GetText("%s is the wrong type of recording and cannot be played.\n"), pdemoname);
snprintf(msg, sizeof(msg), M_GetText("%s is the wrong type of recording and cannot be played.\n"), pdemoname);
CONS_Alert(CONS_ERROR, "%s", msg);
M_StartMessage(msg, M_ReturnToTitleFromError, MM_EVENTHANDLER);
G_ResetDemoPlayback();
@@ -2720,7 +2720,7 @@ void G_DoPlayDemo(char *defdemoname)
{
if (demoflags & DF_MULTIPLAYER)
{
snprintf(msg, 1024, M_GetText("%s is an alpha multiplayer replay and cannot be played.\n"), pdemoname);
snprintf(msg, sizeof(msg), M_GetText("%s is an alpha multiplayer replay and cannot be played.\n"), pdemoname);
CONS_Alert(CONS_ERROR, "%s", msg);
M_StartMessage(msg, M_ReturnToTitleFromError, MM_EVENTHANDLER);
G_ResetDemoPlayback();
@@ -2747,31 +2747,31 @@ void G_DoPlayDemo(char *defdemoname)
switch (error)
{
case DFILE_ERROR_NOTLOADED:
snprintf(msg, 1024,
snprintf(msg, sizeof(msg),
"Required files for this demo are not loaded.\n\nUse\n\"playdemo %s -addfiles\"\nto load them and play the demo.\n",
pdemoname);
break;
case DFILE_ERROR_OUTOFORDER:
snprintf(msg, 1024,
snprintf(msg, sizeof(msg),
"Required files for this demo are loaded out of order.\n\nUse\n\"playdemo %s -force\"\nto play the demo anyway.\n",
pdemoname);
break;
case DFILE_ERROR_INCOMPLETEOUTOFORDER:
snprintf(msg, 1024,
snprintf(msg, sizeof(msg),
"Required files for this demo are not loaded, and some are out of order.\n\nUse\n\"playdemo %s -addfiles\"\nto load needed files and play the demo.\n",
pdemoname);
break;
case DFILE_ERROR_CANNOTLOAD:
snprintf(msg, 1024,
snprintf(msg, sizeof(msg),
"Required files for this demo cannot be loaded.\n\nUse\n\"playdemo %s -force\"\nto play the demo anyway.\n",
pdemoname);
break;
case DFILE_ERROR_EXTRAFILES:
snprintf(msg, 1024,
snprintf(msg, sizeof(msg),
"You have additional files loaded beyond the demo's file list.\n\nUse\n\"playdemo %s -force\"\nto play the demo anyway.\n",
pdemoname);
break;
@@ -2821,7 +2821,7 @@ void G_DoPlayDemo(char *defdemoname)
// ...*map* not loaded?
if (!gamemap || (gamemap > NUMMAPS) || (W_CheckNumForName(G_BuildMapName(gamemap)) == LUMPERROR))
{
snprintf(msg, 1024, M_GetText("%s features a course that is not currently loaded.\n"), pdemoname);
snprintf(msg, sizeof(msg), M_GetText("%s features a course that is not currently loaded.\n"), pdemoname);
CONS_Alert(CONS_ERROR, "%s", msg);
M_StartMessage(msg, M_ReturnToTitleFromError, MM_EVENTHANDLER);
G_ResetDemoPlayback();
@@ -2853,7 +2853,7 @@ void G_DoPlayDemo(char *defdemoname)
// Skin not loaded?
if (!SetPlayerSkin(0, skin))
{
snprintf(msg, 1024, M_GetText("%s features a character that is not currently loaded.\n"), pdemoname);
snprintf(msg, sizeof(msg), M_GetText("%s features a character that is not currently loaded.\n"), pdemoname);
CONS_Alert(CONS_ERROR, "%s", msg);
M_StartMessage(msg, M_ReturnToTitleFromError, MM_EVENTHANDLER);
G_ResetDemoPlayback();
@@ -2863,7 +2863,7 @@ void G_DoPlayDemo(char *defdemoname)
// ...*map* not loaded?
if (!gamemap || (gamemap > NUMMAPS) || !mapheaderinfo[gamemap-1] || !(mapheaderinfo[gamemap-1]->menuflags & LF2_EXISTSHACK))
{
snprintf(msg, 1024, M_GetText("%s features a course that is not currently loaded.\n"), pdemoname);
snprintf(msg, sizeof(msg), M_GetText("%s features a course that is not currently loaded.\n"), pdemoname);
CONS_Alert(CONS_ERROR, "%s", msg);
M_StartMessage(msg, M_ReturnToTitleFromError, MM_EVENTHANDLER);
G_ResetDemoPlayback();
@@ -2886,7 +2886,7 @@ void G_DoPlayDemo(char *defdemoname)
// Sigh ... it's an empty demo.
if (*demobuf.p == DEMOMARKER)
{
snprintf(msg, 1024, M_GetText("%s contains no data to be played.\n"), pdemoname);
snprintf(msg, sizeof(msg), M_GetText("%s contains no data to be played.\n"), pdemoname);
CONS_Alert(CONS_ERROR, "%s", msg);
M_StartMessage(msg, M_ReturnToTitleFromError, MM_EVENTHANDLER);
G_ResetDemoPlayback();
@@ -2924,7 +2924,7 @@ void G_DoPlayDemo(char *defdemoname)
// Sigh ... it's an empty demo.
if (*demobuf.p == DEMOMARKER)
{
snprintf(msg, 1024, M_GetText("%s contains no data to be played.\n"), pdemoname);
snprintf(msg, sizeof(msg), M_GetText("%s contains no data to be played.\n"), pdemoname);
CONS_Alert(CONS_ERROR, "%s", msg);
M_StartMessage(msg, M_ReturnToTitleFromError, MM_EVENTHANDLER);
G_ResetDemoPlayback();
@@ -2973,7 +2973,7 @@ void G_DoPlayDemo(char *defdemoname)
if (modeattacking)
{
snprintf(msg, 1024, M_GetText("%s is a Record Attack replay with spectators, and is thus invalid.\n"), pdemoname);
snprintf(msg, sizeof(msg), M_GetText("%s is a Record Attack replay with spectators, and is thus invalid.\n"), pdemoname);
CONS_Alert(CONS_ERROR, "%s", msg);
M_StartMessage(msg, M_ReturnToTitleFromError, MM_EVENTHANDLER);
G_ResetDemoPlayback();
@@ -2985,7 +2985,7 @@ void G_DoPlayDemo(char *defdemoname)
if (modeattacking && numslots > 1)
{
snprintf(msg, 1024, M_GetText("%s is a Record Attack replay with multiple players, and is thus invalid.\n"), pdemoname);
snprintf(msg, sizeof(msg), M_GetText("%s is a Record Attack replay with multiple players, and is thus invalid.\n"), pdemoname);
CONS_Alert(CONS_ERROR, "%s", msg);
M_StartMessage(msg, M_ReturnToTitleFromError, MM_EVENTHANDLER);
G_ResetDemoPlayback();
+20 -10
View File
@@ -604,14 +604,18 @@ const char *G_BuildMapName(INT32 map)
}
if (map < 100 && map >= 0) // ...but why use signed integer in first place? idk but this prevents warning (and potential buffer overflow lol)
sprintf(&mapname[3], "%.2d", map);
{
snprintf(&mapname[3], sizeof(mapname)-3, "%.2d", map);
}
else
{
mapname[3] = (char)('A' + (char)((map - 100) / 36));
if ((map - 100) % 36 < 10)
mapname[4] = (char)('0' + (char)((map - 100) % 36));
else
mapname[4] = (char)('A' + (char)((map - 100) % 36) - 10);
mapname[5] = '\0';
}
@@ -2626,12 +2630,18 @@ mapthing_t *G_FindRaceStart(INT32 playernum)
// Just spawn there.
//return playerstarts[0];
#if MAXPLAYERS > 16
//this section courtesy of fickle - v1.1 battle royale
// screw collision chex
return playerstarts[pos % numcoopstarts];
#else
if (P_IsLocalPlayerNum(playernum))
{
CONS_Alert(CONS_WARNING, "Could not spawn at any Race starts!\n");
}
return NULL;
#endif
}
if (P_IsLocalPlayerNum(playernum))
@@ -3766,7 +3776,7 @@ void G_LoadGame(UINT32 slot, INT16 mapoverride)
startonmapnum = mapoverride;
#endif
sprintf(savename, savegamename, slot);
snprintf(savename, sizeof(savename), savegamename, slot);
length = FIL_ReadFile(savename, &save.buffer);
if (!length)
@@ -3778,7 +3788,7 @@ void G_LoadGame(UINT32 slot, INT16 mapoverride)
save.p = save.buffer;
memset(vcheck, 0, sizeof (vcheck));
sprintf(vcheck, "version %d", VERSION);
snprintf(vcheck, sizeof(vcheck), "version %d", VERSION);
if (!fastcmp((const char *)save.p, (const char *)vcheck))
{
@@ -3844,8 +3854,8 @@ void G_SaveGame(UINT32 savegameslot)
const char *backup;
savebuffer_t save = {};
sprintf(savename, savegamename, savegameslot);
backup = va("%s",savename);
snprintf(savename, sizeof(savename), savegamename, savegameslot);
backup = va("%s", savename);
// save during evaluation or credits? game's over, folks!
if (gamestate == GS_CREDITS || gamestate == GS_EVALUATION)
@@ -3863,8 +3873,8 @@ void G_SaveGame(UINT32 savegameslot)
return;
}
memset(name, 0, sizeof (name));
sprintf(name, "version %d", VERSION);
memset(name, 0, sizeof(name));
snprintf(name, sizeof(name), "version %d", VERSION);
WRITEMEM(save.p, name, VERSIONSIZE);
P_SaveGame(&save);
@@ -4093,12 +4103,12 @@ char *G_BuildMapTitle(INT32 mapnum)
if (!title)
return NULL;
sprintf(title, "%s", mapheaderinfo[mapnum-1]->lvlttl);
snprintf(title, len, "%s", mapheaderinfo[mapnum-1]->lvlttl);
if (zonetext)
sprintf(title + strlen(title), " %s", zonetext);
snprintf(title + strlen(title), len - strlen(title), " %s", zonetext);
if (actnum)
sprintf(title + strlen(title), " %s", actnum);
snprintf(title + strlen(title), len - strlen(title), " %s", actnum);
}
return title;
+2 -1
View File
@@ -1250,7 +1250,8 @@ const char *G_KeynumToString(INT32 keynum)
return keynames[j].name;
// create a name for unknown keys
sprintf(keynamestr, "KEY%d", keynum);
snprintf(keynamestr, sizeof(keynamestr), "KEY%d", keynum);
return keynamestr;
}
+6 -5
View File
@@ -346,15 +346,15 @@ static void SplitPoly (fdivline_t *dlnp, // splitting parametric line
}
// checks if any line is a portal or horizonline, for optimization
static inline void CheckForPortalsAndHorizonLines(seg_t *lseg, const line_t *line)
static inline void CheckForPortalsAndHorizonLines(boolean firstside, const line_t *line)
{
// portal check
if (!gl_maphasportals && lseg->side == 0 && line->special == PORTALSPECIAL)
if (!gl_maphasportals && firstside && line->special == PORTALSPECIAL)
{
// Find the other side!
INT32 line2 = P_FindSpecialLineFromTag(PORTALSPECIAL, line->tag, -1);
if (line == &lines[line2])
if (line2 >= 0 && line == &lines[line2])
line2 = P_FindSpecialLineFromTag(PORTALSPECIAL, line->tag, line2);
if (line2 >= 0) // found it!
@@ -397,7 +397,7 @@ static poly_t *CutOutSubsecPoly(seg_t *lseg, INT32 segcount, poly_t *poly)
if (!line)
continue;
CheckForPortalsAndHorizonLines(lseg, line);
CheckForPortalsAndHorizonLines(lseg->side == 0, line);
if (line->sidenum[1] != NO_INDEX)
{
@@ -581,7 +581,8 @@ static void loading_status(void)
I_OsPolling();
CON_Drawer();
sprintf(s, "%d%%", (++ls_percent)<<1);
snprintf(s, sizeof(s), "%d%%", (++ls_percent)<<1);
x = BASEVIDWIDTH/2;
y = BASEVIDHEIGHT/2;
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, levelfadecol); // Black background to match fade in effect
+2 -1
View File
@@ -555,7 +555,8 @@ static void HWR_FreePatchCache(boolean freeall)
callback = FreeColormapsCallback;
//Z_IterateTags(PU_PATCH, PU_PATCH_ROTATED, callback);
Z_IterateTags(PU_PATCH, PU_PATCH, callback);
//Z_IterateTags(PU_PATCH, PU_PATCH_LOWPRIORITY, callback); // we dont really need to free low priority patches here as P_FreeLevelState takes care of them
Z_IterateTag(PU_PATCH, callback);
Z_IterateTags(PU_SPRITE, PU_HUDGFX, callback);
}
+1
View File
@@ -191,6 +191,7 @@ enum
SHADER_SPRITE,
SHADER_MODEL,
SHADER_WATER,
SHADER_WATERREFRACT,
SHADER_FOG,
SHADER_SKY,
SHADER_PALETTE_POSTPROCESS,
+1
View File
@@ -39,6 +39,7 @@ void GL_EnableStencilTest(void);
void GL_DisableStencilTest(void);
void GL_DrawPolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, FBITFIELD PolyFlags);
void GL_DrawWaterPolygon(FOutVector *pOutVerts, FUINT iNumPts);
void GL_DrawIndexedTriangles(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, FBITFIELD PolyFlags, unsigned int *IndexArray);
void GL_Draw2DLine(F2DCoord *v1, F2DCoord *v2, RGBA_t Color);
+265 -8
View File
@@ -103,6 +103,8 @@ static constexpr INT32 bsp_culling_distances[] = {
// Performance stats
ps_metric_t ps_hw_nodesorttime = {};
ps_metric_t ps_hw_nodedrawtime = {};
ps_metric_t ps_hw_waterdrawtime = {};
ps_metric_t ps_hw_spritesorttime = {};
ps_metric_t ps_hw_spritedrawtime = {};
@@ -514,7 +516,7 @@ static FUINT HWR_CalcWallLight(FUINT lightnum, seg_t *seg, extracolormap_t *colo
const INT16 offset = (cv_glfakecontrast.value == 2) ? seg->hwLightOffset : ((INT16)seg->lightOffset * 8);
finallight += offset;
finallight = CLAMP(finallight, 0 , 255);
finallight = CLAMP(finallight, 0, 255);
}
return (FUINT)finallight;
@@ -532,7 +534,7 @@ static FUINT HWR_CalcSlopeLight(FUINT lightnum, pslope_t *slope, const sector_t
const INT16 offset = (cv_glfakecontrast.value == 2) ? slope->hwLightOffset : ((INT16)slope->lightOffset * 8);
finallight += (fof ? -offset : offset);
finallight = CLAMP(finallight, 0 , 255);
finallight = CLAMP(finallight, 0, 255);
}
return (FUINT)finallight;
@@ -712,7 +714,9 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool
if (PolyFlags & PF_Fog)
shader = SHADER_FOG;
else if (cv_ripplewater.value && (PolyFlags & PF_Ripple))
{
shader = SHADER_WATER;
}
else
shader = SHADER_FLOOR;
@@ -807,6 +811,164 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool
#undef SETUP3DVERT
}
// cut down version of HWR_RenderPlane
// which renders only the refracted scene in place of planes
// FIXME: we probably could just use stencil stuff for this
// but i hate messing with that
static void HWR_RenderRefractionPlane(subsector_t *subsector, extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight, sector_t *FOFsector)
{
FOutVector *v3d;
polyvertex_t *pv;
pslope_t *slope = NULL;
size_t nrPlaneVerts;
INT32 i;
float height; // constant y for all points on the convex flat polygon
static FOutVector *planeVerts = NULL;
static UINT16 numAllocedPlaneVerts = 0;
poly_t *planepoly = xsub->planepoly;
// no convex poly were generated for this subsector
if (!planepoly)
return;
nrPlaneVerts = planepoly->numpts;
if (nrPlaneVerts < 3) // not even a triangle ?
return;
const sector_t *sec = FOFsector;
// Get the slope pointer to simplify future code
if (!isceiling && sec->f_slope)
slope = sec->f_slope;
else if (isceiling && sec->c_slope)
slope = sec->c_slope;
height = FixedToFloat(fixedheight);
// Allocate plane-vertex buffer if we need to
if (!planeVerts || nrPlaneVerts > numAllocedPlaneVerts)
{
numAllocedPlaneVerts = (UINT16)nrPlaneVerts;
Z_Free(planeVerts);
Z_Malloc(numAllocedPlaneVerts * sizeof (FOutVector), PU_LEVEL, &planeVerts);
}
pv = planepoly->pts;
#define SETUP3DVERT(vert, vx, vy) {\
vert->s = 0.0f;\
vert->t = 0.0f;\
\
if (slope)\
{\
fixedheight = P_GetSlopeZAt(slope, FloatToFixed((vx)), FloatToFixed((vy)));\
height = FixedToFloat(fixedheight);\
}\
\
vert->x = (vx);\
vert->y = height;\
vert->z = (vy);\
\
}
for (i = 0, v3d = planeVerts; i < (INT32)nrPlaneVerts; i++, v3d++, pv++)
SETUP3DVERT(v3d, pv->x, pv->y);
GL_DrawWaterPolygon(planeVerts, nrPlaneVerts);
//FIXME: horizonlines with fofs dont work in gl for some reason!
(void)subsector;
/*if (gl_maphashorizonlines && subsector && cv_glhorizonlines.value)
{
// Horizon lines
FOutVector horizonpts[6];
float dist, vx, vy;
float x1, y1, xd, yd;
UINT8 numplanes, j;
vertex_t v; // For determining the closest distance from the line to the camera, to split render planes for minimum distortion;
static constexpr float renderdist = 27000.0f; // How far out to properly render the plane
static constexpr float farrenderdist = 32768.0f; // From here, raise plane to horizon level to fill in the line with some texture distortion
const seg_t *line = &segs[subsector->firstline];
for (i = 0; i < subsector->numlines; i++, line++)
{
if (line->polyseg)
continue;
line_t* ld = line->linedef;
// this check sucks and is a hotspot lel
if (LIKELY(ld->special != HORIZONSPECIAL))
continue;
if (R_PointOnSegSide(viewx, viewy, line) != 0)
continue;
P_ClosestPointOnLine(viewx, viewy, ld, &v);
dist = FixedToFloat(R_PointToDist(v.x, v.y));
x1 = (line->fv1.x);
y1 = (line->fv1.y);
xd = (line->fv2.x) - x1;
yd = (line->fv2.y) - y1;
// Based on the seg length and the distance from the line, split horizon into multiple poly sets to reduce distortion
dist = sqrtf((xd*xd) + (yd*yd)) / dist / 16.0f;
if (dist > 100.0f)
numplanes = 100;
else
numplanes = (UINT8)dist + 1;
for (j = 0; j < numplanes; j++)
{
// Left side
vx = x1 + xd * j / numplanes;
vy = y1 + yd * j / numplanes;
SETUP3DVERT((&horizonpts[1]), vx, vy);
dist = sqrtf(powf(vx - gl_viewx, 2) + powf(vy - gl_viewy, 2));
vx = (vx - gl_viewx) * renderdist / dist + gl_viewx;
vy = (vy - gl_viewy) * renderdist / dist + gl_viewy;
SETUP3DVERT((&horizonpts[0]), vx, vy);
// Right side
vx = x1 + xd * (j+1) / numplanes;
vy = y1 + yd * (j+1) / numplanes;
SETUP3DVERT((&horizonpts[2]), vx, vy);
dist = sqrtf(powf(vx - gl_viewx, 2) + powf(vy - gl_viewy, 2));
vx = (vx - gl_viewx) * renderdist / dist + gl_viewx;
vy = (vy - gl_viewy) * renderdist / dist + gl_viewy;
SETUP3DVERT((&horizonpts[3]), vx, vy);
// Horizon fills
vx = (horizonpts[0].x - gl_viewx) * farrenderdist / renderdist + gl_viewx;
vy = (horizonpts[0].z - gl_viewy) * farrenderdist / renderdist + gl_viewy;
SETUP3DVERT((&horizonpts[5]), vx, vy);
horizonpts[5].y = gl_viewz;
vx = (horizonpts[3].x - gl_viewx) * farrenderdist / renderdist + gl_viewx;
vy = (horizonpts[3].z - gl_viewy) * farrenderdist / renderdist + gl_viewy;
SETUP3DVERT((&horizonpts[4]), vx, vy);
horizonpts[4].y = gl_viewz;
// Draw
GL_DrawWaterPolygon(&Surf, horizonpts, 6, PF_NoTexture|PF_Ripple);
}
}
}
*/
#undef SETUP3DVERT
}
#ifdef WALLSPLATS
static void HWR_DrawSegsSplats(FSurfaceInfo * pSurf)
{
@@ -2306,7 +2468,7 @@ static inline void DoAddLine(seg_t* line, angle_t angle1, angle_t angle2)
// Find the other side!
INT32 line2 = P_FindSpecialLineFromTag(PORTALSPECIAL, line->linedef->tag, -1);
if (line->linedef == &lines[line2])
if (line2 >= 0 && line->linedef == &lines[line2])
line2 = P_FindSpecialLineFromTag(PORTALSPECIAL, line->linedef->tag, line2);
if (line2 >= 0) // found it!
@@ -4225,7 +4387,9 @@ static void HWR_RenderDrawNodes(void)
// Reversed order
for (i = 0; i < numdrawnodes; i++)
{
sortindex[i] = numdrawnodes - i - 1;
}
// The order is correct apart from planes in the same subsector.
// So scan the list and sort out these cases.
@@ -4301,7 +4465,6 @@ static void HWR_RenderDrawNodes(void)
HWR_RenderPolyObjectPlane(polyplane->polysector, polyplane->isceiling, polyplane->fixedheight, polyplane->blend, polyplane->lightlevel,
polyplane->lumpnum, polyplane->FOFSector, polyplane->alpha, polyplane->planecolormap);
}
break;
case DRAWNODE_WALL:
@@ -4325,6 +4488,89 @@ static void HWR_RenderDrawNodes(void)
drawnodes.clear(); // clear so our size is 0 again!
}
static void HWR_RenderRefractionWater(void)
{
// this basically just draws a refracted screen copy in the place of water planes
// best approach i can think of to handle translucent things being drawn behind water planes
// this means other translucent shit will appear "correctly" and does not cause any sorting issues
// caveat: anything translucent behind water planes will be unaffected by the refraction effect
// there just is no better way to do this unless we wanna trash performance to hell by doing a screen copy per water plane
// it "might" be possible to only partially copy the screen like the software renderer
// but that will be rather tricky to implement since we dont really have "screen bounds" we can use for this
// plus i also immensely suck at maths
static std::vector<gl_drawnode_t> waterdrawnodes;
const size_t numdrawnodes = drawnodes.size();
// no drawnodes...
if (!numdrawnodes)
return;
waterdrawnodes.reserve(DRAWNODES_INIT_SIZE/2); // surely there will be less water than other stuff, right?
// go through our drawnodes to pull out the water
// HWR_RenderDrawNodes will skip those
// we do this before since trying to capture
// anything translucent in the refraction is utter arse pain
for (size_t w = 0; w < numdrawnodes; w++)
{
gl_drawnode_t *drawnode = &drawnodes[w];
// gotta be a plane duh
if (drawnode->type != DRAWNODE_PLANE)
continue;
planeinfo_t *plane = &drawnode->u.plane;
// uh dont think we actually need this lol
// but better be safe for now
if (plane->alpha >= 255)
continue;
// this only applies to translucent water with ripple effect!
if (!(plane->blend & PF_Ripple))
continue;
waterdrawnodes.push_back(drawnodes[w]);
}
const size_t numwaterdrawnodes = waterdrawnodes.size();
// no water....
if (!numwaterdrawnodes)
return;
// this is probably a bit wasteful
// since we only copy the screen once
// but you might be able to see both planes not overlap if you look from a wonky angle
auto wotercompare = [](const void *p1, const void *p2)
{
const gl_drawnode_t *n1 = (const gl_drawnode_t *)p1;
const gl_drawnode_t *n2 = (const gl_drawnode_t *)p2;
return abs(n2->u.plane.fixedheight - viewz) -
abs(n1->u.plane.fixedheight - viewz);
};
qs22j(waterdrawnodes.data(), waterdrawnodes.size(), sizeof(gl_drawnode_t), wotercompare);
GL_SetTransform(&atransform);
GL_CopyMainFramebufferTexture();
GL_CopyMainFramebufferDepth();
// now finally render the refraction planes
for (auto &drawnode : waterdrawnodes)
{
planeinfo_t *plane = &drawnode.u.plane;
gl_frontsector = NULL;
HWR_RenderRefractionPlane(NULL, plane->xsub, plane->isceiling, plane->fixedheight, plane->FOFSector);
}
waterdrawnodes.clear();
}
// --------------------------------------------------------------------------
// Draw all vissprites
// --------------------------------------------------------------------------
@@ -5601,9 +5847,20 @@ static void HWR_RenderViewpoint(gl_portal_t *rootportal, int stencil_level, bool
HWR_DrawSprites<DrawSpritesType::kSprites>();
PS_STOP_TIMING(ps_hw_spritedrawtime);
ps_numdrawnodes.value.i = 0;
ps_hw_nodesorttime.value.p = 0;
ps_hw_nodedrawtime.value.p = 0;
ps_numdrawnodes.value.i = 0;
ps_hw_nodesorttime.value.p = 0;
ps_hw_nodedrawtime.value.p = 0;
ps_hw_waterdrawtime.value.p = 0;
// thisll be a good mess making this toggable
if (cv_ripplewater.value && HWR_UseShader() && !wireframe) // dont need this without shaders do we
{
// should we not do this during portal render?
// wonder how bad the perf will be....
PS_START_TIMING(ps_hw_waterdrawtime);
HWR_RenderRefractionWater();
PS_STOP_TIMING(ps_hw_waterdrawtime);
}
HWR_RenderDrawNodes();
@@ -6121,7 +6378,7 @@ static boolean HWR_WipeCheck(UINT8 wipenum, UINT8 scrnnum)
}
// puts the numbers into the lumpname
sprintf(&lumpname[4], "%.2hu%.2hu", (UINT16)wipenum, (UINT16)scrnnum);
snprintf(&lumpname[4], sizeof(lumpname) - 4, "%.2hu%.2hu", (UINT16)wipenum, (UINT16)scrnnum);
wipelumpnum = W_CheckNumForName(lumpname);
// again, shouldn't be here really
+1
View File
@@ -68,6 +68,7 @@ enum
// Performance stats
extern ps_metric_t ps_hw_nodesorttime;
extern ps_metric_t ps_hw_nodedrawtime;
extern ps_metric_t ps_hw_waterdrawtime;
extern ps_metric_t ps_hw_spritesorttime;
extern ps_metric_t ps_hw_spritedrawtime;
+2 -2
View File
@@ -1247,7 +1247,7 @@ void HWR_DrawMD2(gl_vissprite_t *spr)
if (!md2->model)
{
CONS_Debug(DBG_RENDER, "Loading model... (%s, %s)", sprnames[spr->mobj->sprite], md2->filename);
sprintf(filename, "mdls/%s", md2->filename);
snprintf(filename, sizeof(filename), "mdls/%s", md2->filename);
md2->model = md2_readModel(filename);
if (md2->model)
@@ -1483,7 +1483,7 @@ void HWR_Draw2DModel(md2_t *md2, INT32 x, INT32 y, INT32 skinnum, skincolors_t c
{
char filename[64];
CONS_Debug(DBG_RENDER, "Loading model... (%s)\n", md2->filename);
sprintf(filename, "mdls/%s", md2->filename);
snprintf(filename, sizeof(filename), "mdls/%s", md2->filename);
md2->model = md2_readModel(filename);
if (md2->model)
+1 -57
View File
@@ -275,13 +275,6 @@ model_t *MD2_LoadModel(const char *fileName, int ztag, boolean useFloat)
return NULL;
retModel = (model_t*)Z_Calloc(sizeof(model_t), ztag, NULL);
//size_t fileLen;
//int i, j;
//size_t namelen;
//char *texturefilename;
texPos = strchr(fileName, '/');
if (texPos)
@@ -318,8 +311,6 @@ model_t *MD2_LoadModel(const char *fileName, int ztag, boolean useFloat)
retModel->numMeshes = 1; // MD2 only has one mesh
retModel->meshes = (mesh_t*)Z_Calloc(sizeof(mesh_t) * retModel->numMeshes, ztag, NULL);
retModel->meshes[0].numFrames = header->numFrames;
// const float WUNITS = 1.0f;
// float dataScale = WUNITS;
// Tris and ST are simple structures that can be straight-copied
tris = (md2triangle_t*)&buffer[header->offsetTris];
@@ -355,47 +346,6 @@ model_t *MD2_LoadModel(const char *fileName, int ztag, boolean useFloat)
retModel->materials[t].specular[3] = 1.0f;
retModel->materials[t].shininess = 0.0f;
retModel->materials[t].spheremap = false;
/* retModel->materials[t].texture = Texture::ReadTexture((char*)texturefilename, ZT_TEXTURE);
if (!systemSucks)
{
// Check for a normal map...??
char openfilename[1024];
char normalMapName[1024];
strcpy(normalMapName, texturefilename);
size_t len = strlen(normalMapName);
char *ptr = &normalMapName[len];
ptr--; // z
ptr--; // u
ptr--; // b
ptr--; // .
*ptr++ = '_';
*ptr++ = 'n';
*ptr++ = '.';
*ptr++ = 'b';
*ptr++ = 'u';
*ptr++ = 'z';
*ptr++ = '\0';
sprintf(openfilename, "%s/%s", "textures", normalMapName);
// Convert backslashes to forward slashes
for (int k = 0; k < 1024; k++)
{
if (openfilename[k] == '\0')
break;
if (openfilename[k] == '\\')
openfilename[k] = '/';
}
Resource::resource_t *res = Resource::Open(openfilename);
if (res)
{
Resource::Close(res);
retModel->materials[t].lightmap = Texture::ReadTexture(normalMapName, ZT_TEXTURE);
}
}*/
}
retModel->meshes[0].numTriangles = header->numTris;
@@ -425,15 +375,11 @@ model_t *MD2_LoadModel(const char *fileName, int ztag, boolean useFloat)
md2frame_t *framePtr = (md2frame_t*)ptr;
retModel->meshes[0].tinyframes[i].vertices = (short*)Z_Malloc(sizeof(short) * 3 * header->numXYZ, ztag, NULL);
retModel->meshes[0].tinyframes[i].normals = (char*)Z_Malloc(sizeof(char) * 3 * header->numXYZ, ztag, NULL);
// if (retModel->materials[0].lightmap)
// retModel->meshes[0].tinyframes[i].tangents = (char*)malloc(sizeof(char));//(char*)Z_Malloc(sizeof(char)*3*header->numVerts, ztag);
retModel->meshes[0].indices = (unsigned short*)Z_Malloc(sizeof(unsigned short) * 3 * header->numTris, ztag, NULL);
vertptr = retModel->meshes[0].tinyframes[i].vertices;
normptr = retModel->meshes[0].tinyframes[i].normals;
// tanptr = retModel->meshes[0].tinyframes[i].tangents;
retModel->meshes[0].tinyframes[i].material = &retModel->materials[0];
framePtr++; // Advance to vertex list
@@ -509,9 +455,7 @@ model_t *MD2_LoadModel(const char *fileName, int ztag, boolean useFloat)
md2frame_t *framePtr = (md2frame_t*)ptr;
retModel->meshes[0].frames[i].normals = (float*)Z_Malloc(sizeof(float) * 3 * header->numTris * 3, ztag, NULL);
retModel->meshes[0].frames[i].vertices = (float*)Z_Malloc(sizeof(float) * 3 * header->numTris * 3, ztag, NULL);
// if (retModel->materials[0].lightmap)
// retModel->meshes[0].frames[i].tangents = (float*)malloc(sizeof(float));//(float*)Z_Malloc(sizeof(float)*3*header->numTris*3, ztag);
//float *vertptr, *normptr;
normptr = (float*)retModel->meshes[0].frames[i].normals;
vertptr = (float*)retModel->meshes[0].frames[i].vertices;
trisPtr = tris;
+1 -79
View File
@@ -243,48 +243,6 @@ model_t *MD3_LoadModel(const char *fileName, int ztag, boolean useFloat)
mdShader[j].name[len-1] = 'z';
mdShader[j].name[len-2] = 'u';
mdShader[j].name[len-3] = 'b';
// Load material
/* retModel->materials[matCount].texture = Texture::ReadTexture(mdShader[j].name, ZT_TEXTURE);
if (!systemSucks)
{
// Check for a normal map...??
char openfilename[1024];
char normalMapName[1024];
strcpy(normalMapName, mdShader[j].name);
len = strlen(normalMapName);
char *ptr = &normalMapName[len];
ptr--; // z
ptr--; // u
ptr--; // b
ptr--; // .
*ptr++ = '_';
*ptr++ = 'n';
*ptr++ = '.';
*ptr++ = 'b';
*ptr++ = 'u';
*ptr++ = 'z';
*ptr++ = '\0';
sprintf(openfilename, "%s/%s", "textures", normalMapName);
// Convert backslashes to forward slashes
for (int k = 0; k < 1024; k++)
{
if (openfilename[k] == '\0')
break;
if (openfilename[k] == '\\')
openfilename[k] = '/';
}
Resource::resource_t *res = Resource::Open(openfilename);
if (res)
{
Resource::Close(res);
retModel->materials[matCount].lightmap = Texture::ReadTexture(normalMapName, ZT_TEXTURE);
}
}*/
}
retModel->meshes[i].numFrames = mdS->numFrames;
@@ -305,19 +263,15 @@ model_t *MD3_LoadModel(const char *fileName, int ztag, boolean useFloat)
{
short *vertptr;
char *normptr;
// char *tanptr;
int k;
md3Vertex *mdV = (md3Vertex*)((char*)mdS + mdS->offsetXYZNormal + (mdS->numVerts*j*sizeof(md3Vertex)));
retModel->meshes[i].tinyframes[j].vertices = (short*)Z_Malloc(sizeof(short)*3*mdS->numVerts, ztag, NULL);
retModel->meshes[i].tinyframes[j].normals = (char*)Z_Malloc(sizeof(char)*3*mdS->numVerts, ztag, NULL);
// if (retModel->materials[0].lightmap)
// retModel->meshes[i].tinyframes[j].tangents = (char*)malloc(sizeof(char));//(char*)Z_Malloc(sizeof(char)*3*mdS->numVerts, ztag);
retModel->meshes[i].indices = (unsigned short*)Z_Malloc(sizeof(unsigned short) * 3 * mdS->numTriangles, ztag, NULL);
vertptr = retModel->meshes[i].tinyframes[j].vertices;
normptr = retModel->meshes[i].tinyframes[j].normals;
// tanptr = retModel->meshes[i].tinyframes[j].tangents;
retModel->meshes[i].tinyframes[j].material = &retModel->materials[i];
for (k = 0; k < mdS->numVerts; k++)
@@ -384,8 +338,7 @@ model_t *MD3_LoadModel(const char *fileName, int ztag, boolean useFloat)
md3Vertex *mdV = (md3Vertex*)((char*)mdS + mdS->offsetXYZNormal + (mdS->numVerts*j*sizeof(md3Vertex)));
retModel->meshes[i].frames[j].vertices = (float*)Z_Malloc(sizeof(float)*3*mdS->numTriangles*3, ztag, NULL);
retModel->meshes[i].frames[j].normals = (float*)Z_Malloc(sizeof(float)*3*mdS->numTriangles*3, ztag, NULL);
// if (retModel->materials[i].lightmap)
// retModel->meshes[i].frames[j].tangents = (float*)malloc(sizeof(float));//(float*)Z_Malloc(sizeof(float)*3*mdS->numTriangles*3, ztag);
vertptr = retModel->meshes[i].frames[j].vertices;
normptr = retModel->meshes[i].frames[j].normals;
retModel->meshes[i].frames[j].material = &retModel->materials[i];
@@ -471,37 +424,6 @@ model_t *MD3_LoadModel(const char *fileName, int ztag, boolean useFloat)
}
}
}
/*
// Tags?
retModel->numTags = mdh->numTags;
retModel->maxNumFrames = mdh->numFrames;
retModel->tags = (tag_t*)Z_Calloc(sizeof(tag_t) * retModel->numTags * mdh->numFrames, ztag);
md3Tag *mdTag = (md3Tag*)&buffer[mdh->offsetTags];
tag_t *curTag = retModel->tags;
for (i = 0; i < mdh->numFrames; i++)
{
int j;
for (j = 0; j < retModel->numTags; j++, mdTag++)
{
strcpys(curTag->name, mdTag->name, sizeof(curTag->name) / sizeof(char));
curTag->transform.m[0][0] = mdTag->axis[0];
curTag->transform.m[0][1] = mdTag->axis[1];
curTag->transform.m[0][2] = mdTag->axis[2];
curTag->transform.m[1][0] = mdTag->axis[3];
curTag->transform.m[1][1] = mdTag->axis[4];
curTag->transform.m[1][2] = mdTag->axis[5];
curTag->transform.m[2][0] = mdTag->axis[6];
curTag->transform.m[2][1] = mdTag->axis[7];
curTag->transform.m[2][2] = mdTag->axis[8];
curTag->transform.m[3][0] = mdTag->origin[0] * WUNITS;
curTag->transform.m[3][1] = mdTag->origin[1] * WUNITS;
curTag->transform.m[3][2] = mdTag->origin[2] * WUNITS;
curTag->transform.m[3][3] = 1.0f;
Matrix::Rotate(&curTag->transform, 90.0f, &Vector::Xaxis);
curTag++;
}
}*/
free(buffer);
+3
View File
@@ -41,6 +41,9 @@ static struct {
// Water shader
{GLSL_DEFAULT_VERTEX_SHADER, GLSL_WATER_FRAGMENT_SHADER},
// Water refraction shader
{GLSL_DEFAULT_VERTEX_SHADER, GLSL_WATERREFRACT_FRAGMENT_SHADER},
// Fog shader
{GLSL_DEFAULT_VERTEX_SHADER, GLSL_FOG_FRAGMENT_SHADER},
+38 -8
View File
@@ -243,23 +243,30 @@
// Water surface shader
//
// Mostly guesstimated, rather than the rest being built off Software science.
// Still needs to distort things underneath/around the water...
// Still needs to distort things underneath/around the water... // huehueuehuehue
//
// readjusted to match software much more closely
#define GLSL_WATER_CONST \
"const float freq = 0.07;\n" \
"const float amp = 0.07;\n" \
"const float amp_t = 0.025;\n" \
"const float speed = 4.0;\n" \
"const float pi = 3.14159;\n" \
"const float falltresh = 0.007;\n" \
#define GLSL_WATER_TEXEL \
"float water_z = (gl_FragCoord.z / gl_FragCoord.w) / 2.0;\n" \
"float a = -pi * (water_z * freq) + (leveltime * speed);\n" \
"float sdistort = sin(a) * amp;\n" \
"float cdistort = cos(a) * amp;\n" \
"vec4 texel = texture2D(tex, vec2(gl_TexCoord[0].s - sdistort, gl_TexCoord[0].t - cdistort));\n"
"float falloff = 1.0 / (1.0 + water_z * falltresh);\n" \
"float distort = sin(a) * amp * falloff;\n" \
"vec4 texel = texture2D(tex, vec2(gl_TexCoord[0].s - distort, gl_TexCoord[0].t));\n" \
#define GLSL_WATER_FRAGMENT_SHADER \
"#version 120\n" \
GLSL_FLOOR_FUDGES \
"const float freq = 0.025;\n" \
"const float amp = 0.025;\n" \
"const float speed = 2.0;\n" \
"const float pi = 3.14159;\n" \
GLSL_WATER_CONST \
"#ifdef SRB2_PALETTE_RENDERING\n" \
"uniform sampler2D tex;\n" \
"uniform sampler3D palette_lookup_tex;\n" \
@@ -294,6 +301,29 @@
"}\n" \
"#endif\0"
// water refraction stuff
// this is probably complete shit but i dont care
// got the idea for depth testing from https://lettier.github.io/3d-game-shaders-for-beginners/screen-space-refraction.html
#define GLSL_WATERREFRACT_FRAGMENT_SHADER \
"#version 120\n" \
GLSL_WATER_CONST \
"uniform sampler2D scene_tex;\n" \
"uniform sampler2D scene_depth_tex;\n" \
"uniform vec2 scr_resolution;\n" \
"uniform float leveltime;\n" \
"void main(void) {\n" \
"float water_z = (gl_FragCoord.z / gl_FragCoord.w) / 2.0;\n" \
"float a = -pi * (water_z * freq) + (leveltime * speed);\n" \
"float falloff = 1.0 / (1.0 + water_z * falltresh);\n" \
"float distort = sin(a) * amp * falloff;\n" \
"vec2 uv = (gl_FragCoord.xy / scr_resolution) + vec2(distort, distort * 2.0) * 0.04;\n" \
"float scenedepth = texture2D(scene_depth_tex, uv).r;\n" \
"if (scenedepth < gl_FragCoord.z) {\n" \
"discard;\n" \
"}\n" \
"gl_FragColor = texture2D(scene_tex, uv);\n" \
"}\0"
//
// Fog block shader
//
+91
View File
@@ -173,6 +173,15 @@ boolean supportstencil = false;
// can know when the textures aren't there, as textures are always considered resident in their virtual memory
static GLuint screenTextures[NUMSCREENTEXTURES] = {};
// for water refraction
enum
{
SCENE_TEX,
SCENE_DEPTHTEX,
NUMSCENETEXTURES
};
static GLuint sceneTextures[NUMSCENETEXTURES] = {};
#define byte2float(byte) (GLfloat)(byte / 255.0f)
// -----------------+
@@ -723,6 +732,9 @@ typedef enum
gluniform_palette_lookup_tex, // 3d texture containing the rgb->index lookup table
gluniform_lighttable_tex, // 2d texture containing a light table
gluniform_scene_tex,
gluniform_scene_depth_tex,
// misc.
gluniform_leveltime,
@@ -2386,6 +2398,9 @@ static boolean GL_Shader_CompileProgram(gl_shader_t *shader, GLint i)
// misc.
shader->uniforms[gluniform_leveltime] = GETUNI("leveltime");
shader->uniforms[gluniform_scene_tex] = GETUNI("scene_tex");
shader->uniforms[gluniform_scene_depth_tex] = GETUNI("scene_depth_tex");
#undef GETUNI
// set permanent uniform values
@@ -2400,6 +2415,9 @@ static boolean GL_Shader_CompileProgram(gl_shader_t *shader, GLint i)
UNIFORM_1(shader->uniforms[gluniform_palette_lookup_tex], 1, pglUniform1i);
UNIFORM_1(shader->uniforms[gluniform_lighttable_tex], 2, pglUniform1i);
UNIFORM_1(shader->uniforms[gluniform_scene_tex], 4, pglUniform1i);
UNIFORM_1(shader->uniforms[gluniform_scene_depth_tex], 5, pglUniform1i);
// restore gl shader state
pglUseProgram(gl_shaderstate.program);
#undef UNIFORM_1
@@ -2480,6 +2498,24 @@ void GL_DrawPolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, F
Clamp2D(GL_TEXTURE_WRAP_T);
}
void GL_DrawWaterPolygon(FOutVector *pOutVerts, FUINT iNumPts)
{
GL_SetShader(HWR_GetShaderFromTarget(SHADER_WATERREFRACT));
pglActiveTexture(GL_TEXTURE4);
pglBindTexture(GL_TEXTURE_2D, sceneTextures[SCENE_TEX]);
pglActiveTexture(GL_TEXTURE0);
pglActiveTexture(GL_TEXTURE5);
pglBindTexture(GL_TEXTURE_2D, sceneTextures[SCENE_DEPTHTEX]);
pglActiveTexture(GL_TEXTURE0);
GL_PreparePolygon(NULL, PF_NoTexture|PF_Ripple);
pglVertexPointer(3, GL_FLOAT, sizeof(FOutVector), &pOutVerts[0].x);
pglDrawArrays(GL_TRIANGLE_FAN, 0, iNumPts);
}
void GL_DrawIndexedTriangles(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, FBITFIELD PolyFlags, unsigned int *IndexArray)
{
GL_PreparePolygon(pSurf, PolyFlags);
@@ -3384,6 +3420,57 @@ void GL_Framebuffer_Disable(void)
}
#endif
// faster than fbo blitting ig...
// just copies the whole framebuffer as a texture
void GL_CopyMainFramebufferTexture(void)
{
if (!sceneTextures[SCENE_TEX])
{
pglGenTextures(1, &sceneTextures[SCENE_TEX]);
pglBindTexture(GL_TEXTURE_2D, sceneTextures[SCENE_TEX]);
pglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, screen_width, screen_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
Clamp2D(GL_TEXTURE_WRAP_S);
Clamp2D(GL_TEXTURE_WRAP_T);
pglBindTexture(GL_TEXTURE_2D, 0);
}
// now copy the whole scene
pglBindTexture(GL_TEXTURE_2D, sceneTextures[SCENE_TEX]);
pglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, screen_width, screen_height);
// not sure why, but this is needed
// otherwise bad things happen
tex_downloaded = sceneTextures[SCENE_TEX];
pglBindTexture(GL_TEXTURE_2D, 0);
}
void GL_CopyMainFramebufferDepth(void)
{
if (!sceneTextures[SCENE_DEPTHTEX])
{
pglGenTextures(1, &sceneTextures[SCENE_DEPTHTEX]);
pglBindTexture(GL_TEXTURE_2D, sceneTextures[SCENE_DEPTHTEX]);
pglTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, screen_width, screen_height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
Clamp2D(GL_TEXTURE_WRAP_S);
Clamp2D(GL_TEXTURE_WRAP_T);
pglBindTexture(GL_TEXTURE_2D, 0);
}
// and copy the depth from the scene
// we need this for depth testing within the shader
// so we can discard stuff in front of the water
// this aint reflections after all!
pglBindTexture(GL_TEXTURE_2D, sceneTextures[SCENE_DEPTHTEX]);
pglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, screen_width, screen_height);
pglBindTexture(GL_TEXTURE_2D, 0);
}
static const float defaultscreenVerts[12] =
{
-1.0f, -1.0f, 1.0f,
@@ -3505,6 +3592,10 @@ void GL_FlushScreenTextures(void)
{
pglDeleteTextures(NUMSCREENTEXTURES, screenTextures);
memset(screenTextures, 0, sizeof(screenTextures));
// gotta wipe the scene textures for the water refraction stuff aswell
pglDeleteTextures(NUMSCENETEXTURES, sceneTextures);
memset(sceneTextures, 0, sizeof(sceneTextures));
}
void GL_DrawScreenTexture(int tex, FSurfaceInfo *surf, FBITFIELD polyflags)
+3
View File
@@ -104,6 +104,9 @@ void GL_Framebuffer_Disable(void);
extern int supportFBO;
#endif
void GL_CopyMainFramebufferTexture(void);
void GL_CopyMainFramebufferDepth(void);
// ==========================================================================
// GLOBAL
// ==========================================================================
+10 -8
View File
@@ -135,8 +135,7 @@ HMS_on_read (char *s, size_t _1, size_t n, void *userdata)
return n;
}
static struct HMS_buffer *
HMS_connect (const char *format, ...)
static struct HMS_buffer *HMS_connect(const char *format, ...)
{
va_list ap;
CURL *curl;
@@ -174,7 +173,7 @@ HMS_connect (const char *format, ...)
if (cv_masterserver_token.string && cv_masterserver_token.string[0])
{
quack_token = curl_easy_escape(curl, cv_masterserver_token.string, 0);
token_length = ( sizeof "&token="-1 )+ strlen(quack_token);
token_length = ( sizeof "&token="-1 ) + strlen(quack_token);
}
else
{
@@ -186,27 +185,30 @@ HMS_connect (const char *format, ...)
I_lock_mutex(&hms_api_mutex);
#endif
seek = strlen(hms_api) + 1;/* + '/' */
seek = strlen(hms_api) + 1; /* + '/' */
va_start (ap, format);
url = malloc(seek + vsnprintf(NULL, 0, format, ap) + sizeof HMS_QUERY_VERSION - 1 + token_length + 1);
size_t url_size = (seek + vsnprintf(NULL, 0, format, ap) +
sizeof HMS_QUERY_VERSION - 1 +
token_length + 1);
url = malloc(url_size);
va_end (ap);
sprintf(url, "%s/", hms_api);
snprintf(url, seek + 1, "%s/", hms_api);
#ifdef HAVE_THREADS
I_unlock_mutex(hms_api_mutex);
#endif
va_start (ap, format);
seek += vsprintf(&url[seek], format, ap);
seek += vsnprintf(&url[seek], url_size - seek, format, ap);
va_end (ap);
strcpy(&url[seek], HMS_QUERY_VERSION);
seek += sizeof HMS_QUERY_VERSION - 1;
if (quack_token)
sprintf(&url[seek], "&token=%s", quack_token);
snprintf(&url[seek], url_size - seek, "&token=%s", quack_token);
Printf_url(url);
+12 -11
View File
@@ -154,14 +154,14 @@ void HU_LoadGraphics(void)
for (i = 0; i < HU_FONTSIZE; i++, j++)
{
// cache the heads-up font for entire game execution
sprintf(buffer, "STCFN%.3d", j);
snprintf(buffer, sizeof(buffer), "STCFN%.3d", j);
if (W_CheckNumForName(buffer) == LUMPERROR)
hu_font[i] = NULL;
else
hu_font[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX);
// tiny version of the heads-up font
sprintf(buffer, "TNYFN%.3d", j);
snprintf(buffer, sizeof(buffer), "TNYFN%.3d", j);
if (W_CheckNumForName(buffer) == LUMPERROR)
tny_font[i] = NULL;
else
@@ -188,7 +188,7 @@ void HU_LoadGraphics(void)
for (i = 0; i < KART_FONTSIZE; i++, j++)
{
// cache the heads-up font for entire game execution
sprintf(buffer, "MKFNT%.3d", j);
snprintf(buffer, sizeof(buffer), "MKFNT%.3d", j);
if (W_CheckNumForName(buffer) == LUMPERROR)
kart_font[i] = NULL;
else
@@ -199,7 +199,7 @@ void HU_LoadGraphics(void)
j = LT_FONTSTART;
for (i = 0; i < LT_FONTSIZE; i++)
{
sprintf(buffer, "LTFNT%.3d", j);
snprintf(buffer, sizeof(buffer), "LTFNT%.3d", j);
j++;
if (W_CheckNumForName(buffer) == LUMPERROR)
@@ -212,7 +212,7 @@ void HU_LoadGraphics(void)
j = CRED_FONTSTART;
for (i = 0; i < CRED_FONTSIZE; i++)
{
sprintf(buffer, "CRFNT%.3d", j);
snprintf(buffer, sizeof(buffer), "CRFNT%.3d", j);
j++;
if (W_CheckNumForName(buffer) == LUMPERROR)
@@ -224,11 +224,11 @@ void HU_LoadGraphics(void)
// cache numbers too!
for (i = 0; i < 10; i++)
{
sprintf(buffer, "STTNUM%d", i);
snprintf(buffer, sizeof(buffer), "STTNUM%d", i);
tallnum[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX);
sprintf(buffer, "PINGN%d", i);
snprintf(buffer, sizeof(buffer), "PINGN%d", i);
pingnum[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX);
sprintf(buffer, "OPPRNK0%d", i);
snprintf(buffer, sizeof(buffer), "OPPRNK0%d", i);
ranknum[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX);
}
@@ -240,7 +240,7 @@ void HU_LoadGraphics(void)
// cache ping gfx:
for (i = 0; i < 5; i++)
{
sprintf(buffer, "PINGGFX%d", i+1);
snprintf(buffer, sizeof(buffer), "PINGGFX%d", i+1);
pinggfx[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX);
}
@@ -2830,8 +2830,9 @@ static void HU_DrawRankings(void)
scorelines++;
#if MAXPLAYERS > 16
if (scorelines > 16)
break; //dont draw past bottom of screen, show the best only
// 32 Player TODO: port over and cleanup scoreboard from sat-32p/blankart
if (scorelines >= 16)
break; // dont draw past bottom of screen, show the best only
#endif
}
+15
View File
@@ -237,6 +237,21 @@ char *I_GetUserName(void);
*/
INT32 I_mkdir(const char *dirname, INT32 unixright);
/** \brief Change current working directory
\param path directory path
\return 0 on success, -1 on error
*/
INT32 I_ChDir(const char *path);
/** \brief Get current working directory
\param buf buffer to store path
\param size size of buffer
\return buf on success, NULL on error
*/
char *I_GetCwd(char *buf, size_t size);
/** \brief Find main WAD
\return path to main WAD
*/
+4 -5
View File
@@ -213,7 +213,7 @@ static char *get_WSAErrorStr(int e)
NULL);
if (!buf[0]) // provide a fallback error message if no message is available for some reason
sprintf(buf, "Unknown error");
snprintf(buf, sizeof(buf), "Unknown error");
return buf;
}
@@ -364,12 +364,12 @@ static const char *SOCK_AddrToStr(mysockaddr_t *sk)
if (addr == NULL)
{
sprintf(s, "No address");
snprintf(s, sizeof(s), "No address");
}
else if (inet_ntop(sk->any.sa_family, addr, &s[v6], sizeof (s) - v6) == NULL)
{
e = errno;
sprintf(s, "Unknown family type, error #%u: %s", e, strerror(e));
snprintf(s, sizeof(s), "Unknown family type, error #%u: %s", e, strerror(e));
}
#ifdef HAVE_IPV6
else if(sk->any.sa_family == AF_INET6)
@@ -416,7 +416,7 @@ static const char *SOCK_GetBanMask(size_t ban)
if (ban >= numbans)
return NULL;
if (sprintf(s,"%d",banned[ban].mask) > 0)
if (snprintf(s, sizeof(s), "%d",banned[ban].mask) > 0)
return s;
return NULL;
@@ -622,7 +622,6 @@ static boolean hole_punch(ssize_t c)
{
return false;
}
}
#endif //ifdef HOLEPUNCH
+33 -19
View File
@@ -388,7 +388,7 @@ static void K_LoadSaturnHUDGraphics(void)
skp_speedpatchesdial[3] = (patch_t *)W_CachePatchName("SP_DFRAC", PU_HUDGFX);
skp_speedpatchesdial[4] = (patch_t *)W_CachePatchName("SP_DPERC", PU_HUDGFX);
sprintf(buffer, "K_DSPNMx");
snprintf(buffer, sizeof(buffer), "K_DSPNMx");
for (i = 0; i < 10; i++)
{
buffer[7] = '0'+(i%10);
@@ -507,7 +507,7 @@ static void K_LoadSaturnHUDGraphics(void)
skp_speedpatchesdialclr[3] = (patch_t *)W_CachePatchName("SC_DFRAC", PU_HUDGFX);
skp_speedpatchesdialclr[4] = (patch_t *)W_CachePatchName("SC_DPERC", PU_HUDGFX);
sprintf(buffer, "K_DSPNCx");
snprintf(buffer, sizeof(buffer), "K_DSPNCx");
for (i = 0; i < 10; i++)
{
buffer[7] = '0'+(i%10);
@@ -677,7 +677,7 @@ void K_LoadKartHUDGraphics(void)
kp_racefinish[5] = (patch_t *)W_CachePatchName("K_2PFINB", PU_HUDGFX);
// Position numbers
sprintf(buffer, "K_POSNxx");
snprintf(buffer, sizeof(buffer), "K_POSNxx");
for (i = 0; i < NUMPOSNUMS; i++)
{
buffer[6] = '0'+i;
@@ -688,14 +688,17 @@ void K_LoadKartHUDGraphics(void)
}
}
sprintf(buffer, "K_POSNWx");
snprintf(buffer, sizeof(buffer), "K_POSNWx");
for (i = 0; i < NUMWINFRAMES; i++)
{
buffer[7] = '0'+i;
kp_winnernum[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX);
}
sprintf(buffer, "OPPRNKxx");
// 32 player note: there are only 16 of those!
// so slots after this will just be missing patches!
// but keeping like this incase of missed adjustments which might cause crashes otherwise
snprintf(buffer, sizeof(buffer), "OPPRNKxx");
for (i = 0; i <= MAXPLAYERS; i++)
{
buffer[6] = '0'+(i/10);
@@ -703,7 +706,7 @@ void K_LoadKartHUDGraphics(void)
kp_facenum[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX);
}
sprintf(buffer, "K_CHILIx");
snprintf(buffer, sizeof(buffer), "K_CHILIx");
for (i = 0; i < 8; i++)
{
buffer[7] = '0'+(i+1);
@@ -772,21 +775,21 @@ void K_LoadKartHUDGraphics(void)
kp_kitchensink[1] = (patch_t *)W_CachePatchName("K_ISSINK", PU_HUDGFX);
kp_sadface[1] = (patch_t *)W_CachePatchName("K_ISSAD", PU_HUDGFX);
sprintf(buffer, "K_ITINVx");
snprintf(buffer, sizeof(buffer), "K_ITINVx");
for (i = 0; i < 7; i++)
{
buffer[7] = '1'+i;
kp_invincibility[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX);
}
sprintf(buffer, "K_ITORBx");
snprintf(buffer, sizeof(buffer), "K_ITORBx");
for (i = 0; i < 4; i++)
{
buffer[7] = '1'+i;
kp_orbinaut[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX);
}
sprintf(buffer, "K_ISINVx");
snprintf(buffer, sizeof(buffer), "K_ISINVx");
for (i = 0; i < 6; i++)
{
buffer[7] = '1'+i;
@@ -794,7 +797,7 @@ void K_LoadKartHUDGraphics(void)
}
// CHECK indicators
sprintf(buffer, "K_CHECKx");
snprintf(buffer, sizeof(buffer), "K_CHECKx");
for (i = 0; i < 6; i++)
{
buffer[7] = '1'+i;
@@ -802,7 +805,7 @@ void K_LoadKartHUDGraphics(void)
}
// Eggman warning numbers
sprintf(buffer, "K_EGGNx");
snprintf(buffer, sizeof(buffer), "K_EGGNx");
for (i = 0; i < 4; i++)
{
buffer[6] = '0'+i;
@@ -815,7 +818,7 @@ void K_LoadKartHUDGraphics(void)
kp_fpview[2] = (patch_t *)W_CachePatchName("VIEWC0E0", PU_HUDGFX);
// Input UI Wheel
sprintf(buffer, "K_WHEELx");
snprintf(buffer, sizeof(buffer), "K_WHEELx");
for (i = 0; i < 5; i++)
{
buffer[7] = '0'+i;
@@ -823,7 +826,7 @@ void K_LoadKartHUDGraphics(void)
}
// HERE COMES A NEW CHALLENGER
sprintf(buffer, "K_CHALxx");
snprintf(buffer, sizeof(buffer), "K_CHALxx");
for (i = 0; i < 25; i++)
{
buffer[6] = '0'+((i+1)/10);
@@ -832,14 +835,14 @@ void K_LoadKartHUDGraphics(void)
}
// Lap start animation
sprintf(buffer, "K_LAP0x");
snprintf(buffer, sizeof(buffer), "K_LAP0x");
for (i = 0; i < 7; i++)
{
buffer[6] = '0'+(i+1);
kp_lapanim_lap[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX);
}
sprintf(buffer, "K_LAPFxx");
snprintf(buffer, sizeof(buffer), "K_LAPFxx");
for (i = 0; i < 11; i++)
{
buffer[6] = '0'+((i+1)/10);
@@ -847,7 +850,7 @@ void K_LoadKartHUDGraphics(void)
kp_lapanim_final[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX);
}
sprintf(buffer, "K_LAPNxx");
snprintf(buffer, sizeof(buffer), "K_LAPNxx");
for (i = 0; i < 10; i++)
{
buffer[6] = '0'+i;
@@ -858,14 +861,14 @@ void K_LoadKartHUDGraphics(void)
}
}
sprintf(buffer, "K_LAPE0x");
snprintf(buffer, sizeof(buffer), "K_LAPE0x");
for (i = 0; i < 2; i++)
{
buffer[7] = '0'+(i+1);
kp_lapanim_emblem[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX);
}
sprintf(buffer, "K_LAPH0x");
snprintf(buffer, sizeof(buffer), "K_LAPH0x");
for (i = 0; i < 3; i++)
{
buffer[7] = '0'+(i+1);
@@ -1974,7 +1977,7 @@ void K_drawKartTimestamp(tic_t drawtime, INT32 TX, INT32 TY, INT16 emblemmap, UI
goto bademblem;
}
snprintf(targettext, 9, "%i'%02i\"%02i",
snprintf(targettext, sizeof(targettext), "%i'%02i\"%02i",
G_TicsToMinutes(timetoreach, false),
G_TicsToSeconds(timetoreach),
G_TicsToCentiseconds(timetoreach));
@@ -2294,6 +2297,11 @@ static boolean K_drawKartPositionFaces(void)
if (pos < 0 || pos > MAXPLAYERS)
pos = 0;
#if MAXPLAYERS > 16
if (pos > 16)
V_DrawPingNum(FACE_X+2, Y+10, V_HUDTRANS|V_SNAPTOLEFT, pos, NULL);
else
#endif
// Draws the little number over the face
V_DrawScaledPatch(FACE_X-5, Y+10, V_HUDTRANS|V_SNAPTOLEFT, kp_facenum[pos]);
}
@@ -2385,6 +2393,12 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I
INT32 pos = player->kartstuff[k_position];
if (pos < 0 || pos > MAXPLAYERS)
pos = 0;
#if MAXPLAYERS > 16
if (pos > 16)
V_DrawPingNum(x+2, y+10, 0, pos, NULL);
else
#endif
// Draws the little number over the face
V_DrawScaledPatch(x-5, y+6, 0, kp_facenum[pos]);
}
+6
View File
@@ -1033,6 +1033,12 @@ INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, fixed_t mashed, boolean spbrush)
}
}
#if MAXPLAYERS > 16
// courtesy of fickle from 1.1 battleroyale
// battleroyale: limit how much items will scale to try to prevent shit-tier items in shit-huge netames
pingame = min(pingame, 12);
#endif
if (first != -1 && second != -1) // calculate 2nd's distance from 1st, for SPB
{
secondist = P_AproxDistance(P_AproxDistance(players[first].mo->x - players[second].mo->x,
+7 -8
View File
@@ -579,8 +579,8 @@ FUNCINLINE static ATTRINLINE int call_mobj_type_hooks(Hook_State *hook, mobjtype
static UINT8 seen = 0; // so we dont have to check all this shit constantly
int numCalls = call_mapped(hook, &mobjHookIds[mobj_type][hook->hook_type]);
if (!seen && numCalls > 0 && mobj_type == MT_NULL && (
hook->hook_type == MOBJ_HOOK(MobjThinker )
if (!seen && numCalls > 0 && mobj_type == MT_NULL &&
( hook->hook_type == MOBJ_HOOK(MobjThinker )
|| hook->hook_type == MOBJ_HOOK(MobjCollide )
|| hook->hook_type == MOBJ_HOOK(MobjMoveCollide)
|| hook->hook_type == MOBJ_HOOK(MobjFuse )
@@ -588,6 +588,7 @@ FUNCINLINE static ATTRINLINE int call_mobj_type_hooks(Hook_State *hook, mobjtype
))
{
seen = 1;
CONS_Alert(
CONS_WARNING, "%s\n", va(
"%s hooks not attached to a specific mobj type may cause performance issues!",
@@ -609,12 +610,10 @@ FUNCINLINE static ATTRINLINE int call_mobj_type_hooks(Hook_State *hook, mobjtype
return numCalls;
}
/*
FUNCINLINE static ATTRINLINE int call_mobj_type_hooks(Hook_State *hook, mobjtype_t mobj_type)
/*FUNCINLINE static ATTRINLINE int call_mobj_type_hooks(Hook_State *hook, mobjtype_t mobj_type)
{
return call_mapped(hook, &mobjHookIds[mobj_type][hook->hook_type]);
}
*/
}*/
static int call_hooks
(
@@ -899,7 +898,7 @@ int LUA_HookShouldDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT3
int LUA_HookMobjDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage)
{
return damage_hook(target, inflictor, source, damage,
MOBJ_HOOK(MobjDamage), res_true);
MOBJ_HOOK(MobjDamage), res_true);
}
int LUA_HookMobjDeath(mobj_t *target, mobj_t *inflictor, mobj_t *source)
@@ -988,7 +987,7 @@ void LUA_HookLinedefExecute(line_t *line, mobj_t *mo, sector_t *sector)
{
Hook_State hook = {};
if (prepare_string_hook
(&hook, 0, STRING_HOOK(LinedefExecute), line->text))
(&hook, 0, STRING_HOOK(LinedefExecute), line->text))
{
LUA_PushUserdata(gL, line, META_LINE);
LUA_PushUserdata(gL, mo, META_MOBJ);
+6 -5
View File
@@ -277,20 +277,19 @@ void LUA_LoadLump(UINT16 wad, UINT16 lump)
if (wadfiles[wad]->type == RET_LUA)
{
name = malloc(len+1);
strcpy(name, wadfiles[wad]->filename);
name = malloc(len + 1);
snprintf(name, len + 1, "%s", wadfiles[wad]->filename);
}
else // If it's not a .lua file, copy the lump name in too.
{
lumpinfo_t *lump_p = &wadfiles[wad]->lumpinfo[lump];
len += 1 + strlen(lump_p->fullname); // length of file name, '|', and lump name
name = malloc(len+1);
name = malloc(len + 1);
if (!name)
I_Error("LUA_LoadLump: Out of memory!\n");
sprintf(name, "%s|%s", wadfiles[wad]->filename, lump_p->fullname);
name[len] = '\0';
snprintf(name, len + 1, "%s|%s", wadfiles[wad]->filename, lump_p->fullname);
}
LUA_LoadFile(&f, name); // actually load file!
@@ -592,6 +591,7 @@ void LUA_InvalidateLevel(void)
for (i = 0; i < numsubsectors; i++)
LUA_InvalidateUserdata(&subsectors[i]);
for (i = 0; i < numsectors; i++)
{
LUA_InvalidateUserdata(&sectors[i]);
@@ -612,6 +612,7 @@ void LUA_InvalidateLevel(void)
for (i = 0; i < numsides; i++)
LUA_InvalidateUserdata(&sides[i]);
for (i = 0; i < numvertexes; i++)
LUA_InvalidateUserdata(&vertexes[i]);
+18 -18
View File
@@ -616,7 +616,7 @@ void Nextmap_OnChange(void)
if (!gpath)
return;
sprintf(gpath,"%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value));
snprintf(gpath, glen, "%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value));
CV_StealthSetValue(&cv_dummystaff, 0);
@@ -735,7 +735,7 @@ static void Dummystaff_OnChange(void)
while (*temp)
temp++;
sprintf(temp, " - %d", cv_dummystaff.value);
snprintf(temp, sizeof(dummystaffname) - (size_t)(temp - dummystaffname), " - %d", cv_dummystaff.value);
}
}
@@ -825,7 +825,8 @@ static void M_ChangeCvar(INT32 choice)
float increment;
increment = FIXED_TO_FLOAT(cv->value)+(choice)*((currentMenu->menuitems[itemOn].status & IT_CV_BIGFLOAT) ? 0.5f : (1.0f/16.0f));
sprintf(s,"%ld%s",(long)increment,M_Ftrim(increment));
snprintf(s, sizeof(s), "%ld%s", (long)increment, M_Ftrim(increment));
CV_Set(cv, s);
}
else
@@ -4185,12 +4186,12 @@ static void PrepReplayList(boolean reset)
if (dirmenu[i][DIR_TYPE] == EXT_UP)
{
demolist_all[i].type = MD_SUBDIR;
sprintf(demolist_all[i].title, "UP");
snprintf(demolist_all[i].title, sizeof(demolist_all[i].title), "UP");
}
else if (dirmenu[i][DIR_TYPE] == EXT_FOLDER)
{
demolist_all[i].type = MD_SUBDIR;
strncpy(demolist_all[i].title, dirmenu[i] + DIR_STRING, 64);
snprintf(demolist_all[i].title, sizeof(demolist_all[i].title), "%s", dirmenu[i] + DIR_STRING);
}
else
{
@@ -4198,7 +4199,7 @@ static void PrepReplayList(boolean reset)
snprintf(demolist_all[i].filepath, sizeof(demolist_all[i].filepath),
// 255 = UINT8 limit. dirmenu entries are restricted to this length (see DIR_LEN).
"%s%.255s", menupath, dirmenu[i] + DIR_STRING);
sprintf(demolist_all[i].title, ".....");
snprintf(demolist_all[i].title, sizeof(demolist_all[i].title), ".....");
}
}
@@ -5983,7 +5984,8 @@ static void M_DrawStatsMaps(void)
V_DrawString(20, 42, highlightflags|MENUCAPS, "Combined time records:");
sprintf(beststr, "%i:%02i:%02i.%02i", G_TicsToHours(besttime), G_TicsToMinutes(besttime, false), G_TicsToSeconds(besttime), G_TicsToCentiseconds(besttime));
snprintf(beststr, sizeof(beststr), "%i:%02i:%02i.%02i", G_TicsToHours(besttime), G_TicsToMinutes(besttime, false), G_TicsToSeconds(besttime), G_TicsToCentiseconds(besttime));
V_DrawRightAlignedString(BASEVIDWIDTH-16, 42, (mapsunfinished ? warningflags : 0), beststr);
if (mapsunfinished)
@@ -7150,7 +7152,7 @@ static void M_CheckMODVersion(int id)
if (updatecheck)
{
sprintf(updatestring, UPDATE_ALERT_STRING, VERSIONSTRING, updatecheck);
snprintf(updatestring, sizeof(updatestring), UPDATE_ALERT_STRING, VERSIONSTRING, updatecheck);
#ifdef HAVE_THREADS
I_lock_mutex(&m_menu_mutex);
#endif
@@ -7648,11 +7650,8 @@ static void M_DrawMPMainMenu(void)
// use generic drawer for cursor, items and title
M_DrawGenericMenu();
#if MAXPLAYERS != 16
Update the maxplayers label...
#endif
V_DrawRightAlignedString(BASEVIDWIDTH-x, y+MP_MainMenu[4].alphaKey,
((itemOn == 4) ? highlightflags : 0)|MENUCAPS, "(2-16 Players)");
((itemOn == 4) ? highlightflags : 0)|MENUCAPS, va("(2-%d Players)", MAXPLAYERS));
V_DrawRightAlignedString(BASEVIDWIDTH-x, y+MP_MainMenu[5].alphaKey,
((itemOn == 5) ? highlightflags : 0)|MENUCAPS,
@@ -9602,11 +9601,13 @@ static void M_ChangecontrolResponse(event_t *ev)
menu_t *prev = currentMenu->prevMenu;
if (controltochange == gc_pause)
sprintf(tmp, M_GetText("The \x82Pause Key \x80is enabled, but \nyou may select another key. \n\nHit another key for\n%s\nESC for Cancel"),
controltochangetext);
{
snprintf(tmp, sizeof(tmp), M_GetText("The \x82Pause Key \x80is enabled, but \nyou may select another key. \n\nHit another key for\n%s\nESC for Cancel"), controltochangetext);
}
else
sprintf(tmp, M_GetText("The \x82Pause Key \x80is enabled, but \nit is not configurable. \n\nHit another key for\n%s\nESC for Cancel"),
controltochangetext);
{
snprintf(tmp, sizeof(tmp), M_GetText("The \x82Pause Key \x80is enabled, but \nit is not configurable. \n\nHit another key for\n%s\nESC for Cancel"), controltochangetext);
}
M_StartMessage(tmp, M_ChangecontrolResponse, MM_EVENTHANDLER);
currentMenu->prevMenu = prev;
@@ -9627,8 +9628,7 @@ static void M_ChangeControl(INT32 choice)
static char tmp[68];
controltochange = currentMenu->menuitems[choice].alphaKey;
sprintf(tmp, M_GetText("Hit the new key for\n%s\nESC for Cancel"),
currentMenu->menuitems[choice].text);
snprintf(tmp, sizeof(tmp), M_GetText("Hit the new key for\n%s\nESC for Cancel"), currentMenu->menuitems[choice].text);
strlcpy(controltochangetext, currentMenu->menuitems[choice].text, 33);
M_StartMessage(tmp, M_ChangecontrolResponse, MM_EVENTHANDLER);
+17 -16
View File
@@ -515,8 +515,8 @@ static boolean M_BackupConfig(const char *filename)
{
char backupfile[MAX_WADPATH+4];
snprintf(backupfile, sizeof backupfile, "%s.bak", filename);
backupfile[sizeof backupfile - 1] = '\0';
snprintf(backupfile, sizeof(backupfile), "%s.bak", filename);
backupfile[sizeof(backupfile) - 1] = '\0';
FILE *config = fopen(filename, "r");
@@ -766,27 +766,27 @@ static void M_PNGText(png_structp png_ptr, png_infop png_info_ptr, PNG_CONST png
}
if (gamestate == GS_LEVEL)
snprintf(maptext, 8, "%s", G_BuildMapName(gamemap));
snprintf(maptext, sizeof(maptext), "%s", G_BuildMapName(gamemap));
else
snprintf(maptext, 8, "Unknown");
snprintf(maptext, sizeof(maptext), "Unknown");
if (gamestate == GS_LEVEL && mapheaderinfo[gamemap-1]->lvlttl[0] != '\0')
snprintf(lvlttltext, 48, "%s%s%s",
snprintf(lvlttltext, sizeof(lvlttltext), "%s%s%s",
mapheaderinfo[gamemap-1]->lvlttl,
(strlen(mapheaderinfo[gamemap-1]->zonttl) > 0) ? va(" %s",mapheaderinfo[gamemap-1]->zonttl) : // SRB2kart
((mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE) ? "" : " ZONE"),
(strlen(mapheaderinfo[gamemap-1]->actnum) > 0) ? va(" %s",mapheaderinfo[gamemap-1]->actnum) : "");
else
snprintf(lvlttltext, 48, "Unknown");
snprintf(lvlttltext, sizeof(lvlttltext), "Unknown");
if (gamestate == GS_LEVEL && players[displayplayers[0]].mo)
snprintf(locationtxt, 40, "X:%d Y:%d Z:%d A:%d",
snprintf(locationtxt, sizeof(locationtxt), "X:%d Y:%d Z:%d A:%d",
players[displayplayers[0]].mo->x>>FRACBITS,
players[displayplayers[0]].mo->y>>FRACBITS,
players[displayplayers[0]].mo->z>>FRACBITS,
FixedInt(AngleFixed(players[displayplayers[0]].mo->angle)));
else
snprintf(locationtxt, 40, "Unknown");
snprintf(locationtxt, sizeof(locationtxt), "Unknown");
memset(png_infotext, 0x00, sizeof(png_infotext));
@@ -1253,7 +1253,6 @@ boolean M_ScreenshotResponder(event_t *ev)
return true;
}
void M_ScrollString(const char name[], size_t len, char result[], size_t maxlen, tic_t timer)
{
// How much should we scroll. Not sure why +1 is needed, but without it this function skips 2
@@ -1394,7 +1393,7 @@ char *va(const char *format, ...)
static char string[1024];
va_start(argptr, format);
vsnprintf(string, 1024, format, argptr);
vsnprintf(string, sizeof(string), format, argptr);
va_end(argptr);
return string;
@@ -1708,7 +1707,7 @@ const char * M_Ftrim(double f)
int i;
/* I know I said it's the default, but just in case... */
sprintf(dig, "%.6f", fabs(modf(f, &f)));
snprintf(dig, sizeof(dig), "%.6f", fabs(modf(f, &f)));
/* trim trailing zeroes */
for (i = strlen(dig)-1; dig[i] == '0'; --i)
@@ -1736,6 +1735,7 @@ UINT8 M_CountBits(UINT32 num, UINT8 size)
const char *GetRevisionString(void)
{
static char rev[9] = {0};
if (rev[0])
return rev;
@@ -1743,6 +1743,7 @@ const char *GetRevisionString(void)
strncpy(rev, comprevision, 7);
else
snprintf(rev, 7, "r%s", comprevision);
rev[7] = '\0';
return rev;
@@ -1814,35 +1815,35 @@ TMatrix *RotateZMatrix(angle_t rad)
char *sizeu1(size_t num)
{
static char sizeu1_buf[28];
sprintf(sizeu1_buf, "%"PRIdS, num);
snprintf(sizeu1_buf, sizeof(sizeu1_buf), "%" PRIdS, num);
return sizeu1_buf;
}
char *sizeu2(size_t num)
{
static char sizeu2_buf[28];
sprintf(sizeu2_buf, "%"PRIdS, num);
snprintf(sizeu2_buf, sizeof(sizeu2_buf), "%" PRIdS, num);
return sizeu2_buf;
}
char *sizeu3(size_t num)
{
static char sizeu3_buf[28];
sprintf(sizeu3_buf, "%"PRIdS, num);
snprintf(sizeu3_buf, sizeof(sizeu3_buf), "%" PRIdS, num);
return sizeu3_buf;
}
char *sizeu4(size_t num)
{
static char sizeu4_buf[28];
sprintf(sizeu4_buf, "%"PRIdS, num);
snprintf(sizeu4_buf, sizeof(sizeu4_buf), "%" PRIdS, num);
return sizeu4_buf;
}
char *sizeu5(size_t num)
{
static char sizeu5_buf[28];
sprintf(sizeu5_buf, "%"PRIdS, num);
snprintf(sizeu5_buf, sizeof(sizeu5_buf), "%" PRIdS, num);
return sizeu5_buf;
}
+2
View File
@@ -98,6 +98,7 @@ perfstatrow_t rendertime_rows[] = {
{" sprdraw", " Sprite render: ", &ps_hw_spritedrawtime, PS_TIME|PS_LEVEL|PS_HW},
{" nodesrt", " Drwnode sort: ", &ps_hw_nodesorttime, PS_TIME|PS_LEVEL|PS_HW},
{" nodedrw", " Drwnode render:", &ps_hw_nodedrawtime, PS_TIME|PS_LEVEL|PS_HW},
{" wtrdrw", " Water render: ", &ps_hw_waterdrawtime, PS_TIME|PS_LEVEL|PS_HW},
{" other ", " Other: ", &ps_otherrendertime, PS_TIME|PS_LEVEL|PS_HW},
#endif
@@ -536,6 +537,7 @@ static void PS_UpdateFrameStats(void)
ps_skyboxtime.value.p +
ps_hw_nodesorttime.value.p +
ps_hw_nodedrawtime.value.p +
ps_hw_waterdrawtime.value.p +
ps_hw_spritesorttime.value.p +
ps_hw_spritedrawtime.value.p;
+1
View File
@@ -2632,6 +2632,7 @@ void P_PlayerRingBurst(player_t *player, INT32 num_rings)
if (i & 1)
P_SetObjectMomZ(mo, ns, true);
}
if (player->mo->eflags & MFE_VERTICALFLIP)
mo->momz *= -1;
}
+3 -3
View File
@@ -245,12 +245,12 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
static void P_DoFanAndGasJet(mobj_t *spring, mobj_t *object)
{
player_t *p = object->player; // will be NULL if not a player
player_t *player = object->player; // will be NULL if not a player
fixed_t zdist; // distance between bottoms
fixed_t speed = spring->info->mass; // conveniently, both fans and gas jets use this for the vertical thrust
SINT8 flipval = P_MobjFlip(spring); // virtually everything here centers around the thruster's gravity, not the object's!
if (p && object->state == &states[object->info->painstate]) // can't use fans and gas jets when player is in pain!
if (player && object->state == &states[object->info->painstate]) // can't use fans and gas jets when player is in pain!
return;
// is object's top below thruster's position? if not, calculate distance between their bottoms
@@ -276,7 +276,7 @@ static void P_DoFanAndGasJet(mobj_t *spring, mobj_t *object)
break;
if (flipval*object->momz >= FixedMul(speed, spring->scale)) // if object's already moving faster than your best, don't bother
break;
if (p && (p->climbing || p->pflags & PF_GLIDING)) // doesn't affect Knux when he's using his abilities!
if (player && (player->climbing || player->pflags & PF_GLIDING)) // doesn't affect Knux when he's using his abilities!
break;
object->momz += flipval*FixedMul(speed/4, spring->scale);
+1 -1
View File
@@ -466,7 +466,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
// Check for collision with front side's midtexture if Effect 4 is set
if (linedef->flags & ML_EFFECT4
&& !linedef->polyobj) // don't do anything for polyobjects! ...for now
{
{
side_t *side = &sides[linedef->sidenum[0]];
fixed_t textop, texbottom, texheight;
fixed_t texmid, delta1, delta2;
+1 -1
View File
@@ -113,7 +113,7 @@ typedef enum
// Don't use the blocklinks (inert but displayable)
MF_NOBLOCKMAP = 1<<4,
// Thin, paper-like collision bound (for visual equivalent, see FF_PAPERSPRITE)
MF_PAPERCOLLISION = 1<<5,
MF_PAPERCOLLISION = 1<<5,
// You can push this object. It can activate switches and things by pushing it on top.
MF_PUSHABLE = 1<<6,
// Object is a boss.
+10
View File
@@ -1108,7 +1108,11 @@ static void SaveMobjThinker(savebuffer_t *save, const thinker_t *th, const UINT8
diff2 = 0;
// not the default but the most probable
#ifdef COMPAT_VANILLA
if (mobj->momx != 0 || mobj->momy != 0 || mobj->momz != 0)
#else
if (mobj->momx != 0 || mobj->momy != 0 || mobj->momz != 0 || mobj->pmomz !=0)
#endif
diff |= MD_MOM;
if (mobj->radius != mobj->info->radius)
diff |= MD_RADIUS;
@@ -1236,6 +1240,9 @@ static void SaveMobjThinker(savebuffer_t *save, const thinker_t *th, const UINT8
WRITEFIXED(save->p, mobj->momx);
WRITEFIXED(save->p, mobj->momy);
WRITEFIXED(save->p, mobj->momz);
#ifndef COMPAT_VANILLA
WRITEFIXED(save->p, mobj->pmomz);
#endif
}
if (diff & MD_RADIUS)
WRITEFIXED(save->p, mobj->radius);
@@ -2055,6 +2062,9 @@ static void LoadMobjThinker(savebuffer_t *save, actionf_p1 thinker)
mobj->momx = READFIXED(save->p);
mobj->momy = READFIXED(save->p);
mobj->momz = READFIXED(save->p);
#ifndef COMPAT_VANILLA
mobj->pmomz = READFIXED(save->p);
#endif
} // otherwise they're zero, and the memset took care of it
if (diff & MD_RADIUS)
+18 -13
View File
@@ -180,7 +180,7 @@ FUNCNORETURN static ATTRNORETURN void CorruptMapError(const char *msg)
// don't use va() because the calling function probably uses it
char mapnum[10];
sprintf(mapnum, "%hd", gamemap);
snprintf(mapnum, sizeof(mapnum), "%hd", gamemap);
CON_LogMessage("Map ");
CON_LogMessage(mapnum);
CON_LogMessage(" is corrupt: ");
@@ -266,8 +266,8 @@ static void P_ClearSingleMapHeaderInfo(INT16 i)
mapheaderinfo[num]->actnum[0] = '\0';
mapheaderinfo[num]->typeoflevel = 0;
mapheaderinfo[num]->nextlevel = (INT16)(i + 1);
snprintf(mapheaderinfo[num]->musname, 7, "%sM", G_BuildMapName(i));
mapheaderinfo[num]->musname[6] = 0;
snprintf(mapheaderinfo[num]->musname, sizeof(mapheaderinfo[num]->musname), "%sM", G_BuildMapName(i));
mapheaderinfo[num]->musname[sizeof(mapheaderinfo[num]->musname)-1] = 0;
mapheaderinfo[num]->mustrack = 0;
mapheaderinfo[num]->muspos = 0;
mapheaderinfo[num]->forcecharacter[0] = '\0';
@@ -2205,7 +2205,7 @@ void P_SetupLevelSky(INT32 skynum, boolean global)
{
char skytexname[12];
sprintf(skytexname, "SKY%d", skynum);
snprintf(skytexname, sizeof(skytexname), "SKY%d", skynum);
skytexture = R_TextureNumForName(skytexname);
levelskynum = skynum;
@@ -2425,7 +2425,8 @@ static void P_RunLevelScript(const char *scriptname)
lumpnum_t lumpnum;
char newname[9];
strlcpy(newname, scriptname, sizeof(newname));
strncpy(newname, scriptname, sizeof(newname)-1);
newname[sizeof(newname)-1] = '\0';
lumpnum = W_CheckNumForName(newname);
@@ -2435,7 +2436,7 @@ static void P_RunLevelScript(const char *scriptname)
return;
}
COM_BufInsertText(W_CacheLumpNum(lumpnum, PU_CACHE));
COM_BufInsertTextEx(W_CacheLumpNum(lumpnum, PU_CACHE), W_LumpLength(lumpnum));
}
else
{
@@ -2450,23 +2451,26 @@ static void P_ForceCharacter(const char *forcecharskin)
if (netgame)
{
char skincmd[33];
if (splitscreen)
{
sprintf(skincmd, "skin2 %s\n", forcecharskin);
snprintf(skincmd, sizeof(skincmd), "skin2 %s\n", forcecharskin);
CV_Set(&cv_skin2, forcecharskin);
if (splitscreen > 1)
{
sprintf(skincmd, "skin3 %s\n", forcecharskin);
snprintf(skincmd, sizeof(skincmd), "skin3 %s\n", forcecharskin);
CV_Set(&cv_skin3, forcecharskin);
if (splitscreen > 2)
{
sprintf(skincmd, "skin4 %s\n", forcecharskin);
snprintf(skincmd, sizeof(skincmd), "skin4 %s\n", forcecharskin);
CV_Set(&cv_skin4, forcecharskin);
}
}
}
sprintf(skincmd, "skin %s\n", forcecharskin);
snprintf(skincmd, sizeof(skincmd), "skin %s\n", forcecharskin);
COM_BufAddText(skincmd);
}
else
@@ -2523,7 +2527,7 @@ static void P_LoadRecordGhosts(void)
const char *mapname = G_BuildMapName(gamemap);
sprintf(gpath,"%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s", srb2home, timeattackfolder, mapname);
snprintf(gpath, glen, "%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s", srb2home, timeattackfolder, mapname);
// Best Time ghost
if (cv_ghost_besttime.value)
@@ -2879,7 +2883,8 @@ static void P_SetupPlayer(void)
if (!demo.playback && multiplayer && D_NumPlayers())
{
static char buf[256];
sprintf(buf, "replay"PATHSEP"online"PATHSEP"%d-%s", (int)(time(NULL)), G_BuildMapName(gamemap));
snprintf(buf, sizeof(buf), "replay"PATHSEP"online"PATHSEP"%d-%s", (int)(time(NULL)), G_BuildMapName(gamemap));
I_mkdir(va("%s"PATHSEP"replay", srb2home), 0755);
I_mkdir(va("%s"PATHSEP"replay"PATHSEP"online", srb2home), 0755);
@@ -3061,7 +3066,7 @@ boolean P_SetupLevel(boolean fromnetsave, boolean reloadinggamestate)
// Don't include these in the fade!
char tx[64];
V_DrawSmallString(1, 191, V_ALLOWLOWERCASE, M_GetText("Speeding off to..."));
snprintf(tx, 63, "%s%s%s",
snprintf(tx, sizeof(tx)-1, "%s%s%s",
mapheader->lvlttl,
(strlen(mapheader->zonttl) > 0) ? va(" %s",mapheader->zonttl) : // SRB2kart
((mapheader->levelflags & LF_NOZONE) ? "" : " Zone"),
+5 -12
View File
@@ -2161,7 +2161,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
newname[1] = 'C';
newname[2] = 'R';
scrnum = sides[line->sidenum[0]].textureoffset>>FRACBITS;
scrnum = sides[line->sidenum[0]].textureoffset >> FRACBITS;
if (scrnum < 0 || scrnum > 999)
{
scrnum = 0;
@@ -2169,9 +2169,9 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
}
else
{
newname[5] = (char)('0' + (char)((scrnum/100)));
newname[6] = (char)('0' + (char)((scrnum%100)/10));
newname[7] = (char)('0' + (char)(scrnum%10));
newname[5] = (char)('0' + (char)((scrnum / 100)));
newname[6] = (char)('0' + (char)((scrnum % 100) / 10));
newname[7] = (char)('0' + (char)(scrnum % 10));
}
newname[8] = '\0';
@@ -2184,14 +2184,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
else
{
// W_CacheLumpNum may not have null terminator, so we need to do this :blobcatgooglyholditsheadinitshands:
size_t len = W_LumpLength(lumpnum);
char *script = Z_Malloc(len+1, PU_STATIC, NULL);
memcpy(script, W_CacheLumpNum(lumpnum, PU_CACHE), len);
script[len] = 0;
COM_BufInsertText(script);
Z_Free(script);
COM_BufInsertTextEx(W_CacheLumpNum(lumpnum, PU_CACHE), W_LumpLength(lumpnum));
}
}
break;
+12 -4
View File
@@ -625,15 +625,23 @@ boolean P_EndingMusic(player_t *player)
}
if (G_RaceGametype() && bestlocalpos == MAXPLAYERS+1)
sprintf(buffer, "k*fail"); // F-Zero death results theme
{
snprintf(buffer, sizeof(buffer), "k*fail"); // F-Zero death results theme
}
else
{
if (bestlocalpos == 1)
sprintf(buffer, "k*win");
{
snprintf(buffer, sizeof(buffer), "k*win");
}
else if (isPlayerLosing(bestlocalplayer))
sprintf(buffer, "k*lose");
{
snprintf(buffer, sizeof(buffer), "k*lose");
}
else
sprintf(buffer, "k*ok");
{
snprintf(buffer, sizeof(buffer), "k*ok");
}
}
S_SpeedMusic(1.0f);
+1 -1
View File
@@ -395,7 +395,7 @@ static void R_AddLine(seg_t *line)
// Find the other side!
INT32 line2 = P_FindSpecialLineFromTag(PORTALSPECIAL, line->linedef->tag, -1);
if (line->linedef == &lines[line2])
if (line2 >= 0 && line->linedef == &lines[line2])
line2 = P_FindSpecialLineFromTag(PORTALSPECIAL, line->linedef->tag, line2);
if (line2 >= 0) // found it!
+11 -11
View File
@@ -334,7 +334,7 @@ lumpnum_t S_GetSfxLumpNum(sfxinfo_t *sfx)
char namebuf[9];
lumpnum_t sfxlump;
sprintf(namebuf, "ds%s", sfx->name);
snprintf(namebuf, sizeof(namebuf), "ds%s", sfx->name);
sfxlump = W_CheckNumForName(namebuf);
if (sfxlump != LUMPERROR)
@@ -433,7 +433,7 @@ static boolean S_CheckSameSoundLimit(sfxenum_t sfx_id)
return true;
for (cnum = 0; cnum < numofchannels; cnum++)
if ((size_t)(channels[cnum].sfxinfo - S_sfx) == (size_t)sfx_id)
if (channels[cnum].sfxinfo == &S_sfx[sfx_id])
scount++;
//CONS_Printf("same sound count: %d for sfx: %d\n", scount, sfx_id);
@@ -864,18 +864,18 @@ void S_SetSfxVolume(INT32 volume)
if (volume < 0 || volume > 31)
CONS_Alert(CONS_WARNING, "sfxvolume should be between 0-31\n");
CV_SetValue(&cv_soundvolume, volume&0x1F);
CV_SetValue(&cv_soundvolume, volume & 0x1F);
actualsfxvolume = cv_soundvolume.value; // check for change of var
// now hardware volume
I_SetSfxVolume(volume&0x1F);
I_SetSfxVolume(volume & 0x1F);
}
void S_ClearSfx(void)
{
size_t i;
for (i = 1; i < NUMSFX; i++)
I_FreeSfx(S_sfx + i);
I_FreeSfx(&S_sfx[i]);
}
static void S_StopChannel(INT32 cnum)
@@ -1067,12 +1067,12 @@ INT32 S_OriginPlaying(void *origin)
// Searches through the channels and checks if a given id
// is playing anywhere.
INT32 S_IdPlaying(sfxenum_t id)
INT32 S_IdPlaying(sfxenum_t sfx_id)
{
INT32 cnum;
for (cnum = 0; cnum < numofchannels; cnum++)
if ((size_t)(channels[cnum].sfxinfo - S_sfx) == (size_t)id)
if (channels[cnum].sfxinfo == &S_sfx[sfx_id])
return 1;
return 0;
@@ -1080,7 +1080,7 @@ INT32 S_IdPlaying(sfxenum_t id)
// Searches through the channels and checks for
// origin x playing sound id y.
INT32 S_SoundPlaying(void *origin, sfxenum_t id)
INT32 S_SoundPlaying(void *origin, sfxenum_t sfx_id)
{
INT32 cnum;
@@ -1089,8 +1089,8 @@ INT32 S_SoundPlaying(void *origin, sfxenum_t id)
for (cnum = 0; cnum < numofchannels; cnum++)
{
if (channels[cnum].origin == origin
&& (size_t)(channels[cnum].sfxinfo - S_sfx) == (size_t)id)
if (channels[cnum].origin == origin &&
channels[cnum].sfxinfo == &S_sfx[sfx_id])
return 1;
}
@@ -2193,7 +2193,7 @@ static void Command_Tunes_f(void)
track = (UINT16)atoi(COM_Argv(2))-1;
if (tunenum)
snprintf(mapmusic.name, 7, "%sM", G_BuildMapName(tunenum));
snprintf(mapmusic.name, sizeof(mapmusic.name), "%sM", G_BuildMapName(tunenum));
else
strlcpy(mapmusic.name, tunearg, sizeof(mapmusic.name));
+2 -2
View File
@@ -286,8 +286,8 @@ void S_SetSfxVolume(INT32 volume);
void S_SetMusicVolume(INT32 volume);
INT32 S_OriginPlaying(void *origin);
INT32 S_IdPlaying(sfxenum_t id);
INT32 S_SoundPlaying(void *origin, sfxenum_t id);
INT32 S_IdPlaying(sfxenum_t sfx_id);
INT32 S_SoundPlaying(void *origin, sfxenum_t sfx_id);
void S_StartSoundName(void *mo, const char *soundname);
+4
View File
@@ -177,6 +177,10 @@ if(${SDL2_FOUND})
)
endif()
if("${CMAKE_SYSTEM_NAME}" MATCHES "OpenBSD")
target_link_libraries(SRB2SDL2 PRIVATE pthread execinfo)
endif()
if(${CMAKE_SYSTEM} MATCHES Windows AND ${CMAKE_C_COMPILER_ID} MATCHES "GNU" AND ${SRB2_SYSTEM_BITS} EQUAL 32)
target_link_libraries(SRB2SDL2 PRIVATE
"${CMAKE_CURRENT_SOURCE_DIR}/../../libs/drmingw/lib/win32/libexchndl.a"
+67 -35
View File
@@ -57,10 +57,13 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T);
#include <time.h>
#include <stdlib.h>
#include <string.h>
#ifdef __GNUC__
#include <unistd.h>
#endif
#if defined (__unix__) || defined (UNIXCOMMON)
#include <sys/stat.h>
#include <fcntl.h>
#endif
@@ -577,7 +580,7 @@ void I_OutputMsg(const char *fmt, ...)
I_Error("I_OutputMsg: Out of memory!\n");
va_start(argptr, fmt);
vsprintf(txt, fmt, argptr);
vsnprintf(txt, len+1, fmt, argptr);
va_end(argptr);
#ifdef HAVE_TTF
@@ -585,7 +588,7 @@ void I_OutputMsg(const char *fmt, ...)
DEFAULTFONTBGR, DEFAULTFONTBGG, DEFAULTFONTBGB, DEFAULTFONTBGA, txt);
#endif
len = strlen(txt);
len = strnlen(txt, len+1);
#ifdef LOGMESSAGES
if (logstream)
@@ -983,13 +986,13 @@ void I_InitJoystick(UINT8 index)
{
char dbpath[1024];
sprintf(dbpath, "%s" PATHSEP "gamecontrollerdb.txt", srb2path);
snprintf(dbpath, sizeof(dbpath), "%s" PATHSEP "gamecontrollerdb.txt", srb2path);
SDL_GameControllerAddMappingsFromFile(dbpath);
}
{
char dbpath[1024];
sprintf(dbpath, "%s" PATHSEP "gamecontrollerdb_user.txt", srb2home);
snprintf(dbpath, sizeof(dbpath), "%s" PATHSEP "gamecontrollerdb_user.txt", srb2home);
SDL_GameControllerAddMappingsFromFile(dbpath);
}
@@ -1151,8 +1154,7 @@ const char *I_GetJoyName(INT32 joyindex)
if (tempname)
{
memcpy(joyname, tempname, 255);
joyname[255] = '\0';
snprintf(joyname, sizeof(joyname), "%s", tempname);
}
}
@@ -1279,7 +1281,7 @@ static void I_SetupMumble(void)
int shmfd;
char memname[256];
snprintf(memname, 256, "/MumbleLink.%d", getuid());
snprintf(memname, sizeof(memname), "/MumbleLink.%d", getuid());
shmfd = shm_open(memname, O_RDWR, S_IRUSR | S_IWUSR);
if (shmfd < 0)
@@ -1396,10 +1398,14 @@ void I_Sleep(UINT32 ms)
void I_SleepDuration(precise_t duration)
{
#if defined(__linux__) || defined(__FreeBSD__) || defined(__HAIKU__)
#if defined(__linux__) || defined(__FreeBSD__) || defined(__HAIKU__) || defined(__OpenBSD__)
UINT64 precision = I_GetPrecisePrecision();
precise_t dest = I_GetPreciseTime() + duration;
#ifdef __OpenBSD__
precise_t slack = (precision / 50); // 20 ms slack
#else
precise_t slack = (precision / 5000); // 0.2 ms slack
#endif
if (duration > slack)
{
duration -= slack;
@@ -1412,7 +1418,11 @@ void I_SleepDuration(precise_t duration)
#endif
};
int status;
#ifdef __OpenBSD__
do status = nanosleep(&ts, &ts);
#else
do status = clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, &ts);
#endif
while (status == EINTR);
}
@@ -1697,16 +1707,20 @@ static void I_PrintSignal(INT32 signal_num, boolean core_dumped, char *signal_ms
if (core_dumped)
{
if (sigmsg)
sprintf(signal_msg, "%s (core dumped)", sigmsg);
{
snprintf(signal_msg, 512, "%s (core dumped)", sigmsg);
}
else
{
strcat(signal_msg, " (core dumped)");
}
}
else
{
sprintf(signal_msg, "%s", sigmsg);
snprintf(signal_msg, 512, "%s", sigmsg);
}
sprintf(signal_name, "%s", signame);
snprintf(signal_name, 128, "%s", signame);
}
int I_OpenURL(const char *url)
@@ -1884,7 +1898,7 @@ FUNCNORETURN static ATTRNORETURN void newsignalhandler_Warn(const char *pr)
{
char text[128];
snprintf(text, sizeof text,
snprintf(text, sizeof(text),
"Error while setting up signal reporting: %s: %s",
pr,
strerror(errno)
@@ -2100,7 +2114,7 @@ FUNCIERROR void ATTRNORETURN I_Error(const char *error, ...)
if (errorcount > 20)
{
va_start(argptr, error);
vsnprintf(buffer, 8192, error, argptr);
vsnprintf(buffer, sizeof(buffer), error, argptr);
va_end(argptr);
sigttl = "SRB2Kart " VERSIONSTRING " Recursive Error";
@@ -2114,7 +2128,7 @@ FUNCIERROR void ATTRNORETURN I_Error(const char *error, ...)
// Display error message in the console before we start shutting it down
va_start(argptr, error);
vsnprintf(buffer, 8192, error, argptr);
vsnprintf(buffer, sizeof(buffer), error, argptr);
va_end(argptr);
I_OutputMsg("\nI_Error(): %s\n", buffer);
@@ -2257,6 +2271,7 @@ void I_ShutdownSystem(void)
for (c = MAX_QUIT_FUNCS-1; c >= 0; c--)
if (quit_funcs[c])
(*quit_funcs[c])();
#ifdef LOGMESSAGES
if (logstream)
{
@@ -2341,7 +2356,8 @@ char *I_GetUserName(void)
}
}
}
strncpy(username, p, MAXPLAYERNAME);
snprintf(username, sizeof(username), "%s", p);
}
if (!fastcmp(username, ""))
@@ -2365,6 +2381,24 @@ INT32 I_mkdir(const char *dirname, INT32 unixright)
#endif
}
INT32 I_ChDir(const char *path)
{
#ifdef _WIN32
return (SetCurrentDirectoryA(path) ? 0 : -1);
#else
return chdir(path);
#endif
}
char *I_GetCwd(char *buf, size_t size)
{
#ifdef _WIN32
return (GetCurrentDirectoryA((DWORD)size, buf) ? buf : NULL);
#else
return getcwd(buf, size);
#endif
}
char *I_GetEnv(const char *name)
{
#ifdef NEED_SDL_GETENV
@@ -2386,13 +2420,15 @@ INT32 I_PutEnv(char *variable)
INT32 I_ClipboardCopy(const char *data, size_t size)
{
char storage[256];
if (size > 255)
size = 255;
memcpy(storage, data, size);
storage[size] = 0;
snprintf(storage, sizeof(storage), "%.*s", (int)size, data);
if (SDL_SetClipboardText(storage))
return 0;
return -1;
}
@@ -2405,7 +2441,7 @@ const char *I_ClipboardPaste(void)
return NULL;
clipboard_contents = SDL_GetClipboardText();
strlcpy(clipboard_modified, clipboard_contents, 256);
snprintf(clipboard_modified, sizeof(clipboard_modified), "%s", clipboard_contents);
SDL_free(clipboard_contents);
while (*i)
@@ -2421,6 +2457,7 @@ const char *I_ClipboardPaste(void)
*i = '?'; // Nonprintable chars become question marks
++i;
}
return (const char *)&clipboard_modified;
}
@@ -2434,28 +2471,23 @@ const char *I_ClipboardPaste(void)
*/
static boolean isWadPathOk(const char *path)
{
char *wad3path = static_cast<char*>(malloc(256));
char wad3path[256];
if (!wad3path)
return false;
sprintf(wad3path, pandf, path, WADKEYWORD);
snprintf(wad3path, sizeof(wad3path), pandf, path, WADKEYWORD);
if (FIL_ReadFileOK(wad3path))
{
free(wad3path);
return true;
}
free(wad3path);
return false;
}
static void pathonly(char *s)
static void pathonly(char *s, size_t size)
{
size_t j;
for (j = strlen(s); j != (size_t)-1; j--)
for (j = strnlen(s, size); j != (size_t)-1; j--)
{
if ((s[j] == '\\') || (s[j] == ':') || (s[j] == '/'))
{
@@ -2482,11 +2514,12 @@ static const char *searchWad(const char *searchDir)
static char tempsw[256] = "";
filestatus_t fstemp;
strcpy(tempsw, WADKEYWORD);
snprintf(tempsw, sizeof(tempsw), "%s", WADKEYWORD);
fstemp = filesearch(tempsw, searchDir, NULL, true, 20);
if (fstemp == FS_FOUND)
{
pathonly(tempsw);
pathonly(tempsw, sizeof(tempsw));
return tempsw;
}
@@ -2524,7 +2557,7 @@ static const char *locateWad(void)
#ifndef NOCWD
// examine current dir
strcpy(returnWadPath, ".");
snprintf(returnWadPath, sizeof(returnWadPath), "%s", ".");
I_OutputMsg(",%s", returnWadPath);
if (isWadPathOk(returnWadPath))
return NULL;
@@ -2536,7 +2569,7 @@ static const char *locateWad(void)
// examine user jart directory
if ((envstr = I_GetEnv("HOME")) != NULL)
{
sprintf(returnWadPath, "%s" PATHSEP DEFAULTDIR, envstr);
snprintf(returnWadPath, sizeof(returnWadPath), "%s" PATHSEP DEFAULTDIR, envstr);
CHECKWADPATH(returnWadPath);
}
#endif
@@ -2550,7 +2583,7 @@ static const char *locateWad(void)
// examine default dirs
for (i = 0; wadDefaultPaths[i]; i++)
{
strcpy(returnWadPath, wadDefaultPaths[i]);
snprintf(returnWadPath, sizeof(returnWadPath), "%s", wadDefaultPaths[i]);
CHECKWADPATH(returnWadPath);
}
@@ -2578,12 +2611,11 @@ extern "C" const char *I_LocateWad(void)
// change to the directory where we found srb2.srb
#if defined (_WIN32)
waddir = _fullpath(NULL, waddir, MAX_PATH);
SetCurrentDirectoryA(waddir);
#else
waddir = realpath(waddir, NULL);
if (waddir == NULL || chdir(waddir) == -1)
I_OutputMsg("Couldn't change working directory\n");
#endif
if (waddir == NULL || I_ChDir(waddir) == -1)
I_OutputMsg("Couldn't change working directory\n");
}
return waddir;
+8 -2
View File
@@ -183,13 +183,17 @@ void I_TTFDrawText(TTF_Font *font, TextQuality quality, INT32 fgR, INT32 fgG, IN
TTFRect.x = TTFRectCheck.x;
TTFRect.y = TTFRectCheck.y;
}
// Copy the character to the text buffer.
sprintf(textbuffer, "%s%c", textbuffer, c);
snprintf(textbuffer, sizeof(textbuffer), "%s%c", textbuffer, c);
// Hack to allow TTF_SizeText to work properly.
sprintf(linebuffer, "%c", c);
snprintf(linebuffer, sizeof(linebuffer), "%c", c);
// If we have reached the end of the screen, move to the next available line.
TTF_SizeText(currentfont, linebuffer, &w, &h);
TTFRectCheck.x += w;
if (TTFRectCheck.x >= res.width)
{
// Render cached text to the SDL surface.
@@ -204,8 +208,10 @@ void I_TTFDrawText(TTF_Font *font, TextQuality quality, INT32 fgR, INT32 fgG, IN
TTFRect.y = TTFRectCheck.y;
}
}
// Add 1 to the pointer reference for the character to process.
textmsg++;
// Copy contents of the now-old buffer to somewhere else, so it can be referenced in next loop.
prevc = c;
}
+3 -3
View File
@@ -1538,9 +1538,9 @@ const char *VID_GetModeName(INT32 modeNum)
if (modeNum > MAXWINMODES)
return NULL;
sprintf(&vidModeName[modeNum][0], "%dx%d",
windowedModes[modeNum][0],
windowedModes[modeNum][1]);
snprintf(&vidModeName[modeNum][0], sizeof(vidModeName[modeNum]), "%dx%d",
windowedModes[modeNum][0],
windowedModes[modeNum][1]);
return &vidModeName[modeNum][0];
}
+1 -1
View File
@@ -868,7 +868,7 @@ boolean I_SetSongSpeed(float speed)
{
// deprecated in 0.5.0
char modspd[13];
sprintf(modspd, "%g", speed);
snprintf(modspd, sizeof(modspd), "%g", speed);
openmpt_module_ctl_set(openmpt_mhandle, "play.tempo_factor", modspd);
}
#else
+1 -1
View File
@@ -591,7 +591,7 @@ static void ST_overlayDrawer(void)
char name[MAXPLAYERNAME+12];
INT32 y = (stplyrnum == 0) ? 4 : BASEVIDHEIGHT/2-12;
sprintf(name, "VIEWPOINT: %s", player_names[stplyr-players]);
snprintf(name, sizeof(name), "VIEWPOINT: %s", player_names[stplyr-players]);
V_DrawRightAlignedThinString(BASEVIDWIDTH-40, y, V_HUDTRANSHALF|V_ALLOWLOWERCASE|K_calcSplitFlags(V_SNAPTOTOP|V_SNAPTOBOTTOM|V_SNAPTORIGHT), name);
}
else if (splitscreen)
+2 -4
View File
@@ -292,8 +292,7 @@ static inline void W_LoadDehackedLumpsPK3(UINT16 wadnum)
if (!name)
I_Error("W_LoadDehackedLumpsPK3: Out of memory!\n");
sprintf(name, "%s|%s", wadfiles[wadnum]->filename, lump_p->fullname);
name[length] = '\0';
snprintf(name, length + 1, "%s|%s", wadfiles[wadnum]->filename, lump_p->fullname);
CONS_Printf("Loading SOC from %s\n", name);
DEH_LoadDehackedLumpPwad(wadnum, posStart);
free(name);
@@ -328,8 +327,7 @@ static inline void W_LoadDehackedLumps(UINT16 wadnum)
if (!name)
I_Error("W_LoadDehackedLumps: Out of memory!\n");
sprintf(name, "%s|%s", wadfiles[wadnum]->filename, lump_p->fullname);
name[length] = '\0';
snprintf(name, length + 1, "%s|%s", wadfiles[wadnum]->filename, lump_p->fullname);
CONS_Printf(M_GetText("Loading SOC from %s\n"), name);
DEH_LoadDehackedLumpPwad(wadnum, lump);
+1 -1
View File
@@ -118,7 +118,7 @@ static VOID FPrintf(HANDLE fileHandle, LPCSTR lpFmt, ...)
DWORD bytesWritten;
va_start(arglist, lpFmt);
vsnprintf(str, 1999, lpFmt, arglist);
vsnprintf(str, sizeof(str), lpFmt, arglist);
va_end(arglist);
WriteFile(fileHandle, str, (DWORD)strlen(str), &bytesWritten, NULL);
+37 -21
View File
@@ -153,7 +153,7 @@ static void Y_CalculateMatchData(UINT8 rankingsmode, void (*comparison)(INT32))
;
else if ((data.rankingsmode = (boolean)rankingsmode))
{
sprintf(data.levelstring, "* Total Rankings *");
snprintf(data.levelstring, sizeof(data.levelstring), "* Total Rankings *");
data.encore = false;
}
else
@@ -162,32 +162,41 @@ static void Y_CalculateMatchData(UINT8 rankingsmode, void (*comparison)(INT32))
if (mapheaderinfo[prevmap]->levelflags & LF_NOZONE)
{
if (mapheaderinfo[prevmap]->actnum[0])
{
snprintf(data.levelstring,
sizeof data.levelstring,
sizeof(data.levelstring),
"* %s %s *",
mapheaderinfo[prevmap]->lvlttl, mapheaderinfo[prevmap]->actnum);
}
else
{
snprintf(data.levelstring,
sizeof data.levelstring,
sizeof(data.levelstring),
"* %s *",
mapheaderinfo[prevmap]->lvlttl);
}
}
else
{
const char *zonttl = (mapheaderinfo[prevmap]->zonttl[0] ? mapheaderinfo[prevmap]->zonttl : "Zone");
if (mapheaderinfo[prevmap]->actnum[0])
{
snprintf(data.levelstring,
sizeof data.levelstring,
sizeof(data.levelstring),
"* %s %s %s *",
mapheaderinfo[prevmap]->lvlttl, zonttl, mapheaderinfo[prevmap]->actnum);
}
else
{
snprintf(data.levelstring,
sizeof data.levelstring,
sizeof(data.levelstring),
"* %s %s *",
mapheaderinfo[prevmap]->lvlttl, zonttl);
}
}
data.levelstring[sizeof data.levelstring - 1] = '\0';
data.levelstring[sizeof(data.levelstring) - 1] = '\0';
data.encore = encoremode;
@@ -265,13 +274,13 @@ static void Y_CalculateMatchData(UINT8 rankingsmode, void (*comparison)(INT32))
//
static void Y_PlayerStandingsDrawer(y_data_t *standings, INT32 x, INT32 hilicol)
{
INT32 i;
if (standings->numplayers == 0)
{
return;
}
INT32 i;
#define NUMFORNEWCOLUMN 8
INT32 y = 41, gutter = ((standings->numplayers > NUMFORNEWCOLUMN) ? 0 : (BASEVIDWIDTH/2));
INT32 dupadjust = cv_betainterscreen.value ? 314 : vid.scaledwidth, duptweak = cv_betainterscreen.value ? -3 : (dupadjust - BASEVIDWIDTH)/2;
@@ -312,6 +321,12 @@ static void Y_PlayerStandingsDrawer(y_data_t *standings, INT32 x, INT32 hilicol)
const UINT8 pnum = standings->num[i];
player_t *player = &players[pnum];
#if MAXPLAYERS > 16
// 32 Player TODO: port over and cleanup standings drawer from sat-32p/blankart
if (i > 16)
break;
#endif
if (pnum == MAXPLAYERS)
;
else if (!playeringame[pnum] || player->spectator)
@@ -360,9 +375,9 @@ static void Y_PlayerStandingsDrawer(y_data_t *standings, INT32 x, INT32 hilicol)
if (standings->increase[pnum] != UINT8_MAX)
{
if (standings->increase[pnum] > 9)
snprintf(strtime, sizeof strtime, "(+%02d)", standings->increase[pnum]);
snprintf(strtime, sizeof(strtime), "(+%02d)", standings->increase[pnum]);
else
snprintf(strtime, sizeof strtime, "(+ %d)", standings->increase[pnum]);
snprintf(strtime, sizeof(strtime), "(+ %d)", standings->increase[pnum]);
if (standings->numplayers > NUMFORNEWCOLUMN)
V_DrawRightAlignedThinString(x+135+gutter, y-1, V_6WIDTHSPACE, strtime);
@@ -370,7 +385,7 @@ static void Y_PlayerStandingsDrawer(y_data_t *standings, INT32 x, INT32 hilicol)
V_DrawRightAlignedString(x+120+gutter, y, 0, strtime);
}
snprintf(strtime, sizeof strtime, "%d", standings->val[i]);
snprintf(strtime, sizeof(strtime), "%d", standings->val[i]);
if (standings->numplayers > NUMFORNEWCOLUMN)
V_DrawRightAlignedThinString(x+152+gutter, y-1, V_6WIDTHSPACE, strtime);
@@ -385,9 +400,9 @@ static void Y_PlayerStandingsDrawer(y_data_t *standings, INT32 x, INT32 hilicol)
{
if (intertype == int_race)
{
snprintf(strtime, sizeof strtime, "%i'%02i\"%02i", G_TicsToMinutes(standings->val[i], true),
snprintf(strtime, sizeof(strtime), "%i'%02i\"%02i", G_TicsToMinutes(standings->val[i], true),
G_TicsToSeconds(standings->val[i]), G_TicsToCentiseconds(standings->val[i]));
strtime[sizeof strtime - 1] = '\0';
strtime[sizeof(strtime) - 1] = '\0';
if (standings->numplayers > NUMFORNEWCOLUMN)
V_DrawRightAlignedThinString(x+152+gutter, y-1, V_6WIDTHSPACE, strtime);
@@ -652,15 +667,16 @@ static void Y_UpdateRecordReplays(void)
if ((gpath = malloc(glen)) == NULL)
I_Error("Out of memory for replay filepath\n");
sprintf(gpath,"%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s", srb2home, timeattackfolder, G_BuildMapName(gamemap));
snprintf(lastdemo, 255, "%s-%s-last.lmp", gpath, cv_chooseskin.string);
snprintf(gpath, glen, "%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s", srb2home, timeattackfolder, G_BuildMapName(gamemap));
snprintf(lastdemo, sizeof(lastdemo)-1, "%s-%s-last.lmp", gpath, cv_chooseskin.string);
if (FIL_FileExists(lastdemo))
{
UINT8 *buf;
size_t len = FIL_ReadFile(lastdemo, &buf);
snprintf(bestdemo, 255, "%s-%s-time-best.lmp", gpath, cv_chooseskin.string);
snprintf(bestdemo, sizeof(bestdemo)-1, "%s-%s-time-best.lmp", gpath, cv_chooseskin.string);
if (!FIL_FileExists(bestdemo) || G_CmpDemoTime(bestdemo, lastdemo) & 1)
{ // Better time, save this demo.
if (FIL_FileExists(bestdemo))
@@ -669,7 +685,7 @@ static void Y_UpdateRecordReplays(void)
CONS_Printf("\x83%s\x80 %s '%s'\n", M_GetText("NEW RECORD TIME!"), M_GetText("Saved replay as"), bestdemo);
}
snprintf(bestdemo, 255, "%s-%s-lap-best.lmp", gpath, cv_chooseskin.string);
snprintf(bestdemo, sizeof(bestdemo)-1, "%s-%s-lap-best.lmp", gpath, cv_chooseskin.string);
if (!FIL_FileExists(bestdemo) || G_CmpDemoTime(bestdemo, lastdemo) & (1<<1))
{ // Better lap time, save this demo.
if (FIL_FileExists(bestdemo))
@@ -1499,12 +1515,12 @@ void Y_StartVote(void)
{
if (mapheaderinfo[votelevels[i][0]]->actnum[0])
snprintf(levelinfo[i].str,
sizeof levelinfo[i].str,
sizeof(levelinfo[i].str),
"%s %s",
mapheaderinfo[votelevels[i][0]]->lvlttl, mapheaderinfo[votelevels[i][0]]->actnum);
else
snprintf(levelinfo[i].str,
sizeof levelinfo[i].str,
sizeof(levelinfo[i].str),
"%s",
mapheaderinfo[votelevels[i][0]]->lvlttl);
}
@@ -1512,12 +1528,12 @@ void Y_StartVote(void)
{
if (mapheaderinfo[votelevels[i][0]]->actnum[0])
snprintf(levelinfo[i].str,
sizeof levelinfo[i].str,
sizeof(levelinfo[i].str),
"%s %s %s",
mapheaderinfo[votelevels[i][0]]->lvlttl, mapheaderinfo[votelevels[i][0]]->zonttl, mapheaderinfo[votelevels[i][0]]->actnum);
else
snprintf(levelinfo[i].str,
sizeof levelinfo[i].str,
sizeof(levelinfo[i].str),
"%s %s",
mapheaderinfo[votelevels[i][0]]->lvlttl, mapheaderinfo[votelevels[i][0]]->zonttl);
}