Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision

Target

Select target project
  • STJr/SRB2
  • Sryder/SRB2
  • wolfy852/SRB2
  • Alpha2244/SRB2
  • Inuyasha/SRB2
  • yoshibot/SRB2
  • TehRealSalt/SRB2
  • PrisimaTF/SRB2
  • Hatninja/SRB2
  • SteelT/SRB2
  • james/SRB2
  • ShaderWraith/SRB2
  • SinnamonLat/SRB2
  • mazmazz_/SRB2
  • filpAM/SRB2
  • chaoloveicemdboy/SRB2
  • Whooa21/SRB2
  • Machturne/SRB2
  • Golden/SRB2
  • Tatsuru/SRB2
  • Snu/SRB2
  • Zwip-Zwap_Zapony/SRB2
  • fickleheart/SRB2
  • alphaRexJames/SRB2
  • JJK/SRB2
  • diskpoppy/SRB2
  • Hannu_Hanhi/SRB2
  • ZipperQR/SRB2
  • kays/SRB2
  • spherallic/SRB2
  • Zippy_Zolton/SRB2
  • namiishere/SRB2
  • Ors/SRB2
  • SMS_Alfredo/SRB2
  • sonic_edge/SRB2
  • lavla/SRB2
  • ashi/SRB2
  • X.organic/SRB2
  • Fafabis/SRB2
  • Meziu/SRB2
  • v-rob/SRB2
  • tertu/SRB2
  • bitten2up/SRB2
  • flarn2006/SRB2
  • Krabs/SRB2
  • clairebun/SRB2
  • Lactozilla/SRB2
  • thehackstack/SRB2
  • Spice/SRB2
  • win8linux/SRB2
  • JohnFrostFox/SRB2
  • talktoneon726/SRB2
  • Wane/SRB2
  • Lamibe/SRB2
  • spectrumuk2/srb-2
  • nerdyminer18/srb-2
  • 256nil/SRB2
  • ARJr/SRB2
  • Alam/SRB2
  • Zenya/srb-2-marathon-demos
  • Acelite/srb-2-archivedmodifications
  • MIDIMan/SRB2
  • Lach/SRB2
  • Frostiikin/bounce-tweaks
  • Jaden/SRB2
  • Tyron/SRB2
  • Astronight/SRB2
  • Mari0shi06/SRB2
  • aiire/SRB2
  • Galactice/SRB2
  • srb2-ports/srb2-dreamcast
  • sdasdas/SRB2
  • chreas/srb-2-vr
  • StarManiaKG/the-story-of-sinically-rocketing-and-botching-the-2nd
  • LoganAir/SRB2
  • NepDisk/srb-2
  • alufolie91/SRB2
  • Felicia.iso/SRB2
  • twi/SRB2
  • BarrelsOFun/SRB2
  • Speed2411/SRB2
  • Leather_Realms/SRB2
  • Ayemar/SRB2
  • Acelite/SRB2
  • VladDoc/SRB2
  • kaldrum/model-features
  • strawberryfox417/SRB2
  • Lugent/SRB2
  • Rem/SRB2
  • Refrag/SRB2
  • Henry_3230/srb-3230
  • TehPuertoRicanSpartan2/tprs-srb2
  • Leminn/srb-2-marathon-stuff
  • chromaticpipe2/SRB2
  • MiguelGustavo15/SRB2
  • Maru/srb-2-tests
  • SilicDev/SRB2
  • UnmatchedBracket/SRB2
  • HybridDog/SRB2
  • xordspar0/SRB2
  • jsjhbewfhh/SRB2
  • Fancy2209/SRB2
  • Lorsoen/SRB2
  • shindoukin/SRB2
  • GamerOfDays/SRB2
  • Craftyawesome/SRB2
  • tenshi-tensai-tennoji/SRB2
  • Scarfdudebalder/SRB2
  • luigi-budd/srb-2-fix-interplag-lockon
  • mskluesner/SRB2
  • johnpetersa19/SRB2
  • Pheazant/SRB2
  • chromaticpipe2/srb2classic
  • romoney5/SRB2
  • PAS/SRB2Classic
  • BlueStaggo/SRB2
  • Jisk/srb-2-beef-jerky
