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
  • 21-installer-nodd
  • 2210-pre1
  • 2210-pre2
  • 2210-rc1
  • 2210-rc2
  • 2210-rc3
  • 2211-pre1
  • 2211-pre2
  • 2211-rc1
  • 2212-pre1
  • 2212-pre2
  • 2212-pre3
  • 2212-rc1
  • 2213
  • 2214-pre1
  • 2214-pre2
  • 2214-pre3
  • 2214-pre4
  • 2_2_12
  • 64-gl-log
  • COM_ImmedExecute-lua
  • DJGPP
  • accel-momentum
  • acs
  • action-args
  • alpha-fixes
  • any-resolution
  • appveyor
  • better-distance-math
  • blend-locking
  • blentran
  • blua-unary-not-fix
  • boost-tickrate
  • bustablesoundz
  • cleanup-opengl
  • cleanupmusic
  • clipmidtex
  • cmake-valgrind
  • crawlacommander-sprites
  • custom-map-names
  • custom-teams
  • cutscene-cleanup
  • dd-music-bypass
  • dd-music-fix
  • delfile2
  • deprecate-lua-dedicated-server
  • dpl-2
  • dropshadows-spawning
  • dynabsp
  • emblem-drawing
  • exchndl-xp-fix
  • extra-textures
  • few-kart-lua-changes
  • ffloorclip
  • fix-167
  • fix-cvar-conflicts
  • fix-opengl-parameter-crash
  • fix-opengl-shear-roll
  • flipfuncpointers
  • fof-lightlist-fixes
  • font-FUCK
  • frictionrefactor
  • fuck-macros-1
  • gamepad-luakeydown
  • gamepad-morefixes
  • gamepad_experiments
  • gametype-refactor
  • gametype-refactor-1
  • gametype-refactor-player-spawns
  • ghost-networking
  • gif-splitting
  • grr-lj
  • hitboxviewer
  • hwr-texture-cache-refactor
  • hwrender2
  • improve-439
  • increase-maxconditionsets
  • increase-packet-tics
  • input-display
  • input-display-translucency
  • io
  • joystick-juggling-maz
  • just-in-case
  • keycodes-only
  • ksf-wadfiles
  • ld413-mp-fix
  • levelstruct
  • libpng-version-support
  • linedef-actions
  • lj-test
  • lol-states
  • loopedsounds
  • lower-unpegged-fix
  • lua-change-gametype
  • lua-command-netids
  • lua-gfx-2
  • lua-gfx-sprites
  • lua-local
  • makefile-auto-mingw-gcc
  • makefile-tinkering
  • SRB2_release_2.1
  • SRB2_release_2.1.1
  • SRB2_release_2.1.10
  • SRB2_release_2.1.11
  • SRB2_release_2.1.12
  • SRB2_release_2.1.14
  • SRB2_release_2.1.15
  • SRB2_release_2.1.16
  • SRB2_release_2.1.16a
  • SRB2_release_2.1.17
  • SRB2_release_2.1.18
  • SRB2_release_2.1.19
  • SRB2_release_2.1.2
  • SRB2_release_2.1.20
  • SRB2_release_2.1.21
  • SRB2_release_2.1.22
  • SRB2_release_2.1.23
  • SRB2_release_2.1.24
  • SRB2_release_2.1.25
  • SRB2_release_2.1.3
  • SRB2_release_2.1.4
  • SRB2_release_2.1.5
  • SRB2_release_2.1.6
  • SRB2_release_2.1.7
  • SRB2_release_2.1.8
  • SRB2_release_2.1.9
  • SRB2_release_2.2.0
  • SRB2_release_2.2.1
  • SRB2_release_2.2.10
  • SRB2_release_2.2.11
  • SRB2_release_2.2.12
  • SRB2_release_2.2.13
  • SRB2_release_2.2.15
  • SRB2_release_2.2.2
  • SRB2_release_2.2.3
  • SRB2_release_2.2.4
  • SRB2_release_2.2.5
  • SRB2_release_2.2.6
  • SRB2_release_2.2.7
  • SRB2_release_2.2.8
  • SRB2_release_2.2.9
  • td-release-v1.0.0
142 results

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
  • voltybystorm/SRB2
  • ZenithNeko/srb-2-xp
