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
...@@ -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-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.
...@@ -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
......
...@@ -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.
...@@ -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.
......
...@@ -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-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.
......
...@@ -211,5 +211,15 @@ const char *I_GetSysName(void) ...@@ -211,5 +211,15 @@ const char *I_GetSysName(void)
return NULL; return NULL;
} }
void I_SetTextInputMode(boolean active)
{
(void)active;
}
boolean I_GetTextInputMode(void)
{
return false;
}
#include "../sdl/dosstr.c" #include "../sdl/dosstr.c"
...@@ -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-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.
...@@ -1065,12 +1065,12 @@ static const char *credits[] = { ...@@ -1065,12 +1065,12 @@ static const char *credits[] = {
"Julio \"Chaos Zero 64\" Guir", "Julio \"Chaos Zero 64\" Guir",
"\"Hanicef\"", "\"Hanicef\"",
"\"Hannu_Hanhi\"", // For many OpenGL performance improvements! "\"Hannu_Hanhi\"", // For many OpenGL performance improvements!
"\"hazepastel\"",
"Kepa \"Nev3r\" Iceta", "Kepa \"Nev3r\" Iceta",
"Thomas \"Shadow Hog\" Igoe", "Thomas \"Shadow Hog\" Igoe",
"Iestyn \"Monster Iestyn\" Jealous", "Iestyn \"Monster Iestyn\" Jealous",
"\"Kaito Sinclaire\"", "\"Kaito Sinclaire\"",
"\"Kalaron\"", // Coded some of Sryder13's collection of OpenGL fixes, especially fog "\"Kalaron\"", // Coded some of Sryder13's collection of OpenGL fixes, especially fog
"\"katsy\"",
"Ronald \"Furyhunter\" Kinard", // The SDL2 port "Ronald \"Furyhunter\" Kinard", // The SDL2 port
"\"Lat'\"", // SRB2-CHAT, the chat window from Kart "\"Lat'\"", // SRB2-CHAT, the chat window from Kart
"\"LZA\"", "\"LZA\"",
...@@ -1080,6 +1080,7 @@ static const char *credits[] = { ...@@ -1080,6 +1080,7 @@ static const char *credits[] = {
"Louis-Antoine \"LJ Sonic\" de Moulins", // de Rochefort doesn't quite fit on the screen sorry lol "Louis-Antoine \"LJ Sonic\" de Moulins", // de Rochefort doesn't quite fit on the screen sorry lol
"John \"JTE\" Muniz", "John \"JTE\" Muniz",
"Colin \"Sonict\" Pfaff", "Colin \"Sonict\" Pfaff",
"\"Radicalicious\"",
"James \"james\" Robert Roman", "James \"james\" Robert Roman",
"Sean \"Sryder13\" Ryder", "Sean \"Sryder13\" Ryder",
"Ehab \"Wolfy\" Saeed", "Ehab \"Wolfy\" Saeed",
...@@ -1103,7 +1104,8 @@ static const char *credits[] = { ...@@ -1103,7 +1104,8 @@ static const char *credits[] = {
"\"ChrispyPixels\"", "\"ChrispyPixels\"",
"Paul \"Boinciel\" Clempson", "Paul \"Boinciel\" Clempson",
"Sally \"TehRealSalt\" Cochenour", "Sally \"TehRealSalt\" Cochenour",
"\"Dave Lite\"", "\"DaJumpJump\"", // New Ringslinger graphics (2.2.14)
"\"DeltaSanic\"",
"Desmond \"Blade\" DesJardins", "Desmond \"Blade\" DesJardins",
"Sherman \"CoatRack\" DesJardins", "Sherman \"CoatRack\" DesJardins",
"\"DirkTheHusky\"", "\"DirkTheHusky\"",
...@@ -1119,6 +1121,7 @@ static const char *credits[] = { ...@@ -1119,6 +1121,7 @@ static const char *credits[] = {
"Alice \"Alacroix\" de Lemos", "Alice \"Alacroix\" de Lemos",
"Logan \"Hyperchaotix\" McCloud", "Logan \"Hyperchaotix\" McCloud",
"Alexander \"DrTapeworm\" Moench-Ford", "Alexander \"DrTapeworm\" Moench-Ford",
"\"orbitalviolet\"", // summit showdown hehehehe (aka Evertone)
"Andrew \"Senku Niola\" Moran", "Andrew \"Senku Niola\" Moran",
"\"MotorRoach\"", "\"MotorRoach\"",
"Phillip \"TelosTurntable\" Robinson", "Phillip \"TelosTurntable\" Robinson",
...@@ -1127,6 +1130,7 @@ static const char *credits[] = { ...@@ -1127,6 +1130,7 @@ static const char *credits[] = {
"David \"Instant Sonic\" Spencer Jr.", "David \"Instant Sonic\" Spencer Jr.",
"\"SSNTails\"", "\"SSNTails\"",
"Daniel \"Inazuma\" Trinh", "Daniel \"Inazuma\" Trinh",
"Samuel \"Spectorious\" Tuttle",
"\"VelocitOni\"", "\"VelocitOni\"",
"Jarrett \"JEV3\" Voight", "Jarrett \"JEV3\" Voight",
"", "",
...@@ -1135,6 +1139,7 @@ static const char *credits[] = { ...@@ -1135,6 +1139,7 @@ static const char *credits[] = {
"Victor \"VAdaPEGA\" Ara\x1Fjo", // Araújo "Victor \"VAdaPEGA\" Ara\x1Fjo", // Araújo
"Malcolm \"RedXVI\" Brown", "Malcolm \"RedXVI\" Brown",
"Dave \"DemonTomatoDave\" Bulmer", "Dave \"DemonTomatoDave\" Bulmer",
"Dan Cidoni", // aka Krabs
"Paul \"Boinciel\" Clempson", "Paul \"Boinciel\" Clempson",
"\"Cyan Helkaraxe\"", "\"Cyan Helkaraxe\"",
"Claire \"clairebun\" Ellis", "Claire \"clairebun\" Ellis",
...@@ -1153,24 +1158,30 @@ static const char *credits[] = { ...@@ -1153,24 +1158,30 @@ static const char *credits[] = {
"Colette \"fickleheart\" Bordelon", "Colette \"fickleheart\" Bordelon",
"Hank \"FuriousFox\" Brannock", "Hank \"FuriousFox\" Brannock",
"Matthew \"Fawfulfan\" Chapman", "Matthew \"Fawfulfan\" Chapman",
"Dan Cidoni", // aka Krabs
"Paul \"Boinciel\" Clempson", "Paul \"Boinciel\" Clempson",
"Sally \"TehRealSalt\" Cochenour", "Sally \"TehRealSalt\" Cochenour",
"Desmond \"Blade\" DesJardins", "Desmond \"Blade\" DesJardins",
"Sherman \"CoatRack\" DesJardins", "Sherman \"CoatRack\" DesJardins",
"Ben \"Mystic\" Geyer", "Ben \"Mystic\" Geyer",
"Nathan \"Jazz\" Giroux", "Nathan \"Jazz\" Giroux",
"\"GomaTheMascar\"",
"Vivian \"toaster\" Grannell", "Vivian \"toaster\" Grannell",
"James \"SeventhSentinel\" Hall", "James \"SeventhSentinel\" Hall",
"Kepa \"Nev3r\" Iceta", "Kepa \"Nev3r\" Iceta",
"Thomas \"Shadow Hog\" Igoe", "Thomas \"Shadow Hog\" Igoe",
"Mujamel \"MK\" Khan",
"\"Kaito Sinclaire\"", "\"Kaito Sinclaire\"",
"Alexander \"DrTapeworm\" Moench-Ford", "Alexander \"DrTapeworm\" Moench-Ford",
"\"Radicalicious\"",
"\"Revan\"", "\"Revan\"",
"Anna \"QueenDelta\" Sandlin", "Anna \"QueenDelta\" Sandlin",
"Wessel \"sphere\" Smit", "Wessel \"sphere\" Smit",
"\"SSNTails\"", "\"SSNTails\"",
"Aaron \"Othius\" Stojkov",
"Rob Tisdell", "Rob Tisdell",
"\"Torgo\"", "\"Torgo\"",
"Samuel \"Spectorious\" Tuttle",
"Jarrett \"JEV3\" Voight", "Jarrett \"JEV3\" Voight",
"Johnny \"Sonikku\" Wallbank", "Johnny \"Sonikku\" Wallbank",
"Marco \"mazmazz\" Zafra", "Marco \"mazmazz\" Zafra",
...@@ -2336,7 +2347,7 @@ void F_SkyScroll(const char *patchname) ...@@ -2336,7 +2347,7 @@ void F_SkyScroll(const char *patchname)
} }
#define LOADTTGFX(arr, name, maxf) \ #define LOADTTGFX(arr, name, maxf) \
lumpnum = W_CheckNumForName(name); \ lumpnum = W_CheckNumForPatchName(name); \
if (lumpnum != LUMPERROR) \ if (lumpnum != LUMPERROR) \
{ \ { \
arr[0] = W_CachePatchName(name, PU_PATCH_LOWPRIORITY); \ arr[0] = W_CachePatchName(name, PU_PATCH_LOWPRIORITY); \
...@@ -2350,7 +2361,7 @@ else if (strlen(name) <= 6) \ ...@@ -2350,7 +2361,7 @@ else if (strlen(name) <= 6) \
{ \ { \
sprintf(&lumpname[cnt], "%.2hu", (UINT16)(i+1)); \ sprintf(&lumpname[cnt], "%.2hu", (UINT16)(i+1)); \
lumpname[8] = 0; \ lumpname[8] = 0; \
lumpnum = W_CheckNumForName(lumpname); \ lumpnum = W_CheckNumForPatchName(lumpname); \
if (lumpnum != LUMPERROR) \ if (lumpnum != LUMPERROR) \
arr[i] = W_CachePatchName(lumpname, PU_PATCH_LOWPRIORITY); \ arr[i] = W_CachePatchName(lumpname, PU_PATCH_LOWPRIORITY); \
else \ else \
...@@ -3435,7 +3446,7 @@ void F_TitleScreenTicker(boolean run) ...@@ -3435,7 +3446,7 @@ void F_TitleScreenTicker(boolean run)
{ {
for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next)
{ {
if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) if (th->removing)
continue; continue;
mo2 = (mobj_t *)th; mo2 = (mobj_t *)th;
...@@ -3645,7 +3656,7 @@ static void F_DrawContinueCharacter(INT32 dx, INT32 dy, UINT8 n) ...@@ -3645,7 +3656,7 @@ static void F_DrawContinueCharacter(INT32 dx, INT32 dy, UINT8 n)
( (
HUD_HOOK(continue), luahuddrawlist_continue[n], contPlayers[n], HUD_HOOK(continue), luahuddrawlist_continue[n], contPlayers[n],
dx, dy, contskins[n]->highresscale, dx, dy, contskins[n]->highresscale,
(INT32)(&contskins[n] - skins), cont_spr2[n][0], cont_spr2[n][1], cont_spr2[n][2] + 1, contColors[n], // add 1 to rotation to convert internal angle numbers (0-7) to WAD editor angle numbers (1-8) (INT32)(contskins[n]->skinnum), cont_spr2[n][0], cont_spr2[n][1], cont_spr2[n][2] + 1, contColors[n], // add 1 to rotation to convert internal angle numbers (0-7) to WAD editor angle numbers (1-8)
imcontinuing ? continuetime : timetonext, imcontinuing imcontinuing ? continuetime : timetonext, imcontinuing
); );
} }
...@@ -3711,7 +3722,7 @@ void F_ContinueDrawer(void) ...@@ -3711,7 +3722,7 @@ void F_ContinueDrawer(void)
else if (ncontinues > 10) else if (ncontinues > 10)
{ {
if (!(continuetime & 1) || continuetime > 17) if (!(continuetime & 1) || continuetime > 17)
V_DrawContinueIcon(x, 68, 0, (INT32)(&contskins[0] - skins), contColors[0]); V_DrawContinueIcon(x, 68, 0, contskins[0]->skinnum, contColors[0]);
V_DrawScaledPatch(x+12, 66, 0, stlivex); V_DrawScaledPatch(x+12, 66, 0, stlivex);
V_DrawRightAlignedString(x+38, 64, 0, V_DrawRightAlignedString(x+38, 64, 0,
va("%d",(imcontinuing ? ncontinues-1 : ncontinues))); va("%d",(imcontinuing ? ncontinues-1 : ncontinues)));
...@@ -3725,7 +3736,7 @@ void F_ContinueDrawer(void) ...@@ -3725,7 +3736,7 @@ void F_ContinueDrawer(void)
{ {
if (i == (ncontinues/2) && ((continuetime & 1) || continuetime > 17)) if (i == (ncontinues/2) && ((continuetime & 1) || continuetime > 17))
continue; continue;
V_DrawContinueIcon(x - (i*30), 68, 0, (INT32)(&contskins[0] - skins), contColors[0]); V_DrawContinueIcon(x - (i*30), 68, 0, contskins[0]->skinnum, contColors[0]);
} }
x = BASEVIDWIDTH>>1; x = BASEVIDWIDTH>>1;
} }
...@@ -4116,7 +4127,7 @@ static void F_GetPageTextGeometry(UINT8 *pagelines, boolean *rightside, INT32 *b ...@@ -4116,7 +4127,7 @@ static void F_GetPageTextGeometry(UINT8 *pagelines, boolean *rightside, INT32 *b
// reuse: // reuse:
// cutnum -> promptnum // cutnum -> promptnum
// scenenum -> pagenum // scenenum -> pagenum
lumpnum_t iconlump = W_CheckNumForName(textprompts[cutnum]->page[scenenum].iconname); lumpnum_t iconlump = W_CheckNumForPatchName(textprompts[cutnum]->page[scenenum].iconname);
*pagelines = textprompts[cutnum]->page[scenenum].lines ? textprompts[cutnum]->page[scenenum].lines : 4; *pagelines = textprompts[cutnum]->page[scenenum].lines ? textprompts[cutnum]->page[scenenum].lines : 4;
*rightside = (iconlump != LUMPERROR && textprompts[cutnum]->page[scenenum].rightside); *rightside = (iconlump != LUMPERROR && textprompts[cutnum]->page[scenenum].rightside);
...@@ -4508,7 +4519,7 @@ void F_TextPromptDrawer(void) ...@@ -4508,7 +4519,7 @@ void F_TextPromptDrawer(void)
if (!promptactive) if (!promptactive)
return; return;
iconlump = W_CheckNumForName(textprompts[cutnum]->page[scenenum].iconname); iconlump = W_CheckNumForPatchName(textprompts[cutnum]->page[scenenum].iconname);
F_GetPageTextGeometry(&pagelines, &rightside, &boxh, &texth, &texty, &namey, &chevrony, &textx, &textr); F_GetPageTextGeometry(&pagelines, &rightside, &boxh, &texth, &texty, &namey, &chevrony, &textx, &textr);
// Draw gfx first // Draw gfx first
...@@ -4578,9 +4589,9 @@ void F_TextPromptDrawer(void) ...@@ -4578,9 +4589,9 @@ void F_TextPromptDrawer(void)
players[j].powers[pw_nocontrol] = 1;\ players[j].powers[pw_nocontrol] = 1;\
if (players[j].mo)\ if (players[j].mo)\
{\ {\
if (players[j].mo->state == states+S_PLAY_STND && players[j].mo->tics != -1)\ if (P_IsPlayerInState(&players[j], S_PLAY_STND) && players[j].mo->tics != -1)\
players[j].mo->tics++;\ players[j].mo->tics++;\
else if (players[j].mo->state == states+S_PLAY_WAIT)\ else if (P_IsPlayerInState(&players[j], S_PLAY_WAIT))\
P_SetMobjState(players[j].mo, S_PLAY_STND);\ P_SetMobjState(players[j].mo, S_PLAY_STND);\
}\ }\
} }
......
...@@ -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-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.
......
...@@ -444,12 +444,11 @@ filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *want ...@@ -444,12 +444,11 @@ filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *want
strcpy(&searchpath[searchpathindex[depthleft]],dent->d_name); strcpy(&searchpath[searchpathindex[depthleft]],dent->d_name);
#if defined(__linux__) || defined(__FreeBSD__) #if defined(__linux__) || defined(__FreeBSD__)
if (dent->d_type == DT_UNKNOWN) if (dent->d_type == DT_UNKNOWN || dent->d_type == DT_LNK)
if (lstat(searchpath,&fsstat) == 0 && S_ISDIR(fsstat.st_mode)) if (stat(searchpath,&fsstat) == 0 && S_ISDIR(fsstat.st_mode))
dent->d_type = DT_DIR; dent->d_type = DT_DIR;
// Linux and FreeBSD has a special field for file type on dirent, so use that to speed up lookups. // Linux and FreeBSD has a special field for file type on dirent, so use that to speed up lookups.
// FIXME: should we also follow symlinks?
if (dent->d_type == DT_DIR && depthleft) if (dent->d_type == DT_DIR && depthleft)
#else #else
if (stat(searchpath,&fsstat) < 0) // do we want to follow symlinks? if not: change it to lstat if (stat(searchpath,&fsstat) < 0) // do we want to follow symlinks? if not: change it to lstat
...@@ -699,6 +698,15 @@ static void initdirpath(char *dirpath, size_t *dirpathindex, int depthleft) ...@@ -699,6 +698,15 @@ static void initdirpath(char *dirpath, size_t *dirpathindex, int depthleft)
dirpathindex[depthleft]--; dirpathindex[depthleft]--;
} }
//sortdir by name?
static int lumpnamecompare(const void *A, const void *B)
{
const lumpinfo_t *pA = A;
const lumpinfo_t *pB = B;
return strcmp((pA->fullname), (pB->fullname));
}
lumpinfo_t *getdirectoryfiles(const char *path, UINT16 *nlmp, UINT16 *nfolders) lumpinfo_t *getdirectoryfiles(const char *path, UINT16 *nlmp, UINT16 *nfolders)
{ {
DIR **dirhandle; DIR **dirhandle;
...@@ -889,6 +897,9 @@ lumpinfo_t *getdirectoryfiles(const char *path, UINT16 *nlmp, UINT16 *nfolders) ...@@ -889,6 +897,9 @@ lumpinfo_t *getdirectoryfiles(const char *path, UINT16 *nlmp, UINT16 *nfolders)
free(dirpathindex); free(dirpathindex);
free(dirhandle); free(dirhandle);
//sort files and directories
qsort (lumpinfo, numlumps, sizeof(lumpinfo_t), lumpnamecompare);
(*nlmp) = numlumps; (*nlmp) = numlumps;
return lumpinfo; return lumpinfo;
} }
...@@ -1179,7 +1190,7 @@ boolean preparefilemenu(boolean samedepth) ...@@ -1179,7 +1190,7 @@ boolean preparefilemenu(boolean samedepth)
size_t i; size_t i;
if (filenamebuf == NULL) if (filenamebuf == NULL)
filenamebuf = calloc(sizeof(char) * MAX_WADPATH, numwadfiles); filenamebuf = calloc(numwadfiles, sizeof(char) * MAX_WADPATH);
for (i = 0; i < numwadfiles; i++) for (i = 0; i < numwadfiles; i++)
{ {
......
...@@ -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-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.
...@@ -67,6 +67,8 @@ static UINT8 *metalbuffer = NULL; ...@@ -67,6 +67,8 @@ static UINT8 *metalbuffer = NULL;
static UINT8 *metal_p; static UINT8 *metal_p;
static UINT16 metalversion; static UINT16 metalversion;
consvar_t cv_resyncdemo = CVAR_INIT("resyncdemo", "On", 0, CV_OnOff, NULL);
// extra data stuff (events registered this frame while recording) // extra data stuff (events registered this frame while recording)
static struct { static struct {
UINT8 flags; // EZT flags UINT8 flags; // EZT flags
...@@ -98,7 +100,7 @@ demoghost *ghosts = NULL; ...@@ -98,7 +100,7 @@ demoghost *ghosts = NULL;
// DEMO RECORDING // DEMO RECORDING
// //
#define DEMOVERSION 0x0012 #define DEMOVERSION 0x0011
#define DEMOHEADER "\xF0" "SRB2Replay" "\x0F" #define DEMOHEADER "\xF0" "SRB2Replay" "\x0F"
#define DF_GHOST 0x01 // This demo contains ghost data too! #define DF_GHOST 0x01 // This demo contains ghost data too!
...@@ -183,11 +185,7 @@ void G_ReadDemoTiccmd(ticcmd_t *cmd, INT32 playernum) ...@@ -183,11 +185,7 @@ void G_ReadDemoTiccmd(ticcmd_t *cmd, INT32 playernum)
if (ziptic & ZT_ANGLE) if (ziptic & ZT_ANGLE)
oldcmd.angleturn = READINT16(demo_p); oldcmd.angleturn = READINT16(demo_p);
if (ziptic & ZT_BUTTONS) if (ziptic & ZT_BUTTONS)
{
oldcmd.buttons = (oldcmd.buttons & (BT_CAMLEFT|BT_CAMRIGHT)) | (READUINT16(demo_p) & ~(BT_CAMLEFT|BT_CAMRIGHT)); oldcmd.buttons = (oldcmd.buttons & (BT_CAMLEFT|BT_CAMRIGHT)) | (READUINT16(demo_p) & ~(BT_CAMLEFT|BT_CAMRIGHT));
if (demoversion < 0x0012 && oldcmd.buttons & BT_SPIN)
oldcmd.buttons |= BT_SHIELD; // Copy BT_SPIN to BT_SHIELD for pre-Shield-button demos
}
if (ziptic & ZT_AIMING) if (ziptic & ZT_AIMING)
oldcmd.aiming = READINT16(demo_p); oldcmd.aiming = READINT16(demo_p);
if (ziptic & ZT_LATENCY) if (ziptic & ZT_LATENCY)
...@@ -549,6 +547,9 @@ void G_ConsGhostTic(void) ...@@ -549,6 +547,9 @@ void G_ConsGhostTic(void)
testmo = players[0].mo; testmo = players[0].mo;
if (P_MobjWasRemoved(testmo))
return; // No valid mobj exists, probably because of unexpected quit
// Grab ghost data. // Grab ghost data.
ziptic = READUINT8(demo_p); ziptic = READUINT8(demo_p);
if (ziptic & GZT_XYZ) if (ziptic & GZT_XYZ)
...@@ -609,7 +610,7 @@ void G_ConsGhostTic(void) ...@@ -609,7 +610,7 @@ void G_ConsGhostTic(void)
mobj = NULL; mobj = NULL;
for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next)
{ {
if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) if (th->removing)
continue; continue;
mobj = (mobj_t *)th; mobj = (mobj_t *)th;
if (mobj->type == (mobjtype_t)type && mobj->x == x && mobj->y == y && mobj->z == z) if (mobj->type == (mobjtype_t)type && mobj->x == x && mobj->y == y && mobj->z == z)
...@@ -664,11 +665,14 @@ void G_ConsGhostTic(void) ...@@ -664,11 +665,14 @@ void G_ConsGhostTic(void)
CONS_Alert(CONS_WARNING, M_GetText("Demo playback has desynced!\n")); CONS_Alert(CONS_WARNING, M_GetText("Demo playback has desynced!\n"));
demosynced = false; demosynced = false;
P_UnsetThingPosition(testmo); if (cv_resyncdemo.value)
testmo->x = oldghost.x; {
testmo->y = oldghost.y; P_UnsetThingPosition(testmo);
P_SetThingPosition(testmo); testmo->x = oldghost.x;
testmo->z = oldghost.z; testmo->y = oldghost.y;
P_SetThingPosition(testmo);
testmo->z = oldghost.z;
}
} }
if (*demo_p == DEMOMARKER) if (*demo_p == DEMOMARKER)
...@@ -1446,6 +1450,7 @@ void G_BeginRecording(void) ...@@ -1446,6 +1450,7 @@ void G_BeginRecording(void)
char *filename; char *filename;
UINT16 totalfiles; UINT16 totalfiles;
UINT8 *m; UINT8 *m;
save_t savebuffer;
if (demo_p) if (demo_p)
return; return;
...@@ -1595,7 +1600,11 @@ void G_BeginRecording(void) ...@@ -1595,7 +1600,11 @@ void G_BeginRecording(void)
} }
// Save netvar data // Save netvar data
CV_SaveDemoVars(&demo_p); savebuffer.buf = demo_p;
savebuffer.size = demoend - demo_p;
savebuffer.pos = 0;
CV_SaveDemoVars(&savebuffer);
demo_p = &savebuffer.buf[savebuffer.pos];
memset(&oldcmd,0,sizeof(oldcmd)); memset(&oldcmd,0,sizeof(oldcmd));
memset(&oldghost,0,sizeof(oldghost)); memset(&oldghost,0,sizeof(oldghost));
...@@ -2228,10 +2237,24 @@ void G_DoPlayDemo(char *defdemoname) ...@@ -2228,10 +2237,24 @@ void G_DoPlayDemo(char *defdemoname)
// net var data // net var data
#ifdef OLD22DEMOCOMPAT #ifdef OLD22DEMOCOMPAT
if (demoversion < 0x000d) if (demoversion < 0x000d)
CV_LoadOldDemoVars(&demo_p); {
save_t savebuffer;
savebuffer.buf = demo_p;
savebuffer.size = demoend - demo_p;
savebuffer.pos = 0;
CV_LoadOldDemoVars(&savebuffer);
demo_p = &savebuffer.buf[savebuffer.pos];
}
else else
#endif #endif
CV_LoadDemoVars(&demo_p); {
save_t savebuffer;
savebuffer.buf = demo_p;
savebuffer.size = demoend - demo_p;
savebuffer.pos = 0;
CV_LoadDemoVars(&savebuffer);
demo_p = &savebuffer.buf[savebuffer.pos];
}
// Sigh ... it's an empty demo. // Sigh ... it's an empty demo.
if (*demo_p == DEMOMARKER) if (*demo_p == DEMOMARKER)
...@@ -2669,7 +2692,7 @@ void G_DoPlayMetal(void) ...@@ -2669,7 +2692,7 @@ void G_DoPlayMetal(void)
// find metal sonic // find metal sonic
for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next)
{ {
if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) if (th->removing)
continue; continue;
mo = (mobj_t *)th; mo = (mobj_t *)th;
......
...@@ -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-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.
...@@ -35,6 +35,7 @@ typedef enum ...@@ -35,6 +35,7 @@ typedef enum
} demo_file_override_e; } demo_file_override_e;
extern demo_file_override_e demofileoverride; extern demo_file_override_e demofileoverride;
extern consvar_t cv_resyncdemo;
// Quit after playing a demo from cmdline. // Quit after playing a demo from cmdline.
extern boolean singledemo; extern boolean singledemo;
......
...@@ -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-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.
...@@ -256,8 +256,6 @@ boolean precache = true; // if true, load all graphics at start ...@@ -256,8 +256,6 @@ boolean precache = true; // if true, load all graphics at start
INT16 prevmap, nextmap; INT16 prevmap, nextmap;
static UINT8 *savebuffer;
// Analog Control // Analog Control
static void UserAnalog_OnChange(void); static void UserAnalog_OnChange(void);
static void UserAnalog2_OnChange(void); static void UserAnalog2_OnChange(void);
...@@ -403,29 +401,27 @@ consvar_t cv_cam_lockonboss[2] = { ...@@ -403,29 +401,27 @@ consvar_t cv_cam_lockonboss[2] = {
CVAR_INIT ("cam2_lockaimassist", "Full", CV_SAVE|CV_ALLOWLUA, lockedassist_cons_t, NULL), CVAR_INIT ("cam2_lockaimassist", "Full", CV_SAVE|CV_ALLOWLUA, lockedassist_cons_t, NULL),
}; };
consvar_t cv_moveaxis = CVAR_INIT ("joyaxis_move", "Y-Axis", CV_SAVE, joyaxis_cons_t, NULL); consvar_t cv_moveaxis = CVAR_INIT ("joyaxis_move", "Y-Axis", CV_SAVE, joyaxis_cons_t, NULL);
consvar_t cv_sideaxis = CVAR_INIT ("joyaxis_side", "X-Axis", CV_SAVE, joyaxis_cons_t, NULL); consvar_t cv_sideaxis = CVAR_INIT ("joyaxis_side", "X-Axis", CV_SAVE, joyaxis_cons_t, NULL);
consvar_t cv_lookaxis = CVAR_INIT ("joyaxis_look", "X-Rudder-", CV_SAVE, joyaxis_cons_t, NULL); consvar_t cv_lookaxis = CVAR_INIT ("joyaxis_look", "X-Rudder-", CV_SAVE, joyaxis_cons_t, NULL);
consvar_t cv_turnaxis = CVAR_INIT ("joyaxis_turn", "Z-Axis", CV_SAVE, joyaxis_cons_t, NULL); consvar_t cv_turnaxis = CVAR_INIT ("joyaxis_turn", "Z-Axis", CV_SAVE, joyaxis_cons_t, NULL);
consvar_t cv_jumpaxis = CVAR_INIT ("joyaxis_jump", "None", CV_SAVE, joyaxis_cons_t, NULL); consvar_t cv_jumpaxis = CVAR_INIT ("joyaxis_jump", "None", CV_SAVE, joyaxis_cons_t, NULL);
consvar_t cv_spinaxis = CVAR_INIT ("joyaxis_spin", "None", CV_SAVE, joyaxis_cons_t, NULL); consvar_t cv_spinaxis = CVAR_INIT ("joyaxis_spin", "None", CV_SAVE, joyaxis_cons_t, NULL);
consvar_t cv_shieldaxis = CVAR_INIT ("joyaxis_shield", "None", CV_SAVE, joyaxis_cons_t, NULL); consvar_t cv_fireaxis = CVAR_INIT ("joyaxis_fire", "Z-Rudder", CV_SAVE, joyaxis_cons_t, NULL);
consvar_t cv_fireaxis = CVAR_INIT ("joyaxis_fire", "Z-Rudder", CV_SAVE, joyaxis_cons_t, NULL); consvar_t cv_firenaxis = CVAR_INIT ("joyaxis_firenormal", "Z-Axis", CV_SAVE, joyaxis_cons_t, NULL);
consvar_t cv_firenaxis = CVAR_INIT ("joyaxis_firenormal", "Z-Axis", CV_SAVE, joyaxis_cons_t, NULL); consvar_t cv_deadzone = CVAR_INIT ("joy_deadzone", "0.125", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL);
consvar_t cv_deadzone = CVAR_INIT ("joy_deadzone", "0.125", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL); consvar_t cv_digitaldeadzone = CVAR_INIT ("joy_digdeadzone", "0.25", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL);
consvar_t cv_digitaldeadzone = CVAR_INIT ("joy_digdeadzone", "0.25", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL);
consvar_t cv_moveaxis2 = CVAR_INIT ("joyaxis2_move", "Y-Axis", CV_SAVE, joyaxis_cons_t, NULL);
consvar_t cv_moveaxis2 = CVAR_INIT ("joyaxis2_move", "Y-Axis", CV_SAVE, joyaxis_cons_t, NULL); consvar_t cv_sideaxis2 = CVAR_INIT ("joyaxis2_side", "X-Axis", CV_SAVE, joyaxis_cons_t, NULL);
consvar_t cv_sideaxis2 = CVAR_INIT ("joyaxis2_side", "X-Axis", CV_SAVE, joyaxis_cons_t, NULL); consvar_t cv_lookaxis2 = CVAR_INIT ("joyaxis2_look", "X-Rudder-", CV_SAVE, joyaxis_cons_t, NULL);
consvar_t cv_lookaxis2 = CVAR_INIT ("joyaxis2_look", "X-Rudder-", CV_SAVE, joyaxis_cons_t, NULL); consvar_t cv_turnaxis2 = CVAR_INIT ("joyaxis2_turn", "Z-Axis", CV_SAVE, joyaxis_cons_t, NULL);
consvar_t cv_turnaxis2 = CVAR_INIT ("joyaxis2_turn", "Z-Axis", CV_SAVE, joyaxis_cons_t, NULL); consvar_t cv_jumpaxis2 = CVAR_INIT ("joyaxis2_jump", "None", CV_SAVE, joyaxis_cons_t, NULL);
consvar_t cv_jumpaxis2 = CVAR_INIT ("joyaxis2_jump", "None", CV_SAVE, joyaxis_cons_t, NULL); consvar_t cv_spinaxis2 = CVAR_INIT ("joyaxis2_spin", "None", CV_SAVE, joyaxis_cons_t, NULL);
consvar_t cv_spinaxis2 = CVAR_INIT ("joyaxis2_spin", "None", CV_SAVE, joyaxis_cons_t, NULL); consvar_t cv_fireaxis2 = CVAR_INIT ("joyaxis2_fire", "Z-Rudder", CV_SAVE, joyaxis_cons_t, NULL);
consvar_t cv_shieldaxis2 = CVAR_INIT ("joyaxis2_shield", "None", CV_SAVE, joyaxis_cons_t, NULL); consvar_t cv_firenaxis2 = CVAR_INIT ("joyaxis2_firenormal", "Z-Axis", CV_SAVE, joyaxis_cons_t, NULL);
consvar_t cv_fireaxis2 = CVAR_INIT ("joyaxis2_fire", "Z-Rudder", CV_SAVE, joyaxis_cons_t, NULL); consvar_t cv_deadzone2 = CVAR_INIT ("joy_deadzone2", "0.125", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL);
consvar_t cv_firenaxis2 = CVAR_INIT ("joyaxis2_firenormal", "Z-Axis", CV_SAVE, joyaxis_cons_t, NULL); consvar_t cv_digitaldeadzone2 = CVAR_INIT ("joy_digdeadzone2", "0.25", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL);
consvar_t cv_deadzone2 = CVAR_INIT ("joy_deadzone2", "0.125", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL);
consvar_t cv_digitaldeadzone2 = CVAR_INIT ("joy_digdeadzone2", "0.25", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL);
player_t *seenplayer; // player we're aiming at right now player_t *seenplayer; // player we're aiming at right now
...@@ -896,9 +892,6 @@ INT32 JoyAxis(joyaxis_e axissel) ...@@ -896,9 +892,6 @@ INT32 JoyAxis(joyaxis_e axissel)
case JA_SPIN: case JA_SPIN:
axisval = cv_spinaxis.value; axisval = cv_spinaxis.value;
break; break;
case JA_SHIELD:
axisval = cv_shieldaxis.value;
break;
case JA_FIRE: case JA_FIRE:
axisval = cv_fireaxis.value; axisval = cv_fireaxis.value;
break; break;
...@@ -972,9 +965,6 @@ INT32 Joy2Axis(joyaxis_e axissel) ...@@ -972,9 +965,6 @@ INT32 Joy2Axis(joyaxis_e axissel)
case JA_SPIN: case JA_SPIN:
axisval = cv_spinaxis2.value; axisval = cv_spinaxis2.value;
break; break;
case JA_SHIELD:
axisval = cv_shieldaxis2.value;
break;
case JA_FIRE: case JA_FIRE:
axisval = cv_fireaxis2.value; axisval = cv_fireaxis2.value;
break; break;
...@@ -1342,10 +1332,10 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) ...@@ -1342,10 +1332,10 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
if (PLAYERINPUTDOWN(ssplayer, GC_WEAPONPREV)) if (PLAYERINPUTDOWN(ssplayer, GC_WEAPONPREV))
cmd->buttons |= BT_WEAPONPREV; // Previous Weapon cmd->buttons |= BT_WEAPONPREV; // Previous Weapon
#if NUM_WEAPONS > 7 #if NUM_WEAPONS > 10
"Add extra inputs to g_input.h/gamecontrols_e, and fix conflicts in d_ticcmd.h/ticcmd_t/buttons" "Add extra inputs to g_input.h/gamecontrols_e"
#endif #endif
//use the three avaliable bits to determine the weapon. //use the four avaliable bits to determine the weapon.
cmd->buttons &= ~BT_WEAPONMASK; cmd->buttons &= ~BT_WEAPONMASK;
for (i = 0; i < NUM_WEAPONS; ++i) for (i = 0; i < NUM_WEAPONS; ++i)
if (PLAYERINPUTDOWN(ssplayer, GC_WEPSLOT1 + i)) if (PLAYERINPUTDOWN(ssplayer, GC_WEPSLOT1 + i))
...@@ -1363,15 +1353,9 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) ...@@ -1363,15 +1353,9 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
axis = PlayerJoyAxis(ssplayer, JA_FIRENORMAL); axis = PlayerJoyAxis(ssplayer, JA_FIRENORMAL);
if (PLAYERINPUTDOWN(ssplayer, GC_FIRENORMAL) || (usejoystick && axis > 0)) if (PLAYERINPUTDOWN(ssplayer, GC_FIRENORMAL) || (usejoystick && axis > 0))
cmd->buttons |= BT_FIRENORMAL; cmd->buttons |= BT_FIRENORMAL;
// Toss flag button
if (PLAYERINPUTDOWN(ssplayer, GC_TOSSFLAG)) if (PLAYERINPUTDOWN(ssplayer, GC_TOSSFLAG))
cmd->buttons |= BT_TOSSFLAG; cmd->buttons |= BT_TOSSFLAG;
// Shield button
axis = PlayerJoyAxis(ssplayer, JA_SHIELD);
if (PLAYERINPUTDOWN(ssplayer, GC_SHIELD) || (usejoystick && axis > 0))
cmd->buttons |= BT_SHIELD;
// Lua scriptable buttons // Lua scriptable buttons
if (PLAYERINPUTDOWN(ssplayer, GC_CUSTOM1)) if (PLAYERINPUTDOWN(ssplayer, GC_CUSTOM1))
...@@ -1386,6 +1370,13 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) ...@@ -1386,6 +1370,13 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
if (PLAYERINPUTDOWN(ssplayer, GC_SPIN) || (usejoystick && axis > 0)) if (PLAYERINPUTDOWN(ssplayer, GC_SPIN) || (usejoystick && axis > 0))
cmd->buttons |= BT_SPIN; cmd->buttons |= BT_SPIN;
if (gamestate == GS_INTRO) // prevent crash in intro
{
cmd->angleturn = ticcmd_oldangleturn[forplayer];
cmd->aiming = G_ClipAimingPitch(myaiming);
return;
}
// Centerview can be a toggle in simple mode! // Centerview can be a toggle in simple mode!
{ {
static boolean last_centerviewdown[2], centerviewhold[2]; // detect taps for toggle behavior static boolean last_centerviewdown[2], centerviewhold[2]; // detect taps for toggle behavior
...@@ -1420,7 +1411,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) ...@@ -1420,7 +1411,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
ticcmd_centerviewdown[forplayer] = true; ticcmd_centerviewdown[forplayer] = true;
} }
else if (ticcmd_centerviewdown[forplayer]) else if (ticcmd_centerviewdown[forplayer] || (leveltime < 5))
{ {
if (controlstyle == CS_SIMPLE) if (controlstyle == CS_SIMPLE)
{ {
...@@ -1435,6 +1426,9 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) ...@@ -1435,6 +1426,9 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
{ {
if ( if (
P_MobjWasRemoved(ticcmd_ztargetfocus[forplayer]) || P_MobjWasRemoved(ticcmd_ztargetfocus[forplayer]) ||
(leveltime < 5) ||
(player->playerstate != PST_LIVE) ||
player->exiting ||
!ticcmd_ztargetfocus[forplayer]->health || !ticcmd_ztargetfocus[forplayer]->health ||
(ticcmd_ztargetfocus[forplayer]->type == MT_EGGMOBILE3 && !ticcmd_ztargetfocus[forplayer]->movecount) // Sea Egg is moving around underground and shouldn't be tracked (ticcmd_ztargetfocus[forplayer]->type == MT_EGGMOBILE3 && !ticcmd_ztargetfocus[forplayer]->movecount) // Sea Egg is moving around underground and shouldn't be tracked
) )
...@@ -1466,7 +1460,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) ...@@ -1466,7 +1460,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
P_SetTarget(&newtarget->target, ticcmd_ztargetfocus[forplayer]); P_SetTarget(&newtarget->target, ticcmd_ztargetfocus[forplayer]);
newtarget->drawonlyforplayer = player; // Hide it from the other player in splitscreen, and yourself when spectating newtarget->drawonlyforplayer = player; // Hide it from the other player in splitscreen, and yourself when spectating
if (player->mo && P_AproxDistance( if (player->mo && R_PointToDist2(0, 0,
player->mo->x - ticcmd_ztargetfocus[forplayer]->x, player->mo->x - ticcmd_ztargetfocus[forplayer]->x,
player->mo->y - ticcmd_ztargetfocus[forplayer]->y player->mo->y - ticcmd_ztargetfocus[forplayer]->y
) > 50*player->mo->scale) ) > 50*player->mo->scale)
...@@ -1926,6 +1920,8 @@ void G_DoLoadLevel(boolean resetplayer) ...@@ -1926,6 +1920,8 @@ void G_DoLoadLevel(boolean resetplayer)
// //
void G_StartTitleCard(void) void G_StartTitleCard(void)
{ {
ST_stopTitleCard();
// The title card has been disabled for this map. // The title card has been disabled for this map.
// Oh well. // Oh well.
if (!G_IsTitleCardAvailable()) if (!G_IsTitleCardAvailable())
...@@ -2274,6 +2270,11 @@ boolean G_LuaResponder(event_t *ev) ...@@ -2274,6 +2270,11 @@ boolean G_LuaResponder(event_t *ev)
cancelled = LUA_HookKey(ev, HOOK(KeyUp)); cancelled = LUA_HookKey(ev, HOOK(KeyUp));
LUA_InvalidateUserdata(ev); LUA_InvalidateUserdata(ev);
} }
else if (ev->type == ev_text)
{
cancelled = LUA_HookText(ev, HOOK(TextInput));
LUA_InvalidateUserdata(ev);
}
return cancelled; return cancelled;
} }
...@@ -2614,6 +2615,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) ...@@ -2614,6 +2615,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
boolean spectator; boolean spectator;
boolean outofcoop; boolean outofcoop;
boolean removing; boolean removing;
boolean muted;
INT16 bot; INT16 bot;
SINT8 pity; SINT8 pity;
INT16 rings; INT16 rings;
...@@ -2631,6 +2633,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) ...@@ -2631,6 +2633,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
spectator = players[player].spectator; spectator = players[player].spectator;
outofcoop = players[player].outofcoop; outofcoop = players[player].outofcoop;
removing = players[player].removing; removing = players[player].removing;
muted = players[player].muted;
pflags = (players[player].pflags & (PF_FLIPCAM|PF_ANALOGMODE|PF_DIRECTIONCHAR|PF_AUTOBRAKE|PF_TAGIT|PF_GAMETYPEOVER)); pflags = (players[player].pflags & (PF_FLIPCAM|PF_ANALOGMODE|PF_DIRECTIONCHAR|PF_AUTOBRAKE|PF_TAGIT|PF_GAMETYPEOVER));
playerangleturn = players[player].angleturn; playerangleturn = players[player].angleturn;
oldrelangleturn = players[player].oldrelangleturn; oldrelangleturn = players[player].oldrelangleturn;
...@@ -2708,6 +2711,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) ...@@ -2708,6 +2711,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
p->spectator = spectator; p->spectator = spectator;
p->outofcoop = outofcoop; p->outofcoop = outofcoop;
p->removing = removing; p->removing = removing;
p->muted = muted;
p->angleturn = playerangleturn; p->angleturn = playerangleturn;
p->oldrelangleturn = oldrelangleturn; p->oldrelangleturn = oldrelangleturn;
...@@ -2764,7 +2768,6 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) ...@@ -2764,7 +2768,6 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
p->pflags |= PF_SPINDOWN; p->pflags |= PF_SPINDOWN;
p->pflags |= PF_ATTACKDOWN; p->pflags |= PF_ATTACKDOWN;
p->pflags |= PF_JUMPDOWN; p->pflags |= PF_JUMPDOWN;
p->pflags |= PF_SHIELDDOWN;
p->playerstate = PST_LIVE; p->playerstate = PST_LIVE;
p->panim = PA_IDLE; // standing animation p->panim = PA_IDLE; // standing animation
...@@ -3059,7 +3062,7 @@ void G_ChangePlayerReferences(mobj_t *oldmo, mobj_t *newmo) ...@@ -3059,7 +3062,7 @@ void G_ChangePlayerReferences(mobj_t *oldmo, mobj_t *newmo)
// scan all thinkers // scan all thinkers
for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next)
{ {
if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) if (th->removing)
continue; continue;
mo2 = (mobj_t *)th; mo2 = (mobj_t *)th;
...@@ -3342,7 +3345,7 @@ void G_AddPlayer(INT32 playernum) ...@@ -3342,7 +3345,7 @@ void G_AddPlayer(INT32 playernum)
p->playerstate = PST_REBORN; p->playerstate = PST_REBORN;
p->height = mobjinfo[MT_PLAYER].height; p->height = skins[p->skin]->height;
if (G_GametypeUsesLives() || ((netgame || multiplayer) && (gametyperules & GTR_FRIENDLY))) if (G_GametypeUsesLives() || ((netgame || multiplayer) && (gametyperules & GTR_FRIENDLY)))
p->lives = cv_startinglives.value; p->lives = cv_startinglives.value;
...@@ -4018,7 +4021,7 @@ INT16 G_GetNextMap(boolean ignoretokens, boolean silent) ...@@ -4018,7 +4021,7 @@ INT16 G_GetNextMap(boolean ignoretokens, boolean silent)
INT32 i; INT32 i;
INT16 newmapnum; INT16 newmapnum;
boolean spec = G_IsSpecialStage(gamemap); boolean spec = G_IsSpecialStage(gamemap);
// go to next level // go to next level
// newmapnum is 0-based, unlike gamemap // newmapnum is 0-based, unlike gamemap
if (nextmapoverride != 0) if (nextmapoverride != 0)
...@@ -4122,7 +4125,7 @@ INT16 G_GetNextMap(boolean ignoretokens, boolean silent) ...@@ -4122,7 +4125,7 @@ INT16 G_GetNextMap(boolean ignoretokens, boolean silent)
if (spec && (!gottoken || ignoretokens) && !nextmapoverride) if (spec && (!gottoken || ignoretokens) && !nextmapoverride)
newmapnum = lastmap; // Exiting from a special stage? Go back to the game. Tails 08-11-2001 newmapnum = lastmap; // Exiting from a special stage? Go back to the game. Tails 08-11-2001
if (!(gametyperules & GTR_CAMPAIGN)) if (!(gametyperules & GTR_CAMPAIGN))
{ {
if (cv_advancemap.value == 0) // Stay on same map. if (cv_advancemap.value == 0) // Stay on same map.
...@@ -4130,7 +4133,7 @@ INT16 G_GetNextMap(boolean ignoretokens, boolean silent) ...@@ -4130,7 +4133,7 @@ INT16 G_GetNextMap(boolean ignoretokens, boolean silent)
else if (cv_advancemap.value == 2) // Go to random map. else if (cv_advancemap.value == 2) // Go to random map.
newmapnum = RandMap(G_TOLFlag(gametype_to_use), prevmap); newmapnum = RandMap(G_TOLFlag(gametype_to_use), prevmap);
} }
return newmapnum; return newmapnum;
} }
...@@ -4140,7 +4143,7 @@ INT16 G_GetNextMap(boolean ignoretokens, boolean silent) ...@@ -4140,7 +4143,7 @@ INT16 G_GetNextMap(boolean ignoretokens, boolean silent)
static void G_DoCompleted(void) static void G_DoCompleted(void)
{ {
INT32 i; INT32 i;
tokenlist = 0; // Reset the list tokenlist = 0; // Reset the list
if (modeattacking && pausedelay) if (modeattacking && pausedelay)
...@@ -4168,7 +4171,7 @@ static void G_DoCompleted(void) ...@@ -4168,7 +4171,7 @@ static void G_DoCompleted(void)
//Get and set prevmap/nextmap //Get and set prevmap/nextmap
prevmap = (INT16)(gamemap-1); prevmap = (INT16)(gamemap-1);
nextmap = G_GetNextMap(false, false); nextmap = G_GetNextMap(false, false);
automapactive = false; automapactive = false;
// We are committed to this map now. // We are committed to this map now.
...@@ -4386,7 +4389,7 @@ void G_LoadGameSettings(void) ...@@ -4386,7 +4389,7 @@ void G_LoadGameSettings(void)
// Loads the main data file, which stores information such as emblems found, etc. // Loads the main data file, which stores information such as emblems found, etc.
void G_LoadGameData(gamedata_t *data) void G_LoadGameData(gamedata_t *data)
{ {
size_t length; save_t savebuffer;
INT32 i, j; INT32 i, j;
UINT32 versionID; UINT32 versionID;
...@@ -4428,18 +4431,18 @@ void G_LoadGameData(gamedata_t *data) ...@@ -4428,18 +4431,18 @@ void G_LoadGameData(gamedata_t *data)
return; return;
} }
length = FIL_ReadFile(va(pandf, srb2home, gamedatafilename), &savebuffer); savebuffer.size = FIL_ReadFile(va(pandf, srb2home, gamedatafilename), &savebuffer.buf);
if (!length) if (!savebuffer.size)
{ {
// No gamedata. We can save a new one. // No gamedata. We can save a new one.
data->loaded = true; data->loaded = true;
return; return;
} }
save_p = savebuffer; savebuffer.pos = 0;
// Version check // Version check
versionID = READUINT32(save_p); versionID = P_ReadUINT32(&savebuffer);
if (versionID != GAMEDATA_ID if (versionID != GAMEDATA_ID
#ifdef COMPAT_GAMEDATA_ID // backwards compat behavior #ifdef COMPAT_GAMEDATA_ID // backwards compat behavior
&& versionID != COMPAT_GAMEDATA_ID && versionID != COMPAT_GAMEDATA_ID
...@@ -4450,8 +4453,7 @@ void G_LoadGameData(gamedata_t *data) ...@@ -4450,8 +4453,7 @@ void G_LoadGameData(gamedata_t *data)
if (strcmp(srb2home,".")) if (strcmp(srb2home,"."))
gdfolder = srb2home; gdfolder = srb2home;
Z_Free(savebuffer); Z_Free(savebuffer.buf);
save_p = NULL;
I_Error("Game data is from another version of SRB2.\nDelete %s(maybe in %s) and try again.", gamedatafilename, gdfolder); I_Error("Game data is from another version of SRB2.\nDelete %s(maybe in %s) and try again.", gamedatafilename, gdfolder);
} }
...@@ -4463,14 +4465,14 @@ void G_LoadGameData(gamedata_t *data) ...@@ -4463,14 +4465,14 @@ void G_LoadGameData(gamedata_t *data)
} }
#endif #endif
data->totalplaytime = READUINT32(save_p); data->totalplaytime = P_ReadUINT32(&savebuffer);
#ifdef COMPAT_GAMEDATA_ID #ifdef COMPAT_GAMEDATA_ID
if (versionID == COMPAT_GAMEDATA_ID) if (versionID == COMPAT_GAMEDATA_ID)
{ {
// We'll temporarily use the old condition when loading an older file. // We'll temporarily use the old condition when loading an older file.
// The proper mod-specific hash will get saved in afterwards. // The proper mod-specific hash will get saved in afterwards.
boolean modded = READUINT8(save_p); boolean modded = P_ReadUINT8(&savebuffer);
if (modded && !savemoddata) if (modded && !savemoddata)
{ {
...@@ -4490,13 +4492,13 @@ void G_LoadGameData(gamedata_t *data) ...@@ -4490,13 +4492,13 @@ void G_LoadGameData(gamedata_t *data)
strcpy(currentfilename, gamedatafilename); strcpy(currentfilename, gamedatafilename);
STRBUFCPY(backupfilename, strcat(currentfilename, bak)); STRBUFCPY(backupfilename, strcat(currentfilename, bak));
FIL_WriteFile(va(pandf, srb2home, backupfilename), savebuffer, length); FIL_WriteFile(va(pandf, srb2home, backupfilename), &savebuffer.buf, savebuffer.size);
} }
else else
#endif #endif
{ {
// Quick & dirty hash for what mod this save file is for. // Quick & dirty hash for what mod this save file is for.
UINT32 modID = READUINT32(save_p); UINT32 modID = P_ReadUINT32(&savebuffer);
UINT32 expectedID = quickncasehash(timeattackfolder, sizeof timeattackfolder); UINT32 expectedID = quickncasehash(timeattackfolder, sizeof timeattackfolder);
if (modID != expectedID) if (modID != expectedID)
...@@ -4508,50 +4510,50 @@ void G_LoadGameData(gamedata_t *data) ...@@ -4508,50 +4510,50 @@ void G_LoadGameData(gamedata_t *data)
// TODO put another cipher on these things? meh, I don't care... // TODO put another cipher on these things? meh, I don't care...
for (i = 0; i < NUMMAPS; i++) for (i = 0; i < NUMMAPS; i++)
if ((data->mapvisited[i] = READUINT8(save_p)) > MV_MAX) if ((data->mapvisited[i] = P_ReadUINT8(&savebuffer)) > MV_MAX)
goto datacorrupt; goto datacorrupt;
// To save space, use one bit per collected/achieved/unlocked flag // To save space, use one bit per collected/achieved/unlocked flag
for (i = 0; i < max_emblems;) for (i = 0; i < max_emblems;)
{ {
rtemp = READUINT8(save_p); rtemp = P_ReadUINT8(&savebuffer);
for (j = 0; j < 8 && j+i < max_emblems; ++j) for (j = 0; j < 8 && j+i < max_emblems; ++j)
data->collected[j+i] = ((rtemp >> j) & 1); data->collected[j+i] = ((rtemp >> j) & 1);
i += j; i += j;
} }
for (i = 0; i < max_extraemblems;) for (i = 0; i < max_extraemblems;)
{ {
rtemp = READUINT8(save_p); rtemp = P_ReadUINT8(&savebuffer);
for (j = 0; j < 8 && j+i < max_extraemblems; ++j) for (j = 0; j < 8 && j+i < max_extraemblems; ++j)
data->extraCollected[j+i] = ((rtemp >> j) & 1); data->extraCollected[j+i] = ((rtemp >> j) & 1);
i += j; i += j;
} }
for (i = 0; i < max_unlockables;) for (i = 0; i < max_unlockables;)
{ {
rtemp = READUINT8(save_p); rtemp = P_ReadUINT8(&savebuffer);
for (j = 0; j < 8 && j+i < max_unlockables; ++j) for (j = 0; j < 8 && j+i < max_unlockables; ++j)
data->unlocked[j+i] = ((rtemp >> j) & 1); data->unlocked[j+i] = ((rtemp >> j) & 1);
i += j; i += j;
} }
for (i = 0; i < max_conditionsets;) for (i = 0; i < max_conditionsets;)
{ {
rtemp = READUINT8(save_p); rtemp = P_ReadUINT8(&savebuffer);
for (j = 0; j < 8 && j+i < max_conditionsets; ++j) for (j = 0; j < 8 && j+i < max_conditionsets; ++j)
data->achieved[j+i] = ((rtemp >> j) & 1); data->achieved[j+i] = ((rtemp >> j) & 1);
i += j; i += j;
} }
data->timesBeaten = READUINT32(save_p); data->timesBeaten = P_ReadUINT32(&savebuffer);
data->timesBeatenWithEmeralds = READUINT32(save_p); data->timesBeatenWithEmeralds = P_ReadUINT32(&savebuffer);
data->timesBeatenUltimate = READUINT32(save_p); data->timesBeatenUltimate = P_ReadUINT32(&savebuffer);
// Main records // Main records
for (i = 0; i < NUMMAPS; ++i) for (i = 0; i < NUMMAPS; ++i)
{ {
recscore = READUINT32(save_p); recscore = P_ReadUINT32(&savebuffer);
rectime = (tic_t)READUINT32(save_p); rectime = (tic_t)P_ReadUINT32(&savebuffer);
recrings = READUINT16(save_p); recrings = P_ReadUINT16(&savebuffer);
save_p++; // compat P_ReadUINT8(&savebuffer); // compat
if (recrings > 10000 || recscore > MAXSCORE) if (recrings > 10000 || recscore > MAXSCORE)
goto datacorrupt; goto datacorrupt;
...@@ -4568,16 +4570,16 @@ void G_LoadGameData(gamedata_t *data) ...@@ -4568,16 +4570,16 @@ void G_LoadGameData(gamedata_t *data)
// Nights records // Nights records
for (i = 0; i < NUMMAPS; ++i) for (i = 0; i < NUMMAPS; ++i)
{ {
if ((recmares = READUINT8(save_p)) == 0) if ((recmares = P_ReadUINT8(&savebuffer)) == 0)
continue; continue;
G_AllocNightsRecordData((INT16)i, data); G_AllocNightsRecordData((INT16)i, data);
for (curmare = 0; curmare < (recmares+1); ++curmare) for (curmare = 0; curmare < (recmares+1); ++curmare)
{ {
data->nightsrecords[i]->score[curmare] = READUINT32(save_p); data->nightsrecords[i]->score[curmare] = P_ReadUINT32(&savebuffer);
data->nightsrecords[i]->grade[curmare] = READUINT8(save_p); data->nightsrecords[i]->grade[curmare] = P_ReadUINT8(&savebuffer);
data->nightsrecords[i]->time[curmare] = (tic_t)READUINT32(save_p); data->nightsrecords[i]->time[curmare] = (tic_t)P_ReadUINT32(&savebuffer);
if (data->nightsrecords[i]->grade[curmare] > GRADE_S) if (data->nightsrecords[i]->grade[curmare] > GRADE_S)
{ {
...@@ -4589,8 +4591,7 @@ void G_LoadGameData(gamedata_t *data) ...@@ -4589,8 +4591,7 @@ void G_LoadGameData(gamedata_t *data)
} }
// done // done
Z_Free(savebuffer); Z_Free(savebuffer.buf);
save_p = NULL;
// Don't consider loaded until it's a success! // Don't consider loaded until it's a success!
// It used to do this much earlier, but this would cause the gamedata to // It used to do this much earlier, but this would cause the gamedata to
...@@ -4611,8 +4612,7 @@ void G_LoadGameData(gamedata_t *data) ...@@ -4611,8 +4612,7 @@ void G_LoadGameData(gamedata_t *data)
if (strcmp(srb2home,".")) if (strcmp(srb2home,"."))
gdfolder = srb2home; gdfolder = srb2home;
Z_Free(savebuffer); Z_Free(savebuffer.buf);
save_p = NULL;
I_Error("Corrupt game data file.\nDelete %s(maybe in %s) and try again.", gamedatafilename, gdfolder); I_Error("Corrupt game data file.\nDelete %s(maybe in %s) and try again.", gamedatafilename, gdfolder);
} }
...@@ -4622,9 +4622,8 @@ void G_LoadGameData(gamedata_t *data) ...@@ -4622,9 +4622,8 @@ void G_LoadGameData(gamedata_t *data)
// Saves the main data file, which stores information such as emblems found, etc. // Saves the main data file, which stores information such as emblems found, etc.
void G_SaveGameData(gamedata_t *data) void G_SaveGameData(gamedata_t *data)
{ {
UINT8 *data_p; save_t savebuffer;
size_t length;
INT32 i, j; INT32 i, j;
UINT8 btemp; UINT8 btemp;
...@@ -4636,30 +4635,31 @@ void G_SaveGameData(gamedata_t *data) ...@@ -4636,30 +4635,31 @@ void G_SaveGameData(gamedata_t *data)
if (!data->loaded) if (!data->loaded)
return; // If never loaded (-nodata), don't save return; // If never loaded (-nodata), don't save
data_p = savebuffer = (UINT8 *)malloc(GAMEDATASIZE); savebuffer.size = GAMEDATASIZE;
if (!data_p) savebuffer.buf = (UINT8 *)malloc(savebuffer.size);
if (!savebuffer.buf)
{ {
CONS_Alert(CONS_ERROR, M_GetText("No more free memory for saving game data\n")); CONS_Alert(CONS_ERROR, M_GetText("No more free memory for saving game data\n"));
return; return;
} }
savebuffer.pos = 0;
if (usedCheats) if (usedCheats)
{ {
free(savebuffer); free(savebuffer.buf);
savebuffer = NULL;
return; return;
} }
// Version test // Version test
WRITEUINT32(data_p, GAMEDATA_ID); P_WriteUINT32(&savebuffer, GAMEDATA_ID);
WRITEUINT32(data_p, data->totalplaytime); P_WriteUINT32(&savebuffer, data->totalplaytime);
WRITEUINT32(data_p, quickncasehash(timeattackfolder, sizeof timeattackfolder)); P_WriteUINT32(&savebuffer, quickncasehash(timeattackfolder, sizeof timeattackfolder));
// TODO put another cipher on these things? meh, I don't care... // TODO put another cipher on these things? meh, I don't care...
for (i = 0; i < NUMMAPS; i++) for (i = 0; i < NUMMAPS; i++)
WRITEUINT8(data_p, (data->mapvisited[i] & MV_MAX)); P_WriteUINT8(&savebuffer, (data->mapvisited[i] & MV_MAX));
// To save space, use one bit per collected/achieved/unlocked flag // To save space, use one bit per collected/achieved/unlocked flag
for (i = 0; i < MAXEMBLEMS;) for (i = 0; i < MAXEMBLEMS;)
...@@ -4667,7 +4667,7 @@ void G_SaveGameData(gamedata_t *data) ...@@ -4667,7 +4667,7 @@ void G_SaveGameData(gamedata_t *data)
btemp = 0; btemp = 0;
for (j = 0; j < 8 && j+i < MAXEMBLEMS; ++j) for (j = 0; j < 8 && j+i < MAXEMBLEMS; ++j)
btemp |= (data->collected[j+i] << j); btemp |= (data->collected[j+i] << j);
WRITEUINT8(data_p, btemp); P_WriteUINT8(&savebuffer, btemp);
i += j; i += j;
} }
for (i = 0; i < MAXEXTRAEMBLEMS;) for (i = 0; i < MAXEXTRAEMBLEMS;)
...@@ -4675,7 +4675,7 @@ void G_SaveGameData(gamedata_t *data) ...@@ -4675,7 +4675,7 @@ void G_SaveGameData(gamedata_t *data)
btemp = 0; btemp = 0;
for (j = 0; j < 8 && j+i < MAXEXTRAEMBLEMS; ++j) for (j = 0; j < 8 && j+i < MAXEXTRAEMBLEMS; ++j)
btemp |= (data->extraCollected[j+i] << j); btemp |= (data->extraCollected[j+i] << j);
WRITEUINT8(data_p, btemp); P_WriteUINT8(&savebuffer, btemp);
i += j; i += j;
} }
for (i = 0; i < MAXUNLOCKABLES;) for (i = 0; i < MAXUNLOCKABLES;)
...@@ -4683,7 +4683,7 @@ void G_SaveGameData(gamedata_t *data) ...@@ -4683,7 +4683,7 @@ void G_SaveGameData(gamedata_t *data)
btemp = 0; btemp = 0;
for (j = 0; j < 8 && j+i < MAXUNLOCKABLES; ++j) for (j = 0; j < 8 && j+i < MAXUNLOCKABLES; ++j)
btemp |= (data->unlocked[j+i] << j); btemp |= (data->unlocked[j+i] << j);
WRITEUINT8(data_p, btemp); P_WriteUINT8(&savebuffer, btemp);
i += j; i += j;
} }
for (i = 0; i < MAXCONDITIONSETS;) for (i = 0; i < MAXCONDITIONSETS;)
...@@ -4691,30 +4691,30 @@ void G_SaveGameData(gamedata_t *data) ...@@ -4691,30 +4691,30 @@ void G_SaveGameData(gamedata_t *data)
btemp = 0; btemp = 0;
for (j = 0; j < 8 && j+i < MAXCONDITIONSETS; ++j) for (j = 0; j < 8 && j+i < MAXCONDITIONSETS; ++j)
btemp |= (data->achieved[j+i] << j); btemp |= (data->achieved[j+i] << j);
WRITEUINT8(data_p, btemp); P_WriteUINT8(&savebuffer, btemp);
i += j; i += j;
} }
WRITEUINT32(data_p, data->timesBeaten); P_WriteUINT32(&savebuffer, data->timesBeaten);
WRITEUINT32(data_p, data->timesBeatenWithEmeralds); P_WriteUINT32(&savebuffer, data->timesBeatenWithEmeralds);
WRITEUINT32(data_p, data->timesBeatenUltimate); P_WriteUINT32(&savebuffer, data->timesBeatenUltimate);
// Main records // Main records
for (i = 0; i < NUMMAPS; i++) for (i = 0; i < NUMMAPS; i++)
{ {
if (data->mainrecords[i]) if (data->mainrecords[i])
{ {
WRITEUINT32(data_p, data->mainrecords[i]->score); P_WriteUINT32(&savebuffer, data->mainrecords[i]->score);
WRITEUINT32(data_p, data->mainrecords[i]->time); P_WriteUINT32(&savebuffer, data->mainrecords[i]->time);
WRITEUINT16(data_p, data->mainrecords[i]->rings); P_WriteUINT16(&savebuffer, data->mainrecords[i]->rings);
} }
else else
{ {
WRITEUINT32(data_p, 0); P_WriteUINT32(&savebuffer, 0);
WRITEUINT32(data_p, 0); P_WriteUINT32(&savebuffer, 0);
WRITEUINT16(data_p, 0); P_WriteUINT16(&savebuffer, 0);
} }
WRITEUINT8(data_p, 0); // compat P_WriteUINT8(&savebuffer, 0); // compat
} }
// NiGHTS records // NiGHTS records
...@@ -4722,25 +4722,22 @@ void G_SaveGameData(gamedata_t *data) ...@@ -4722,25 +4722,22 @@ void G_SaveGameData(gamedata_t *data)
{ {
if (!data->nightsrecords[i] || !data->nightsrecords[i]->nummares) if (!data->nightsrecords[i] || !data->nightsrecords[i]->nummares)
{ {
WRITEUINT8(data_p, 0); P_WriteUINT8(&savebuffer, 0);
continue; continue;
} }
WRITEUINT8(data_p, data->nightsrecords[i]->nummares); P_WriteUINT8(&savebuffer, data->nightsrecords[i]->nummares);
for (curmare = 0; curmare < (data->nightsrecords[i]->nummares + 1); ++curmare) for (curmare = 0; curmare < (data->nightsrecords[i]->nummares + 1); ++curmare)
{ {
WRITEUINT32(data_p, data->nightsrecords[i]->score[curmare]); P_WriteUINT32(&savebuffer, data->nightsrecords[i]->score[curmare]);
WRITEUINT8(data_p, data->nightsrecords[i]->grade[curmare]); P_WriteUINT8(&savebuffer, data->nightsrecords[i]->grade[curmare]);
WRITEUINT32(data_p, data->nightsrecords[i]->time[curmare]); P_WriteUINT32(&savebuffer, data->nightsrecords[i]->time[curmare]);
} }
} }
length = data_p - savebuffer; FIL_WriteFile(va(pandf, srb2home, gamedatafilename), savebuffer.buf, savebuffer.pos);
free(savebuffer.buf);
FIL_WriteFile(va(pandf, srb2home, gamedatafilename), savebuffer, length);
free(savebuffer);
savebuffer = NULL;
} }
#define VERSIONSIZE 16 #define VERSIONSIZE 16
...@@ -4751,7 +4748,7 @@ void G_SaveGameData(gamedata_t *data) ...@@ -4751,7 +4748,7 @@ void G_SaveGameData(gamedata_t *data)
// //
void G_LoadGame(UINT32 slot, INT16 mapoverride) void G_LoadGame(UINT32 slot, INT16 mapoverride)
{ {
size_t length; save_t savebuffer;
char vcheck[VERSIONSIZE]; char vcheck[VERSIONSIZE];
char savename[255]; char savename[255];
...@@ -4768,18 +4765,18 @@ void G_LoadGame(UINT32 slot, INT16 mapoverride) ...@@ -4768,18 +4765,18 @@ void G_LoadGame(UINT32 slot, INT16 mapoverride)
else else
sprintf(savename, savegamename, slot); sprintf(savename, savegamename, slot);
length = FIL_ReadFile(savename, &savebuffer); savebuffer.size = FIL_ReadFile(savename, &savebuffer.buf);
if (!length) if (!savebuffer.size)
{ {
CONS_Printf(M_GetText("Couldn't read file %s\n"), savename); CONS_Printf(M_GetText("Couldn't read file %s\n"), savename);
return; return;
} }
save_p = savebuffer; savebuffer.pos = 0;
memset(vcheck, 0, sizeof (vcheck)); memset(vcheck, 0, sizeof (vcheck));
sprintf(vcheck, (marathonmode ? "back-up %d" : "version %d"), VERSION); sprintf(vcheck, (marathonmode ? "back-up %d" : "version %d"), VERSION);
if (strcmp((const char *)save_p, (const char *)vcheck)) if (strcmp((const char *)&savebuffer.buf[savebuffer.pos], (const char *)vcheck))
{ {
#ifdef SAVEGAME_OTHERVERSIONS #ifdef SAVEGAME_OTHERVERSIONS
M_StartMessage(M_GetText("Save game from different version.\nYou can load this savegame, but\nsaving afterwards will be disabled.\n\nDo you want to continue anyway?\n\n(Press 'Y' to confirm)\n"), M_StartMessage(M_GetText("Save game from different version.\nYou can load this savegame, but\nsaving afterwards will be disabled.\n\nDo you want to continue anyway?\n\n(Press 'Y' to confirm)\n"),
...@@ -4789,15 +4786,14 @@ void G_LoadGame(UINT32 slot, INT16 mapoverride) ...@@ -4789,15 +4786,14 @@ void G_LoadGame(UINT32 slot, INT16 mapoverride)
M_ClearMenus(true); // so ESC backs out to title M_ClearMenus(true); // so ESC backs out to title
M_StartMessage(M_GetText("Save game from different version\n\nPress ESC\n"), NULL, MM_NOTHING); M_StartMessage(M_GetText("Save game from different version\n\nPress ESC\n"), NULL, MM_NOTHING);
Command_ExitGame_f(); Command_ExitGame_f();
Z_Free(savebuffer); Z_Free(savebuffer.buf);
save_p = savebuffer = NULL;
// no cheating! // no cheating!
memset(&savedata, 0, sizeof(savedata)); memset(&savedata, 0, sizeof(savedata));
#endif #endif
return; // bad version return; // bad version
} }
save_p += VERSIONSIZE; savebuffer.pos += VERSIONSIZE;
// if (demoplayback) // reset game engine // if (demoplayback) // reset game engine
// G_StopDemo(); // G_StopDemo();
...@@ -4806,13 +4802,12 @@ void G_LoadGame(UINT32 slot, INT16 mapoverride) ...@@ -4806,13 +4802,12 @@ void G_LoadGame(UINT32 slot, INT16 mapoverride)
// automapactive = false; // automapactive = false;
// dearchive all the modifications // dearchive all the modifications
if (!P_LoadGame(mapoverride)) if (!P_LoadGame(&savebuffer, mapoverride))
{ {
M_ClearMenus(true); // so ESC backs out to title M_ClearMenus(true); // so ESC backs out to title
M_StartMessage(M_GetText("Savegame file corrupted\n\nPress ESC\n"), NULL, MM_NOTHING); M_StartMessage(M_GetText("Savegame file corrupted\n\nPress ESC\n"), NULL, MM_NOTHING);
Command_ExitGame_f(); Command_ExitGame_f();
Z_Free(savebuffer); Z_Free(savebuffer.buf);
save_p = savebuffer = NULL;
// no cheating! // no cheating!
memset(&savedata, 0, sizeof(savedata)); memset(&savedata, 0, sizeof(savedata));
...@@ -4820,13 +4815,12 @@ void G_LoadGame(UINT32 slot, INT16 mapoverride) ...@@ -4820,13 +4815,12 @@ void G_LoadGame(UINT32 slot, INT16 mapoverride)
} }
if (marathonmode) if (marathonmode)
{ {
marathontime = READUINT32(save_p); marathontime = P_ReadUINT32(&savebuffer);
marathonmode |= READUINT8(save_p); marathonmode |= P_ReadUINT8(&savebuffer);
} }
// done // done
Z_Free(savebuffer); Z_Free(savebuffer.buf);
save_p = savebuffer = NULL;
displayplayer = consoleplayer; displayplayer = consoleplayer;
multiplayer = splitscreen = false; multiplayer = splitscreen = false;
...@@ -4844,6 +4838,7 @@ void G_LoadGame(UINT32 slot, INT16 mapoverride) ...@@ -4844,6 +4838,7 @@ void G_LoadGame(UINT32 slot, INT16 mapoverride)
// //
void G_SaveGame(UINT32 slot, INT16 mapnum) void G_SaveGame(UINT32 slot, INT16 mapnum)
{ {
save_t savebuffer;
boolean saved; boolean saved;
char savename[256] = ""; char savename[256] = "";
const char *backup; const char *backup;
...@@ -4857,33 +4852,32 @@ void G_SaveGame(UINT32 slot, INT16 mapnum) ...@@ -4857,33 +4852,32 @@ void G_SaveGame(UINT32 slot, INT16 mapnum)
gameaction = ga_nothing; gameaction = ga_nothing;
{ {
char name[VERSIONSIZE]; char name[VERSIONSIZE];
size_t length;
save_p = savebuffer = (UINT8 *)malloc(SAVEGAMESIZE); savebuffer.size = SAVEGAMESIZE;
if (!save_p) savebuffer.buf = (UINT8 *)malloc(savebuffer.size);
if (!savebuffer.buf)
{ {
CONS_Alert(CONS_ERROR, M_GetText("No more free memory for saving game data\n")); CONS_Alert(CONS_ERROR, M_GetText("No more free memory for saving game data\n"));
return; return;
} }
savebuffer.pos = 0;
memset(name, 0, sizeof (name)); memset(name, 0, sizeof (name));
sprintf(name, (marathonmode ? "back-up %d" : "version %d"), VERSION); sprintf(name, (marathonmode ? "back-up %d" : "version %d"), VERSION);
WRITEMEM(save_p, name, VERSIONSIZE); P_WriteMem(&savebuffer, name, VERSIONSIZE);
P_SaveGame(mapnum); P_SaveGame(&savebuffer, mapnum);
if (marathonmode) if (marathonmode)
{ {
UINT32 writetime = marathontime; UINT32 writetime = marathontime;
if (!(marathonmode & MA_INGAME)) if (!(marathonmode & MA_INGAME))
writetime += TICRATE*5; // live event backup penalty because we don't know how long it takes to get to the next map writetime += TICRATE*5; // live event backup penalty because we don't know how long it takes to get to the next map
WRITEUINT32(save_p, writetime); P_WriteUINT32(&savebuffer, writetime);
WRITEUINT8(save_p, (marathonmode & ~MA_INIT)); P_WriteUINT8(&savebuffer, (marathonmode & ~MA_INIT));
} }
length = save_p - savebuffer; saved = FIL_WriteFile(backup, savebuffer.buf, savebuffer.pos);
saved = FIL_WriteFile(backup, savebuffer, length); free(savebuffer.buf);
free(savebuffer);
save_p = savebuffer = NULL;
} }
gameaction = ga_nothing; gameaction = ga_nothing;
...@@ -4895,11 +4889,10 @@ void G_SaveGame(UINT32 slot, INT16 mapnum) ...@@ -4895,11 +4889,10 @@ void G_SaveGame(UINT32 slot, INT16 mapnum)
} }
#define BADSAVE goto cleanup; #define BADSAVE goto cleanup;
#define CHECKPOS if (save_p >= end_p) BADSAVE
void G_SaveGameOver(UINT32 slot, boolean modifylives) void G_SaveGameOver(UINT32 slot, boolean modifylives)
{ {
save_t savebuffer;
boolean saved = false; boolean saved = false;
size_t length;
char vcheck[VERSIONSIZE]; char vcheck[VERSIONSIZE];
char savename[255]; char savename[255];
const char *backup; const char *backup;
...@@ -4910,42 +4903,38 @@ void G_SaveGameOver(UINT32 slot, boolean modifylives) ...@@ -4910,42 +4903,38 @@ void G_SaveGameOver(UINT32 slot, boolean modifylives)
sprintf(savename, savegamename, slot); sprintf(savename, savegamename, slot);
backup = va("%s",savename); backup = va("%s",savename);
length = FIL_ReadFile(savename, &savebuffer); savebuffer.size = FIL_ReadFile(savename, &savebuffer.buf);
if (!length) if (!savebuffer.size)
{ {
CONS_Printf(M_GetText("Couldn't read file %s\n"), savename); CONS_Printf(M_GetText("Couldn't read file %s\n"), savename);
return; return;
} }
savebuffer.pos = 0;
{ {
char temp[sizeof(timeattackfolder)]; char temp[sizeof(timeattackfolder)];
UINT8 *end_p = savebuffer + length;
UINT8 *lives_p; UINT8 *lives_p;
SINT8 pllives; SINT8 pllives;
#ifdef NEWSKINSAVES #ifdef NEWSKINSAVES
INT16 backwardsCompat = 0; INT16 backwardsCompat = 0;
#endif #endif
save_p = savebuffer;
// Version check // Version check
memset(vcheck, 0, sizeof (vcheck)); memset(vcheck, 0, sizeof (vcheck));
sprintf(vcheck, (marathonmode ? "back-up %d" : "version %d"), VERSION); sprintf(vcheck, (marathonmode ? "back-up %d" : "version %d"), VERSION);
if (strcmp((const char *)save_p, (const char *)vcheck)) BADSAVE if (strcmp((const char *)&savebuffer.buf[savebuffer.pos], (const char *)vcheck)) BADSAVE
save_p += VERSIONSIZE; savebuffer.pos += VERSIONSIZE;
// P_UnArchiveMisc() // P_UnArchiveMisc()
(void)READINT16(save_p); (void)P_ReadINT16(&savebuffer);
CHECKPOS (void)P_ReadUINT16(&savebuffer); // emeralds
(void)READUINT16(save_p); // emeralds P_ReadStringN(&savebuffer, temp, sizeof(temp)); // mod it belongs to
CHECKPOS
READSTRINGN(save_p, temp, sizeof(temp)); // mod it belongs to
if (strcmp(temp, timeattackfolder)) BADSAVE if (strcmp(temp, timeattackfolder)) BADSAVE
// P_UnArchivePlayer() // P_UnArchivePlayer()
CHECKPOS
#ifdef NEWSKINSAVES #ifdef NEWSKINSAVES
backwardsCompat = READUINT16(save_p); backwardsCompat = P_ReadUINT16(&savebuffer);
CHECKPOS
if (backwardsCompat == NEWSKINSAVES) // New save, read skin names if (backwardsCompat == NEWSKINSAVES) // New save, read skin names
#endif #endif
...@@ -4953,47 +4942,37 @@ void G_SaveGameOver(UINT32 slot, boolean modifylives) ...@@ -4953,47 +4942,37 @@ void G_SaveGameOver(UINT32 slot, boolean modifylives)
char ourSkinName[SKINNAMESIZE+1]; char ourSkinName[SKINNAMESIZE+1];
char botSkinName[SKINNAMESIZE+1]; char botSkinName[SKINNAMESIZE+1];
READSTRINGN(save_p, ourSkinName, SKINNAMESIZE); P_ReadStringN(&savebuffer, ourSkinName, SKINNAMESIZE);
CHECKPOS
READSTRINGN(save_p, botSkinName, SKINNAMESIZE); P_ReadStringN(&savebuffer, botSkinName, SKINNAMESIZE);
CHECKPOS
} }
WRITEUINT8(save_p, numgameovers); P_WriteUINT8(&savebuffer, numgameovers);
CHECKPOS
lives_p = save_p; lives_p = &savebuffer.buf[savebuffer.pos];
pllives = READSINT8(save_p); // lives pllives = P_ReadSINT8(&savebuffer); // lives
CHECKPOS
if (modifylives && pllives < startinglivesbalance[numgameovers]) if (modifylives && pllives < startinglivesbalance[numgameovers])
{ {
pllives = startinglivesbalance[numgameovers]; *lives_p = startinglivesbalance[numgameovers];
WRITESINT8(lives_p, pllives);
} }
(void)READINT32(save_p); // Score (void)P_ReadINT32(&savebuffer); // Score
CHECKPOS (void)P_ReadINT32(&savebuffer); // continues
(void)READINT32(save_p); // continues
// File end marker check // File end marker check
CHECKPOS switch (P_ReadUINT8(&savebuffer))
switch (READUINT8(save_p))
{ {
case 0xb7: case 0xb7:
{ {
UINT8 i, banksinuse; UINT8 i, banksinuse;
CHECKPOS banksinuse = P_ReadUINT8(&savebuffer);
banksinuse = READUINT8(save_p);
CHECKPOS
if (banksinuse > NUM_LUABANKS) if (banksinuse > NUM_LUABANKS)
BADSAVE BADSAVE
for (i = 0; i < banksinuse; i++) for (i = 0; i < banksinuse; i++)
{ {
(void)READINT32(save_p); (void)P_ReadINT32(&savebuffer);
CHECKPOS
} }
if (READUINT8(save_p) != 0x1d) if (P_ReadUINT8(&savebuffer) != 0x1d)
BADSAVE BADSAVE
} }
case 0x1d: case 0x1d:
...@@ -5003,7 +4982,7 @@ void G_SaveGameOver(UINT32 slot, boolean modifylives) ...@@ -5003,7 +4982,7 @@ void G_SaveGameOver(UINT32 slot, boolean modifylives)
} }
// done // done
saved = FIL_WriteFile(backup, savebuffer, length); saved = FIL_WriteFile(backup, savebuffer.buf, savebuffer.size);
} }
cleanup: cleanup:
...@@ -5011,11 +4990,9 @@ cleanup: ...@@ -5011,11 +4990,9 @@ cleanup:
CONS_Printf(M_GetText("Game saved.\n")); CONS_Printf(M_GetText("Game saved.\n"));
else if (!saved) else if (!saved)
CONS_Alert(CONS_ERROR, M_GetText("Error while writing to %s for save slot %u, base: %s\n"), backup, slot, (marathonmode ? liveeventbackup : savegamename)); CONS_Alert(CONS_ERROR, M_GetText("Error while writing to %s for save slot %u, base: %s\n"), backup, slot, (marathonmode ? liveeventbackup : savegamename));
Z_Free(savebuffer); Z_Free(savebuffer.buf);
save_p = savebuffer = NULL;
} }
#undef CHECKPOS
#undef BADSAVE #undef BADSAVE
// //
......
...@@ -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-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.
...@@ -71,8 +71,8 @@ typedef enum { ...@@ -71,8 +71,8 @@ typedef enum {
#define P_ControlStyle(player) ((((player)->pflags & PF_ANALOGMODE) ? CS_LMAOGALOG : 0) | (((player)->pflags & PF_DIRECTIONCHAR) ? CS_STANDARD : 0)) #define P_ControlStyle(player) ((((player)->pflags & PF_ANALOGMODE) ? CS_LMAOGALOG : 0) | (((player)->pflags & PF_DIRECTIONCHAR) ? CS_STANDARD : 0))
extern consvar_t cv_autobrake, cv_autobrake2; extern consvar_t cv_autobrake, cv_autobrake2;
extern consvar_t cv_sideaxis, cv_turnaxis, cv_moveaxis, cv_lookaxis, cv_jumpaxis, cv_spinaxis, cv_shieldaxis, cv_fireaxis, cv_firenaxis, cv_deadzone, cv_digitaldeadzone; extern consvar_t cv_sideaxis,cv_turnaxis,cv_moveaxis,cv_lookaxis,cv_jumpaxis,cv_spinaxis,cv_fireaxis,cv_firenaxis,cv_deadzone,cv_digitaldeadzone;
extern consvar_t cv_sideaxis2,cv_turnaxis2,cv_moveaxis2,cv_lookaxis2,cv_jumpaxis2,cv_spinaxis2,cv_shieldaxis2,cv_fireaxis2,cv_firenaxis2,cv_deadzone2,cv_digitaldeadzone2; extern consvar_t cv_sideaxis2,cv_turnaxis2,cv_moveaxis2,cv_lookaxis2,cv_jumpaxis2,cv_spinaxis2,cv_fireaxis2,cv_firenaxis2,cv_deadzone2,cv_digitaldeadzone2;
extern consvar_t cv_ghost_bestscore, cv_ghost_besttime, cv_ghost_bestrings, cv_ghost_last, cv_ghost_guest; extern consvar_t cv_ghost_bestscore, cv_ghost_besttime, cv_ghost_bestrings, cv_ghost_last, cv_ghost_guest;
// hi here's some new controls // hi here's some new controls
...@@ -100,7 +100,6 @@ typedef enum ...@@ -100,7 +100,6 @@ typedef enum
JA_JUMP = JA_DIGITAL, JA_JUMP = JA_DIGITAL,
JA_SPIN, JA_SPIN,
JA_SHIELD,
JA_FIRE, JA_FIRE,
JA_FIRENORMAL, JA_FIRENORMAL,
} joyaxis_e; } joyaxis_e;
......
// 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.
...@@ -576,7 +576,9 @@ static const char *gamecontrolname[NUM_GAMECONTROLS] = ...@@ -576,7 +576,9 @@ static const char *gamecontrolname[NUM_GAMECONTROLS] =
"weapon5", "weapon5",
"weapon6", "weapon6",
"weapon7", "weapon7",
"shield", "weapon8",
"weapon9",
"weapon10",
"fire", "fire",
"firenormal", "firenormal",
"tossflag", "tossflag",
...@@ -691,7 +693,6 @@ void G_DefineDefaultControls(void) ...@@ -691,7 +693,6 @@ void G_DefineDefaultControls(void)
gamecontroldefault[gcs_fps][GC_CENTERVIEW ][0] = KEY_LCTRL; gamecontroldefault[gcs_fps][GC_CENTERVIEW ][0] = KEY_LCTRL;
gamecontroldefault[gcs_fps][GC_JUMP ][0] = KEY_SPACE; gamecontroldefault[gcs_fps][GC_JUMP ][0] = KEY_SPACE;
gamecontroldefault[gcs_fps][GC_SPIN ][0] = KEY_LSHIFT; gamecontroldefault[gcs_fps][GC_SPIN ][0] = KEY_LSHIFT;
gamecontroldefault[gcs_fps][GC_SHIELD ][0] = KEY_LALT;
gamecontroldefault[gcs_fps][GC_FIRE ][0] = KEY_RCTRL; gamecontroldefault[gcs_fps][GC_FIRE ][0] = KEY_RCTRL;
gamecontroldefault[gcs_fps][GC_FIRE ][1] = KEY_MOUSE1+0; gamecontroldefault[gcs_fps][GC_FIRE ][1] = KEY_MOUSE1+0;
gamecontroldefault[gcs_fps][GC_FIRENORMAL ][0] = KEY_RALT; gamecontroldefault[gcs_fps][GC_FIRENORMAL ][0] = KEY_RALT;
...@@ -712,7 +713,6 @@ void G_DefineDefaultControls(void) ...@@ -712,7 +713,6 @@ void G_DefineDefaultControls(void)
gamecontroldefault[gcs_platform][GC_CENTERVIEW ][0] = KEY_END; gamecontroldefault[gcs_platform][GC_CENTERVIEW ][0] = KEY_END;
gamecontroldefault[gcs_platform][GC_JUMP ][0] = KEY_SPACE; gamecontroldefault[gcs_platform][GC_JUMP ][0] = KEY_SPACE;
gamecontroldefault[gcs_platform][GC_SPIN ][0] = KEY_LSHIFT; gamecontroldefault[gcs_platform][GC_SPIN ][0] = KEY_LSHIFT;
gamecontroldefault[gcs_platform][GC_SHIELD ][0] = KEY_LALT;
gamecontroldefault[gcs_platform][GC_FIRE ][0] = 's'; gamecontroldefault[gcs_platform][GC_FIRE ][0] = 's';
gamecontroldefault[gcs_platform][GC_FIRE ][1] = KEY_MOUSE1+0; gamecontroldefault[gcs_platform][GC_FIRE ][1] = KEY_MOUSE1+0;
gamecontroldefault[gcs_platform][GC_FIRENORMAL ][0] = 'w'; gamecontroldefault[gcs_platform][GC_FIRENORMAL ][0] = 'w';
...@@ -728,6 +728,9 @@ void G_DefineDefaultControls(void) ...@@ -728,6 +728,9 @@ void G_DefineDefaultControls(void)
gamecontroldefault[i][GC_WEPSLOT5 ][0] = '5'; gamecontroldefault[i][GC_WEPSLOT5 ][0] = '5';
gamecontroldefault[i][GC_WEPSLOT6 ][0] = '6'; gamecontroldefault[i][GC_WEPSLOT6 ][0] = '6';
gamecontroldefault[i][GC_WEPSLOT7 ][0] = '7'; gamecontroldefault[i][GC_WEPSLOT7 ][0] = '7';
gamecontroldefault[i][GC_WEPSLOT8 ][0] = '8';
gamecontroldefault[i][GC_WEPSLOT9 ][0] = '9';
gamecontroldefault[i][GC_WEPSLOT10 ][0] = '0';
gamecontroldefault[i][GC_TOSSFLAG ][0] = '\''; gamecontroldefault[i][GC_TOSSFLAG ][0] = '\'';
gamecontroldefault[i][GC_CAMTOGGLE ][0] = 'v'; gamecontroldefault[i][GC_CAMTOGGLE ][0] = 'v';
gamecontroldefault[i][GC_CAMRESET ][0] = 'r'; gamecontroldefault[i][GC_CAMRESET ][0] = 'r';
...@@ -743,34 +746,34 @@ void G_DefineDefaultControls(void) ...@@ -743,34 +746,34 @@ void G_DefineDefaultControls(void)
// Gamepad controls -- same for both schemes // Gamepad controls -- same for both schemes
gamecontroldefault[i][GC_JUMP ][1] = KEY_JOY1+0; // A gamecontroldefault[i][GC_JUMP ][1] = KEY_JOY1+0; // A
gamecontroldefault[i][GC_SPIN ][1] = KEY_JOY1+2; // X gamecontroldefault[i][GC_SPIN ][1] = KEY_JOY1+2; // X
gamecontroldefault[i][GC_SHIELD ][1] = KEY_JOY1+1; // B gamecontroldefault[i][GC_CUSTOM1 ][1] = KEY_JOY1+1; // B
gamecontroldefault[i][GC_CUSTOM1 ][1] = KEY_JOY1+3; // Y gamecontroldefault[i][GC_CUSTOM2 ][1] = KEY_JOY1+3; // Y
gamecontroldefault[i][GC_CUSTOM2 ][1] = KEY_JOY1+4; // LB
gamecontroldefault[i][GC_CENTERVIEW ][1] = KEY_JOY1+5; // RB
gamecontroldefault[i][GC_CUSTOM3 ][1] = KEY_JOY1+8; // Left Stick gamecontroldefault[i][GC_CUSTOM3 ][1] = KEY_JOY1+8; // Left Stick
gamecontroldefault[i][GC_CAMTOGGLE ][1] = KEY_JOY1+9; // Right Stick gamecontroldefault[i][GC_CAMTOGGLE ][1] = KEY_JOY1+4; // LB
gamecontroldefault[i][GC_SCORES ][1] = KEY_JOY1+6; // Back gamecontroldefault[i][GC_CENTERVIEW ][1] = KEY_JOY1+5; // RB
gamecontroldefault[i][GC_SCREENSHOT ][1] = KEY_JOY1+6; // Back
gamecontroldefault[i][GC_SYSTEMMENU ][0] = KEY_JOY1+7; // Start gamecontroldefault[i][GC_SYSTEMMENU ][0] = KEY_JOY1+7; // Start
gamecontroldefault[i][GC_VIEWPOINTNEXT][1] = KEY_HAT1+0; // D-Pad Up
gamecontroldefault[i][GC_TOSSFLAG ][1] = KEY_HAT1+1; // D-Pad Down
gamecontroldefault[i][GC_WEAPONPREV ][1] = KEY_HAT1+2; // D-Pad Left gamecontroldefault[i][GC_WEAPONPREV ][1] = KEY_HAT1+2; // D-Pad Left
gamecontroldefault[i][GC_WEAPONNEXT ][1] = KEY_HAT1+3; // D-Pad Right gamecontroldefault[i][GC_WEAPONNEXT ][1] = KEY_HAT1+3; // D-Pad Right
gamecontroldefault[i][GC_VIEWPOINTNEXT][1] = KEY_JOY1+9; // Right Stick
gamecontroldefault[i][GC_TOSSFLAG ][1] = KEY_HAT1+0; // D-Pad Up
gamecontroldefault[i][GC_SCORES ][1] = KEY_HAT1+1; // D-Pad Down
// Second player controls only have joypad defaults // Second player controls only have joypad defaults
gamecontrolbisdefault[i][GC_JUMP ][1] = KEY_2JOY1+0; // A gamecontrolbisdefault[i][GC_JUMP ][1] = KEY_2JOY1+0; // A
gamecontrolbisdefault[i][GC_SPIN ][1] = KEY_2JOY1+2; // X gamecontrolbisdefault[i][GC_SPIN ][1] = KEY_2JOY1+2; // X
gamecontrolbisdefault[i][GC_SHIELD ][1] = KEY_2JOY1+1; // B gamecontrolbisdefault[i][GC_CUSTOM1 ][1] = KEY_2JOY1+1; // B
gamecontrolbisdefault[i][GC_CUSTOM1 ][1] = KEY_2JOY1+3; // Y gamecontrolbisdefault[i][GC_CUSTOM2 ][1] = KEY_2JOY1+3; // Y
gamecontrolbisdefault[i][GC_CUSTOM2 ][1] = KEY_2JOY1+4; // LB
gamecontrolbisdefault[i][GC_CENTERVIEW ][1] = KEY_2JOY1+5; // RB
gamecontrolbisdefault[i][GC_CUSTOM3 ][1] = KEY_2JOY1+8; // Left Stick gamecontrolbisdefault[i][GC_CUSTOM3 ][1] = KEY_2JOY1+8; // Left Stick
gamecontrolbisdefault[i][GC_CAMTOGGLE ][1] = KEY_2JOY1+9; // Right Stick gamecontrolbisdefault[i][GC_CAMTOGGLE ][1] = KEY_2JOY1+4; // LB
//gamecontrolbisdefault[i][GC_SCORES ][1] = KEY_2JOY1+6; // Back gamecontrolbisdefault[i][GC_CENTERVIEW ][1] = KEY_2JOY1+5; // RB
gamecontrolbisdefault[i][GC_SCREENSHOT ][1] = KEY_2JOY1+6; // Back
//gamecontrolbisdefault[i][GC_SYSTEMMENU ][0] = KEY_2JOY1+7; // Start //gamecontrolbisdefault[i][GC_SYSTEMMENU ][0] = KEY_2JOY1+7; // Start
gamecontrolbisdefault[i][GC_VIEWPOINTNEXT][1] = KEY_2HAT1+0; // D-Pad Up
gamecontrolbisdefault[i][GC_TOSSFLAG ][1] = KEY_2HAT1+1; // D-Pad Down
gamecontrolbisdefault[i][GC_WEAPONPREV ][1] = KEY_2HAT1+2; // D-Pad Left gamecontrolbisdefault[i][GC_WEAPONPREV ][1] = KEY_2HAT1+2; // D-Pad Left
gamecontrolbisdefault[i][GC_WEAPONNEXT ][1] = KEY_2HAT1+3; // D-Pad Right gamecontrolbisdefault[i][GC_WEAPONNEXT ][1] = KEY_2HAT1+3; // D-Pad Right
gamecontrolbisdefault[i][GC_VIEWPOINTNEXT][1] = KEY_2JOY1+9; // Right Stick
gamecontrolbisdefault[i][GC_TOSSFLAG ][1] = KEY_2HAT1+0; // D-Pad Up
//gamecontrolbisdefault[i][GC_SCORES ][1] = KEY_2HAT1+1; // D-Pad Down
} }
} }
......
...@@ -74,7 +74,9 @@ typedef enum ...@@ -74,7 +74,9 @@ typedef enum
GC_WEPSLOT5, GC_WEPSLOT5,
GC_WEPSLOT6, GC_WEPSLOT6,
GC_WEPSLOT7, GC_WEPSLOT7,
GC_SHIELD, GC_WEPSLOT8,
GC_WEPSLOT9,
GC_WEPSLOT10,
GC_FIRE, GC_FIRE,
GC_FIRENORMAL, GC_FIRENORMAL,
GC_TOSSFLAG, GC_TOSSFLAG,
......
// SONIC ROBO BLAST 2 // SONIC ROBO BLAST 2
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Copyright (C) 2020-2023 by Sonic Team Junior. // Copyright (C) 2020-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.
...@@ -114,7 +114,7 @@ void HWR_ProcessPolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPt ...@@ -114,7 +114,7 @@ void HWR_ProcessPolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPt
polygonArray[polygonArraySize].numVerts = iNumPts; polygonArray[polygonArraySize].numVerts = iNumPts;
polygonArray[polygonArraySize].polyFlags = PolyFlags; polygonArray[polygonArraySize].polyFlags = PolyFlags;
polygonArray[polygonArraySize].texture = current_texture; polygonArray[polygonArraySize].texture = current_texture;
polygonArray[polygonArraySize].shader = (shader_target != -1) ? HWR_GetShaderFromTarget(shader_target) : shader_target; polygonArray[polygonArraySize].shader = (shader_target != SHADER_NONE) ? HWR_GetShaderFromTarget(shader_target) : shader_target;
polygonArray[polygonArraySize].horizonSpecial = horizonSpecial; polygonArray[polygonArraySize].horizonSpecial = horizonSpecial;
// default to polygonArraySize so we don't lose order on horizon lines // default to polygonArraySize so we don't lose order on horizon lines
// (yes, it's supposed to be negative, since we're sorting in that direction) // (yes, it's supposed to be negative, since we're sorting in that direction)
...@@ -311,7 +311,6 @@ void HWR_RenderBatches(void) ...@@ -311,7 +311,6 @@ void HWR_RenderBatches(void)
int nextIndex = polygonIndexArray[polygonReadPos]; int nextIndex = polygonIndexArray[polygonReadPos];
if (polygonArray[index].hash != polygonArray[nextIndex].hash) if (polygonArray[index].hash != polygonArray[nextIndex].hash)
{ {
changeState = true;
nextShader = polygonArray[nextIndex].shader; nextShader = polygonArray[nextIndex].shader;
nextTexture = polygonArray[nextIndex].texture; nextTexture = polygonArray[nextIndex].texture;
nextPolyFlags = polygonArray[nextIndex].polyFlags; nextPolyFlags = polygonArray[nextIndex].polyFlags;
...@@ -320,14 +319,17 @@ void HWR_RenderBatches(void) ...@@ -320,14 +319,17 @@ void HWR_RenderBatches(void)
nextTexture = 0; nextTexture = 0;
if (currentShader != nextShader && cv_glshaders.value && gl_shadersavailable) if (currentShader != nextShader && cv_glshaders.value && gl_shadersavailable)
{ {
changeState = true;
changeShader = true; changeShader = true;
} }
if (currentTexture != nextTexture) if (currentTexture != nextTexture)
{ {
changeState = true;
changeTexture = true; changeTexture = true;
} }
if (currentPolyFlags != nextPolyFlags) if (currentPolyFlags != nextPolyFlags)
{ {
changeState = true;
changePolyFlags = true; changePolyFlags = true;
} }
if (cv_glshaders.value && gl_shadersavailable) if (cv_glshaders.value && gl_shadersavailable)
...@@ -339,6 +341,7 @@ void HWR_RenderBatches(void) ...@@ -339,6 +341,7 @@ void HWR_RenderBatches(void)
currentSurfaceInfo.LightInfo.fade_start != nextSurfaceInfo.LightInfo.fade_start || currentSurfaceInfo.LightInfo.fade_start != nextSurfaceInfo.LightInfo.fade_start ||
currentSurfaceInfo.LightInfo.fade_end != nextSurfaceInfo.LightInfo.fade_end) currentSurfaceInfo.LightInfo.fade_end != nextSurfaceInfo.LightInfo.fade_end)
{ {
changeState = true;
changeSurfaceInfo = true; changeSurfaceInfo = true;
} }
} }
...@@ -346,6 +349,7 @@ void HWR_RenderBatches(void) ...@@ -346,6 +349,7 @@ void HWR_RenderBatches(void)
{ {
if (currentSurfaceInfo.PolyColor.rgba != nextSurfaceInfo.PolyColor.rgba) if (currentSurfaceInfo.PolyColor.rgba != nextSurfaceInfo.PolyColor.rgba)
{ {
changeState = true;
changeSurfaceInfo = true; changeSurfaceInfo = true;
} }
} }
......
// SONIC ROBO BLAST 2 // SONIC ROBO BLAST 2
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Copyright (C) 2020-2023 by Sonic Team Junior. // Copyright (C) 2020-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.
......
...@@ -450,15 +450,10 @@ static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *grtex, GLMipmap_t ...@@ -450,15 +450,10 @@ static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *grtex, GLMipmap_t
texture = textures[texnum]; texture = textures[texnum];
mipmap->flags = TF_WRAPXY;
mipmap->width = (UINT16)texture->width;
mipmap->height = (UINT16)texture->height;
mipmap->format = textureformat;
blockwidth = texture->width; blockwidth = texture->width;
blockheight = texture->height; blockheight = texture->height;
blocksize = (blockwidth * blockheight); blocksize = blockwidth * blockheight;
block = MakeBlock(&grtex->mipmap); block = MakeBlock(mipmap);
// Composite the columns together. // Composite the columns together.
for (i = 0, patch = texture->patches; i < texture->patchcount; i++, patch++) for (i = 0, patch = texture->patches; i < texture->patchcount; i++, patch++)
...@@ -488,7 +483,7 @@ static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *grtex, GLMipmap_t ...@@ -488,7 +483,7 @@ static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *grtex, GLMipmap_t
realpatch = W_CachePatchNumPwad(wadnum, lumpnum, PU_PATCH); realpatch = W_CachePatchNumPwad(wadnum, lumpnum, PU_PATCH);
} }
HWR_DrawTexturePatchInCache(&grtex->mipmap, blockwidth, blockheight, texture, patch, realpatch); HWR_DrawTexturePatchInCache(mipmap, blockwidth, blockheight, texture, patch, realpatch);
if (free_patch) if (free_patch)
Patch_Free(realpatch); Patch_Free(realpatch);
...@@ -680,25 +675,24 @@ void HWR_InitMapTextures(void) ...@@ -680,25 +675,24 @@ void HWR_InitMapTextures(void)
gl_maptexturesloaded = false; gl_maptexturesloaded = false;
} }
static void DeleteTextureMipmap(GLMipmap_t *grMipmap) static void DeleteTextureMipmap(GLMipmap_t *grMipmap, boolean delete_mipmap)
{ {
HWD.pfnDeleteTexture(grMipmap); HWD.pfnDeleteTexture(grMipmap);
// Chroma-keyed textures do not own their texture data, so do not free it if (delete_mipmap)
if (!(grMipmap->flags & TF_CHROMAKEYED))
Z_Free(grMipmap->data); Z_Free(grMipmap->data);
} }
static void FreeMapTexture(GLMapTexture_t *tex) static void FreeMapTexture(GLMapTexture_t *tex, boolean delete_chromakeys)
{ {
if (tex->mipmap.nextcolormap) if (tex->mipmap.nextcolormap)
{ {
DeleteTextureMipmap(tex->mipmap.nextcolormap); DeleteTextureMipmap(tex->mipmap.nextcolormap, delete_chromakeys);
free(tex->mipmap.nextcolormap); free(tex->mipmap.nextcolormap);
tex->mipmap.nextcolormap = NULL; tex->mipmap.nextcolormap = NULL;
} }
DeleteTextureMipmap(&tex->mipmap); DeleteTextureMipmap(&tex->mipmap, true);
} }
void HWR_FreeMapTextures(void) void HWR_FreeMapTextures(void)
...@@ -707,8 +701,8 @@ void HWR_FreeMapTextures(void) ...@@ -707,8 +701,8 @@ void HWR_FreeMapTextures(void)
for (i = 0; i < gl_numtextures; i++) for (i = 0; i < gl_numtextures; i++)
{ {
FreeMapTexture(&gl_textures[i]); FreeMapTexture(&gl_textures[i], true);
FreeMapTexture(&gl_flats[i]); FreeMapTexture(&gl_flats[i], false);
} }
// now the heap don't have any 'user' pointing to our // now the heap don't have any 'user' pointing to our
...@@ -741,22 +735,7 @@ void HWR_LoadMapTextures(size_t pnumtextures) ...@@ -741,22 +735,7 @@ void HWR_LoadMapTextures(size_t pnumtextures)
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// Make sure texture is downloaded and set it as the source // Make sure texture is downloaded and set it as the source
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
static void GetMapTexture(INT32 tex, GLMapTexture_t *grtex, GLMipmap_t *mipmap) GLMapTexture_t *HWR_GetTexture(INT32 tex, boolean chromakeyed)
{
// Generate texture if missing from the cache
if (!mipmap->data && !mipmap->downloaded)
HWR_GenerateTexture(tex, grtex, mipmap);
// If hardware does not have the texture, then call pfnSetTexture to upload it
if (!mipmap->downloaded)
HWD.pfnSetTexture(mipmap);
HWR_SetCurrentTexture(mipmap);
// The system-memory data can be purged now.
Z_ChangeTag(mipmap->data, PU_HWRCACHE_UNLOCKED);
}
GLMapTexture_t *HWR_GetTexture(INT32 tex)
{ {
if (tex < 0 || tex >= (signed)gl_numtextures) if (tex < 0 || tex >= (signed)gl_numtextures)
{ {
...@@ -769,7 +748,46 @@ GLMapTexture_t *HWR_GetTexture(INT32 tex) ...@@ -769,7 +748,46 @@ GLMapTexture_t *HWR_GetTexture(INT32 tex)
GLMapTexture_t *grtex = &gl_textures[tex]; GLMapTexture_t *grtex = &gl_textures[tex];
GetMapTexture(tex, grtex, &grtex->mipmap); GLMipmap_t *grMipmap = &grtex->mipmap;
GLMipmap_t *originalMipmap = grMipmap;
if (!originalMipmap->downloaded)
{
originalMipmap->flags = TF_WRAPXY;
originalMipmap->width = (UINT16)textures[tex]->width;
originalMipmap->height = (UINT16)textures[tex]->height;
originalMipmap->format = textureformat;
}
// If chroma-keyed, create or use a different mipmap for the variant
if (chromakeyed && !textures[tex]->transparency)
{
// Allocate it if it wasn't already
if (!originalMipmap->nextcolormap)
{
GLMipmap_t *newMipmap = calloc(1, sizeof (*grMipmap));
if (newMipmap == NULL)
I_Error("%s: Out of memory", "HWR_GetTexture");
newMipmap->flags = originalMipmap->flags | TF_CHROMAKEYED;
newMipmap->width = originalMipmap->width;
newMipmap->height = originalMipmap->height;
newMipmap->format = originalMipmap->format;
originalMipmap->nextcolormap = newMipmap;
}
// Generate, upload and bind the variant texture instead of the original one
grMipmap = originalMipmap->nextcolormap;
}
if (!grMipmap->data)
HWR_GenerateTexture(tex, grtex, grMipmap);
if (!grMipmap->downloaded)
HWD.pfnSetTexture(grMipmap);
HWR_SetCurrentTexture(grMipmap);
Z_ChangeTag(grMipmap->data, PU_HWRCACHE_UNLOCKED);
return grtex; return grtex;
} }
...@@ -1240,20 +1258,29 @@ void HWR_SetMapPalette(void) ...@@ -1240,20 +1258,29 @@ void HWR_SetMapPalette(void)
// Creates a hardware lighttable from the supplied lighttable. // Creates a hardware lighttable from the supplied lighttable.
// Returns the id of the hw lighttable, usable in FSurfaceInfo. // Returns the id of the hw lighttable, usable in FSurfaceInfo.
UINT32 HWR_CreateLightTable(UINT8 *lighttable) UINT32 HWR_CreateLightTable(UINT8 *lighttable, RGBA_t *hw_lighttable)
{ {
UINT32 i, id; UINT32 i;
RGBA_t *palette = HWR_GetTexturePalette(); RGBA_t *palette = HWR_GetTexturePalette();
RGBA_t *hw_lighttable = Z_Malloc(256 * 32 * sizeof(RGBA_t), PU_STATIC, NULL);
// To make the palette index -> RGBA mapping easier for the shader, // To make the palette index -> RGBA mapping easier for the shader,
// the hardware lighttable is composed of RGBA colors instead of palette indices. // the hardware lighttable is composed of RGBA colors instead of palette indices.
for (i = 0; i < 256 * 32; i++) for (i = 0; i < 256 * 32; i++)
hw_lighttable[i] = palette[lighttable[i]]; hw_lighttable[i] = palette[lighttable[i]];
id = HWD.pfnCreateLightTable(hw_lighttable); return HWD.pfnCreateLightTable(hw_lighttable);
Z_Free(hw_lighttable); }
return id;
// Updates a hardware lighttable of a given id from the supplied lighttable.
void HWR_UpdateLightTable(UINT32 id, UINT8 *lighttable, RGBA_t *hw_lighttable)
{
UINT32 i;
RGBA_t *palette = HWR_GetTexturePalette();
for (i = 0; i < 256 * 32; i++)
hw_lighttable[i] = palette[lighttable[i]];
HWD.pfnUpdateLightTable(id, hw_lighttable);
} }
// get hwr lighttable id for colormap, create it if it doesn't already exist // get hwr lighttable id for colormap, create it if it doesn't already exist
...@@ -1267,25 +1294,41 @@ UINT32 HWR_GetLightTableID(extracolormap_t *colormap) ...@@ -1267,25 +1294,41 @@ UINT32 HWR_GetLightTableID(extracolormap_t *colormap)
default_colormap = true; default_colormap = true;
} }
UINT8 *colormap_pointer;
if (default_colormap)
colormap_pointer = colormaps; // don't actually use the data from the "default colormap"
else
colormap_pointer = colormap->colormap;
// create hw lighttable if there isn't one // create hw lighttable if there isn't one
if (!colormap->gl_lighttable_id) if (colormap->gl_lighttable.data == NULL)
{ {
UINT8 *colormap_pointer; Z_Malloc(256 * 32 * sizeof(RGBA_t), PU_HWRLIGHTTABLEDATA, &colormap->gl_lighttable.data);
}
if (default_colormap) // Generate the texture for this light table
colormap_pointer = colormaps; // don't actually use the data from the "default colormap" if (!colormap->gl_lighttable.id)
else {
colormap_pointer = colormap->colormap; colormap->gl_lighttable.id = HWR_CreateLightTable(colormap_pointer, colormap->gl_lighttable.data);
colormap->gl_lighttable_id = HWR_CreateLightTable(colormap_pointer); }
// Update the texture if it was directly changed by a script
else if (colormap->gl_lighttable.needs_update)
{
HWR_UpdateLightTable(colormap->gl_lighttable.id, colormap_pointer, colormap->gl_lighttable.data);
} }
return colormap->gl_lighttable_id; colormap->gl_lighttable.needs_update = false;
return colormap->gl_lighttable.id;
} }
// Note: all hardware lighttable ids assigned before this // Note: all hardware lighttable ids assigned before this
// call become invalid and must not be used. // call become invalid and must not be used.
void HWR_ClearLightTables(void) void HWR_ClearLightTables(void)
{ {
Z_FreeTag(PU_HWRLIGHTTABLEDATA);
if (vid.glstate == VID_GL_LIBRARY_LOADED) if (vid.glstate == VID_GL_LIBRARY_LOADED)
HWD.pfnClearLightTables(); HWD.pfnClearLightTables();
} }
......
// 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.
......
// 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.
...@@ -256,8 +256,8 @@ void HWR_DrawStretchyFixedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t p ...@@ -256,8 +256,8 @@ void HWR_DrawStretchyFixedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t p
} }
// positions of the cx, cy, are between 0 and vid.width/vid.height now, we need them to be between -1 and 1 // positions of the cx, cy, are between 0 and vid.width/vid.height now, we need them to be between -1 and 1
cx = -1 + (cx / (vid.width/2)); cx = -1.0f + (cx / (vid.width / 2.0f));
cy = 1 - (cy / (vid.height/2)); cy = 1.0f - (cy / (vid.height / 2.0f));
// fwidth and fheight are similar // fwidth and fheight are similar
fwidth /= vid.width / 2; fwidth /= vid.width / 2;
...@@ -598,43 +598,76 @@ void HWR_DrawCroppedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, ...@@ -598,43 +598,76 @@ void HWR_DrawCroppedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale,
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// Fills a box of pixels using a flat texture as a pattern // Fills a box of pixels using a flat texture as a pattern
// Fixed to properly align like the other draw functions -luigi budd
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
void HWR_DrawFlatFill (INT32 x, INT32 y, INT32 w, INT32 h, lumpnum_t flatlumpnum) void HWR_DrawFlatFill(INT32 x, INT32 y, INT32 w, INT32 h, lumpnum_t flatlumpnum)
{ {
FOutVector v[4]; FOutVector v[4];
const size_t len = W_LumpLength(flatlumpnum); const size_t len = W_LumpLength(flatlumpnum);
UINT16 flatflag = R_GetFlatSize(len) - 1; UINT16 flatflag = R_GetFlatSize(len);
double dflatsize = (double)(flatflag + 1); double dflatsize = (double)(flatflag);
// compilers are COOL!
float dup = (float)vid.dup;
float fx = (float)x * dup;
float fy = (float)y * dup;
float fw = (float)w * dup;
float fh = (float)h * dup;
/*
fx *= dup;
fy *= dup;
fw *= dup;
fh *= dup;
*/
if (fw <= 0 || fh <= 0)
return;
if (fabsf((float)vid.width - (float)BASEVIDWIDTH * vid.dup) > 1.0E-36f)
{
fx += ((float)vid.width - ((float)BASEVIDWIDTH * vid.dup)) / 2;
}
if (fabsf((float)vid.height - (float)BASEVIDHEIGHT * vid.dup) > 1.0E-36f)
{
fy += ((float)vid.height - ((float)BASEVIDHEIGHT * vid.dup)) / 2;
}
if (fx >= vid.width || fy >= vid.height)
return;
fx = -1.0f + (fx / (vid.width / 2.0f));
fy = 1.0f - (fy / (vid.height / 2.0f));
fw /= vid.width / 2;
fh /= vid.height / 2;
// 3--2 // 3--2
// | /| // | /|
// |/ | // |/ |
// 0--1 // 0--1
// position vertices
v[0].x = v[3].x = fx;
v[2].x = v[1].x = fx + fw;
v[0].x = v[3].x = (x - 160.0f)/160.0f; v[0].y = v[1].y = fy;
v[2].x = v[1].x = ((x+w) - 160.0f)/160.0f; v[2].y = v[3].y = fy - fh;
v[0].y = v[1].y = -(y - 100.0f)/100.0f;
v[2].y = v[3].y = -((y+h) - 100.0f)/100.0f;
v[0].z = v[1].z = v[2].z = v[3].z = 1.0f; v[0].z = v[1].z = v[2].z = v[3].z = 1.0f;
v[0].s = v[3].s = (float)((x & flatflag)/dflatsize); // sides
v[2].s = v[1].s = (float)(v[0].s + w/dflatsize); v[0].s = v[3].s = (float)(flatflag/dflatsize) * 2;
v[0].t = v[1].t = (float)((y & flatflag)/dflatsize); v[2].s = v[1].s = (float)(v[0].s + w/dflatsize) * 2;
v[2].t = v[3].t = (float)(v[0].t + h/dflatsize);
HWR_GetRawFlat(flatlumpnum); // top/bottom
v[0].t = v[1].t = (float)(flatflag/dflatsize) * 2;
v[2].t = v[3].t = (float)(v[0].t + h/dflatsize) * 2;
//Hurdler: Boris, the same comment as above... but maybe for pics // needed to texture the poly
// it not a problem since they don't have any transparent pixel HWR_GetRawFlat(flatlumpnum);
// if I'm right !?
// BTW, I see we put 0 for PFs, and If I'm right, that
// means we take the previous PFs as default
// how can we be sure they are ok?
HWD.pfnDrawPolygon(NULL, v, 4, PF_NoDepthTest); //PF_Translucent); HWD.pfnDrawPolygon(NULL, v, 4, PF_NoDepthTest); //PF_Translucent);
} }
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// Fade down the screen so that the menu drawn on top of it looks brighter // Fade down the screen so that the menu drawn on top of it looks brighter
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
......
// 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.
...@@ -71,6 +71,7 @@ EXPORT void HWRAPI(SetShaderInfo) (hwdshaderinfo_t info, INT32 value); ...@@ -71,6 +71,7 @@ EXPORT void HWRAPI(SetShaderInfo) (hwdshaderinfo_t info, INT32 value);
EXPORT void HWRAPI(SetPaletteLookup)(UINT8 *lut); EXPORT void HWRAPI(SetPaletteLookup)(UINT8 *lut);
EXPORT UINT32 HWRAPI(CreateLightTable)(RGBA_t *hw_lighttable); EXPORT UINT32 HWRAPI(CreateLightTable)(RGBA_t *hw_lighttable);
EXPORT void HWRAPI(UpdateLightTable)(UINT32 id, RGBA_t *hw_lighttable);
EXPORT void HWRAPI(ClearLightTables)(void); EXPORT void HWRAPI(ClearLightTables)(void);
EXPORT void HWRAPI(SetScreenPalette)(RGBA_t *palette); EXPORT void HWRAPI(SetScreenPalette)(RGBA_t *palette);
...@@ -125,6 +126,7 @@ struct hwdriver_s ...@@ -125,6 +126,7 @@ struct hwdriver_s
SetPaletteLookup pfnSetPaletteLookup; SetPaletteLookup pfnSetPaletteLookup;
CreateLightTable pfnCreateLightTable; CreateLightTable pfnCreateLightTable;
UpdateLightTable pfnUpdateLightTable;
ClearLightTables pfnClearLightTables; ClearLightTables pfnClearLightTables;
SetScreenPalette pfnSetScreenPalette; SetScreenPalette pfnSetScreenPalette;
}; };
......
// 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.
...@@ -120,7 +120,7 @@ void HWR_GetPatch(patch_t *patch); ...@@ -120,7 +120,7 @@ void HWR_GetPatch(patch_t *patch);
void HWR_GetMappedPatch(patch_t *patch, const UINT8 *colormap); void HWR_GetMappedPatch(patch_t *patch, const UINT8 *colormap);
void HWR_GetFadeMask(lumpnum_t fademasklumpnum); void HWR_GetFadeMask(lumpnum_t fademasklumpnum);
GLMapTexture_t *HWR_GetTexture(INT32 tex); GLMapTexture_t *HWR_GetTexture(INT32 tex, boolean chromakeyed);
void HWR_GetLevelFlat(levelflat_t *levelflat, boolean chromakeyed); void HWR_GetLevelFlat(levelflat_t *levelflat, boolean chromakeyed);
void HWR_GetRawFlat(lumpnum_t flatlumpnum); void HWR_GetRawFlat(lumpnum_t flatlumpnum);
...@@ -133,7 +133,8 @@ void HWR_UnlockCachedPatch(GLPatch_t *gpatch); ...@@ -133,7 +133,8 @@ void HWR_UnlockCachedPatch(GLPatch_t *gpatch);
void HWR_SetPalette(RGBA_t *palette); void HWR_SetPalette(RGBA_t *palette);
void HWR_SetMapPalette(void); void HWR_SetMapPalette(void);
UINT32 HWR_CreateLightTable(UINT8 *lighttable); UINT32 HWR_CreateLightTable(UINT8 *lighttable, RGBA_t *hw_lighttable);
void HWR_UpdateLightTable(UINT32 id, UINT8 *lighttable, RGBA_t *hw_lighttable);
UINT32 HWR_GetLightTableID(extracolormap_t *colormap); UINT32 HWR_GetLightTableID(extracolormap_t *colormap);
void HWR_ClearLightTables(void); void HWR_ClearLightTables(void);
......