117 results
Select Git revision
Show changes
// SONIC ROBO BLAST 2 // SONIC ROBO BLAST 2
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Copyright (C) 1998-2000 by DooM Legacy Team. // Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2023 by Sonic Team Junior. // Copyright (C) 1999-2024 by Sonic Team Junior.
// //
// This program is free software distributed under the // This program is free software distributed under the
// terms of the GNU General Public License, version 2. // terms of the GNU General Public License, version 2.
...@@ -11,9 +11,6 @@ ...@@ -11,9 +11,6 @@
/// \brief Macros to read/write from/to a UINT8 *, /// \brief Macros to read/write from/to a UINT8 *,
/// used for packet creation and such /// used for packet creation and such
#if defined (__alpha__) || defined (__arm__) || defined (__mips__) || defined (__ia64__) || defined (__clang__)
#define DEALIGNED
#endif
#include "endian.h" #include "endian.h"
...@@ -21,7 +18,6 @@ ...@@ -21,7 +18,6 @@
// //
// Little-endian machines // Little-endian machines
// //
#ifdef DEALIGNED
#define WRITEUINT8(p,b) do { UINT8 *p_tmp = (void *)p; const UINT8 tv = ( UINT8)(b); memcpy(p, &tv, sizeof( UINT8)); p_tmp++; p = (void *)p_tmp; } while (0) #define WRITEUINT8(p,b) do { UINT8 *p_tmp = (void *)p; const UINT8 tv = ( UINT8)(b); memcpy(p, &tv, sizeof( UINT8)); p_tmp++; p = (void *)p_tmp; } while (0)
#define WRITESINT8(p,b) do { SINT8 *p_tmp = (void *)p; const SINT8 tv = ( UINT8)(b); memcpy(p, &tv, sizeof( UINT8)); p_tmp++; p = (void *)p_tmp; } while (0) #define WRITESINT8(p,b) do { SINT8 *p_tmp = (void *)p; const SINT8 tv = ( UINT8)(b); memcpy(p, &tv, sizeof( UINT8)); p_tmp++; p = (void *)p_tmp; } while (0)
#define WRITEINT16(p,b) do { INT16 *p_tmp = (void *)p; const INT16 tv = ( INT16)(b); memcpy(p, &tv, sizeof( INT16)); p_tmp++; p = (void *)p_tmp; } while (0) #define WRITEINT16(p,b) do { INT16 *p_tmp = (void *)p; const INT16 tv = ( INT16)(b); memcpy(p, &tv, sizeof( INT16)); p_tmp++; p = (void *)p_tmp; } while (0)
...@@ -31,20 +27,8 @@ ...@@ -31,20 +27,8 @@
#define WRITECHAR(p,b) do { char *p_tmp = (void *)p; const char tv = ( char)(b); memcpy(p, &tv, sizeof( char)); p_tmp++; p = (void *)p_tmp; } while (0) #define WRITECHAR(p,b) do { char *p_tmp = (void *)p; const char tv = ( char)(b); memcpy(p, &tv, sizeof( char)); p_tmp++; p = (void *)p_tmp; } while (0)
#define WRITEFIXED(p,b) do { fixed_t *p_tmp = (void *)p; const fixed_t tv = (fixed_t)(b); memcpy(p, &tv, sizeof(fixed_t)); p_tmp++; p = (void *)p_tmp; } while (0) #define WRITEFIXED(p,b) do { fixed_t *p_tmp = (void *)p; const fixed_t tv = (fixed_t)(b); memcpy(p, &tv, sizeof(fixed_t)); p_tmp++; p = (void *)p_tmp; } while (0)
#define WRITEANGLE(p,b) do { angle_t *p_tmp = (void *)p; const angle_t tv = (angle_t)(b); memcpy(p, &tv, sizeof(angle_t)); p_tmp++; p = (void *)p_tmp; } while (0) #define WRITEANGLE(p,b) do { angle_t *p_tmp = (void *)p; const angle_t tv = (angle_t)(b); memcpy(p, &tv, sizeof(angle_t)); p_tmp++; p = (void *)p_tmp; } while (0)
#else
#define WRITEUINT8(p,b) do { UINT8 *p_tmp = ( UINT8 *)p; *p_tmp = ( UINT8)(b); p_tmp++; p = (void *)p_tmp; } while (0)
#define WRITESINT8(p,b) do { SINT8 *p_tmp = ( SINT8 *)p; *p_tmp = ( SINT8)(b); p_tmp++; p = (void *)p_tmp; } while (0)
#define WRITEINT16(p,b) do { INT16 *p_tmp = ( INT16 *)p; *p_tmp = ( INT16)(b); p_tmp++; p = (void *)p_tmp; } while (0)
#define WRITEUINT16(p,b) do { UINT16 *p_tmp = ( UINT16 *)p; *p_tmp = ( UINT16)(b); p_tmp++; p = (void *)p_tmp; } while (0)
#define WRITEINT32(p,b) do { INT32 *p_tmp = ( INT32 *)p; *p_tmp = ( INT32)(b); p_tmp++; p = (void *)p_tmp; } while (0)
#define WRITEUINT32(p,b) do { UINT32 *p_tmp = ( UINT32 *)p; *p_tmp = ( UINT32)(b); p_tmp++; p = (void *)p_tmp; } while (0)
#define WRITECHAR(p,b) do { char *p_tmp = ( char *)p; *p_tmp = ( char)(b); p_tmp++; p = (void *)p_tmp; } while (0)
#define WRITEFIXED(p,b) do { fixed_t *p_tmp = (fixed_t *)p; *p_tmp = (fixed_t)(b); p_tmp++; p = (void *)p_tmp; } while (0)
#define WRITEANGLE(p,b) do { angle_t *p_tmp = (angle_t *)p; *p_tmp = (angle_t)(b); p_tmp++; p = (void *)p_tmp; } while (0)
#endif
#ifdef __GNUC__ #ifdef __GNUC__
#ifdef DEALIGNED
#define READUINT8(p) ({ UINT8 *p_tmp = (void *)p; UINT8 b; memcpy(&b, p, sizeof( UINT8)); p_tmp++; p = (void *)p_tmp; b; }) #define READUINT8(p) ({ UINT8 *p_tmp = (void *)p; UINT8 b; memcpy(&b, p, sizeof( UINT8)); p_tmp++; p = (void *)p_tmp; b; })
#define READSINT8(p) ({ SINT8 *p_tmp = (void *)p; SINT8 b; memcpy(&b, p, sizeof( SINT8)); p_tmp++; p = (void *)p_tmp; b; }) #define READSINT8(p) ({ SINT8 *p_tmp = (void *)p; SINT8 b; memcpy(&b, p, sizeof( SINT8)); p_tmp++; p = (void *)p_tmp; b; })
#define READINT16(p) ({ INT16 *p_tmp = (void *)p; INT16 b; memcpy(&b, p, sizeof( INT16)); p_tmp++; p = (void *)p_tmp; b; }) #define READINT16(p) ({ INT16 *p_tmp = (void *)p; INT16 b; memcpy(&b, p, sizeof( INT16)); p_tmp++; p = (void *)p_tmp; b; })
...@@ -55,17 +39,6 @@ ...@@ -55,17 +39,6 @@
#define READFIXED(p) ({ fixed_t *p_tmp = (void *)p; fixed_t b; memcpy(&b, p, sizeof(fixed_t)); p_tmp++; p = (void *)p_tmp; b; }) #define READFIXED(p) ({ fixed_t *p_tmp = (void *)p; fixed_t b; memcpy(&b, p, sizeof(fixed_t)); p_tmp++; p = (void *)p_tmp; b; })
#define READANGLE(p) ({ angle_t *p_tmp = (void *)p; angle_t b; memcpy(&b, p, sizeof(angle_t)); p_tmp++; p = (void *)p_tmp; b; }) #define READANGLE(p) ({ angle_t *p_tmp = (void *)p; angle_t b; memcpy(&b, p, sizeof(angle_t)); p_tmp++; p = (void *)p_tmp; b; })
#else #else
#define READUINT8(p) ({ UINT8 *p_tmp = ( UINT8 *)p; UINT8 b = *p_tmp; p_tmp++; p = (void *)p_tmp; b; })
#define READSINT8(p) ({ SINT8 *p_tmp = ( SINT8 *)p; SINT8 b = *p_tmp; p_tmp++; p = (void *)p_tmp; b; })
#define READINT16(p) ({ INT16 *p_tmp = ( INT16 *)p; INT16 b = *p_tmp; p_tmp++; p = (void *)p_tmp; b; })
#define READUINT16(p) ({ UINT16 *p_tmp = ( UINT16 *)p; UINT16 b = *p_tmp; p_tmp++; p = (void *)p_tmp; b; })
#define READINT32(p) ({ INT32 *p_tmp = ( INT32 *)p; INT32 b = *p_tmp; p_tmp++; p = (void *)p_tmp; b; })
#define READUINT32(p) ({ UINT32 *p_tmp = ( UINT32 *)p; UINT32 b = *p_tmp; p_tmp++; p = (void *)p_tmp; b; })
#define READCHAR(p) ({ char *p_tmp = ( char *)p; char b = *p_tmp; p_tmp++; p = (void *)p_tmp; b; })
#define READFIXED(p) ({ fixed_t *p_tmp = (fixed_t *)p; fixed_t b = *p_tmp; p_tmp++; p = (void *)p_tmp; b; })
#define READANGLE(p) ({ angle_t *p_tmp = (angle_t *)p; angle_t b = *p_tmp; p_tmp++; p = (void *)p_tmp; b; })
#endif
#else
#define READUINT8(p) *(( UINT8 *)p)++ #define READUINT8(p) *(( UINT8 *)p)++
#define READSINT8(p) *(( SINT8 *)p)++ #define READSINT8(p) *(( SINT8 *)p)++
#define READINT16(p) *(( INT16 *)p)++ #define READINT16(p) *(( INT16 *)p)++
...@@ -148,8 +121,6 @@ FUNCINLINE static ATTRINLINE UINT32 readulong(void *ptr) ...@@ -148,8 +121,6 @@ FUNCINLINE static ATTRINLINE UINT32 readulong(void *ptr)
#define READANGLE(p) ({ angle_t *p_tmp = (angle_t *)p; angle_t b = readulong(p); p_tmp++; p = (void *)p_tmp; b; }) #define READANGLE(p) ({ angle_t *p_tmp = (angle_t *)p; angle_t b = readulong(p); p_tmp++; p = (void *)p_tmp; b; })
#endif //SRB2_BIG_ENDIAN #endif //SRB2_BIG_ENDIAN
#undef DEALIGNED
#define WRITESTRINGN(p, s, n) { \ #define WRITESTRINGN(p, s, n) { \
size_t tmp_i; \ size_t tmp_i; \
\ \
......
// SONIC ROBO BLAST 2 // SONIC ROBO BLAST 2
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Copyright (C) 1998-2000 by DooM Legacy Team. // Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2023 by Sonic Team Junior. // Copyright (C) 1999-2024 by Sonic Team Junior.
// //
// This program is free software distributed under the // This program is free software distributed under the
// terms of the GNU General Public License, version 2. // terms of the GNU General Public License, version 2.
...@@ -648,7 +648,7 @@ static void COM_ExecuteString(char *ptext) ...@@ -648,7 +648,7 @@ static void COM_ExecuteString(char *ptext)
{ {
if ((com_flags & COM_LUA) && !(cmd->flags & COM_LUA)) if ((com_flags & COM_LUA) && !(cmd->flags & COM_LUA))
{ {
CONS_Alert(CONS_WARNING, "Command '%s' cannot be run from Lua.\n", cmd->name); CONS_Alert(CONS_WARNING, "Command '%s' cannot be run from a script.\n", cmd->name);
return; return;
} }
...@@ -705,7 +705,7 @@ static void add_alias(char *newname, char *newcmd) ...@@ -705,7 +705,7 @@ static void add_alias(char *newname, char *newcmd)
{ {
if (!stricmp(newname, a->name)) if (!stricmp(newname, a->name))
{ {
Z_Free(a->value); // Free old cmd Z_Free(a->value); // Free old cmd
a->value = newcmd; a->value = newcmd;
return; return;
} }
...@@ -809,49 +809,60 @@ static void COM_CEchoDuration_f(void) ...@@ -809,49 +809,60 @@ static void COM_CEchoDuration_f(void)
/** Executes a script file. /** Executes a script file.
*/ */
static void COM_Exec_f(void) boolean COM_ExecFile(const char *scriptname, com_flags_t flags, boolean silent)
{ {
UINT8 *buf = NULL; UINT8 *buf = NULL;
char filename[256]; char filename[256];
if (COM_Argc() < 2 || COM_Argc() > 3) if (!D_CheckPathAllowed(scriptname, "tried to exec"))
{ return false;
CONS_Printf(M_GetText("exec <filename>: run a script file\n"));
return;
}
if (!D_CheckPathAllowed(COM_Argv(1), "tried to exec"))
return;
// load file // load file
// Try with Argv passed verbatim first, for back compat // Try with Argv passed verbatim first, for back compat
FIL_ReadFile(COM_Argv(1), &buf); FIL_ReadFile(scriptname, &buf);
if (!buf) if (!buf)
{ {
// Now try by searching the file path // Now try by searching the file path
// filename is modified with the full found path // filename is modified with the full found path
strcpy(filename, COM_Argv(1)); strlcpy(filename, scriptname, sizeof(filename));
if (findfile(filename, NULL, true) != FS_NOTFOUND) if (findfile(filename, NULL, true) != FS_NOTFOUND)
FIL_ReadFile(filename, &buf); FIL_ReadFile(filename, &buf);
if (!buf) if (!buf)
{ return false;
if (!COM_CheckParm("-noerror"))
CONS_Printf(M_GetText("couldn't execute file %s\n"), COM_Argv(1));
return;
}
} }
if (!COM_CheckParm("-silent")) if (!silent)
CONS_Printf(M_GetText("executing %s\n"), COM_Argv(1)); CONS_Printf(M_GetText("Executing %s\n"), scriptname);
// insert text file into the command buffer // insert text file into the command buffer
COM_BufAddTextEx((char *)buf, com_flags); COM_BufAddTextEx((char *)buf, flags);
COM_BufAddTextEx("\n", com_flags); COM_BufAddTextEx("\n", flags);
// free buffer // free buffer
Z_Free(buf); Z_Free(buf);
return true;
}
static void COM_Exec_f(void)
{
boolean silent;
if (COM_Argc() < 2 || COM_Argc() > 3)
{
CONS_Printf(M_GetText("exec <filename>: run a script file\n"));
return;
}
silent = COM_CheckParm("-silent");
if (COM_ExecFile(COM_Argv(1), com_flags, silent))
return;
if (!COM_CheckParm("-noerror"))
CONS_Printf(M_GetText("Couldn't execute file %s\n"), COM_Argv(1));
} }
/** Delays execution of the rest of the commands until the next frame. /** Delays execution of the rest of the commands until the next frame.
...@@ -1722,8 +1733,7 @@ badinput: ...@@ -1722,8 +1733,7 @@ badinput:
static boolean serverloading = false; static boolean serverloading = false;
static consvar_t * static consvar_t *ReadNetVar(save_t *p, char **return_value, boolean *return_stealth)
ReadNetVar (UINT8 **p, char **return_value, boolean *return_stealth)
{ {
UINT16 netid; UINT16 netid;
char *val; char *val;
...@@ -1731,10 +1741,10 @@ ReadNetVar (UINT8 **p, char **return_value, boolean *return_stealth) ...@@ -1731,10 +1741,10 @@ ReadNetVar (UINT8 **p, char **return_value, boolean *return_stealth)
consvar_t *cvar; consvar_t *cvar;
netid = READUINT16 (*p); netid = P_ReadUINT16(p);
val = (char *)*p; val = (char *)&p->buf[p->pos];
SKIPSTRING (*p); P_SkipString(p);
stealth = READUINT8 (*p); stealth = P_ReadUINT8(p);
cvar = CV_FindNetVar(netid); cvar = CV_FindNetVar(netid);
...@@ -1752,8 +1762,7 @@ ReadNetVar (UINT8 **p, char **return_value, boolean *return_stealth) ...@@ -1752,8 +1762,7 @@ ReadNetVar (UINT8 **p, char **return_value, boolean *return_stealth)
} }
#ifdef OLD22DEMOCOMPAT #ifdef OLD22DEMOCOMPAT
static consvar_t * static consvar_t *ReadOldDemoVar(save_t *p, char **return_value, boolean *return_stealth)
ReadOldDemoVar (UINT8 **p, char **return_value, boolean *return_stealth)
{ {
UINT16 id; UINT16 id;
char *val; char *val;
...@@ -1761,10 +1770,10 @@ ReadOldDemoVar (UINT8 **p, char **return_value, boolean *return_stealth) ...@@ -1761,10 +1770,10 @@ ReadOldDemoVar (UINT8 **p, char **return_value, boolean *return_stealth)
old_demo_var_t *demovar; old_demo_var_t *demovar;
id = READUINT16 (*p); id = P_ReadUINT16(p);
val = (char *)*p; val = (char *)&p->buf[p->pos];
SKIPSTRING (*p); P_SkipString(p);
stealth = READUINT8 (*p); stealth = P_ReadUINT8(p);
demovar = CV_FindOldDemoVar(id); demovar = CV_FindOldDemoVar(id);
...@@ -1783,8 +1792,7 @@ ReadOldDemoVar (UINT8 **p, char **return_value, boolean *return_stealth) ...@@ -1783,8 +1792,7 @@ ReadOldDemoVar (UINT8 **p, char **return_value, boolean *return_stealth)
} }
#endif/*OLD22DEMOCOMPAT*/ #endif/*OLD22DEMOCOMPAT*/
static consvar_t * static consvar_t *ReadDemoVar(save_t *p, char **return_value, boolean *return_stealth)
ReadDemoVar (UINT8 **p, char **return_value, boolean *return_stealth)
{ {
char *name; char *name;
char *val; char *val;
...@@ -1792,11 +1800,11 @@ ReadDemoVar (UINT8 **p, char **return_value, boolean *return_stealth) ...@@ -1792,11 +1800,11 @@ ReadDemoVar (UINT8 **p, char **return_value, boolean *return_stealth)
consvar_t *cvar; consvar_t *cvar;
name = (char *)*p; name = (char *)&p->buf[p->pos];
SKIPSTRING (*p); P_SkipString(p);
val = (char *)*p; val = (char *)&p->buf[p->pos];
SKIPSTRING (*p); P_SkipString(p);
stealth = READUINT8 (*p); stealth = P_ReadUINT8(p);
cvar = CV_FindVar(name); cvar = CV_FindVar(name);
...@@ -1826,41 +1834,46 @@ static void Got_NetVar(UINT8 **p, INT32 playernum) ...@@ -1826,41 +1834,46 @@ static void Got_NetVar(UINT8 **p, INT32 playernum)
return; return;
} }
cvar = ReadNetVar(p, &svalue, &stealth); save_t save_p;
save_p.buf = *p;
save_p.size = MAXTEXTCMD;
save_p.pos = 0;
cvar = ReadNetVar(&save_p, &svalue, &stealth);
*p = &save_p.buf[save_p.pos];
if (cvar) if (cvar)
Setvalue(cvar, svalue, stealth); Setvalue(cvar, svalue, stealth);
} }
void CV_SaveVars(UINT8 **p, boolean in_demo) void CV_SaveVars(save_t *p, boolean in_demo)
{ {
consvar_t *cvar; consvar_t *cvar;
UINT8 *count_p = *p; UINT8 *count_p = &p->buf[p->pos];
UINT16 count = 0; UINT16 count = 0;
// send only changed cvars ... // send only changed cvars ...
// the client will reset all netvars to default before loading // the client will reset all netvars to default before loading
WRITEUINT16(*p, 0x0000); P_WriteUINT16(p, 0x0000);
for (cvar = consvar_vars; cvar; cvar = cvar->next) for (cvar = consvar_vars; cvar; cvar = cvar->next)
if ((cvar->flags & CV_NETVAR) && !CV_IsSetToDefault(cvar)) if ((cvar->flags & CV_NETVAR) && !CV_IsSetToDefault(cvar))
{ {
if (in_demo) if (in_demo)
{ {
WRITESTRING(*p, cvar->name); P_WriteString(p, cvar->name);
} }
else else
{ {
WRITEUINT16(*p, cvar->netid); P_WriteUINT16(p, cvar->netid);
} }
WRITESTRING(*p, cvar->string); P_WriteString(p, cvar->string);
WRITEUINT8(*p, false); P_WriteUINT8(p, false);
++count; ++count;
} }
WRITEUINT16(count_p, count); WRITEUINT16(count_p, count);
} }
static void CV_LoadVars(UINT8 **p, static void CV_LoadVars(save_t *p,
consvar_t *(*got)(UINT8 **p, char **ret_value, boolean *ret_stealth)) consvar_t *(*got)(save_t *p, char **ret_value, boolean *ret_stealth))
{ {
const boolean store = (client || demoplayback); const boolean store = (client || demoplayback);
...@@ -1888,7 +1901,7 @@ static void CV_LoadVars(UINT8 **p, ...@@ -1888,7 +1901,7 @@ static void CV_LoadVars(UINT8 **p,
} }
} }
count = READUINT16(*p); count = P_ReadUINT16(p);
while (count--) while (count--)
{ {
cvar = (*got)(p, &val, &stealth); cvar = (*got)(p, &val, &stealth);
...@@ -1921,19 +1934,19 @@ void CV_RevertNetVars(void) ...@@ -1921,19 +1934,19 @@ void CV_RevertNetVars(void)
} }
} }
void CV_LoadNetVars(UINT8 **p) void CV_LoadNetVars(save_t *p)
{ {
CV_LoadVars(p, ReadNetVar); CV_LoadVars(p, ReadNetVar);
} }
#ifdef OLD22DEMOCOMPAT #ifdef OLD22DEMOCOMPAT
void CV_LoadOldDemoVars(UINT8 **p) void CV_LoadOldDemoVars(save_t *p)
{ {
CV_LoadVars(p, ReadOldDemoVar); CV_LoadVars(p, ReadOldDemoVar);
} }
#endif #endif
void CV_LoadDemoVars(UINT8 **p) void CV_LoadDemoVars(save_t *p)
{ {
CV_LoadVars(p, ReadDemoVar); CV_LoadVars(p, ReadDemoVar);
} }
...@@ -1986,13 +1999,13 @@ static void CV_SetCVar(consvar_t *var, const char *value, boolean stealth) ...@@ -1986,13 +1999,13 @@ static void CV_SetCVar(consvar_t *var, const char *value, boolean stealth)
if (!var->string) if (!var->string)
I_Error("CV_Set: %s no string set!\n", var->name); I_Error("CV_Set: %s no string set!\n", var->name);
#endif #endif
if (!var || !var->string || !value || !stricmp(var->string, value)) if (!var || !var->string || !value || (var->can_change == NULL && !stricmp(var->string, value)))
return; // no changes return; // no changes
if (var->flags & CV_NETVAR) if (var->flags & CV_NETVAR)
{ {
// send the value of the variable // send the value of the variable
UINT8 buf[128]; UINT8 buf[512];
UINT8 *p = buf; UINT8 *p = buf;
// Loading from a config in a netgame? Set revert value. // Loading from a config in a netgame? Set revert value.
...@@ -2065,11 +2078,10 @@ static void CV_SetValueMaybeStealth(consvar_t *var, INT32 value, boolean stealth ...@@ -2065,11 +2078,10 @@ static void CV_SetValueMaybeStealth(consvar_t *var, INT32 value, boolean stealth
if (var == &cv_forceskin) // Special handling. if (var == &cv_forceskin) // Special handling.
{ {
const char *tmpskin = NULL; const char *tmpskin = NULL;
if ((value < 0) || (value >= numskins)) if (value >= 0 && value < numskins)
;
else
tmpskin = skins[value]->name; tmpskin = skins[value]->name;
memcpy(val, tmpskin, SKINNAMESIZE); if (tmpskin)
memcpy(val, tmpskin, SKINNAMESIZE);
} }
else else
sprintf(val, "%d", value); sprintf(val, "%d", value);
...@@ -2470,6 +2482,22 @@ static boolean CV_FilterVarByVersion(consvar_t *v, const char *valstr) ...@@ -2470,6 +2482,22 @@ static boolean CV_FilterVarByVersion(consvar_t *v, const char *valstr)
if (!CV_FilterJoyAxisVars(v, valstr)) if (!CV_FilterJoyAxisVars(v, valstr))
return false; return false;
} }
if (GETMAJOREXECVERSION(cv_execversion.value) < 57) // 57 = 2.2.16
{
if (
(!stricmp(v->name, "movebob") && atoi(valstr) == FRACUNIT) ||
(!stricmp(v->name, "playersforexit") && atoi(valstr) == 4) || // 4 = all
(!stricmp(v->name, "advancemap") && atoi(valstr) == 1) || // 1 = next
(!stricmp(v->name, "cam_speed") && !stricmp(valstr, "0.3")) ||
(!stricmp(v->name, "cam2_speed") && !stricmp(valstr, "0.3")) ||
(!stricmp(v->name, "timerres") && atoi(valstr) == 0) || // 0 = classic
(!stricmp(v->name, "gr_modelinterpolation")) || // Force reset
(!stricmp(v->name, "fov") && atoi(valstr) == 90)
)
return false;
}
return true; return true;
} }
...@@ -2492,7 +2520,7 @@ static boolean CV_Command(void) ...@@ -2492,7 +2520,7 @@ static boolean CV_Command(void)
if (CV_Immutable(v)) if (CV_Immutable(v))
{ {
CONS_Alert(CONS_WARNING, "Variable '%s' cannot be changed from Lua.\n", v->name); CONS_Alert(CONS_WARNING, "Variable '%s' cannot be changed from a script.\n", v->name);
return true; return true;
} }
......
// SONIC ROBO BLAST 2 // SONIC ROBO BLAST 2
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Copyright (C) 1998-2000 by DooM Legacy Team. // Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2023 by Sonic Team Junior. // Copyright (C) 1999-2024 by Sonic Team Junior.
// //
// This program is free software distributed under the // This program is free software distributed under the
// terms of the GNU General Public License, version 2. // terms of the GNU General Public License, version 2.
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include <stdio.h> #include <stdio.h>
#include "doomdef.h" #include "doomdef.h"
#include "p_saveg.h"
//=================================== //===================================
// Command buffer & command execution // Command buffer & command execution
...@@ -65,6 +66,9 @@ void COM_ImmedExecute(const char *ptext); ...@@ -65,6 +66,9 @@ void COM_ImmedExecute(const char *ptext);
// Execute commands in buffer, flush them // Execute commands in buffer, flush them
void COM_BufExecute(void); void COM_BufExecute(void);
// Executes a script from a file
boolean COM_ExecFile(const char *scriptname, com_flags_t flags, boolean silent);
// As above; and progress the wait timer. // As above; and progress the wait timer.
void COM_BufTicker(void); void COM_BufTicker(void);
...@@ -218,19 +222,19 @@ void CV_AddValue(consvar_t *var, INT32 increment); ...@@ -218,19 +222,19 @@ void CV_AddValue(consvar_t *var, INT32 increment);
void CV_SaveVariables(FILE *f); void CV_SaveVariables(FILE *f);
// load/save gamesate (load and save option and for network join in game) // load/save gamesate (load and save option and for network join in game)
void CV_SaveVars(UINT8 **p, boolean in_demo); void CV_SaveVars(save_t *p, boolean in_demo);
#define CV_SaveNetVars(p) CV_SaveVars(p, false) #define CV_SaveNetVars(p) CV_SaveVars(p, false)
void CV_LoadNetVars(UINT8 **p); void CV_LoadNetVars(save_t *p);
// then revert after leaving a netgame // then revert after leaving a netgame
void CV_RevertNetVars(void); void CV_RevertNetVars(void);
#define CV_SaveDemoVars(p) CV_SaveVars(p, true) #define CV_SaveDemoVars(p) CV_SaveVars(p, true)
void CV_LoadDemoVars(UINT8 **p); void CV_LoadDemoVars(save_t *p);
#ifdef OLD22DEMOCOMPAT #ifdef OLD22DEMOCOMPAT
void CV_LoadOldDemoVars(UINT8 **p); void CV_LoadOldDemoVars(save_t *p);
#endif #endif
// reset cheat netvars after cheats is deactivated // reset cheat netvars after cheats is deactivated
......
...@@ -40,12 +40,14 @@ ...@@ -40,12 +40,14 @@
* Last updated 2023 / 05 / 02 - v2.2.11 - patch.pk3 & zones.pk3 * Last updated 2023 / 05 / 02 - v2.2.11 - patch.pk3 & zones.pk3
* Last updated 2023 / 09 / 06 - v2.2.12 - patch.pk3 * Last updated 2023 / 09 / 06 - v2.2.12 - patch.pk3
* Last updated 2023 / 09 / 09 - v2.2.13 - none * Last updated 2023 / 09 / 09 - v2.2.13 - none
* Last updated 2025 / 01 / 16 - v2.2.14 - main assets
* Last updated 2025 / 01 / 24 - v2.2.15 - main assets
*/ */
#define ASSET_HASH_SRB2_PK3 "ad911f29a28a18968ee5b2d11c2acb39" #define ASSET_HASH_SRB2_PK3 "3182ce524acc2072ddaa81acf4b6a9aa"
#define ASSET_HASH_ZONES_PK3 "1c8adf8d079ecb87d00081f158acf3c7" #define ASSET_HASH_ZONES_PK3 "88ff4c300851ccdb0406698eadd89907"
#define ASSET_HASH_PLAYER_DTA "2e7aaae8a6b1b77d90ffe7606ceadb6c" #define ASSET_HASH_CHARACTERS_PK3 "5c5936b8a690e007c0939bd0785a41fb"
#ifdef USE_PATCH_DTA #ifdef USE_PATCH_DTA
#define ASSET_HASH_PATCH_PK3 "3c7b73f34af7e9a7bceb2d5260f76172" #define ASSET_HASH_PATCH_PK3 "00000000000000000000000000000000"
#endif #endif
#endif #endif
// SONIC ROBO BLAST 2 // SONIC ROBO BLAST 2
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Copyright (C) 1998-2000 by DooM Legacy Team. // Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2023 by Sonic Team Junior. // Copyright (C) 1999-2024 by Sonic Team Junior.
// //
// This program is free software distributed under the // This program is free software distributed under the
// terms of the GNU General Public License, version 2. // terms of the GNU General Public License, version 2.
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
#include "m_menu.h" #include "m_menu.h"
#include "filesrch.h" #include "filesrch.h"
#include "m_misc.h" #include "m_misc.h"
#include "lua_libs.h"
#ifdef _WINDOWS #ifdef _WINDOWS
#include "win32/win_main.h" #include "win32/win_main.h"
...@@ -918,12 +919,26 @@ static void CON_InputDelChar(void) ...@@ -918,12 +919,26 @@ static void CON_InputDelChar(void)
// ---- // ----
// //
//
// Same as CON_Responder, but is process before everything else, so it cannot be blocked.
//
boolean CON_PreResponder(event_t *ev)
{
if (ev->type == ev_keydown && shiftdown == 1 && ev->key == KEY_ESCAPE)
{
I_SetTextInputMode(con_destlines == 0 ? true : textinputmodeenabledbylua); // inverse, since this is changed next tic.
consoletoggle = true;
return true;
}
return false;
}
//
// Handles console key input // Handles console key input
// //
boolean CON_Responder(event_t *ev) boolean CON_Responder(event_t *ev)
{ {
static UINT8 consdown = false; // console is treated differently due to rare usage
// sequential completions a la 4dos // sequential completions a la 4dos
static char completioncmd[80 + sizeof("find ")] = "find "; static char completioncmd[80 + sizeof("find ")] = "find ";
static char *completion = &completioncmd[sizeof("find ")-1]; static char *completion = &completioncmd[sizeof("find ")-1];
...@@ -943,32 +958,31 @@ boolean CON_Responder(event_t *ev) ...@@ -943,32 +958,31 @@ boolean CON_Responder(event_t *ev)
// let go keyup events, don't eat them // let go keyup events, don't eat them
if (ev->type != ev_keydown && ev->type != ev_text && ev->type != ev_console) if (ev->type != ev_keydown && ev->type != ev_text && ev->type != ev_console)
{ {
if (ev->key == gamecontrol[GC_CONSOLE][0] || ev->key == gamecontrol[GC_CONSOLE][1])
consdown = false;
return false; return false;
} }
key = ev->key; key = ev->key;
// check for console toggle key // check for console toggle key
if (ev->type != ev_console) if (ev->type == ev_keydown)
{ {
if (modeattacking || metalrecording || marathonmode) if (modeattacking || metalrecording || marathonmode)
return false; return false;
if (ev->type == ev_keydown && ((key == gamecontrol[GC_CONSOLE][0] || key == gamecontrol[GC_CONSOLE][1]) && !shiftdown)) if ((key == gamecontrol[GC_CONSOLE][0] || key == gamecontrol[GC_CONSOLE][1]) && !shiftdown)
{ {
if (consdown) // ignore repeat if (con_destlines == 0 && I_GetTextInputMode())
return true; return false; // some other component is holding keyboard input, don't hijack it!
I_SetTextInputMode(con_destlines == 0 ? true : textinputmodeenabledbylua); // inverse, since this is changed next tic.
consoletoggle = true; consoletoggle = true;
consdown = true;
return true; return true;
} }
// check other keys only if console prompt is active // check other keys only if console prompt is active
if (!consoleready && key < NUMINPUTS) // metzgermeister: boundary check!! if (!consoleready && key < NUMINPUTS) // metzgermeister: boundary check!!
{ {
if (ev->type == ev_keydown && !menuactive && bindtable[key]) if (!menuactive && bindtable[key])
{ {
COM_BufAddText(bindtable[key]); COM_BufAddText(bindtable[key]);
COM_BufAddText("\n"); COM_BufAddText("\n");
...@@ -980,14 +994,14 @@ boolean CON_Responder(event_t *ev) ...@@ -980,14 +994,14 @@ boolean CON_Responder(event_t *ev)
// escape key toggle off console // escape key toggle off console
if (key == KEY_ESCAPE) if (key == KEY_ESCAPE)
{ {
I_SetTextInputMode(textinputmodeenabledbylua);
consoletoggle = true; consoletoggle = true;
return true; return true;
} }
} }
else if (ev->type == ev_text)
if (ev->type == ev_text)
{ {
if (!consoletoggle) if (!consoletoggle && consoleready)
CON_InputAddChar(key); CON_InputAddChar(key);
return true; return true;
} }
...@@ -1036,7 +1050,7 @@ boolean CON_Responder(event_t *ev) ...@@ -1036,7 +1050,7 @@ boolean CON_Responder(event_t *ev)
} }
else if (key == KEY_BACKSPACE) else if (key == KEY_BACKSPACE)
{ {
if (ctrldown) if (ctrldown && input_cur != 0)
{ {
input_sel = M_JumpWordReverse(inputlines[inputline], input_cur); input_sel = M_JumpWordReverse(inputlines[inputline], input_cur);
CON_InputDelSelection(); CON_InputDelSelection();
...@@ -1094,7 +1108,9 @@ boolean CON_Responder(event_t *ev) ...@@ -1094,7 +1108,9 @@ boolean CON_Responder(event_t *ev)
if (key == 'x' || key == 'X') if (key == 'x' || key == 'X')
{ {
if (input_sel > input_cur) if (input_sel == input_cur) // Don't replace the clipboard without a text selection
return true;
else if (input_sel > input_cur)
I_ClipboardCopy(&inputlines[inputline][input_cur], input_sel-input_cur); I_ClipboardCopy(&inputlines[inputline][input_cur], input_sel-input_cur);
else else
I_ClipboardCopy(&inputlines[inputline][input_sel], input_cur-input_sel); I_ClipboardCopy(&inputlines[inputline][input_sel], input_cur-input_sel);
...@@ -1104,7 +1120,9 @@ boolean CON_Responder(event_t *ev) ...@@ -1104,7 +1120,9 @@ boolean CON_Responder(event_t *ev)
} }
else if (key == 'c' || key == 'C') else if (key == 'c' || key == 'C')
{ {
if (input_sel > input_cur) if (input_sel == input_cur) // Don't replace the clipboard without a text selection
return true;
else if (input_sel > input_cur)
I_ClipboardCopy(&inputlines[inputline][input_cur], input_sel-input_cur); I_ClipboardCopy(&inputlines[inputline][input_cur], input_sel-input_cur);
else else
I_ClipboardCopy(&inputlines[inputline][input_sel], input_cur-input_sel); I_ClipboardCopy(&inputlines[inputline][input_sel], input_cur-input_sel);
...@@ -1730,12 +1748,12 @@ static void CON_DrawBackpic(void) ...@@ -1730,12 +1748,12 @@ static void CON_DrawBackpic(void)
// Get the lumpnum for CONSBACK, STARTUP (Only during game startup) or fallback into MISSING. // Get the lumpnum for CONSBACK, STARTUP (Only during game startup) or fallback into MISSING.
if (con_startup) if (con_startup)
piclump = W_CheckNumForName("STARTUP"); piclump = W_CheckNumForPatchName("STARTUP");
else else
piclump = W_CheckNumForName("CONSBACK"); piclump = W_CheckNumForPatchName("CONSBACK");
if (piclump == LUMPERROR) if (piclump == LUMPERROR)
piclump = W_GetNumForName("MISSING"); piclump = W_GetNumForPatchName("MISSING");
// Cache the patch. // Cache the patch.
con_backpic = W_CachePatchNum(piclump, PU_PATCH); con_backpic = W_CachePatchNum(piclump, PU_PATCH);
......
// SONIC ROBO BLAST 2 // SONIC ROBO BLAST 2
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Copyright (C) 1998-2000 by DooM Legacy Team. // Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2023 by Sonic Team Junior. // Copyright (C) 1999-2024 by Sonic Team Junior.
// //
// This program is free software distributed under the // This program is free software distributed under the
// terms of the GNU General Public License, version 2. // terms of the GNU General Public License, version 2.
...@@ -19,6 +19,7 @@ void CON_Init(void); ...@@ -19,6 +19,7 @@ void CON_Init(void);
void CON_StartRefresh(void); void CON_StartRefresh(void);
void CON_StopRefresh(void); void CON_StopRefresh(void);
boolean CON_PreResponder(event_t *ev);
boolean CON_Responder(event_t *ev); boolean CON_Responder(event_t *ev);
#ifdef HAVE_THREADS #ifdef HAVE_THREADS
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1993-1996 by id Software, Inc.
// Copyright (C) 1998-2000 by DooM Legacy Team. // Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2023 by Sonic Team Junior. // Copyright (C) 1999-2025 by Sonic Team Junior.
// //
// This program is free software distributed under the // This program is free software distributed under the
// terms of the GNU General Public License, version 2. // terms of the GNU General Public License, version 2.
...@@ -227,6 +227,9 @@ void D_ProcessEvents(void) ...@@ -227,6 +227,9 @@ void D_ProcessEvents(void)
} }
} }
if (CON_PreResponder(ev))
continue;
// Screenshots over everything so that they can be taken anywhere. // Screenshots over everything so that they can be taken anywhere.
if (M_ScreenshotResponder(ev)) if (M_ScreenshotResponder(ev))
continue; // ate the event continue; // ate the event
...@@ -679,13 +682,13 @@ static void D_Display(void) ...@@ -679,13 +682,13 @@ static void D_Display(void)
s[sizeof s - 1] = '\0'; s[sizeof s - 1] = '\0';
snprintf(s, sizeof s - 1, "get %d b/s", getbps); snprintf(s, sizeof s - 1, "get %d b/s", getbps);
V_DrawRightAlignedString(BASEVIDWIDTH, BASEVIDHEIGHT-ST_HEIGHT-40, V_YELLOWMAP, s); V_DrawRightAlignedString(BASEVIDWIDTH, BASEVIDHEIGHT-40, V_YELLOWMAP, s);
snprintf(s, sizeof s - 1, "send %d b/s", sendbps); snprintf(s, sizeof s - 1, "send %d b/s", sendbps);
V_DrawRightAlignedString(BASEVIDWIDTH, BASEVIDHEIGHT-ST_HEIGHT-30, V_YELLOWMAP, s); V_DrawRightAlignedString(BASEVIDWIDTH, BASEVIDHEIGHT-30, V_YELLOWMAP, s);
snprintf(s, sizeof s - 1, "GameMiss %.2f%%", gamelostpercent); snprintf(s, sizeof s - 1, "GameMiss %.2f%%", gamelostpercent);
V_DrawRightAlignedString(BASEVIDWIDTH, BASEVIDHEIGHT-ST_HEIGHT-20, V_YELLOWMAP, s); V_DrawRightAlignedString(BASEVIDWIDTH, BASEVIDHEIGHT-20, V_YELLOWMAP, s);
snprintf(s, sizeof s - 1, "SysMiss %.2f%%", lostpercent); snprintf(s, sizeof s - 1, "SysMiss %.2f%%", lostpercent);
V_DrawRightAlignedString(BASEVIDWIDTH, BASEVIDHEIGHT-ST_HEIGHT-10, V_YELLOWMAP, s); V_DrawRightAlignedString(BASEVIDWIDTH, BASEVIDHEIGHT-10, V_YELLOWMAP, s);
} }
if (cv_perfstats.value) if (cv_perfstats.value)
...@@ -758,9 +761,9 @@ void D_SRB2Loop(void) ...@@ -758,9 +761,9 @@ void D_SRB2Loop(void)
/* Smells like a hack... Don't fade Sonic's ass into the title screen. */ /* Smells like a hack... Don't fade Sonic's ass into the title screen. */
if (gamestate != GS_TITLESCREEN) if (gamestate != GS_TITLESCREEN)
{ {
gstartuplumpnum = W_CheckNumForName("STARTUP"); gstartuplumpnum = W_CheckNumForPatchName("STARTUP");
if (gstartuplumpnum == LUMPERROR) if (gstartuplumpnum == LUMPERROR)
gstartuplumpnum = W_GetNumForName("MISSING"); gstartuplumpnum = W_GetNumForPatchName("MISSING");
V_DrawScaledPatch(0, 0, 0, W_CachePatchNum(gstartuplumpnum, PU_PATCH)); V_DrawScaledPatch(0, 0, 0, W_CachePatchNum(gstartuplumpnum, PU_PATCH));
} }
...@@ -983,7 +986,7 @@ void D_StartTitle(void) ...@@ -983,7 +986,7 @@ void D_StartTitle(void)
emeralds = 0; emeralds = 0;
memset(&luabanks, 0, sizeof(luabanks)); memset(&luabanks, 0, sizeof(luabanks));
lastmaploaded = 0; lastmaploaded = 0;
pickedchar = R_SkinAvailable(cv_defaultskin.string); pickedchar = R_SkinAvailable(cv_skin.string);
// In case someone exits out at the same time they start a time attack run, // In case someone exits out at the same time they start a time attack run,
// reset modeattacking // reset modeattacking
...@@ -1024,7 +1027,7 @@ void D_StartTitle(void) ...@@ -1024,7 +1027,7 @@ void D_StartTitle(void)
#define REALLOC_FILE_LIST \ #define REALLOC_FILE_LIST \
if (list->files == NULL) \ if (list->files == NULL) \
{ \ { \
list->files = calloc(sizeof(list->files), 2); \ list->files = calloc(2, sizeof(list->files)); \
list->numfiles = 1; \ list->numfiles = 1; \
} \ } \
else \ else \
...@@ -1179,8 +1182,8 @@ static void IdentifyVersion(void) ...@@ -1179,8 +1182,8 @@ static void IdentifyVersion(void)
// Add the maps // Add the maps
D_AddFile(&startupwadfiles, va(pandf,srb2waddir, "zones.pk3")); D_AddFile(&startupwadfiles, va(pandf,srb2waddir, "zones.pk3"));
// Add the players // Add the characters
D_AddFile(&startupwadfiles, va(pandf,srb2waddir, "player.dta")); D_AddFile(&startupwadfiles, va(pandf,srb2waddir, "characters.pk3"));
#ifdef USE_PATCH_DTA #ifdef USE_PATCH_DTA
// Add our crappy patches to fix our bugs // Add our crappy patches to fix our bugs
...@@ -1199,7 +1202,7 @@ static void IdentifyVersion(void) ...@@ -1199,7 +1202,7 @@ static void IdentifyVersion(void)
I_Error("File "str" has been modified with non-music/sound lumps"); \ I_Error("File "str" has been modified with non-music/sound lumps"); \
} }
MUSICTEST("music.dta") MUSICTEST("music.pk3")
//MUSICTEST("patch_music.pk3") //MUSICTEST("patch_music.pk3")
} }
#endif #endif
...@@ -1250,7 +1253,7 @@ void D_SRB2Main(void) ...@@ -1250,7 +1253,7 @@ void D_SRB2Main(void)
// Print GPL notice for our console users (Linux) // Print GPL notice for our console users (Linux)
CONS_Printf( CONS_Printf(
"\n\nSonic Robo Blast 2\n" "\n\nSonic Robo Blast 2\n"
"Copyright (C) 1998-2023 by Sonic Team Junior\n\n" "Copyright (C) 1998-2025 by Sonic Team Junior\n\n"
"This program comes with ABSOLUTELY NO WARRANTY.\n\n" "This program comes with ABSOLUTELY NO WARRANTY.\n\n"
"This is free software, and you are welcome to redistribute it\n" "This is free software, and you are welcome to redistribute it\n"
"and/or modify it under the terms of the GNU General Public License\n" "and/or modify it under the terms of the GNU General Public License\n"
...@@ -1431,7 +1434,7 @@ void D_SRB2Main(void) ...@@ -1431,7 +1434,7 @@ void D_SRB2Main(void)
// Make backups of some SOCcable tables. // Make backups of some SOCcable tables.
P_BackupTables(); P_BackupTables();
mainwads = 3; // doesn't include music.dta mainwads = 3; // doesn't include music.pk3
#ifdef USE_PATCH_DTA #ifdef USE_PATCH_DTA
mainwads++; mainwads++;
#endif #endif
...@@ -1446,11 +1449,11 @@ void D_SRB2Main(void) ...@@ -1446,11 +1449,11 @@ void D_SRB2Main(void)
// Check MD5s of autoloaded files // Check MD5s of autoloaded files
W_VerifyFileMD5(0, ASSET_HASH_SRB2_PK3); // srb2.pk3 W_VerifyFileMD5(0, ASSET_HASH_SRB2_PK3); // srb2.pk3
W_VerifyFileMD5(1, ASSET_HASH_ZONES_PK3); // zones.pk3 W_VerifyFileMD5(1, ASSET_HASH_ZONES_PK3); // zones.pk3
W_VerifyFileMD5(2, ASSET_HASH_PLAYER_DTA); // player.dta W_VerifyFileMD5(2, ASSET_HASH_CHARACTERS_PK3); // characters.pk3
#ifdef USE_PATCH_DTA #ifdef USE_PATCH_DTA
W_VerifyFileMD5(3, ASSET_HASH_PATCH_PK3); // patch.pk3 W_VerifyFileMD5(3, ASSET_HASH_PATCH_PK3); // patch.pk3
#endif #endif
// don't check music.dta because people like to modify it, and it doesn't matter if they do // don't check music.pk3 because people like to modify it, and it doesn't matter if they do
// ...except it does if they slip maps in there, and that's what W_VerifyNMUSlumps is for. // ...except it does if they slip maps in there, and that's what W_VerifyNMUSlumps is for.
#endif //ifndef DEVELOP #endif //ifndef DEVELOP
...@@ -1535,7 +1538,7 @@ void D_SRB2Main(void) ...@@ -1535,7 +1538,7 @@ void D_SRB2Main(void)
I_Error("Cannot find a map remotely named '%s'\n", word); I_Error("Cannot find a map remotely named '%s'\n", word);
else else
{ {
if (!M_CheckParm("-server")) if (!(M_CheckParm("-server") || dedicated))
G_SetUsedCheats(true); G_SetUsedCheats(true);
autostart = true; autostart = true;
} }
...@@ -1600,7 +1603,7 @@ void D_SRB2Main(void) ...@@ -1600,7 +1603,7 @@ void D_SRB2Main(void)
{ {
if (!M_IsNextParm()) if (!M_IsNextParm())
I_Error("usage: -room <room_id>\nCheck the Master Server's webpage for room ID numbers.\n"); I_Error("usage: -room <room_id>\nCheck the Master Server's webpage for room ID numbers.\n");
ms_RoomId = atoi(M_GetNextParm()); CV_SetValue(&cv_masterserver_room_id, atoi(M_GetNextParm()));
#ifdef UPDATE_ALERT #ifdef UPDATE_ALERT
GetMODVersion_Console(); GetMODVersion_Console();
...@@ -1842,17 +1845,21 @@ static boolean check_top_dir(const char **path, const char *top) ...@@ -1842,17 +1845,21 @@ static boolean check_top_dir(const char **path, const char *top)
return true; return true;
} }
static int cmp_strlen_desc(const void *a, const void *b) static int cmp_strlen_desc(const void *A, const void *B)
{ {
return ((int)strlen(*(const char*const*)b) - (int)strlen(*(const char*const*)a)); const char *pA = A;
const char *pB = B;
size_t As = strlen(pA);
size_t Bs = strlen(pB);
return ((int)Bs - (int)As);
} }
boolean D_IsPathAllowed(const char *path) boolean D_IsPathAllowed(const char *path)
{ {
const char *paths[] = { char *paths[] = {
srb2home, srb2home,
srb2path, srb2path,
cv_addons_folder.string cv_addons_folder.zstring
}; };
const size_t n_paths = sizeof paths / sizeof *paths; const size_t n_paths = sizeof paths / sizeof *paths;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1993-1996 by id Software, Inc.
// Copyright (C) 1998-2000 by DooM Legacy Team. // Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2023 by Sonic Team Junior. // Copyright (C) 1999-2025 by Sonic Team Junior.
// //
// This program is free software distributed under the // This program is free software distributed under the
// terms of the GNU General Public License, version 2. // terms of the GNU General Public License, version 2.
...@@ -45,14 +45,16 @@ typedef enum ...@@ -45,14 +45,16 @@ typedef enum
SF_MARIODAMAGE = SF_NOJUMPDAMAGE|SF_STOMPDAMAGE, // The Mario method of being able to damage enemies, etc. SF_MARIODAMAGE = SF_NOJUMPDAMAGE|SF_STOMPDAMAGE, // The Mario method of being able to damage enemies, etc.
SF_MACHINE = 1<<10, // Beep boop. Are you a robot? SF_MACHINE = 1<<10, // Beep boop. Are you a robot?
SF_DASHMODE = 1<<11, // Sonic Advance 2 style top speed increase? SF_DASHMODE = 1<<11, // Sonic Advance 2 style top speed increase?
SF_FASTEDGE = 1<<12, // Faster edge teeter? SF_FASTWAIT = 1<<12, // Faster wait animation?
SF_MULTIABILITY = 1<<13, // Revenge of Final Demo. SF_FASTEDGE = 1<<13, // Faster edge teeter?
SF_NONIGHTSROTATION = 1<<14, // Disable sprite rotation for NiGHTS SF_JETFUME = 1<<14, // Follow item uses Metal Sonic's jet fume behavior
SF_NONIGHTSSUPER = 1<<15, // Disable super colors for NiGHTS (if you have SF_SUPER) SF_MULTIABILITY = 1<<15, // Revenge of Final Demo.
SF_NOSUPERSPRITES = 1<<16, // Don't use super sprites while super SF_NONIGHTSROTATION = 1<<16, // Disable sprite rotation for NiGHTS
SF_NOSUPERJUMPBOOST = 1<<17, // Disable the jump boost given while super (i.e. Knuckles) SF_NONIGHTSSUPER = 1<<17, // Disable super sprites and colors for NiGHTS
SF_CANBUSTWALLS = 1<<18, // Can naturally bust walls on contact? (i.e. Knuckles) SF_NOSUPERSPRITES = 1<<18, // Don't use super sprites while super
SF_NOSHIELDABILITY = 1<<19, // Disable shield abilities SF_NOSUPERJUMPBOOST = 1<<19, // Disable the jump boost given while super (i.e. Knuckles)
SF_CANBUSTWALLS = 1<<20, // Can naturally bust walls on contact? (i.e. Knuckles)
SF_NOSHIELDABILITY = 1<<21, // Disable shield abilities
// free up to and including 1<<31 // free up to and including 1<<31
} skinflags_t; } skinflags_t;
...@@ -158,10 +160,6 @@ typedef enum ...@@ -158,10 +160,6 @@ typedef enum
PF_FORCESTRAFE = 1<<28, // Turning inputs are translated into strafing inputs PF_FORCESTRAFE = 1<<28, // Turning inputs are translated into strafing inputs
PF_CANCARRY = 1<<29, // Can carry another player? PF_CANCARRY = 1<<29, // Can carry another player?
PF_FINISHED = 1<<30, // The player finished the level. NOT the same as exiting PF_FINISHED = 1<<30, // The player finished the level. NOT the same as exiting
// True if shield button down last tic
// This may be the final flag, but 2.3 could free up the others
PF_SHIELDDOWN = 1<<31,
// up to 1<<31 is free // up to 1<<31 is free
} pflags_t; } pflags_t;
......
...@@ -51,6 +51,8 @@ typedef struct thinker_s ...@@ -51,6 +51,8 @@ typedef struct thinker_s
// killough 11/98: count of how many other objects reference // killough 11/98: count of how many other objects reference
// this one using pointers. Used for garbage collection. // this one using pointers. Used for garbage collection.
INT32 references; INT32 references;
boolean removing;
boolean cachable; boolean cachable;
#ifdef PARANOIA #ifdef PARANOIA
......
...@@ -26,23 +26,20 @@ ...@@ -26,23 +26,20 @@
// Button/action code definitions. // Button/action code definitions.
typedef enum typedef enum
{ {
// First 3 bits are weapon change info, DO NOT USE! // First 4 bits are weapon change info, DO NOT USE!
BT_WEAPONMASK = 0x07, //our first three bits. BT_WEAPONMASK = 0x0F, //our first four bits.
BT_SHIELD = 1<<3, // shield or super action
BT_WEAPONNEXT = 1<<4, // select next weapon BT_WEAPONNEXT = 1<<4,
BT_WEAPONPREV = 1<<5, // select previous weapon BT_WEAPONPREV = 1<<5,
BT_ATTACK = 1<<6, // shoot rings
BT_SPIN = 1<<7,
BT_CAMLEFT = 1<<8, // turn camera left
BT_CAMRIGHT = 1<<9, // turn camera right
BT_TOSSFLAG = 1<<10,
BT_JUMP = 1<<11,
BT_FIRENORMAL = 1<<12, // Fire a normal ring no matter what
BT_ATTACK = 1<<6, // shoot rings
BT_SPIN = 1<<7, // spin action
BT_CAMLEFT = 1<<8, // turn camera left
BT_CAMRIGHT = 1<<9, // turn camera right
BT_TOSSFLAG = 1<<10, // toss flag or emeralds
BT_JUMP = 1<<11, // jump action
BT_FIRENORMAL = 1<<12, // fire a normal ring no matter what
// custom lua buttons
BT_CUSTOM1 = 1<<13, BT_CUSTOM1 = 1<<13,
BT_CUSTOM2 = 1<<14, BT_CUSTOM2 = 1<<14,
BT_CUSTOM3 = 1<<15, BT_CUSTOM3 = 1<<15,
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
// //
// Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1993-1996 by id Software, Inc.
// Portions Copyright (C) 1998-2000 by DooM Legacy Team. // Portions Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 2014-2023 by Sonic Team Junior. // Copyright (C) 2014-2025 by Sonic Team Junior.
// //
// This program is free software; you can redistribute it and/or // This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License // modify it under the terms of the GNU General Public License
...@@ -65,10 +65,11 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T); ...@@ -65,10 +65,11 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T);
#pragma warning(default : 4214 4244) #pragma warning(default : 4214 4244)
#endif #endif
#if defined (__unix__) || defined(__APPLE__) || (defined (UNIXCOMMON) && !defined (__HAIKU__)) #if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON)
#if defined (__linux__) #if defined (__linux__) || defined (__HAIKU__)
#include <sys/vfs.h> #include <sys/statvfs.h>
#else #else
#include <sys/statvfs.h>
#include <sys/param.h> #include <sys/param.h>
#include <sys/mount.h> #include <sys/mount.h>
/*For meminfo*/ /*For meminfo*/
...@@ -81,7 +82,7 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T); ...@@ -81,7 +82,7 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T);
#endif #endif
#endif #endif
#if defined (__linux__) || (defined (UNIXCOMMON) && !defined (__HAIKU__)) #if defined (__linux__) || defined (UNIXCOMMON)
#ifndef NOTERMIOS #ifndef NOTERMIOS
#include <termios.h> #include <termios.h>
#include <sys/ioctl.h> // ioctl #include <sys/ioctl.h> // ioctl
...@@ -96,8 +97,10 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T); ...@@ -96,8 +97,10 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T);
#if defined (__unix__) || (defined (UNIXCOMMON) && !defined (__APPLE__)) #if defined (__unix__) || (defined (UNIXCOMMON) && !defined (__APPLE__))
#include <errno.h> #include <errno.h>
#include <sys/wait.h> #include <sys/wait.h>
#ifndef __HAIKU__ // haiku's crash dialog is just objectively better
#define NEWSIGNALHANDLER #define NEWSIGNALHANDLER
#endif #endif
#endif
#ifndef NOMUMBLE #ifndef NOMUMBLE
#ifdef __linux__ // need -lrt #ifdef __linux__ // need -lrt
...@@ -374,15 +377,24 @@ void I_Sleep(UINT32 ms) ...@@ -374,15 +377,24 @@ void I_Sleep(UINT32 ms)
void I_SleepDuration(precise_t duration) void I_SleepDuration(precise_t duration)
{ {
#if defined(__linux__) || defined(__FreeBSD__) #if defined(__linux__) || defined(__FreeBSD__) || defined(__HAIKU__)
UINT64 precision = I_GetPrecisePrecision(); UINT64 precision = I_GetPrecisePrecision();
struct timespec ts = { precise_t dest = I_GetPreciseTime() + duration;
.tv_sec = duration / precision, precise_t slack = (precision / 5000); // 0.2 ms slack
.tv_nsec = duration * 1000000000 / precision % 1000000000, if (duration > slack)
}; {
int status; duration -= slack;
do status = clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, &ts); struct timespec ts = {
while (status == EINTR); .tv_sec = duration / precision,
.tv_nsec = duration * 1000000000 / precision % 1000000000,
};
int status;
do status = clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, &ts);
while (status == EINTR);
}
// busy-wait the rest
while (((INT64)dest - (INT64)I_GetPreciseTime()) > 0);
#else #else
UINT64 precision = I_GetPrecisePrecision(); UINT64 precision = I_GetPrecisePrecision();
INT32 sleepvalue = cv_sleep.value; INT32 sleepvalue = cv_sleep.value;
...@@ -705,10 +717,9 @@ typedef struct ...@@ -705,10 +717,9 @@ typedef struct
static feild_t tty_con; static feild_t tty_con;
// when printing general stuff to stdout stderr (Sys_Printf) // lock to prevent clearing partial lines, since not everything
// we need to disable the tty console stuff // printed ends on a newline.
// this increments so we can recursively disable static boolean ttycon_ateol = true;
static INT32 ttycon_hide = 0;
// some key codes that the terminal may be using // some key codes that the terminal may be using
// TTimo NOTE: I'm not sure how relevant this is // TTimo NOTE: I'm not sure how relevant this is
static INT32 tty_erase; static INT32 tty_erase;
...@@ -736,63 +747,31 @@ static inline void tty_FlushIn(void) ...@@ -736,63 +747,31 @@ static inline void tty_FlushIn(void)
// TTimo NOTE: it seems on some terminals just sending '\b' is not enough // TTimo NOTE: it seems on some terminals just sending '\b' is not enough
// so for now, in any case we send "\b \b" .. yeah well .. // so for now, in any case we send "\b \b" .. yeah well ..
// (there may be a way to find out if '\b' alone would work though) // (there may be a way to find out if '\b' alone would work though)
// Hanicef NOTE: using \b this way is unreliable because of terminal state,
// it's better to use \r to reset the cursor to the beginning of the
// line and clear from there.
static void tty_Back(void) static void tty_Back(void)
{ {
char key; write(STDOUT_FILENO, "\r", 1);
ssize_t d;
key = '\b';
d = write(STDOUT_FILENO, &key, 1);
key = ' ';
d = write(STDOUT_FILENO, &key, 1);
key = '\b';
d = write(STDOUT_FILENO, &key, 1);
(void)d;
}
static void tty_Clear(void)
{
size_t i;
if (tty_con.cursor>0) if (tty_con.cursor>0)
{ {
for (i=0; i<tty_con.cursor; i++) write(STDOUT_FILENO, tty_con.buffer, tty_con.cursor);
{
tty_Back();
}
} }
write(STDOUT_FILENO, " \b", 2);
} }
// clear the display of the line currently edited static void tty_Clear(void)
// bring cursor back to beginning of line
static inline void tty_Hide(void)
{
//I_Assert(consolevent);
if (ttycon_hide)
{
ttycon_hide++;
return;
}
tty_Clear();
ttycon_hide++;
}
// show the current line
// FIXME TTimo need to position the cursor if needed??
static inline void tty_Show(void)
{ {
size_t i; size_t i;
ssize_t d; write(STDOUT_FILENO, "\r", 1);
//I_Assert(consolevent); if (tty_con.cursor>0)
I_Assert(ttycon_hide>0);
ttycon_hide--;
if (ttycon_hide == 0 && tty_con.cursor)
{ {
for (i=0; i<tty_con.cursor; i++) for (i=0; i<tty_con.cursor; i++)
{ {
d = write(STDOUT_FILENO, tty_con.buffer+i, 1); write(STDOUT_FILENO, " ", 1);
} }
write(STDOUT_FILENO, "\r", 1);
} }
(void)d;
} }
// never exit without calling this, or your terminal will be left in a pretty bad state // never exit without calling this, or your terminal will be left in a pretty bad state
...@@ -900,6 +879,11 @@ static void I_GetConsoleEvents(void) ...@@ -900,6 +879,11 @@ static void I_GetConsoleEvents(void)
tty_con.cursor = 0; tty_con.cursor = 0;
ev.key = KEY_ENTER; ev.key = KEY_ENTER;
} }
else if (key == 0x4) // ^D, aka EOF
{
// shut down, most unix programs behave this way
I_Quit();
}
else continue; else continue;
} }
else if (tty_con.cursor < sizeof(tty_con.buffer)) else if (tty_con.cursor < sizeof(tty_con.buffer))
...@@ -999,20 +983,8 @@ static void I_GetConsoleEvents(void) ...@@ -999,20 +983,8 @@ static void I_GetConsoleEvents(void)
static void I_StartupConsole(void) static void I_StartupConsole(void)
{ {
HANDLE ci, co; HANDLE ci, co;
const INT32 ded = M_CheckParm("-dedicated"); BOOL gotConsole = AllocConsole();
BOOL gotConsole = FALSE; consolevent = !M_CheckParm("-noconsole");
if (M_CheckParm("-console") || ded)
gotConsole = AllocConsole();
#ifdef _DEBUG
else if (M_CheckParm("-noconsole") && !ded)
#else
else if (!M_CheckParm("-console") && !ded)
#endif
{
FreeConsole();
gotConsole = FALSE;
}
if (gotConsole) if (gotConsole)
{ {
SetConsoleTitleA("SRB2 Console"); SetConsoleTitleA("SRB2 Console");
...@@ -1040,12 +1012,7 @@ static inline void I_ShutdownConsole(void){} ...@@ -1040,12 +1012,7 @@ static inline void I_ShutdownConsole(void){}
static void I_GetConsoleEvents(void){} static void I_GetConsoleEvents(void){}
static inline void I_StartupConsole(void) static inline void I_StartupConsole(void)
{ {
#ifdef _DEBUG
consolevent = !M_CheckParm("-noconsole"); consolevent = !M_CheckParm("-noconsole");
#else
consolevent = M_CheckParm("-console");
#endif
framebuffer = M_CheckParm("-framebuffer"); framebuffer = M_CheckParm("-framebuffer");
if (framebuffer) if (framebuffer)
...@@ -1063,6 +1030,9 @@ void I_OutputMsg(const char *fmt, ...) ...@@ -1063,6 +1030,9 @@ void I_OutputMsg(const char *fmt, ...)
va_start(argptr,fmt); va_start(argptr,fmt);
len = vsnprintf(NULL, 0, fmt, argptr); len = vsnprintf(NULL, 0, fmt, argptr);
va_end(argptr); va_end(argptr);
if (len == 0)
return;
txt = malloc(len+1); txt = malloc(len+1);
va_start(argptr,fmt); va_start(argptr,fmt);
vsprintf(txt, fmt, argptr); vsprintf(txt, fmt, argptr);
...@@ -1152,18 +1122,20 @@ void I_OutputMsg(const char *fmt, ...) ...@@ -1152,18 +1122,20 @@ void I_OutputMsg(const char *fmt, ...)
} }
#else #else
#ifdef HAVE_TERMIOS #ifdef HAVE_TERMIOS
if (consolevent) if (consolevent && ttycon_ateol)
{ {
tty_Hide(); tty_Clear();
ttycon_ateol = false;
} }
#endif #endif
if (!framebuffer) if (!framebuffer)
fprintf(stderr, "%s", txt); fprintf(stderr, "%s", txt);
#ifdef HAVE_TERMIOS #ifdef HAVE_TERMIOS
if (consolevent) if (consolevent && txt[len-1] == '\n')
{ {
tty_Show(); write(STDOUT_FILENO, tty_con.buffer, tty_con.cursor);
ttycon_ateol = true;
} }
#endif #endif
...@@ -1243,18 +1215,13 @@ void I_ShutdownSystem(void) ...@@ -1243,18 +1215,13 @@ void I_ShutdownSystem(void)
void I_GetDiskFreeSpace(INT64* freespace) void I_GetDiskFreeSpace(INT64* freespace)
{ {
#if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON) #if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON)
#if defined (SOLARIS) || defined (__HAIKU__) struct statvfs stfs;
*freespace = INT32_MAX; if (statvfs(srb2home, &stfs) == -1)
return;
#else // Both Linux and BSD have this, apparently.
struct statfs stfs;
if (statfs(srb2home, &stfs) == -1)
{ {
*freespace = INT32_MAX; *freespace = INT32_MAX;
return; return;
} }
*freespace = stfs.f_bavail * stfs.f_bsize; *freespace = stfs.f_bavail * stfs.f_bsize;
#endif
#elif defined (_WIN32) #elif defined (_WIN32)
static p_GetDiskFreeSpaceExA pfnGetDiskFreeSpaceEx = NULL; static p_GetDiskFreeSpaceExA pfnGetDiskFreeSpaceEx = NULL;
static boolean testwin95 = false; static boolean testwin95 = false;
...@@ -1390,8 +1357,8 @@ static const char *searchWad(const char *searchDir) ...@@ -1390,8 +1357,8 @@ static const char *searchWad(const char *searchDir)
#define CHECKWADPATH(ret) \ #define CHECKWADPATH(ret) \
do { \ do { \
I_OutputMsg(",%s", returnWadPath); \ I_OutputMsg(",%s", ret); \
if (isWadPathOk(returnWadPath)) \ if (isWadPathOk(ret)) \
return ret; \ return ret; \
} while (0) } while (0)
...@@ -1416,7 +1383,9 @@ static const char *locateWad(void) ...@@ -1416,7 +1383,9 @@ static const char *locateWad(void)
#ifndef NOCWD #ifndef NOCWD
// examine current dir // examine current dir
strcpy(returnWadPath, "."); strcpy(returnWadPath, ".");
CHECKWADPATH(NULL); I_OutputMsg(",%s", returnWadPath);
if (isWadPathOk(returnWadPath))
return NULL;
#endif #endif
#ifdef __APPLE__ #ifdef __APPLE__
...@@ -1433,9 +1402,15 @@ static const char *locateWad(void) ...@@ -1433,9 +1402,15 @@ static const char *locateWad(void)
#ifndef NOHOME #ifndef NOHOME
// find in $HOME // find in $HOME
I_OutputMsg(",HOME");
if ((envstr = I_GetEnv("HOME")) != NULL) if ((envstr = I_GetEnv("HOME")) != NULL)
SEARCHWAD(envstr); {
char *tmp = malloc(strlen(envstr) + 1 + sizeof(DEFAULTDIR));
strcpy(tmp, envstr);
strcat(tmp, "/");
strcat(tmp, DEFAULTDIR);
CHECKWADPATH(tmp);
free(tmp);
}
#endif #endif
// search paths // search paths
...@@ -1462,8 +1437,10 @@ const char *I_LocateWad(void) ...@@ -1462,8 +1437,10 @@ const char *I_LocateWad(void)
{ {
// change to the directory where we found srb2.pk3 // change to the directory where we found srb2.pk3
#if defined (_WIN32) #if defined (_WIN32)
waddir = _fullpath(NULL, waddir, MAX_PATH);
SetCurrentDirectoryA(waddir); SetCurrentDirectoryA(waddir);
#else #else
waddir = realpath(waddir, NULL);
if (chdir(waddir) == -1) if (chdir(waddir) == -1)
I_OutputMsg("Couldn't change working directory\n"); I_OutputMsg("Couldn't change working directory\n");
#endif #endif
...@@ -1585,5 +1562,14 @@ void I_GetCursorPosition(INT32 *x, INT32 *y) ...@@ -1585,5 +1562,14 @@ void I_GetCursorPosition(INT32 *x, INT32 *y)
(void)y; (void)y;
} }
#include "../sdl/dosstr.c" void I_SetTextInputMode(boolean active)
{
(void)active;
}
boolean I_GetTextInputMode(void)
{
return false;
}
#include "../sdl/dosstr.c"
...@@ -157,7 +157,7 @@ void I_wake_all_cond(I_cond *anchor) ...@@ -157,7 +157,7 @@ void I_wake_all_cond(I_cond *anchor)
pthread_mutex_lock(&thread_lock); pthread_mutex_lock(&thread_lock);
if (*anchor == NULL) if (*anchor == NULL)
{ {
*anchor = malloc(sizeof(pthread_t)); *anchor = malloc(sizeof(pthread_cond_t));
pthread_cond_init(*anchor, NULL); pthread_cond_init(*anchor, NULL);
} }
pthread_mutex_unlock(&thread_lock); pthread_mutex_unlock(&thread_lock);
......
#include "../doomdef.h" #include "../doomdef.h"
#include "../command.h" #include "../command.h"
#include "../i_video.h" #include "../i_video.h"
...@@ -76,4 +76,3 @@ void I_ReadScreen(UINT8 *scr) ...@@ -76,4 +76,3 @@ void I_ReadScreen(UINT8 *scr)
void I_BeginRead(void){} void I_BeginRead(void){}
void I_EndRead(void){} void I_EndRead(void){}
// SONIC ROBO BLAST 2 // SONIC ROBO BLAST 2
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Copyright (C) 1998-2000 by DooM Legacy Team. // Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2023 by Sonic Team Junior. // Copyright (C) 1999-2024 by Sonic Team Junior.
// //
// This program is free software distributed under the // This program is free software distributed under the
// terms of the GNU General Public License, version 2. // terms of the GNU General Public License, version 2.
...@@ -11,7 +11,6 @@ ...@@ -11,7 +11,6 @@
/// \brief Lua SOC library /// \brief Lua SOC library
#include "deh_lua.h" #include "deh_lua.h"
#include "g_input.h"
// freeslot takes a name (string only!) // freeslot takes a name (string only!)
// and allocates it to the appropriate free slot. // and allocates it to the appropriate free slot.
...@@ -28,6 +27,12 @@ static inline int lib_freeslot(lua_State *L) ...@@ -28,6 +27,12 @@ static inline int lib_freeslot(lua_State *L)
if (!lua_lumploading) if (!lua_lumploading)
return luaL_error(L, "This function cannot be called from within a hook or coroutine!"); return luaL_error(L, "This function cannot be called from within a hook or coroutine!");
if (!deh_loaded)
{
initfreeslots();
deh_loaded = true;
}
while (n-- > 0) while (n-- > 0)
{ {
s = Z_StrDup(luaL_checkstring(L,1)); s = Z_StrDup(luaL_checkstring(L,1));
...@@ -594,20 +599,12 @@ static int ScanConstants(lua_State *L, boolean mathlib, const char *word) ...@@ -594,20 +599,12 @@ static int ScanConstants(lua_State *L, boolean mathlib, const char *word)
return luaL_error(L, "translation '%s' could not be found.\n", word); return luaL_error(L, "translation '%s' could not be found.\n", word);
} }
// TODO: 2.3: Delete these aliases // TODO: 2.3: Delete this alias
else if (fastcmp(word, "BT_USE")) if (fastcmp(word, "BT_USE"))
{ {
CacheAndPushConstant(L, word, (lua_Integer)BT_SPIN); CacheAndPushConstant(L, word, (lua_Integer)BT_SPIN);
return 1; return 1;
} }
else if (fastcmp(word, "GC_WEPSLOT8") || fastcmp(word, "GC_WEPSLOT9") || fastcmp(word, "GC_WEPSLOT10"))
{
// Using GC_WEPSLOT7 isn't accurate, but ensures that "if x >= GC_WEPSLOT1 and x <= GC_WEPSLOT10" keeps the intended effect
CacheAndPushConstant(L, word, (lua_Integer)GC_WEPSLOT7);
if (!mathlib)
LUA_Deprecated(L, "GC_WEPSLOT8\"-\"GC_WEPSLOT10", "GC_WEPSLOT1\"-\"GC_WEPSLOT7");
return 1;
}
for (i = 0; INT_CONST[i].n; i++) for (i = 0; INT_CONST[i].n; i++)
if (fastcmp(word,INT_CONST[i].n)) { if (fastcmp(word,INT_CONST[i].n)) {
......
// SONIC ROBO BLAST 2 // SONIC ROBO BLAST 2
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Copyright (C) 1998-2000 by DooM Legacy Team. // Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2023 by Sonic Team Junior. // Copyright (C) 1999-2025 by Sonic Team Junior.
// //
// This program is free software distributed under the // This program is free software distributed under the
// terms of the GNU General Public License, version 2. // terms of the GNU General Public License, version 2.
...@@ -286,6 +286,7 @@ void readPlayer(MYFILE *f, INT32 num) ...@@ -286,6 +286,7 @@ void readPlayer(MYFILE *f, INT32 num)
} }
if (playertext) if (playertext)
{ {
// PLAYERTEXT is really weird, so this doesn't use deh_strlcpy.
strlcpy(description[num].notes, playertext, NOTE_SIZE); strlcpy(description[num].notes, playertext, NOTE_SIZE);
strlcat(description[num].notes, strlcat(description[num].notes,
myhashfgets(playertext, NOTE_SIZE, f), NOTE_SIZE); myhashfgets(playertext, NOTE_SIZE, f), NOTE_SIZE);
...@@ -324,7 +325,8 @@ void readPlayer(MYFILE *f, INT32 num) ...@@ -324,7 +325,8 @@ void readPlayer(MYFILE *f, INT32 num)
if (fastcmp(word, "PICNAME")) if (fastcmp(word, "PICNAME"))
{ {
SLOTFOUND SLOTFOUND
strncpy(description[num].picname, word2, sizeof(description[num].picname)-1); deh_strlcpy(description[num].picname, word2, sizeof description[num].picname,
va("Character %d: picname", num));
} }
else if (fastcmp(word, "DISPLAYNAME")) else if (fastcmp(word, "DISPLAYNAME"))
{ {
...@@ -345,7 +347,8 @@ void readPlayer(MYFILE *f, INT32 num) ...@@ -345,7 +347,8 @@ void readPlayer(MYFILE *f, INT32 num)
cur = strchr(cur, '#'); cur = strchr(cur, '#');
} }
strlcpy(description[num].displayname, stringvalue, sizeof description[num].displayname); deh_strlcpy(description[num].displayname, stringvalue, sizeof description[num].displayname,
va("Character %d: displayname", num));
} }
else if (fastcmp(word, "OPPOSITECOLOR") || fastcmp(word, "OPPOSITECOLOUR")) else if (fastcmp(word, "OPPOSITECOLOR") || fastcmp(word, "OPPOSITECOLOUR"))
{ {
...@@ -355,7 +358,8 @@ void readPlayer(MYFILE *f, INT32 num) ...@@ -355,7 +358,8 @@ void readPlayer(MYFILE *f, INT32 num)
else if (fastcmp(word, "NAMETAG") || fastcmp(word, "TAGNAME")) else if (fastcmp(word, "NAMETAG") || fastcmp(word, "TAGNAME"))
{ {
SLOTFOUND SLOTFOUND
strncpy(description[num].nametag, word2, sizeof(description[num].nametag)-1); deh_strlcpy(description[num].nametag, word2, sizeof description[num].nametag,
va("Character %d: nametag", num));
} }
else if (fastcmp(word, "TAGTEXTCOLOR") || fastcmp(word, "TAGTEXTCOLOUR")) else if (fastcmp(word, "TAGTEXTCOLOR") || fastcmp(word, "TAGTEXTCOLOUR"))
{ {
...@@ -387,7 +391,8 @@ void readPlayer(MYFILE *f, INT32 num) ...@@ -387,7 +391,8 @@ void readPlayer(MYFILE *f, INT32 num)
{ {
// Send to free slot. // Send to free slot.
SLOTFOUND SLOTFOUND
strlcpy(description[num].skinname, word2, sizeof description[num].skinname); deh_strlcpy(description[num].skinname, word2, sizeof description[num].skinname,
va("Character %d: skinname", num));
strlwr(description[num].skinname); strlwr(description[num].skinname);
} }
else if (!failure) else if (!failure)
...@@ -405,7 +410,6 @@ void readfreeslots(MYFILE *f) ...@@ -405,7 +410,6 @@ void readfreeslots(MYFILE *f)
{ {
char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL); char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
char *word,*type; char *word,*type;
char *tmp;
int i; int i;
do do
...@@ -415,10 +419,13 @@ void readfreeslots(MYFILE *f) ...@@ -415,10 +419,13 @@ void readfreeslots(MYFILE *f)
if (s[0] == '\n') if (s[0] == '\n')
break; break;
tmp = strchr(s, '#'); char *hashtag = strchr(s, '#');
if (tmp) char *space = strchr(s, ' ');
*tmp = '\0'; if (hashtag)
if (s == tmp) *hashtag = '\0';
if (space)
*space = '\0';
if (s == hashtag || s == space)
continue; // Skip comment lines, but don't break. continue; // Skip comment lines, but don't break.
type = strtok(s, "_"); type = strtok(s, "_");
...@@ -1194,6 +1201,7 @@ void readgametype(MYFILE *f, char *gtname) ...@@ -1194,6 +1201,7 @@ void readgametype(MYFILE *f, char *gtname)
} }
if (descr) if (descr)
{ {
// DESCRIPTION is really weird, so this doesn't use deh_strlcpy.
strlcpy(gtdescription, descr, sizeof (gtdescription)); strlcpy(gtdescription, descr, sizeof (gtdescription));
strlcat(gtdescription, strlcat(gtdescription,
myhashfgets(descr, sizeof (gtdescription), f), myhashfgets(descr, sizeof (gtdescription), f),
...@@ -1400,7 +1408,7 @@ void readlevelheader(MYFILE *f, INT32 num) ...@@ -1400,7 +1408,7 @@ void readlevelheader(MYFILE *f, INT32 num)
{ {
deh_strlcpy(mapheaderinfo[num-1]->lvlttl, word2, deh_strlcpy(mapheaderinfo[num-1]->lvlttl, word2,
sizeof(mapheaderinfo[num-1]->lvlttl), va("Level header %d: levelname", num)); sizeof(mapheaderinfo[num-1]->lvlttl), va("Level header %d: levelname", num));
strlcpy(mapheaderinfo[num-1]->selectheading, word2, sizeof(mapheaderinfo[num-1]->selectheading)); // not deh_ so only complains once strlcpy(mapheaderinfo[num-1]->selectheading, word2, sizeof(mapheaderinfo[num-1]->selectheading)); // not deh_strlcpy so only complains once
continue; continue;
} }
// CHEAP HACK: move this over here for lowercase subtitles // CHEAP HACK: move this over here for lowercase subtitles
...@@ -1443,10 +1451,10 @@ void readlevelheader(MYFILE *f, INT32 num) ...@@ -1443,10 +1451,10 @@ void readlevelheader(MYFILE *f, INT32 num)
// Newly allocated // Newly allocated
modoption = &mapheaderinfo[num-1]->customopts[j]; modoption = &mapheaderinfo[num-1]->customopts[j];
strncpy(modoption->option, word, 31); deh_strlcpy(modoption->option, word, sizeof(modoption->option),
modoption->option[31] = '\0'; va("Level header %d: custom option %d key", num, j));
strncpy(modoption->value, word2, 255); deh_strlcpy(modoption->value, word2, sizeof(modoption->value),
modoption->value[255] = '\0'; va("Level header %d: custom option %d value", num, j));
continue; continue;
} }
...@@ -1624,7 +1632,7 @@ void readlevelheader(MYFILE *f, INT32 num) ...@@ -1624,7 +1632,7 @@ void readlevelheader(MYFILE *f, INT32 num)
else if (fastcmp(word, "KEYWORDS")) else if (fastcmp(word, "KEYWORDS"))
{ {
deh_strlcpy(mapheaderinfo[num-1]->keywords, word2, deh_strlcpy(mapheaderinfo[num-1]->keywords, word2,
sizeof(mapheaderinfo[num-1]->keywords), va("Level header %d: keywords", num)); sizeof(mapheaderinfo[num-1]->keywords), va("Level header %d: keywords", num));
} }
else if (fastcmp(word, "MUSIC")) else if (fastcmp(word, "MUSIC"))
{ {
...@@ -1673,7 +1681,8 @@ void readlevelheader(MYFILE *f, INT32 num) ...@@ -1673,7 +1681,8 @@ void readlevelheader(MYFILE *f, INT32 num)
} }
else if (fastcmp(word, "FORCECHARACTER")) else if (fastcmp(word, "FORCECHARACTER"))
{ {
strlcpy(mapheaderinfo[num-1]->forcecharacter, word2, SKINNAMESIZE+1); deh_strlcpy(mapheaderinfo[num-1]->forcecharacter, word2, sizeof mapheaderinfo[num-1]->forcecharacter,
va("Level header %d: forcecharacter", num));
strlwr(mapheaderinfo[num-1]->forcecharacter); // skin names are lowercase strlwr(mapheaderinfo[num-1]->forcecharacter); // skin names are lowercase
} }
else if (fastcmp(word, "WEATHER")) else if (fastcmp(word, "WEATHER"))
...@@ -1681,7 +1690,10 @@ void readlevelheader(MYFILE *f, INT32 num) ...@@ -1681,7 +1690,10 @@ void readlevelheader(MYFILE *f, INT32 num)
else if (fastcmp(word, "SKYNUM")) else if (fastcmp(word, "SKYNUM"))
mapheaderinfo[num-1]->skynum = (INT16)i; mapheaderinfo[num-1]->skynum = (INT16)i;
else if (fastcmp(word, "INTERSCREEN")) else if (fastcmp(word, "INTERSCREEN"))
strncpy(mapheaderinfo[num-1]->interscreen, word2, sizeof(mapheaderinfo[num-1]->interscreen)-1); {
deh_strlcpy(mapheaderinfo[num-1]->interscreen, word2, sizeof mapheaderinfo[num-1]->interscreen,
va("Level header %d: interscreen", num));
}
else if (fastcmp(word, "PRECUTSCENENUM")) else if (fastcmp(word, "PRECUTSCENENUM"))
mapheaderinfo[num-1]->precutscenenum = (UINT8)i; mapheaderinfo[num-1]->precutscenenum = (UINT8)i;
else if (fastcmp(word, "CUTSCENENUM")) else if (fastcmp(word, "CUTSCENENUM"))
...@@ -1983,14 +1995,17 @@ static void readcutscenescene(MYFILE *f, INT32 num, INT32 scenenum) ...@@ -1983,14 +1995,17 @@ static void readcutscenescene(MYFILE *f, INT32 num, INT32 scenenum)
picid = (UINT8)atoi(word + 3); picid = (UINT8)atoi(word + 3);
if (picid > 8 || picid == 0) if (picid > 8 || picid == 0)
{ {
deh_warning("CutSceneScene %d: unknown word '%s'", num, word); deh_warning("Cutscene %d, scene %d: pic number %d out of range (1 - %d)",
num + 1, scenenum + 1, picid, 8);
continue; continue;
} }
--picid; --picid;
if (fastcmp(word+4, "NAME")) if (fastcmp(word+4, "NAME"))
{ {
strncpy(cutscenes[num]->scene[scenenum].picname[picid], word2, 8); deh_strlcpy(cutscenes[num]->scene[scenenum].picname[picid], word2,
sizeof cutscenes[num]->scene[scenenum].picname[picid],
va("Cutscene %d, scene %d, pic %d: name", num + 1, scenenum + 1, picid + 1));
} }
else if (fastcmp(word+4, "HIRES")) else if (fastcmp(word+4, "HIRES"))
{ {
...@@ -2009,12 +2024,13 @@ static void readcutscenescene(MYFILE *f, INT32 num, INT32 scenenum) ...@@ -2009,12 +2024,13 @@ static void readcutscenescene(MYFILE *f, INT32 num, INT32 scenenum)
cutscenes[num]->scene[scenenum].ycoord[picid] = usi; cutscenes[num]->scene[scenenum].ycoord[picid] = usi;
} }
else else
deh_warning("CutSceneScene %d: unknown word '%s'", num, word); deh_warning("Cutscene %d, scene %d: unknown word '%s'", num + 1, scenenum + 1, word);
} }
else if (fastcmp(word, "MUSIC")) else if (fastcmp(word, "MUSIC"))
{ {
strncpy(cutscenes[num]->scene[scenenum].musswitch, word2, 7); deh_strlcpy(cutscenes[num]->scene[scenenum].musswitch, word2,
cutscenes[num]->scene[scenenum].musswitch[6] = 0; sizeof cutscenes[num]->scene[scenenum].musswitch,
va("Cutscene %d, scene %d: music", num + 1, scenenum + 1));
} }
else if (fastcmp(word, "MUSICTRACK")) else if (fastcmp(word, "MUSICTRACK"))
{ {
...@@ -2049,7 +2065,7 @@ static void readcutscenescene(MYFILE *f, INT32 num, INT32 scenenum) ...@@ -2049,7 +2065,7 @@ static void readcutscenescene(MYFILE *f, INT32 num, INT32 scenenum)
cutscenes[num]->scene[scenenum].fadecolor = (UINT8)i; cutscenes[num]->scene[scenenum].fadecolor = (UINT8)i;
} }
else else
deh_warning("CutSceneScene %d: unknown word '%s'", num, word); deh_warning("Cutscene %d, scene %d: unknown word '%s'", num + 1, scenenum + 1, word);
} }
} while (!myfeof(f)); // finish when the line is empty } while (!myfeof(f)); // finish when the line is empty
...@@ -2107,11 +2123,10 @@ void readcutscene(MYFILE *f, INT32 num) ...@@ -2107,11 +2123,10 @@ void readcutscene(MYFILE *f, INT32 num)
readcutscenescene(f, num, value - 1); readcutscenescene(f, num, value - 1);
} }
else else
deh_warning("Scene number %d out of range (1 - 128)", value); deh_warning("Cutscene %d: scene number %d out of range (1 - 128)", num + 1, value);
} }
else else
deh_warning("Cutscene %d: unknown word '%s', Scene <num> expected.", num, word); deh_warning("Cutscene %d: unknown word '%s', Scene <num> expected.", num + 1, word);
} }
} while (!myfeof(f)); // finish when the line is empty } while (!myfeof(f)); // finish when the line is empty
...@@ -2232,7 +2247,8 @@ static void readtextpromptpage(MYFILE *f, INT32 num, INT32 pagenum) ...@@ -2232,7 +2247,8 @@ static void readtextpromptpage(MYFILE *f, INT32 num, INT32 pagenum)
for (picid = 0; picid < MAX_PROMPT_PICS; picid++) for (picid = 0; picid < MAX_PROMPT_PICS; picid++)
{ {
strncpy(textprompts[num]->page[pagenum].picname[picid], textprompts[num]->page[metapagenum].picname[picid], 8); // Doesn't use deh_strlcpy because it's not copying input.
strlcpy(textprompts[num]->page[pagenum].picname[picid], textprompts[num]->page[metapagenum].picname[picid], sizeof textprompts[num]->page[pagenum].picname[picid]);
textprompts[num]->page[pagenum].pichires[picid] = textprompts[num]->page[metapagenum].pichires[picid]; textprompts[num]->page[pagenum].pichires[picid] = textprompts[num]->page[metapagenum].pichires[picid];
textprompts[num]->page[pagenum].picduration[picid] = textprompts[num]->page[metapagenum].picduration[picid]; textprompts[num]->page[pagenum].picduration[picid] = textprompts[num]->page[metapagenum].picduration[picid];
textprompts[num]->page[pagenum].xcoord[picid] = textprompts[num]->page[metapagenum].xcoord[picid]; textprompts[num]->page[pagenum].xcoord[picid] = textprompts[num]->page[metapagenum].xcoord[picid];
...@@ -2245,14 +2261,17 @@ static void readtextpromptpage(MYFILE *f, INT32 num, INT32 pagenum) ...@@ -2245,14 +2261,17 @@ static void readtextpromptpage(MYFILE *f, INT32 num, INT32 pagenum)
picid = (UINT8)atoi(word + 3); picid = (UINT8)atoi(word + 3);
if (picid > MAX_PROMPT_PICS || picid == 0) if (picid > MAX_PROMPT_PICS || picid == 0)
{ {
deh_warning("textpromptscene %d: unknown word '%s'", num, word); deh_warning("Text prompt %d, page %d: pic number %d out of range (1 - %d)",
num + 1, pagenum + 1, picid, MAX_PROMPT_PICS);
continue; continue;
} }
--picid; --picid;
if (fastcmp(word+4, "NAME")) if (fastcmp(word+4, "NAME"))
{ {
strncpy(textprompts[num]->page[pagenum].picname[picid], word2, 8); deh_strlcpy(textprompts[num]->page[pagenum].picname[picid], word2,
sizeof textprompts[num]->page[pagenum].picname[picid],
va("Text prompt %d, page %d, pic %d: name", num + 1, pagenum + 1, picid + 1));
} }
else if (fastcmp(word+4, "HIRES")) else if (fastcmp(word+4, "HIRES"))
{ {
...@@ -2271,12 +2290,16 @@ static void readtextpromptpage(MYFILE *f, INT32 num, INT32 pagenum) ...@@ -2271,12 +2290,16 @@ static void readtextpromptpage(MYFILE *f, INT32 num, INT32 pagenum)
textprompts[num]->page[pagenum].ycoord[picid] = usi; textprompts[num]->page[pagenum].ycoord[picid] = usi;
} }
else else
deh_warning("textpromptscene %d: unknown word '%s'", num, word); {
deh_warning("Text prompt %d, page %d: unknown word '%s'",
num + 1, pagenum + 1, word);
}
} }
else if (fastcmp(word, "MUSIC")) else if (fastcmp(word, "MUSIC"))
{ {
strncpy(textprompts[num]->page[pagenum].musswitch, word2, 7); deh_strlcpy(textprompts[num]->page[pagenum].musswitch, word2,
textprompts[num]->page[pagenum].musswitch[6] = 0; sizeof textprompts[num]->page[pagenum].musswitch,
va("Text prompt %d, page %d: music", num + 1, pagenum + 1));
} }
else if (fastcmp(word, "MUSICTRACK")) else if (fastcmp(word, "MUSICTRACK"))
{ {
...@@ -2291,30 +2314,35 @@ static void readtextpromptpage(MYFILE *f, INT32 num, INT32 pagenum) ...@@ -2291,30 +2314,35 @@ static void readtextpromptpage(MYFILE *f, INT32 num, INT32 pagenum)
{ {
if (*word2 != '\0') if (*word2 != '\0')
{ {
INT32 j; size_t j;
// HACK: Add yellow control char now // HACK: Add yellow control char now
// so the drawing function doesn't call it repeatedly // so the drawing function doesn't call it repeatedly
char name[34]; char name[32 + 2];
name[0] = '\x82'; // color yellow name[0] = '\x82'; // color yellow
name[1] = 0;
strncat(name, word2, 32); // So that we still get a warning.
name[33] = 0; deh_strlcpy(name + 1, word2, (sizeof(name)) - 1,
va("Text prompt %d, page %d: name", num + 1, pagenum + 1));
// Replace _ with ' ' // Replace _ with ' '
for (j = 0; j < 32 && name[j]; j++) for (j = 1; j < sizeof(name) && name[j]; j++)
{ {
if (name[j] == '_') if (name[j] == '_')
name[j] = ' '; name[j] = ' ';
} }
strncpy(textprompts[num]->page[pagenum].name, name, sizeof(textprompts[num]->page[pagenum].name)); strlcpy(textprompts[num]->page[pagenum].name, name, sizeof(textprompts[num]->page[pagenum].name));
} }
else else
*textprompts[num]->page[pagenum].name = '\0'; *textprompts[num]->page[pagenum].name = '\0';
} }
else if (fastcmp(word, "ICON")) else if (fastcmp(word, "ICON"))
strncpy(textprompts[num]->page[pagenum].iconname, word2, 8); {
deh_strlcpy(textprompts[num]->page[pagenum].iconname, word2,
sizeof textprompts[num]->page[pagenum].iconname,
va("Text prompt %d, page %d: icon", num + 1, pagenum + 1));
}
else if (fastcmp(word, "ICONALIGN")) else if (fastcmp(word, "ICONALIGN"))
textprompts[num]->page[pagenum].rightside = (i || word2[0] == 'R'); textprompts[num]->page[pagenum].rightside = (i || word2[0] == 'R');
else if (fastcmp(word, "ICONFLIP")) else if (fastcmp(word, "ICONFLIP"))
...@@ -2381,8 +2409,9 @@ static void readtextpromptpage(MYFILE *f, INT32 num, INT32 pagenum) ...@@ -2381,8 +2409,9 @@ static void readtextpromptpage(MYFILE *f, INT32 num, INT32 pagenum)
{ {
UINT8 metapagenum = usi - 1; UINT8 metapagenum = usi - 1;
strncpy(textprompts[num]->page[pagenum].name, textprompts[num]->page[metapagenum].name, 32); // Doesn't use deh_strlcpy because it's not copying input.
strncpy(textprompts[num]->page[pagenum].iconname, textprompts[num]->page[metapagenum].iconname, 8); strlcpy(textprompts[num]->page[pagenum].name, textprompts[num]->page[metapagenum].name, sizeof textprompts[num]->page[pagenum].name);
strlcpy(textprompts[num]->page[pagenum].iconname, textprompts[num]->page[metapagenum].iconname, sizeof textprompts[num]->page[pagenum].iconname);
textprompts[num]->page[pagenum].rightside = textprompts[num]->page[metapagenum].rightside; textprompts[num]->page[pagenum].rightside = textprompts[num]->page[metapagenum].rightside;
textprompts[num]->page[pagenum].iconflip = textprompts[num]->page[metapagenum].iconflip; textprompts[num]->page[pagenum].iconflip = textprompts[num]->page[metapagenum].iconflip;
textprompts[num]->page[pagenum].lines = textprompts[num]->page[metapagenum].lines; textprompts[num]->page[pagenum].lines = textprompts[num]->page[metapagenum].lines;
...@@ -2397,17 +2426,25 @@ static void readtextpromptpage(MYFILE *f, INT32 num, INT32 pagenum) ...@@ -2397,17 +2426,25 @@ static void readtextpromptpage(MYFILE *f, INT32 num, INT32 pagenum)
} }
} }
else if (fastcmp(word, "TAG")) else if (fastcmp(word, "TAG"))
strncpy(textprompts[num]->page[pagenum].tag, word2, 33); {
deh_strlcpy(textprompts[num]->page[pagenum].tag, word2,
sizeof textprompts[num]->page[pagenum].tag,
va("Text prompt %d, page %d: tag", num + 1, pagenum + 1));
}
else if (fastcmp(word, "NEXTPROMPT")) else if (fastcmp(word, "NEXTPROMPT"))
textprompts[num]->page[pagenum].nextprompt = usi; textprompts[num]->page[pagenum].nextprompt = usi;
else if (fastcmp(word, "NEXTPAGE")) else if (fastcmp(word, "NEXTPAGE"))
textprompts[num]->page[pagenum].nextpage = usi; textprompts[num]->page[pagenum].nextpage = usi;
else if (fastcmp(word, "NEXTTAG")) else if (fastcmp(word, "NEXTTAG"))
strncpy(textprompts[num]->page[pagenum].nexttag, word2, 33); {
deh_strlcpy(textprompts[num]->page[pagenum].nexttag, word2,
sizeof textprompts[num]->page[pagenum].nexttag,
va("Text prompt %d, page %d: nexttag", num + 1, pagenum + 1));
}
else if (fastcmp(word, "TIMETONEXT")) else if (fastcmp(word, "TIMETONEXT"))
textprompts[num]->page[pagenum].timetonext = get_number(word2); textprompts[num]->page[pagenum].timetonext = get_number(word2);
else else
deh_warning("PromptPage %d: unknown word '%s'", num, word); deh_warning("Text prompt %d, page %d: unknown word '%s'", num + 1, pagenum + 1, word);
} }
} while (!myfeof(f)); // finish when the line is empty } while (!myfeof(f)); // finish when the line is empty
...@@ -2467,11 +2504,11 @@ void readtextprompt(MYFILE *f, INT32 num) ...@@ -2467,11 +2504,11 @@ void readtextprompt(MYFILE *f, INT32 num)
readtextpromptpage(f, num, value - 1); readtextpromptpage(f, num, value - 1);
} }
else else
deh_warning("Page number %d out of range (1 - %d)", value, MAX_PAGES); deh_warning("Prompt %d: page number %d out of range (1 - %d)", num + 1, value, MAX_PAGES);
} }
else else
deh_warning("Prompt %d: unknown word '%s', Page <num> expected.", num, word); deh_warning("Prompt %d: unknown word '%s', Page <num> expected.", num + 1, word);
} }
} while (!myfeof(f)); // finish when the line is empty } while (!myfeof(f)); // finish when the line is empty
...@@ -2520,7 +2557,8 @@ void readmenu(MYFILE *f, INT32 num) ...@@ -2520,7 +2557,8 @@ void readmenu(MYFILE *f, INT32 num)
if (fastcmp(word, "BACKGROUNDNAME")) if (fastcmp(word, "BACKGROUNDNAME"))
{ {
strncpy(menupres[num].bgname, word2, 8); deh_strlcpy(menupres[num].bgname, word2,
sizeof menupres[num].bgname, va("Menu %d: backgroundname", num));
titlechanged = true; titlechanged = true;
} }
else if (fastcmp(word, "HIDEBACKGROUND")) else if (fastcmp(word, "HIDEBACKGROUND"))
...@@ -2563,7 +2601,8 @@ void readmenu(MYFILE *f, INT32 num) ...@@ -2563,7 +2601,8 @@ void readmenu(MYFILE *f, INT32 num)
} }
else if (fastcmp(word, "TITLEPICSNAME")) else if (fastcmp(word, "TITLEPICSNAME"))
{ {
strncpy(menupres[num].ttname, word2, 9); deh_strlcpy(menupres[num].ttname, word2,
sizeof menupres[num].ttname, va("Menu %d: titlepicsname", num));
titlechanged = true; titlechanged = true;
} }
else if (fastcmp(word, "TITLEPICSX")) else if (fastcmp(word, "TITLEPICSX"))
...@@ -2599,8 +2638,8 @@ void readmenu(MYFILE *f, INT32 num) ...@@ -2599,8 +2638,8 @@ void readmenu(MYFILE *f, INT32 num)
} }
else if (fastcmp(word, "MUSIC")) else if (fastcmp(word, "MUSIC"))
{ {
strncpy(menupres[num].musname, word2, 7); deh_strlcpy(menupres[num].musname, word2,
menupres[num].musname[6] = 0; sizeof menupres[num].musname, va("Menu %d: music", num));
titlechanged = true; titlechanged = true;
} }
else if (fastcmp(word, "MUSICTRACK")) else if (fastcmp(word, "MUSICTRACK"))
...@@ -2789,7 +2828,7 @@ void readframe(MYFILE *f, INT32 num) ...@@ -2789,7 +2828,7 @@ void readframe(MYFILE *f, INT32 num)
size_t z; size_t z;
boolean found = false; boolean found = false;
size_t actionlen = strlen(word2) + 1; size_t actionlen = strlen(word2) + 1;
char *actiontocompare = calloc(actionlen, 1); char *actiontocompare = calloc(1, actionlen);
strcpy(actiontocompare, word2); strcpy(actiontocompare, word2);
strupr(actiontocompare); strupr(actiontocompare);
...@@ -3582,22 +3621,20 @@ void readmaincfg(MYFILE *f) ...@@ -3582,22 +3621,20 @@ void readmaincfg(MYFILE *f)
if (fastcmp(word, "EXECCFG")) if (fastcmp(word, "EXECCFG"))
{ {
if (strchr(word2, '.')) if (strchr(word2, '.'))
COM_BufAddText(va("exec %s\n", word2)); COM_ExecFile(word2, COM_LUA, false);
else else
{ {
lumpnum_t lumpnum; lumpnum_t lumpnum;
char newname[9]; char newname[9];
strncpy(newname, word2, 8); deh_strlcpy(newname, word2, sizeof newname, va("Maincfg: execcfg"));
newname[8] = '\0';
lumpnum = W_CheckNumForName(newname); lumpnum = W_CheckNumForName(newname);
if (lumpnum == LUMPERROR || W_LumpLength(lumpnum) == 0) if (lumpnum == LUMPERROR || W_LumpLength(lumpnum) == 0)
CONS_Debug(DBG_SETUP, "SOC Error: script lump %s not found/not valid.\n", newname); CONS_Debug(DBG_SETUP, "SOC Error: script lump %s not found/not valid.\n", newname);
else else
COM_BufInsertText(W_CacheLumpNum(lumpnum, PU_CACHE)); COM_BufInsertTextEx(W_CacheLumpNum(lumpnum, PU_CACHE), COM_LUA);
} }
} }
...@@ -3798,7 +3835,7 @@ void readmaincfg(MYFILE *f) ...@@ -3798,7 +3835,7 @@ void readmaincfg(MYFILE *f)
} }
else if (fastcmp(word, "TITLEPICSNAME")) else if (fastcmp(word, "TITLEPICSNAME"))
{ {
strncpy(ttname, word2, sizeof(ttname)-1); deh_strlcpy(ttname, word2, sizeof ttname, va("Maincfg: titlepicsname"));
titlechanged = true; titlechanged = true;
} }
else if (fastcmp(word, "TITLEPICSX")) else if (fastcmp(word, "TITLEPICSX"))
...@@ -3908,7 +3945,7 @@ void readmaincfg(MYFILE *f) ...@@ -3908,7 +3945,7 @@ void readmaincfg(MYFILE *f)
} }
else if (fastcmp(word, "CUSTOMVERSION")) else if (fastcmp(word, "CUSTOMVERSION"))
{ {
strlcpy(customversionstring, word2, sizeof (customversionstring)); deh_strlcpy(customversionstring, word2, sizeof customversionstring, va("Maincfg: customversion"));
//titlechanged = true; //titlechanged = true;
} }
else if (fastcmp(word, "BOOTMAP")) else if (fastcmp(word, "BOOTMAP"))
...@@ -3923,6 +3960,7 @@ void readmaincfg(MYFILE *f) ...@@ -3923,6 +3960,7 @@ void readmaincfg(MYFILE *f)
value = get_number(word2); value = get_number(word2);
bootmap = (INT16)value; bootmap = (INT16)value;
bootmapchanged = true;
//titlechanged = true; //titlechanged = true;
} }
else if (fastcmp(word, "STARTCHAR")) else if (fastcmp(word, "STARTCHAR"))
......
// SONIC ROBO BLAST 2 // SONIC ROBO BLAST 2
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Copyright (C) 1998-2000 by DooM Legacy Team. // Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2023 by Sonic Team Junior. // Copyright (C) 1999-2025 by Sonic Team Junior.
// //
// This program is free software distributed under the // This program is free software distributed under the
// terms of the GNU General Public License, version 2. // terms of the GNU General Public License, version 2.
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include "g_game.h" // Joystick axes (for lua) #include "g_game.h" // Joystick axes (for lua)
#include "i_joy.h" #include "i_joy.h"
#include "g_input.h" // Game controls (for lua) #include "g_input.h" // Game controls (for lua)
#include "p_maputl.h" // P_PathTraverse constants (for lua)
#include "deh_tables.h" #include "deh_tables.h"
...@@ -1081,11 +1082,11 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi ...@@ -1081,11 +1082,11 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi
"S_FANG_FIRE1", "S_FANG_FIRE1",
"S_FANG_FIRE2", "S_FANG_FIRE2",
"S_FANG_FIRE3", "S_FANG_FIRE3",
"S_FANG_FIRE4",
"S_FANG_FIREREPEAT", "S_FANG_FIREREPEAT",
"S_FANG_LOBSHOT0", "S_FANG_LOBSHOT0",
"S_FANG_LOBSHOT1", "S_FANG_LOBSHOT1",
"S_FANG_LOBSHOT2", "S_FANG_LOBSHOT2",
"S_FANG_LOBSHOT3",
"S_FANG_WAIT1", "S_FANG_WAIT1",
"S_FANG_WAIT2", "S_FANG_WAIT2",
"S_FANG_WALLHIT", "S_FANG_WALLHIT",
...@@ -1107,6 +1108,7 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi ...@@ -1107,6 +1108,7 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi
"S_FANG_PINCHLOBSHOT2", "S_FANG_PINCHLOBSHOT2",
"S_FANG_PINCHLOBSHOT3", "S_FANG_PINCHLOBSHOT3",
"S_FANG_PINCHLOBSHOT4", "S_FANG_PINCHLOBSHOT4",
"S_FANG_PINCHLOBSHOT5",
"S_FANG_DIE1", "S_FANG_DIE1",
"S_FANG_DIE2", "S_FANG_DIE2",
"S_FANG_DIE3", "S_FANG_DIE3",
...@@ -2245,6 +2247,10 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi ...@@ -2245,6 +2247,10 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi
"S_LAMPPOST2", // with snow "S_LAMPPOST2", // with snow
"S_HANGSTAR", "S_HANGSTAR",
"S_MISTLETOE", "S_MISTLETOE",
"S_SSZTREE",
"S_SSZTREE_BRANCH",
"S_SSZTREE2",
"S_SSZTREE2_BRANCH",
// Xmas GFZ bushes // Xmas GFZ bushes
"S_XMASBLUEBERRYBUSH", "S_XMASBLUEBERRYBUSH",
"S_XMASBERRYBUSH", "S_XMASBERRYBUSH",
...@@ -2252,11 +2258,9 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi ...@@ -2252,11 +2258,9 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi
// FHZ // FHZ
"S_FHZICE1", "S_FHZICE1",
"S_FHZICE2", "S_FHZICE2",
"S_ROSY_IDLE1", "S_ROSY_IDLE",
"S_ROSY_IDLE2",
"S_ROSY_IDLE3",
"S_ROSY_IDLE4",
"S_ROSY_JUMP", "S_ROSY_JUMP",
"S_ROSY_FALL",
"S_ROSY_WALK", "S_ROSY_WALK",
"S_ROSY_HUG", "S_ROSY_HUG",
"S_ROSY_PAIN", "S_ROSY_PAIN",
...@@ -2365,6 +2369,9 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi ...@@ -2365,6 +2369,9 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi
"S_DBALL5", "S_DBALL5",
"S_DBALL6", "S_DBALL6",
"S_EGGSTATUE2", "S_EGGSTATUE2",
"S_GINE",
"S_PPAL",
"S_PPEL",
// Shield Orb // Shield Orb
"S_ARMA1", "S_ARMA1",
...@@ -3249,6 +3256,7 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi ...@@ -3249,6 +3256,7 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi
"S_MARIOBUSH2", "S_MARIOBUSH2",
"S_TOAD", "S_TOAD",
// Nights-specific stuff // Nights-specific stuff
"S_NIGHTSDRONE_MAN1", "S_NIGHTSDRONE_MAN1",
"S_NIGHTSDRONE_MAN2", "S_NIGHTSDRONE_MAN2",
...@@ -3552,6 +3560,12 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi ...@@ -3552,6 +3560,12 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi
"S_YELLOWBRICKDEBRIS", "S_YELLOWBRICKDEBRIS",
"S_NAMECHECK", "S_NAMECHECK",
// LJ Knuckles
"S_OLDK_STND",
"S_OLDK_DIE0",
"S_OLDK_DIE1",
"S_OLDK_DIE2",
}; };
// RegEx to generate this from info.h: ^\tMT_([^,]+), --> \t"MT_\1", // RegEx to generate this from info.h: ^\tMT_([^,]+), --> \t"MT_\1",
...@@ -4023,6 +4037,10 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t ...@@ -4023,6 +4037,10 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t
"MT_LAMPPOST2", // with snow "MT_LAMPPOST2", // with snow
"MT_HANGSTAR", "MT_HANGSTAR",
"MT_MISTLETOE", "MT_MISTLETOE",
"MT_SSZTREE",
"MT_SSZTREE_BRANCH",
"MT_SSZTREE2",
"MT_SSZTREE2_BRANCH",
// Xmas GFZ bushes // Xmas GFZ bushes
"MT_XMASBLUEBERRYBUSH", "MT_XMASBLUEBERRYBUSH",
"MT_XMASBERRYBUSH", "MT_XMASBERRYBUSH",
...@@ -4102,6 +4120,9 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t ...@@ -4102,6 +4120,9 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t
// Misc scenery // Misc scenery
"MT_DBALL", "MT_DBALL",
"MT_EGGSTATUE2", "MT_EGGSTATUE2",
"MT_GINE",
"MT_PPAL",
"MT_PPEL",
// Powerup Indicators // Powerup Indicators
"MT_ELEMENTAL_ORB", // Elemental shield mobj "MT_ELEMENTAL_ORB", // Elemental shield mobj
...@@ -4329,6 +4350,8 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t ...@@ -4329,6 +4350,8 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t
"MT_NAMECHECK", "MT_NAMECHECK",
"MT_RAY", "MT_RAY",
"MT_OLDK",
}; };
const char *const MOBJFLAG_LIST[] = { const char *const MOBJFLAG_LIST[] = {
...@@ -4483,6 +4506,8 @@ const char *const PLAYERFLAG_LIST[] = { ...@@ -4483,6 +4506,8 @@ const char *const PLAYERFLAG_LIST[] = {
"CANCARRY", // Can carry? "CANCARRY", // Can carry?
"FINISHED", "FINISHED",
"SHIELDDOWN", // Shield has been pressed.
NULL // stop loop here. NULL // stop loop here.
}; };
...@@ -5234,7 +5259,9 @@ struct int_const_s const INT_CONST[] = { ...@@ -5234,7 +5259,9 @@ struct int_const_s const INT_CONST[] = {
{"SF_MARIODAMAGE",SF_MARIODAMAGE}, {"SF_MARIODAMAGE",SF_MARIODAMAGE},
{"SF_MACHINE",SF_MACHINE}, {"SF_MACHINE",SF_MACHINE},
{"SF_DASHMODE",SF_DASHMODE}, {"SF_DASHMODE",SF_DASHMODE},
{"SF_FASTWAIT",SF_FASTWAIT},
{"SF_FASTEDGE",SF_FASTEDGE}, {"SF_FASTEDGE",SF_FASTEDGE},
{"SF_JETFUME",SF_JETFUME},
{"SF_MULTIABILITY",SF_MULTIABILITY}, {"SF_MULTIABILITY",SF_MULTIABILITY},
{"SF_NONIGHTSROTATION",SF_NONIGHTSROTATION}, {"SF_NONIGHTSROTATION",SF_NONIGHTSROTATION},
{"SF_NONIGHTSSUPER",SF_NONIGHTSSUPER}, {"SF_NONIGHTSSUPER",SF_NONIGHTSSUPER},
...@@ -5582,8 +5609,7 @@ struct int_const_s const INT_CONST[] = { ...@@ -5582,8 +5609,7 @@ struct int_const_s const INT_CONST[] = {
{"ROTAXIS_Z",ROTAXIS_Z}, {"ROTAXIS_Z",ROTAXIS_Z},
// Buttons (ticcmd_t) // Buttons (ticcmd_t)
{"BT_WEAPONMASK",BT_WEAPONMASK}, //our first three bits. {"BT_WEAPONMASK",BT_WEAPONMASK}, //our first four bits.
{"BT_SHIELD",BT_SHIELD},
{"BT_WEAPONNEXT",BT_WEAPONNEXT}, {"BT_WEAPONNEXT",BT_WEAPONNEXT},
{"BT_WEAPONPREV",BT_WEAPONPREV}, {"BT_WEAPONPREV",BT_WEAPONPREV},
{"BT_ATTACK",BT_ATTACK}, // shoot rings {"BT_ATTACK",BT_ATTACK}, // shoot rings
...@@ -5742,7 +5768,6 @@ struct int_const_s const INT_CONST[] = { ...@@ -5742,7 +5768,6 @@ struct int_const_s const INT_CONST[] = {
{"JA_DIGITAL",JA_DIGITAL}, {"JA_DIGITAL",JA_DIGITAL},
{"JA_JUMP",JA_JUMP}, {"JA_JUMP",JA_JUMP},
{"JA_SPIN",JA_SPIN}, {"JA_SPIN",JA_SPIN},
{"JA_SHIELD",JA_SHIELD},
{"JA_FIRE",JA_FIRE}, {"JA_FIRE",JA_FIRE},
{"JA_FIRENORMAL",JA_FIRENORMAL}, {"JA_FIRENORMAL",JA_FIRENORMAL},
{"JOYAXISRANGE",JOYAXISRANGE}, {"JOYAXISRANGE",JOYAXISRANGE},
...@@ -5764,7 +5789,9 @@ struct int_const_s const INT_CONST[] = { ...@@ -5764,7 +5789,9 @@ struct int_const_s const INT_CONST[] = {
{"GC_WEPSLOT5",GC_WEPSLOT5}, {"GC_WEPSLOT5",GC_WEPSLOT5},
{"GC_WEPSLOT6",GC_WEPSLOT6}, {"GC_WEPSLOT6",GC_WEPSLOT6},
{"GC_WEPSLOT7",GC_WEPSLOT7}, {"GC_WEPSLOT7",GC_WEPSLOT7},
{"GC_SHIELD",GC_SHIELD}, {"GC_WEPSLOT8",GC_WEPSLOT8},
{"GC_WEPSLOT9",GC_WEPSLOT9},
{"GC_WEPSLOT10",GC_WEPSLOT10},
{"GC_FIRE",GC_FIRE}, {"GC_FIRE",GC_FIRE},
{"GC_FIRENORMAL",GC_FIRENORMAL}, {"GC_FIRENORMAL",GC_FIRENORMAL},
{"GC_TOSSFLAG",GC_TOSSFLAG}, {"GC_TOSSFLAG",GC_TOSSFLAG},
...@@ -5803,6 +5830,15 @@ struct int_const_s const INT_CONST[] = { ...@@ -5803,6 +5830,15 @@ struct int_const_s const INT_CONST[] = {
{"MB_BUTTON8",MB_BUTTON8}, {"MB_BUTTON8",MB_BUTTON8},
{"MB_SCROLLUP",MB_SCROLLUP}, {"MB_SCROLLUP",MB_SCROLLUP},
{"MB_SCROLLDOWN",MB_SCROLLDOWN}, {"MB_SCROLLDOWN",MB_SCROLLDOWN},
// P_PathTraverse constants
{"PT_ADDLINES",PT_ADDLINES},
{"PT_ADDTHINGS",PT_ADDTHINGS},
{"PT_EARLYOUT",PT_EARLYOUT},
// screen.h constants
{"BASEVIDWIDTH",BASEVIDWIDTH},
{"BASEVIDHEIGHT",BASEVIDHEIGHT},
{NULL,0} {NULL,0}
}; };
......
// SONIC ROBO BLAST 2 // SONIC ROBO BLAST 2
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Copyright (C) 1998-2000 by DooM Legacy Team. // Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2023 by Sonic Team Junior. // Copyright (C) 1999-2024 by Sonic Team Junior.
// //
// This program is free software distributed under the // This program is free software distributed under the
// terms of the GNU General Public License, version 2. // terms of the GNU General Public License, version 2.
......
...@@ -20,6 +20,7 @@ boolean deh_loaded = false; ...@@ -20,6 +20,7 @@ boolean deh_loaded = false;
boolean gamedataadded = false; boolean gamedataadded = false;
boolean titlechanged = false; boolean titlechanged = false;
boolean introchanged = false; boolean introchanged = false;
boolean bootmapchanged = false;
static int dbg_line; static int dbg_line;
static INT32 deh_num_warning = 0; static INT32 deh_num_warning = 0;
...@@ -192,11 +193,14 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile) ...@@ -192,11 +193,14 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile)
INT32 i; INT32 i;
if (!deh_loaded) if (!deh_loaded)
{
initfreeslots(); initfreeslots();
deh_loaded = true;
}
deh_num_warning = 0; deh_num_warning = 0;
gamedataadded = titlechanged = introchanged = false; gamedataadded = titlechanged = introchanged = bootmapchanged = false;
// it doesn't test the version of SRB2 and version of dehacked file // it doesn't test the version of SRB2 and version of dehacked file
dbg_line = -1; // start at -1 so the first line is 0. dbg_line = -1; // start at -1 so the first line is 0.
...@@ -587,7 +591,12 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile) ...@@ -587,7 +591,12 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile)
if (gamestate == GS_TITLESCREEN) if (gamestate == GS_TITLESCREEN)
{ {
if (introchanged) if (bootmapchanged && bootmap)
{
menuactive = false;
D_MapChange(bootmap, gametype, ultimatemode, true, 0, false, false);
}
else if (introchanged)
{ {
menuactive = false; menuactive = false;
I_UpdateMouseGrab(); I_UpdateMouseGrab();
...@@ -605,14 +614,10 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile) ...@@ -605,14 +614,10 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile)
if (deh_num_warning) if (deh_num_warning)
{ {
CONS_Printf(M_GetText("%d warning%s in the SOC lump\n"), deh_num_warning, deh_num_warning == 1 ? "" : "s"); CONS_Printf(M_GetText("%d warning%s in the SOC lump\n"), deh_num_warning, deh_num_warning == 1 ? "" : "s");
if (devparm) { if (devparm)
I_Error("%s%s",va(M_GetText("%d warning%s in the SOC lump\n"), deh_num_warning, deh_num_warning == 1 ? "" : "s"), M_GetText("See log.txt for details.\n")); I_Error("%s%s",va(M_GetText("%d warning%s in the SOC lump\n"), deh_num_warning, deh_num_warning == 1 ? "" : "s"), M_GetText("See log.txt for details.\n"));
//while (!I_GetKey())
//I_OsPolling();
}
} }
deh_loaded = true;
Z_Free(s); Z_Free(s);
} }
......
...@@ -39,6 +39,7 @@ extern boolean deh_loaded; ...@@ -39,6 +39,7 @@ extern boolean deh_loaded;
extern boolean gamedataadded; extern boolean gamedataadded;
extern boolean titlechanged; extern boolean titlechanged;
extern boolean introchanged; extern boolean introchanged;
extern boolean bootmapchanged;
#define MAX_ACTION_RECURSION 30 #define MAX_ACTION_RECURSION 30
extern const char *luaactions[MAX_ACTION_RECURSION]; extern const char *luaactions[MAX_ACTION_RECURSION];
......
...@@ -75,7 +75,32 @@ enum ...@@ -75,7 +75,32 @@ enum
typedef struct typedef struct
{ {
INT16 x, y; INT16 x, y;
}ATTRPACK mapvertex_t; }ATTRPACK mapvertex_t;
typedef enum {
UDMF_TYPE_STRING,
UDMF_TYPE_FIXED,
UDMF_TYPE_NUMERIC,
UDMF_TYPE_BOOLEAN
} udmf_field_type_t;
typedef union { // v added to avoid random compilers cry about nonsense
char* vstring;
fixed_t vfloat;
INT32 vint;
boolean vbool;
} udmf_field_value_t;
// UDMF's Custom Arguments
typedef struct customargs_s
{
char* name;
udmf_field_type_t type;
udmf_field_value_t value;
struct customargs_s* next;
}ATTRPACK customargs_t;
// A SideDef, defining the visual appearance of a wall, // A SideDef, defining the visual appearance of a wall,
// by setting textures and offsets. // by setting textures and offsets.
...@@ -218,6 +243,7 @@ typedef struct ...@@ -218,6 +243,7 @@ typedef struct
fixed_t spritexscale, spriteyscale; fixed_t spritexscale, spriteyscale;
INT32 args[NUMMAPTHINGARGS]; INT32 args[NUMMAPTHINGARGS];
char *stringargs[NUMMAPTHINGSTRINGARGS]; char *stringargs[NUMMAPTHINGSTRINGARGS];
struct customargs_s* customargs;
struct mobj_s *mobj; struct mobj_s *mobj;
} mapthing_t; } mapthing_t;
......