119 results
Select Git revision
Show changes
...@@ -66,6 +66,9 @@ void COM_ImmedExecute(const char *ptext); ...@@ -66,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);
......
...@@ -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
...@@ -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"
...@@ -45,15 +46,10 @@ ...@@ -45,15 +46,10 @@
#define MAXHUDLINES 20 #define MAXHUDLINES 20
#ifdef HAVE_THREADS
I_mutex con_mutex; I_mutex con_mutex;
# define Lock_state() I_lock_mutex(&con_mutex) # define Lock_state() I_lock_mutex(&con_mutex)
# define Unlock_state() I_unlock_mutex(con_mutex) # define Unlock_state() I_unlock_mutex(con_mutex)
#else/*HAVE_THREADS*/
# define Lock_state()
# define Unlock_state()
#endif/*HAVE_THREADS*/
static boolean con_started = false; // console has been initialised static boolean con_started = false; // console has been initialised
boolean con_startup = false; // true at game startup boolean con_startup = false; // true at game startup
...@@ -918,6 +914,22 @@ static void CON_InputDelChar(void) ...@@ -918,6 +914,22 @@ 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)
...@@ -954,7 +966,10 @@ boolean CON_Responder(event_t *ev) ...@@ -954,7 +966,10 @@ boolean CON_Responder(event_t *ev)
if ((key == gamecontrol[GC_CONSOLE][0] || key == gamecontrol[GC_CONSOLE][1]) && !shiftdown) if ((key == gamecontrol[GC_CONSOLE][0] || key == gamecontrol[GC_CONSOLE][1]) && !shiftdown)
{ {
I_SetTextInputMode(con_destlines == 0); // inverse, since this is changed next tic. if (con_destlines == 0 && I_GetTextInputMode())
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;
return true; return true;
} }
...@@ -974,7 +989,7 @@ boolean CON_Responder(event_t *ev) ...@@ -974,7 +989,7 @@ 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(false); I_SetTextInputMode(textinputmodeenabledbylua);
consoletoggle = true; consoletoggle = true;
return true; return true;
} }
...@@ -1342,11 +1357,11 @@ static void CON_Print(char *msg) ...@@ -1342,11 +1357,11 @@ static void CON_Print(char *msg)
return; return;
if (*msg == '\3') // chat text, makes ding sound if (*msg == '\3') // chat text, makes ding sound
S_StartSound(NULL, sfx_radio); S_StartSoundFromEverywhere(sfx_radio);
else if (*msg == '\4') // chat action, dings and is in yellow else if (*msg == '\4') // chat action, dings and is in yellow
{ {
*msg = '\x82'; // yellow *msg = '\x82'; // yellow
S_StartSound(NULL, sfx_radio); S_StartSoundFromEverywhere(sfx_radio);
} }
Lock_state(); Lock_state();
...@@ -1737,6 +1752,8 @@ static void CON_DrawBackpic(void) ...@@ -1737,6 +1752,8 @@ static void CON_DrawBackpic(void)
// Cache the patch. // Cache the patch.
con_backpic = W_CachePatchNum(piclump, PU_PATCH); con_backpic = W_CachePatchNum(piclump, PU_PATCH);
if (con_backpic == NULL)
return;
// Center the backpic, and draw a vertically cropped patch. // Center the backpic, and draw a vertically cropped patch.
w = con_backpic->width * vid.dup; w = con_backpic->width * vid.dup;
......
...@@ -19,11 +19,10 @@ void CON_Init(void); ...@@ -19,11 +19,10 @@ 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
extern I_mutex con_mutex; extern I_mutex con_mutex;
#endif
// set true when screen size has changed, to adapt console // set true when screen size has changed, to adapt console
extern boolean con_recalc; extern boolean con_recalc;
......
...@@ -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-2024 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.
...@@ -15,6 +15,10 @@ ...@@ -15,6 +15,10 @@
/// plus functions to parse command line parameters, configure game /// plus functions to parse command line parameters, configure game
/// parameters, and call the startup functions. /// parameters, and call the startup functions.
#ifdef __EMSCRIPTEN__
#include <emscripten.h>
#endif
#if defined (__unix__) || defined (__APPLE__) || defined (UNIXCOMMON) #if defined (__unix__) || defined (__APPLE__) || defined (UNIXCOMMON)
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h> #include <sys/types.h>
...@@ -93,6 +97,7 @@ ...@@ -93,6 +97,7 @@
#endif #endif
#include "lua_script.h" #include "lua_script.h"
#include "lua_hud.h"
// Version numbers for netplay :upside_down_face: // Version numbers for netplay :upside_down_face:
int VERSION; int VERSION;
...@@ -227,6 +232,9 @@ void D_ProcessEvents(void) ...@@ -227,6 +232,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
...@@ -244,15 +252,11 @@ void D_ProcessEvents(void) ...@@ -244,15 +252,11 @@ void D_ProcessEvents(void)
} }
// Menu input // Menu input
#ifdef HAVE_THREADS
I_lock_mutex(&m_menu_mutex); I_lock_mutex(&m_menu_mutex);
#endif
{ {
eaten = M_Responder(ev); eaten = M_Responder(ev);
} }
#ifdef HAVE_THREADS
I_unlock_mutex(m_menu_mutex); I_unlock_mutex(m_menu_mutex);
#endif
if (eaten) if (eaten)
continue; // menu ate the event continue; // menu ate the event
...@@ -264,15 +268,11 @@ void D_ProcessEvents(void) ...@@ -264,15 +268,11 @@ void D_ProcessEvents(void)
} }
// console input // console input
#ifdef HAVE_THREADS
I_lock_mutex(&con_mutex); I_lock_mutex(&con_mutex);
#endif
{ {
eaten = CON_Responder(ev); eaten = CON_Responder(ev);
} }
#ifdef HAVE_THREADS
I_unlock_mutex(con_mutex); I_unlock_mutex(con_mutex);
#endif
if (eaten) if (eaten)
continue; // ate the event continue; // ate the event
...@@ -575,7 +575,7 @@ static void D_Display(void) ...@@ -575,7 +575,7 @@ static void D_Display(void)
V_SetPalette(0); V_SetPalette(0);
// draw pause pic // draw pause pic
if (paused && cv_showhud.value && (!menuactive || netgame)) if (paused && cv_showhud.value && LUA_HudEnabled(hud_pause) && (!menuactive || netgame))
{ {
#if 0 #if 0
INT32 py; INT32 py;
...@@ -596,13 +596,9 @@ static void D_Display(void) ...@@ -596,13 +596,9 @@ static void D_Display(void)
// vid size change is now finished if it was on... // vid size change is now finished if it was on...
vid.recalc = 0; vid.recalc = 0;
#ifdef HAVE_THREADS
I_lock_mutex(&m_menu_mutex); I_lock_mutex(&m_menu_mutex);
#endif
M_Drawer(); // menu is drawn even on top of everything M_Drawer(); // menu is drawn even on top of everything
#ifdef HAVE_THREADS
I_unlock_mutex(m_menu_mutex); I_unlock_mutex(m_menu_mutex);
#endif
// focus lost moved to M_Drawer // focus lost moved to M_Drawer
CON_Drawer(); CON_Drawer();
...@@ -705,16 +701,11 @@ static void D_Display(void) ...@@ -705,16 +701,11 @@ static void D_Display(void)
tic_t rendergametic; tic_t rendergametic;
static void D_RunFrame(void);
static tic_t oldentertics = 0;
void D_SRB2Loop(void) void D_SRB2Loop(void)
{ {
tic_t entertic = 0, oldentertics = 0, realtics = 0, rendertimeout = INFTICS;
double deltatics = 0.0;
double deltasecs = 0.0;
static lumpnum_t gstartuplumpnum;
boolean interp = false;
boolean doDisplay = false;
if (dedicated) if (dedicated)
server = true; server = true;
...@@ -750,21 +741,68 @@ void D_SRB2Loop(void) ...@@ -750,21 +741,68 @@ void D_SRB2Loop(void)
// hack to start on a nice clear console screen. // hack to start on a nice clear console screen.
COM_ImmedExecute("cls;version"); COM_ImmedExecute("cls;version");
#ifdef __EMSCRIPTEN__
EM_ASM(
try {
StartedMainLoopCallback();
} catch (err) {
console.log('Faild to find StartedMainLoopCallback()');
}
);
#endif
I_FinishUpdate(); // page flip or blit buffer I_FinishUpdate(); // page flip or blit buffer
/* /*
LMFAO this was showing garbage under OpenGL LMFAO this was showing garbage under OpenGL
because I_FinishUpdate was called afterward because I_FinishUpdate was called afterward
*/ */
/* 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_CheckNumForPatchName("STARTUP"); lumpnum_t gstartuplumpnum = W_CheckNumForPatchName("STARTUP");
if (gstartuplumpnum == LUMPERROR) if (gstartuplumpnum == LUMPERROR)
gstartuplumpnum = W_GetNumForPatchName("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));
} }
#ifdef __EMSCRIPTEN__
emscripten_set_main_loop(D_RunFrame, 0, 1);
#else
for (;;) for (;;)
{
D_RunFrame();
}
#endif
}
static boolean D_LockFrame = false;
#ifdef __EMSCRIPTEN__
int EMSCRIPTEN_KEEPALIVE pause_loop(void)
{
D_LockFrame = true;
emscripten_pause_main_loop();
return 0;
}
int EMSCRIPTEN_KEEPALIVE resume_loop(void)
{
D_LockFrame = false;
emscripten_resume_main_loop();
return 0;
}
#endif
static void D_RunFrame(void)
{
static tic_t entertic = 0, realtics = 0, rendertimeout = INFTICS;
static double deltatics = 0.0;
static double deltasecs = 0.0;
static boolean interp = false;
static boolean doDisplay = false;
if (!D_LockFrame)
{ {
// capbudget is the minimum precise_t duration of a single loop iteration // capbudget is the minimum precise_t duration of a single loop iteration
precise_t capbudget; precise_t capbudget;
...@@ -920,6 +958,7 @@ void D_SRB2Loop(void) ...@@ -920,6 +958,7 @@ void D_SRB2Loop(void)
deltasecs = (double)((INT64)(finishprecise - enterprecise)) / I_GetPrecisePrecision(); deltasecs = (double)((INT64)(finishprecise - enterprecise)) / I_GetPrecisePrecision();
deltatics = deltasecs * NEWTICRATE; deltatics = deltasecs * NEWTICRATE;
} }
return;
} }
// //
...@@ -1179,8 +1218,8 @@ static void IdentifyVersion(void) ...@@ -1179,8 +1218,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 +1238,7 @@ static void IdentifyVersion(void) ...@@ -1199,7 +1238,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 +1289,7 @@ void D_SRB2Main(void) ...@@ -1250,7 +1289,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-2024 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"
...@@ -1367,9 +1406,6 @@ void D_SRB2Main(void) ...@@ -1367,9 +1406,6 @@ void D_SRB2Main(void)
P_SetRandSeed(M_RandomizedSeed()); P_SetRandSeed(M_RandomizedSeed());
if (M_CheckParm("-password") && M_IsNextParm())
D_SetPassword(M_GetNextParm());
// player setup menu colors must be initialized before // player setup menu colors must be initialized before
// any wad file is added, as they may contain colors themselves // any wad file is added, as they may contain colors themselves
M_InitPlayerSetupColors(); M_InitPlayerSetupColors();
...@@ -1377,6 +1413,9 @@ void D_SRB2Main(void) ...@@ -1377,6 +1413,9 @@ void D_SRB2Main(void)
CONS_Printf("Z_Init(): Init zone memory allocation daemon. \n"); CONS_Printf("Z_Init(): Init zone memory allocation daemon. \n");
Z_Init(); Z_Init();
if (M_CheckParm("-password") && M_IsNextParm())
D_SetPassword(M_GetNextParm());
clientGamedata = M_NewGameDataStruct(); clientGamedata = M_NewGameDataStruct();
serverGamedata = M_NewGameDataStruct(); serverGamedata = M_NewGameDataStruct();
...@@ -1431,7 +1470,7 @@ void D_SRB2Main(void) ...@@ -1431,7 +1470,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 +1485,11 @@ void D_SRB2Main(void) ...@@ -1446,11 +1485,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
...@@ -1600,7 +1639,7 @@ void D_SRB2Main(void) ...@@ -1600,7 +1639,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();
......
...@@ -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-2024 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;
...@@ -159,10 +161,6 @@ typedef enum ...@@ -159,10 +161,6 @@ typedef enum
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;
......
...@@ -28,18 +28,11 @@ ...@@ -28,18 +28,11 @@
// To compile this as "ANSI C with classes" we will need to handle the various // To compile this as "ANSI C with classes" we will need to handle the various
// action functions cleanly. // action functions cleanly.
// //
typedef void (*actionf_v)();
typedef void (*actionf_p1)(void *); typedef void (*actionf_p1)(void *);
typedef union
{
actionf_v acv;
actionf_p1 acp1;
} actionf_t;
// Historically, "think_t" is yet another function pointer to a routine // Historically, "think_t" is yet another function pointer to a routine
// to handle an actor. // to handle an actor.
typedef actionf_t think_t; typedef actionf_p1 think_t;
// Doubly linked list of actors. // Doubly linked list of actors.
typedef struct thinker_s typedef struct thinker_s
...@@ -51,6 +44,8 @@ typedef struct thinker_s ...@@ -51,6 +44,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,
BT_WEAPONPREV = 1<<5,
BT_WEAPONNEXT = 1<<4, // select next weapon
BT_WEAPONPREV = 1<<5, // select previous weapon
BT_ATTACK = 1<<6, // shoot rings BT_ATTACK = 1<<6, // shoot rings
BT_SPIN = 1<<7, // spin action BT_SPIN = 1<<7,
BT_CAMLEFT = 1<<8, // turn camera left BT_CAMLEFT = 1<<8, // turn camera left
BT_CAMRIGHT = 1<<9, // turn camera right BT_CAMRIGHT = 1<<9, // turn camera right
BT_TOSSFLAG = 1<<10, // toss flag or emeralds BT_TOSSFLAG = 1<<10,
BT_JUMP = 1<<11, // jump action BT_JUMP = 1<<11,
BT_FIRENORMAL = 1<<12, // fire a normal ring no matter what 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-2024 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,8 +377,13 @@ void I_Sleep(UINT32 ms) ...@@ -374,8 +377,13 @@ 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();
precise_t dest = I_GetPreciseTime() + duration;
precise_t slack = (precision / 5000); // 0.2 ms slack
if (duration > slack)
{
duration -= slack;
struct timespec ts = { struct timespec ts = {
.tv_sec = duration / precision, .tv_sec = duration / precision,
.tv_nsec = duration * 1000000000 / precision % 1000000000, .tv_nsec = duration * 1000000000 / precision % 1000000000,
...@@ -383,6 +391,10 @@ void I_SleepDuration(precise_t duration) ...@@ -383,6 +391,10 @@ void I_SleepDuration(precise_t duration)
int status; int status;
do status = clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, &ts); do status = clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, &ts);
while (status == EINTR); 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();
}
}
}
// clear the display of the line currently edited
// bring cursor back to beginning of line
static inline void tty_Hide(void)
{
//I_Assert(consolevent);
if (ttycon_hide)
{
ttycon_hide++;
return;
} }
tty_Clear(); write(STDOUT_FILENO, " \b", 2);
ttycon_hide++;
} }
// show the current line static void tty_Clear(void)
// 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))
...@@ -1046,6 +1030,9 @@ void I_OutputMsg(const char *fmt, ...) ...@@ -1046,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);
...@@ -1135,18 +1122,20 @@ void I_OutputMsg(const char *fmt, ...) ...@@ -1135,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
...@@ -1192,10 +1181,8 @@ static void I_RegisterSignals (void) ...@@ -1192,10 +1181,8 @@ static void I_RegisterSignals (void)
INT32 I_StartupSystem(void) INT32 I_StartupSystem(void)
{ {
#ifdef HAVE_THREADS
I_start_threads(); I_start_threads();
I_AddExitFunc(I_stop_threads); I_AddExitFunc(I_stop_threads);
#endif
I_StartupConsole(); I_StartupConsole();
I_RegisterSignals(); I_RegisterSignals();
#ifndef NOMUMBLE #ifndef NOMUMBLE
...@@ -1226,18 +1213,13 @@ void I_ShutdownSystem(void) ...@@ -1226,18 +1213,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;
...@@ -1453,8 +1435,10 @@ const char *I_LocateWad(void) ...@@ -1453,8 +1435,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
...@@ -1587,4 +1571,3 @@ boolean I_GetTextInputMode(void) ...@@ -1587,4 +1571,3 @@ boolean I_GetTextInputMode(void)
} }
#include "../sdl/dosstr.c" #include "../sdl/dosstr.c"
...@@ -15,7 +15,6 @@ ...@@ -15,7 +15,6 @@
#include "../i_threads.h" #include "../i_threads.h"
#include "../doomdef.h" #include "../doomdef.h"
#include "../doomtype.h"
typedef struct thread_s thread_t; typedef struct thread_s thread_t;
...@@ -42,10 +41,11 @@ static void *HandleThread(void *data) ...@@ -42,10 +41,11 @@ static void *HandleThread(void *data)
return NULL; return NULL;
} }
void I_spawn_thread(const char *name, I_thread_fn entry, void *userdata) int I_spawn_thread(const char *name, I_thread_fn entry, void *userdata)
{ {
thread_t *thread; thread_t *thread;
(void)name; (void)name;
pthread_mutex_lock(&thread_lock); pthread_mutex_lock(&thread_lock);
thread = thread_list; thread = thread_list;
while (thread != NULL) while (thread != NULL)
...@@ -69,6 +69,13 @@ void I_spawn_thread(const char *name, I_thread_fn entry, void *userdata) ...@@ -69,6 +69,13 @@ void I_spawn_thread(const char *name, I_thread_fn entry, void *userdata)
thread->userdata = userdata; thread->userdata = userdata;
pthread_create(&thread->thread, NULL, HandleThread, thread); pthread_create(&thread->thread, NULL, HandleThread, thread);
pthread_mutex_unlock(&thread_lock); pthread_mutex_unlock(&thread_lock);
return true;
}
int I_can_thread(void)
{
return true;
} }
int I_thread_is_stopped(void) int I_thread_is_stopped(void)
......
#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){}
...@@ -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));
...@@ -183,7 +188,7 @@ static inline int lib_freeslot(lua_State *L) ...@@ -183,7 +188,7 @@ static inline int lib_freeslot(lua_State *L)
// Arguments: mobj_t actor, int var1, int var2 // Arguments: mobj_t actor, int var1, int var2
static int action_call(lua_State *L) static int action_call(lua_State *L)
{ {
actionf_t *action = *((actionf_t **)luaL_checkudata(L, 1, META_ACTION)); actionf_p1 *action = *((actionf_p1 **)luaL_checkudata(L, 1, META_ACTION));
mobj_t *actor = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ)); mobj_t *actor = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ));
var1 = (INT32)luaL_optinteger(L, 3, 0); var1 = (INT32)luaL_optinteger(L, 3, 0);
...@@ -194,7 +199,7 @@ static int action_call(lua_State *L) ...@@ -194,7 +199,7 @@ static int action_call(lua_State *L)
return LUA_ErrInvalid(L, "mobj_t"); return LUA_ErrInvalid(L, "mobj_t");
} }
action->acp1(actor); (*action)(actor);
return 0; return 0;
} }
...@@ -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)) {
...@@ -635,7 +632,7 @@ FUNCINLINE static ATTRINLINE int getEnum(lua_State *L, boolean mathlib, const ch ...@@ -635,7 +632,7 @@ FUNCINLINE static ATTRINLINE int getEnum(lua_State *L, boolean mathlib, const ch
{ {
if (fasticmp(word, actionpointers[i].name)) if (fasticmp(word, actionpointers[i].name))
{ {
// We push the actionf_t* itself as userdata! // We push the actionf_p1* itself as userdata!
LUA_PushUserdata(L, &actionpointers[i].action, META_ACTION); LUA_PushUserdata(L, &actionpointers[i].action, META_ACTION);
return 1; return 1;
} }
...@@ -773,7 +770,7 @@ static int lib_getActionName(lua_State *L) ...@@ -773,7 +770,7 @@ static int lib_getActionName(lua_State *L)
{ {
if (lua_isuserdata(L, 1)) // arg 1 is built-in action, expect action userdata if (lua_isuserdata(L, 1)) // arg 1 is built-in action, expect action userdata
{ {
actionf_t *action = *((actionf_t **)luaL_checkudata(L, 1, META_ACTION)); actionf_p1 *action = *((actionf_p1 **)luaL_checkudata(L, 1, META_ACTION));
const char *name = NULL; const char *name = NULL;
if (!action) if (!action)
return luaL_error(L, "not a valid action?"); return luaL_error(L, "not a valid action?");
...@@ -843,11 +840,11 @@ int LUA_SOCLib(lua_State *L) ...@@ -843,11 +840,11 @@ int LUA_SOCLib(lua_State *L)
const char *LUA_GetActionName(void *action) const char *LUA_GetActionName(void *action)
{ {
actionf_t *act = (actionf_t *)action; actionf_p1 *act = (actionf_p1 *)action;
size_t z; size_t z;
for (z = 0; actionpointers[z].name; z++) for (z = 0; actionpointers[z].name; z++)
{ {
if (actionpointers[z].action.acv == act->acv) if (actionpointers[z].action == *act)
return actionpointers[z].name; return actionpointers[z].name;
} }
return NULL; return NULL;
...@@ -862,8 +859,6 @@ void LUA_SetActionByName(void *state, const char *actiontocompare) ...@@ -862,8 +859,6 @@ void LUA_SetActionByName(void *state, const char *actiontocompare)
if (fasticmp(actiontocompare, actionpointers[z].name)) if (fasticmp(actiontocompare, actionpointers[z].name))
{ {
st->action = actionpointers[z].action; st->action = actionpointers[z].action;
st->action.acv = actionpointers[z].action.acv; // assign
st->action.acp1 = actionpointers[z].action.acp1;
return; return;
} }
} }
......
// 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-2024 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)
...@@ -1196,6 +1201,7 @@ void readgametype(MYFILE *f, char *gtname) ...@@ -1196,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),
...@@ -1402,7 +1408,7 @@ void readlevelheader(MYFILE *f, INT32 num) ...@@ -1402,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
...@@ -1445,10 +1451,10 @@ void readlevelheader(MYFILE *f, INT32 num) ...@@ -1445,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;
} }
...@@ -1675,7 +1681,8 @@ void readlevelheader(MYFILE *f, INT32 num) ...@@ -1675,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"))
...@@ -1683,7 +1690,10 @@ void readlevelheader(MYFILE *f, INT32 num) ...@@ -1683,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"))
...@@ -1985,14 +1995,17 @@ static void readcutscenescene(MYFILE *f, INT32 num, INT32 scenenum) ...@@ -1985,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"))
{ {
...@@ -2011,12 +2024,13 @@ static void readcutscenescene(MYFILE *f, INT32 num, INT32 scenenum) ...@@ -2011,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"))
{ {
...@@ -2051,7 +2065,7 @@ static void readcutscenescene(MYFILE *f, INT32 num, INT32 scenenum) ...@@ -2051,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
...@@ -2109,11 +2123,10 @@ void readcutscene(MYFILE *f, INT32 num) ...@@ -2109,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
...@@ -2234,7 +2247,8 @@ static void readtextpromptpage(MYFILE *f, INT32 num, INT32 pagenum) ...@@ -2234,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];
...@@ -2247,14 +2261,17 @@ static void readtextpromptpage(MYFILE *f, INT32 num, INT32 pagenum) ...@@ -2247,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"))
{ {
...@@ -2273,12 +2290,16 @@ static void readtextpromptpage(MYFILE *f, INT32 num, INT32 pagenum) ...@@ -2273,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"))
{ {
...@@ -2293,30 +2314,35 @@ static void readtextpromptpage(MYFILE *f, INT32 num, INT32 pagenum) ...@@ -2293,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"))
...@@ -2383,8 +2409,9 @@ static void readtextpromptpage(MYFILE *f, INT32 num, INT32 pagenum) ...@@ -2383,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;
...@@ -2399,17 +2426,25 @@ static void readtextpromptpage(MYFILE *f, INT32 num, INT32 pagenum) ...@@ -2399,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
...@@ -2469,11 +2504,11 @@ void readtextprompt(MYFILE *f, INT32 num) ...@@ -2469,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
...@@ -2522,7 +2557,8 @@ void readmenu(MYFILE *f, INT32 num) ...@@ -2522,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"))
...@@ -2565,7 +2601,8 @@ void readmenu(MYFILE *f, INT32 num) ...@@ -2565,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"))
...@@ -2601,8 +2638,8 @@ void readmenu(MYFILE *f, INT32 num) ...@@ -2601,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"))
...@@ -2807,7 +2844,7 @@ void readframe(MYFILE *f, INT32 num) ...@@ -2807,7 +2844,7 @@ void readframe(MYFILE *f, INT32 num)
for (z = 0; actionpointers[z].name; z++) for (z = 0; actionpointers[z].name; z++)
{ {
if (actionpointers[z].action.acv == states[num].action.acv) if (actionpointers[z].action == states[num].action)
break; break;
} }
...@@ -2819,8 +2856,6 @@ void readframe(MYFILE *f, INT32 num) ...@@ -2819,8 +2856,6 @@ void readframe(MYFILE *f, INT32 num)
if (fastcmp(actiontocompare, actionpointers[z].name)) if (fastcmp(actiontocompare, actionpointers[z].name))
{ {
states[num].action = actionpointers[z].action; states[num].action = actionpointers[z].action;
states[num].action.acv = actionpointers[z].action.acv; // assign
states[num].action.acp1 = actionpointers[z].action.acp1;
found = true; found = true;
break; break;
} }
...@@ -3453,6 +3488,18 @@ static void readcondition(UINT8 set, UINT32 id, char *word2) ...@@ -3453,6 +3488,18 @@ static void readcondition(UINT8 set, UINT32 id, char *word2)
return; return;
} }
} }
else if (fastcmp(params[0], "LUA"))
{
PARAMCHECK(1);
ty = UC_LUA;
re = atoi(params[1]);
if (re <= 0 || re > MAXLUACONDITIONS)
{
deh_warning("Lua condition %d out of range (1 - %d)", re, MAXLUACONDITIONS);
return;
}
}
else if (fastcmp(params[0], "CONDITIONSET")) else if (fastcmp(params[0], "CONDITIONSET"))
{ {
PARAMCHECK(1); PARAMCHECK(1);
...@@ -3584,22 +3631,20 @@ void readmaincfg(MYFILE *f) ...@@ -3584,22 +3631,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);
} }
} }
...@@ -3800,7 +3845,7 @@ void readmaincfg(MYFILE *f) ...@@ -3800,7 +3845,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"))
...@@ -3910,7 +3955,7 @@ void readmaincfg(MYFILE *f) ...@@ -3910,7 +3955,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"))
...@@ -3925,6 +3970,7 @@ void readmaincfg(MYFILE *f) ...@@ -3925,6 +3970,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"))
......
This diff is collapsed.
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
#define __DEH_TABLES_H__ #define __DEH_TABLES_H__
#include "doomdef.h" // Constants #include "doomdef.h" // Constants
#include "d_think.h" // actionf_t #include "d_think.h" // actionf_p1
#include "info.h" // Mobj, state, sprite, etc constants #include "info.h" // Mobj, state, sprite, etc constants
#include "lua_script.h" #include "lua_script.h"
...@@ -44,7 +44,7 @@ struct flickytypes_s { ...@@ -44,7 +44,7 @@ struct flickytypes_s {
*/ */
typedef struct typedef struct
{ {
actionf_t action; ///< Function pointer corresponding to the actual action. actionf_p1 action; ///< Function pointer corresponding to the actual action.
const char *name; ///< Name of the action in ALL CAPS. const char *name; ///< Name of the action in ALL CAPS.
} actionpointer_t; } actionpointer_t;
......
...@@ -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];
......
...@@ -77,6 +77,31 @@ typedef struct ...@@ -77,6 +77,31 @@ 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.
typedef struct typedef struct
...@@ -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;
......
...@@ -168,7 +168,7 @@ extern char logfilename[1024]; ...@@ -168,7 +168,7 @@ extern char logfilename[1024];
// Does this version require an added patch file? // Does this version require an added patch file?
// Comment or uncomment this as necessary. // Comment or uncomment this as necessary.
#define USE_PATCH_DTA //#define USE_PATCH_DTA
// Enforce a limit of loaded WAD files. // Enforce a limit of loaded WAD files.
//#define ENFORCE_WAD_LIMIT //#define ENFORCE_WAD_LIMIT
...@@ -703,7 +703,9 @@ extern int ...@@ -703,7 +703,9 @@ extern int
/// This stops the game from storing backups of the states, sprites, and mobjinfo tables. /// This stops the game from storing backups of the states, sprites, and mobjinfo tables.
/// Though this info is compressed under normal circumstances, it's still a lot of extra /// Though this info is compressed under normal circumstances, it's still a lot of extra
/// memory that never gets touched. /// memory that never gets touched.
#if !(defined (__EMSCRIPTEN__) && (__SIZEOF_SIZE_T__ == 4))
#define ALLOW_RESETDATA #define ALLOW_RESETDATA
#endif
/// Experimental tweaks to analog mode. (Needs a lot of work before it's ready for primetime.) /// Experimental tweaks to analog mode. (Needs a lot of work before it's ready for primetime.)
//#define REDSANALOG //#define REDSANALOG
...@@ -731,7 +733,7 @@ extern int ...@@ -731,7 +733,7 @@ extern int
/// Maintain compatibility with older 2.2 demos /// Maintain compatibility with older 2.2 demos
#define OLD22DEMOCOMPAT #define OLD22DEMOCOMPAT
#ifdef HAVE_CURL #if defined (HAVE_CURL) && !(defined(__EMSCRIPTEN__) && !defined(__EMSCRIPTEN_PTHREADS__))
#define MASTERSERVER #define MASTERSERVER
#else #else
#undef UPDATE_ALERT #undef UPDATE_ALERT
......
...@@ -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-2024 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.
...@@ -209,19 +209,19 @@ typedef struct ...@@ -209,19 +209,19 @@ typedef struct
UINT8 picmode; // sequence mode after displaying last pic, 0 = persist, 1 = loop, 2 = destroy UINT8 picmode; // sequence mode after displaying last pic, 0 = persist, 1 = loop, 2 = destroy
UINT8 pictoloop; // if picmode == loop, which pic to loop to? UINT8 pictoloop; // if picmode == loop, which pic to loop to?
UINT8 pictostart; // initial pic number to show UINT8 pictostart; // initial pic number to show
char picname[MAX_PROMPT_PICS][8]; char picname[MAX_PROMPT_PICS][8+1];
UINT8 pichires[MAX_PROMPT_PICS]; UINT8 pichires[MAX_PROMPT_PICS];
UINT16 xcoord[MAX_PROMPT_PICS]; // gfx UINT16 xcoord[MAX_PROMPT_PICS]; // gfx
UINT16 ycoord[MAX_PROMPT_PICS]; // gfx UINT16 ycoord[MAX_PROMPT_PICS]; // gfx
UINT16 picduration[MAX_PROMPT_PICS]; UINT16 picduration[MAX_PROMPT_PICS];
char musswitch[7]; char musswitch[6+1];
UINT16 musswitchflags; UINT16 musswitchflags;
UINT8 musicloop; UINT8 musicloop;
char tag[33]; // page tag char tag[32+1]; // page tag
char name[34]; // narrator name, extra char for color char name[32+2]; // narrator name, extra char for color
char iconname[8]; // narrator icon lump char iconname[8+1]; // narrator icon lump
boolean rightside; // narrator side, false = left, true = right boolean rightside; // narrator side, false = left, true = right
boolean iconflip; // narrator flip icon horizontally boolean iconflip; // narrator flip icon horizontally
UINT8 hidehud; // hide hud, 0 = show all, 1 = hide depending on prompt position (top/bottom), 2 = hide all UINT8 hidehud; // hide hud, 0 = show all, 1 = hide depending on prompt position (top/bottom), 2 = hide all
...@@ -233,7 +233,7 @@ typedef struct ...@@ -233,7 +233,7 @@ typedef struct
sfxenum_t textsfx; // sfx_ id for printing text sfxenum_t textsfx; // sfx_ id for printing text
UINT8 nextprompt; // next prompt to jump to, one-based. 0 = current prompt UINT8 nextprompt; // next prompt to jump to, one-based. 0 = current prompt
UINT8 nextpage; // next page to jump to, one-based. 0 = next page within prompt->numpages UINT8 nextpage; // next page to jump to, one-based. 0 = next page within prompt->numpages
char nexttag[33]; // next tag to jump to. If set, this overrides nextprompt and nextpage. char nexttag[32+1]; // next tag to jump to. If set, this overrides nextprompt and nextpage.
INT32 timetonext; // time in tics to jump to next page automatically. 0 = don't jump automatically INT32 timetonext; // time in tics to jump to next page automatically. 0 = don't jump automatically
char *text; char *text;
} textpage_t; } textpage_t;
...@@ -287,8 +287,8 @@ typedef struct ...@@ -287,8 +287,8 @@ typedef struct
// (This is not ifdeffed so the map header structure can stay identical, just in case.) // (This is not ifdeffed so the map header structure can stay identical, just in case.)
typedef struct typedef struct
{ {
char option[32]; // 31 usable characters char option[31+1]; // 31 usable characters
char value[256]; // 255 usable characters. If this seriously isn't enough then wtf. char value[255+1]; // 255 usable characters. If this seriously isn't enough then wtf.
} customoption_t; } customoption_t;
/** Map header information. /** Map header information.
...@@ -303,7 +303,7 @@ typedef struct ...@@ -303,7 +303,7 @@ typedef struct
INT16 nextlevel; ///< Map number of next level, or 1100-1102 to end. INT16 nextlevel; ///< Map number of next level, or 1100-1102 to end.
INT16 marathonnext; ///< See nextlevel, but for Marathon mode. Necessary to support hub worlds ala SUGOI. INT16 marathonnext; ///< See nextlevel, but for Marathon mode. Necessary to support hub worlds ala SUGOI.
char keywords[32+1]; ///< Keywords separated by space to search for. 32 characters. char keywords[32+1]; ///< Keywords separated by space to search for. 32 characters.
char musname[7]; ///< Music track to play. "" for no music. char musname[6+1]; ///< Music track to play. "" for no music.
UINT16 mustrack; ///< Subsong to play. Only really relevant for music modules and specific formats supported by GME. 0 to ignore. UINT16 mustrack; ///< Subsong to play. Only really relevant for music modules and specific formats supported by GME. 0 to ignore.
UINT32 muspos; ///< Music position to jump to. UINT32 muspos; ///< Music position to jump to.
char forcecharacter[16+1]; ///< (SKINNAMESIZE+1) Skin to switch to or "" to disable. char forcecharacter[16+1]; ///< (SKINNAMESIZE+1) Skin to switch to or "" to disable.
...@@ -330,7 +330,7 @@ typedef struct ...@@ -330,7 +330,7 @@ typedef struct
UINT16 levelflags; ///< LF_flags: merged booleans into one UINT16 for space, see below UINT16 levelflags; ///< LF_flags: merged booleans into one UINT16 for space, see below
UINT8 menuflags; ///< LF2_flags: options that affect record attack / nights mode menus UINT8 menuflags; ///< LF2_flags: options that affect record attack / nights mode menus
char selectheading[22]; ///< Level select heading. Allows for controllable grouping. char selectheading[21+1]; ///< Level select heading. Allows for controllable grouping.
UINT16 startrings; ///< Number of rings players start with. UINT16 startrings; ///< Number of rings players start with.
INT32 sstimer; ///< Timer for special stages. INT32 sstimer; ///< Timer for special stages.
UINT32 ssspheres; ///< Sphere requirement in special stages. UINT32 ssspheres; ///< Sphere requirement in special stages.
...@@ -352,9 +352,9 @@ typedef struct ...@@ -352,9 +352,9 @@ typedef struct
// Music stuff. // Music stuff.
UINT32 musinterfadeout; ///< Fade out level music on intermission screen in milliseconds UINT32 musinterfadeout; ///< Fade out level music on intermission screen in milliseconds
char musintername[7]; ///< Intermission screen music. char musintername[6+1]; ///< Intermission screen music.
char muspostbossname[7]; ///< Post-bossdeath music. char muspostbossname[6+1]; ///< Post-bossdeath music.
UINT16 muspostbosstrack; ///< Post-bossdeath track. UINT16 muspostbosstrack; ///< Post-bossdeath track.
UINT32 muspostbosspos; ///< Post-bossdeath position UINT32 muspostbosspos; ///< Post-bossdeath position
UINT32 muspostbossfadein; ///< Post-bossdeath fade-in milliseconds. UINT32 muspostbossfadein; ///< Post-bossdeath fade-in milliseconds.
......