mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2024-11-15 09:11:48 +00:00
Merge branch '2122-version' into 'next'
Update code versions to 2.1.22 See merge request STJr/SRB2!402
This commit is contained in:
commit
26f956acea
43 changed files with 3399 additions and 375 deletions
|
@ -1,6 +1,6 @@
|
||||||
cmake_minimum_required(VERSION 3.0)
|
cmake_minimum_required(VERSION 3.0)
|
||||||
project(SRB2
|
project(SRB2
|
||||||
VERSION 2.1.21
|
VERSION 2.1.22
|
||||||
LANGUAGES C)
|
LANGUAGES C)
|
||||||
|
|
||||||
if(${PROJECT_SOURCE_DIR} MATCHES ${PROJECT_BINARY_DIR})
|
if(${PROJECT_SOURCE_DIR} MATCHES ${PROJECT_BINARY_DIR})
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
version: 2.1.21.{branch}-{build}
|
version: 2.1.22.{branch}-{build}
|
||||||
os: MinGW
|
os: MinGW
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
|
|
4
debian/changelog
vendored
4
debian/changelog
vendored
|
@ -1,6 +1,6 @@
|
||||||
srb2 (2.1.21~9) trusty; urgency=high
|
srb2 (2.1.22~9) trusty; urgency=high
|
||||||
|
|
||||||
* SRB2 v2.1.21 release
|
* SRB2 v2.1.22 release
|
||||||
|
|
||||||
-- Marco Zafra <marco.a.zafra@gmail.com> Mon, 27 Nov 2018 16:45:00 -0500
|
-- Marco Zafra <marco.a.zafra@gmail.com> Mon, 27 Nov 2018 16:45:00 -0500
|
||||||
|
|
||||||
|
|
4
debian/control
vendored
4
debian/control
vendored
|
@ -18,7 +18,7 @@ Homepage: http://www.srb2.org
|
||||||
|
|
||||||
Package: srb2
|
Package: srb2
|
||||||
Architecture: any
|
Architecture: any
|
||||||
Depends: ${shlibs:Depends}, ${misc:Depends}, srb2-data (>= 2.1.15), srb2-data (<= 2.1.21)
|
Depends: ${shlibs:Depends}, ${misc:Depends}, srb2-data (>= 2.1.15), srb2-data (<= 2.1.22)
|
||||||
Description: A cross-platform 3D Sonic fangame
|
Description: A cross-platform 3D Sonic fangame
|
||||||
Sonic Robo Blast 2 is a 3D open-source Sonic the Hedgehog
|
Sonic Robo Blast 2 is a 3D open-source Sonic the Hedgehog
|
||||||
fangame built using a modified version of the Doom Legacy
|
fangame built using a modified version of the Doom Legacy
|
||||||
|
@ -31,7 +31,7 @@ Description: A cross-platform 3D Sonic fangame
|
||||||
Package: srb2-dbg
|
Package: srb2-dbg
|
||||||
Architecture: any
|
Architecture: any
|
||||||
# FIXME: should be Depends: ${shlibs:Depends}, ${misc:Depends}, srb2-data (= 2.1.14), srb2 but dh_shlibdeps is being an asshat
|
# FIXME: should be Depends: ${shlibs:Depends}, ${misc:Depends}, srb2-data (= 2.1.14), srb2 but dh_shlibdeps is being an asshat
|
||||||
Depends: libc6, ${misc:Depends}, srb2-data (>= 2.1.15), srb2-data (<= 2.1.21), srb2
|
Depends: libc6, ${misc:Depends}, srb2-data (>= 2.1.15), srb2-data (<= 2.1.22), srb2
|
||||||
Description: A cross-platform 3D Sonic fangame
|
Description: A cross-platform 3D Sonic fangame
|
||||||
Sonic Robo Blast 2 is a 3D open-source Sonic the Hedgehog
|
Sonic Robo Blast 2 is a 3D open-source Sonic the Hedgehog
|
||||||
fangame built using a modified version of the Doom Legacy
|
fangame built using a modified version of the Doom Legacy
|
||||||
|
|
|
@ -50,6 +50,7 @@ static void COM_Wait_f(void);
|
||||||
static void COM_Help_f(void);
|
static void COM_Help_f(void);
|
||||||
static void COM_Toggle_f(void);
|
static void COM_Toggle_f(void);
|
||||||
|
|
||||||
|
static void CV_EnforceExecVersion(void);
|
||||||
static boolean CV_FilterVarByVersion(consvar_t *v, const char *valstr);
|
static boolean CV_FilterVarByVersion(consvar_t *v, const char *valstr);
|
||||||
static boolean CV_Command(void);
|
static boolean CV_Command(void);
|
||||||
static consvar_t *CV_FindVar(const char *name);
|
static consvar_t *CV_FindVar(const char *name);
|
||||||
|
@ -64,10 +65,11 @@ CV_PossibleValue_t CV_YesNo[] = {{0, "No"}, {1, "Yes"}, {0, NULL}};
|
||||||
CV_PossibleValue_t CV_Unsigned[] = {{0, "MIN"}, {999999999, "MAX"}, {0, NULL}};
|
CV_PossibleValue_t CV_Unsigned[] = {{0, "MIN"}, {999999999, "MAX"}, {0, NULL}};
|
||||||
CV_PossibleValue_t CV_Natural[] = {{1, "MIN"}, {999999999, "MAX"}, {0, NULL}};
|
CV_PossibleValue_t CV_Natural[] = {{1, "MIN"}, {999999999, "MAX"}, {0, NULL}};
|
||||||
|
|
||||||
// Filter consvars by MODVERSION
|
// Filter consvars by EXECVERSION
|
||||||
// First implementation is 26 (2.1.21), so earlier configs default at 25 (2.1.20)
|
// First implementation is 26 (2.1.21), so earlier configs default at 25 (2.1.20)
|
||||||
// Also set CV_HIDEN during runtime, after config is loaded
|
// Also set CV_HIDEN during runtime, after config is loaded
|
||||||
consvar_t cv_execversion = {"execversion","25",0,CV_Unsigned, NULL, 0, NULL, NULL, 0, 0, NULL};
|
static boolean execversion_enabled = false;
|
||||||
|
consvar_t cv_execversion = {"execversion","25",CV_CALL,CV_Unsigned, CV_EnforceExecVersion, 0, NULL, NULL, 0, 0, NULL};
|
||||||
|
|
||||||
// for default joyaxis detection
|
// for default joyaxis detection
|
||||||
static boolean joyaxis_default = false;
|
static boolean joyaxis_default = false;
|
||||||
|
@ -1598,10 +1600,21 @@ void CV_InitFilterVar(void)
|
||||||
joyaxis_count = joyaxis2_count = 0;
|
joyaxis_count = joyaxis2_count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CV_ToggleExecVersion(boolean enable)
|
||||||
|
{
|
||||||
|
execversion_enabled = enable;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void CV_EnforceExecVersion(void)
|
||||||
|
{
|
||||||
|
if (!execversion_enabled)
|
||||||
|
CV_StealthSetValue(&cv_execversion, EXECVERSION);
|
||||||
|
}
|
||||||
|
|
||||||
static boolean CV_FilterJoyAxisVars(consvar_t *v, const char *valstr)
|
static boolean CV_FilterJoyAxisVars(consvar_t *v, const char *valstr)
|
||||||
{
|
{
|
||||||
// If ALL axis settings are previous defaults, set them to the new defaults
|
// If ALL axis settings are previous defaults, set them to the new defaults
|
||||||
// MODVERSION < 26 (2.1.21)
|
// EXECVERSION < 26 (2.1.21)
|
||||||
|
|
||||||
if (joyaxis_default)
|
if (joyaxis_default)
|
||||||
{
|
{
|
||||||
|
@ -1749,8 +1762,7 @@ static boolean CV_FilterVarByVersion(consvar_t *v, const char *valstr)
|
||||||
if (!(v->flags & CV_SAVE))
|
if (!(v->flags & CV_SAVE))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// We go by MODVERSION here
|
if (GETMAJOREXECVERSION(cv_execversion.value) < 26) // 26 = 2.1.21
|
||||||
if (cv_execversion.value < 26) // 26 = 2.1.21
|
|
||||||
{
|
{
|
||||||
// MOUSE SETTINGS
|
// MOUSE SETTINGS
|
||||||
// alwaysfreelook split between first and third person (chasefreelook)
|
// alwaysfreelook split between first and third person (chasefreelook)
|
||||||
|
|
|
@ -130,6 +130,7 @@ extern CV_PossibleValue_t CV_Natural[];
|
||||||
extern consvar_t cv_execversion;
|
extern consvar_t cv_execversion;
|
||||||
|
|
||||||
void CV_InitFilterVar(void);
|
void CV_InitFilterVar(void);
|
||||||
|
void CV_ToggleExecVersion(boolean enable);
|
||||||
|
|
||||||
// register a variable for use at the console
|
// register a variable for use at the console
|
||||||
void CV_RegisterVar(consvar_t *variable);
|
void CV_RegisterVar(consvar_t *variable);
|
||||||
|
|
|
@ -27,14 +27,15 @@
|
||||||
#else
|
#else
|
||||||
|
|
||||||
/* Manually defined asset hashes for non-CMake builds
|
/* Manually defined asset hashes for non-CMake builds
|
||||||
* Last updated 2015 / 05 / 03
|
* Last updated 2015 / 05 / 03 - v2.1.15 - main assets
|
||||||
|
* Last updated 2018 / 12 / 23 - v2.1.22 - patch.dta
|
||||||
*/
|
*/
|
||||||
#define ASSET_HASH_SRB2_SRB "c1b9577687f8a795104aef4600720ea7"
|
#define ASSET_HASH_SRB2_SRB "c1b9577687f8a795104aef4600720ea7"
|
||||||
#define ASSET_HASH_ZONES_DTA "303838c6c534d9540288360fa49cca60"
|
#define ASSET_HASH_ZONES_DTA "303838c6c534d9540288360fa49cca60"
|
||||||
#define ASSET_HASH_PLAYER_DTA "cfca0f1c73023cbbd8f844f45480f799"
|
#define ASSET_HASH_PLAYER_DTA "cfca0f1c73023cbbd8f844f45480f799"
|
||||||
#define ASSET_HASH_RINGS_DTA "85901ad4bf94637e5753d2ac2c03ea26"
|
#define ASSET_HASH_RINGS_DTA "85901ad4bf94637e5753d2ac2c03ea26"
|
||||||
#ifdef USE_PATCH_DTA
|
#ifdef USE_PATCH_DTA
|
||||||
#define ASSET_HASH_PATCH_DTA "dbbf8bc6121618ee3be2d5b14650429b"
|
#define ASSET_HASH_PATCH_DTA "b04fd9624bfd94dc96dcf4f400f7deb4"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
#include "i_system.h"
|
#include "i_system.h"
|
||||||
#include "d_main.h"
|
#include "d_main.h"
|
||||||
#include "m_menu.h"
|
#include "m_menu.h"
|
||||||
|
#include "filesrch.h"
|
||||||
|
|
||||||
#ifdef _WINDOWS
|
#ifdef _WINDOWS
|
||||||
#include "win32/win_main.h"
|
#include "win32/win_main.h"
|
||||||
|
@ -128,10 +129,15 @@ static CV_PossibleValue_t backpic_cons_t[] = {{0, "translucent"}, {1, "picture"}
|
||||||
// whether to use console background picture, or translucent mode
|
// whether to use console background picture, or translucent mode
|
||||||
static consvar_t cons_backpic = {"con_backpic", "translucent", CV_SAVE, backpic_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
static consvar_t cons_backpic = {"con_backpic", "translucent", CV_SAVE, backpic_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
|
|
||||||
static CV_PossibleValue_t backcolor_cons_t[] = {{0, "White"}, {1, "Gray"}, {2, "Brown"},
|
static CV_PossibleValue_t backcolor_cons_t[] = {{0, "White"}, {1, "Black"}, {2, "Sepia"},
|
||||||
{3, "Red"}, {4, "Orange"}, {5, "Yellow"},
|
{3, "Brown"}, {4, "Pink"}, {5, "Raspberry"},
|
||||||
{6, "Green"}, {7, "Blue"}, {8, "Cyan"},
|
{6, "Red"}, {7, "Creamsicle"}, {8, "Orange"},
|
||||||
|
{9, "Gold"}, {10,"Yellow"}, {11,"Emerald"},
|
||||||
|
{12,"Green"}, {13,"Cyan"}, {14,"Steel"},
|
||||||
|
{15,"Periwinkle"}, {16,"Blue"}, {17,"Purple"},
|
||||||
|
{18,"Lavender"},
|
||||||
{0, NULL}};
|
{0, NULL}};
|
||||||
|
|
||||||
consvar_t cons_backcolor = {"con_backcolor", "Green", CV_CALL|CV_SAVE, backcolor_cons_t, CONS_backcolor_Change, 0, NULL, NULL, 0, 0, NULL};
|
consvar_t cons_backcolor = {"con_backcolor", "Green", CV_CALL|CV_SAVE, backcolor_cons_t, CONS_backcolor_Change, 0, NULL, NULL, 0, 0, NULL};
|
||||||
|
|
||||||
static void CON_Print(char *msg);
|
static void CON_Print(char *msg);
|
||||||
|
@ -238,29 +244,41 @@ void CON_SetupBackColormap(void)
|
||||||
UINT16 i, palsum;
|
UINT16 i, palsum;
|
||||||
UINT8 j, palindex;
|
UINT8 j, palindex;
|
||||||
UINT8 *pal = W_CacheLumpName(GetPalette(), PU_CACHE);
|
UINT8 *pal = W_CacheLumpName(GetPalette(), PU_CACHE);
|
||||||
|
INT32 shift = 6;
|
||||||
|
|
||||||
if (!consolebgmap)
|
if (!consolebgmap)
|
||||||
consolebgmap = (UINT8 *)Z_Malloc(256, PU_STATIC, NULL);
|
consolebgmap = (UINT8 *)Z_Malloc(256, PU_STATIC, NULL);
|
||||||
|
|
||||||
switch (cons_backcolor.value)
|
switch (cons_backcolor.value)
|
||||||
{
|
{
|
||||||
case 0: palindex = 15; break; // White
|
case 0: palindex = 15; break; // White
|
||||||
case 1: palindex = 31; break; // Gray
|
case 1: palindex = 31; break; // Gray
|
||||||
case 2: palindex = 63; break; // Brown
|
case 2: palindex = 47; break; // Sepia
|
||||||
case 3: palindex = 143; break; // Red
|
case 3: palindex = 63; break; // Brown
|
||||||
case 4: palindex = 95; break; // Orange
|
case 4: palindex = 150; shift = 7; break; // Pink
|
||||||
case 5: palindex = 111; break; // Yellow
|
case 5: palindex = 127; shift = 7; break; // Raspberry
|
||||||
case 6: palindex = 175; break; // Green
|
case 6: palindex = 143; break; // Red
|
||||||
case 7: palindex = 239; break; // Blue
|
case 7: palindex = 86; shift = 7; break; // Creamsicle
|
||||||
case 8: palindex = 219; break; // Cyan
|
case 8: palindex = 95; break; // Orange
|
||||||
|
case 9: palindex = 119; shift = 7; break; // Gold
|
||||||
|
case 10: palindex = 111; break; // Yellow
|
||||||
|
case 11: palindex = 191; shift = 7; break; // Emerald
|
||||||
|
case 12: palindex = 175; break; // Green
|
||||||
|
case 13: palindex = 219; break; // Cyan
|
||||||
|
case 14: palindex = 207; shift = 7; break; // Steel
|
||||||
|
case 15: palindex = 230; shift = 7; break; // Periwinkle
|
||||||
|
case 16: palindex = 239; break; // Blue
|
||||||
|
case 17: palindex = 199; shift = 7; break; // Purple
|
||||||
|
case 18: palindex = 255; shift = 7; break; // Lavender
|
||||||
// Default green
|
// Default green
|
||||||
default: palindex = 175; break;
|
default: palindex = 175; break;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// setup background colormap
|
// setup background colormap
|
||||||
for (i = 0, j = 0; i < 768; i += 3, j++)
|
for (i = 0, j = 0; i < 768; i += 3, j++)
|
||||||
{
|
{
|
||||||
palsum = (pal[i] + pal[i+1] + pal[i+2]) >> 6;
|
palsum = (pal[i] + pal[i+1] + pal[i+2]) >> shift;
|
||||||
consolebgmap[j] = (UINT8)(palindex - palsum);
|
consolebgmap[j] = (UINT8)(palindex - palsum);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -839,7 +857,7 @@ boolean CON_Responder(event_t *ev)
|
||||||
|
|
||||||
// ...why shouldn't it eat the key? if it doesn't, it just means you
|
// ...why shouldn't it eat the key? if it doesn't, it just means you
|
||||||
// can control Sonic from the console, which is silly
|
// can control Sonic from the console, which is silly
|
||||||
return true; //return false;
|
return true;//return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// command completion forward (tab) and backward (shift-tab)
|
// command completion forward (tab) and backward (shift-tab)
|
||||||
|
@ -1033,15 +1051,30 @@ boolean CON_Responder(event_t *ev)
|
||||||
else if (key == KEY_KPADSLASH)
|
else if (key == KEY_KPADSLASH)
|
||||||
key = '/';
|
key = '/';
|
||||||
|
|
||||||
if (shiftdown)
|
// capslock
|
||||||
|
if (key == KEY_CAPSLOCK) // it's a toggle.
|
||||||
|
{
|
||||||
|
if (capslock)
|
||||||
|
capslock = false;
|
||||||
|
else
|
||||||
|
capslock = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key >= 'a' && key <= 'z')
|
||||||
|
{
|
||||||
|
if (capslock ^ shiftdown)
|
||||||
|
key = shiftxform[key];
|
||||||
|
}
|
||||||
|
else if (shiftdown)
|
||||||
key = shiftxform[key];
|
key = shiftxform[key];
|
||||||
|
|
||||||
// enter a char into the command prompt
|
// enter a char into the command prompt
|
||||||
if (key < 32 || key > 127)
|
if (key < 32 || key > 127)
|
||||||
return true; // even if key can't be printed, eat it anyway
|
return true;
|
||||||
|
|
||||||
// add key to cmd line here
|
// add key to cmd line here
|
||||||
if (key >= 'A' && key <= 'Z' && !shiftdown) //this is only really necessary for dedicated servers
|
if (key >= 'A' && key <= 'Z' && !(shiftdown ^ capslock)) //this is only really necessary for dedicated servers
|
||||||
key = key + 'a' - 'A';
|
key = key + 'a' - 'A';
|
||||||
|
|
||||||
if (input_sel != input_cur)
|
if (input_sel != input_cur)
|
||||||
|
@ -1258,12 +1291,15 @@ void CONS_Alert(alerttype_t level, const char *fmt, ...)
|
||||||
switch (level)
|
switch (level)
|
||||||
{
|
{
|
||||||
case CONS_NOTICE:
|
case CONS_NOTICE:
|
||||||
|
// no notice for notices, hehe
|
||||||
CONS_Printf("\x83" "%s" "\x80 ", M_GetText("NOTICE:"));
|
CONS_Printf("\x83" "%s" "\x80 ", M_GetText("NOTICE:"));
|
||||||
break;
|
break;
|
||||||
case CONS_WARNING:
|
case CONS_WARNING:
|
||||||
|
refreshdirmenu |= REFRESHDIR_WARNING;
|
||||||
CONS_Printf("\x82" "%s" "\x80 ", M_GetText("WARNING:"));
|
CONS_Printf("\x82" "%s" "\x80 ", M_GetText("WARNING:"));
|
||||||
break;
|
break;
|
||||||
case CONS_ERROR:
|
case CONS_ERROR:
|
||||||
|
refreshdirmenu |= REFRESHDIR_ERROR;
|
||||||
CONS_Printf("\x85" "%s" "\x80 ", M_GetText("ERROR:"));
|
CONS_Printf("\x85" "%s" "\x80 ", M_GetText("ERROR:"));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1419,8 +1455,8 @@ static void CON_DrawHudlines(void)
|
||||||
if (con_hudlines <= 0)
|
if (con_hudlines <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (chat_on)
|
if (chat_on && OLDCHAT)
|
||||||
y = charheight; // leave place for chat input in the first row of text
|
y = charheight; // leave place for chat input in the first row of text (only do it if consolechat is on.)
|
||||||
else
|
else
|
||||||
y = 0;
|
y = 0;
|
||||||
|
|
||||||
|
|
|
@ -2762,7 +2762,7 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
|
||||||
msg = KICK_MSG_CON_FAIL;
|
msg = KICK_MSG_CON_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
CONS_Printf("\x82%s ", player_names[pnum]);
|
//CONS_Printf("\x82%s ", player_names[pnum]);
|
||||||
|
|
||||||
// If a verified admin banned someone, the server needs to know about it.
|
// If a verified admin banned someone, the server needs to know about it.
|
||||||
// If the playernum isn't zero (the server) then the server needs to record the ban.
|
// If the playernum isn't zero (the server) then the server needs to record the ban.
|
||||||
|
@ -2779,17 +2779,17 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
|
||||||
switch (msg)
|
switch (msg)
|
||||||
{
|
{
|
||||||
case KICK_MSG_GO_AWAY:
|
case KICK_MSG_GO_AWAY:
|
||||||
CONS_Printf(M_GetText("has been kicked (Go away)\n"));
|
HU_AddChatText(va("\x82*%s has been kicked (Go away)", player_names[pnum]), false);
|
||||||
kickreason = KR_KICK;
|
kickreason = KR_KICK;
|
||||||
break;
|
break;
|
||||||
#ifdef NEWPING
|
#ifdef NEWPING
|
||||||
case KICK_MSG_PING_HIGH:
|
case KICK_MSG_PING_HIGH:
|
||||||
CONS_Printf(M_GetText("left the game (Broke ping limit)\n"));
|
HU_AddChatText(va("\x82*%s left the game (Broke ping limit)", player_names[pnum]), false);
|
||||||
kickreason = KR_PINGLIMIT;
|
kickreason = KR_PINGLIMIT;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
case KICK_MSG_CON_FAIL:
|
case KICK_MSG_CON_FAIL:
|
||||||
CONS_Printf(M_GetText("left the game (Synch failure)\n"));
|
HU_AddChatText(va("\x82*%s left the game (Synch Failure)", player_names[pnum]), false);
|
||||||
kickreason = KR_SYNCH;
|
kickreason = KR_SYNCH;
|
||||||
|
|
||||||
if (M_CheckParm("-consisdump")) // Helps debugging some problems
|
if (M_CheckParm("-consisdump")) // Helps debugging some problems
|
||||||
|
@ -2826,26 +2826,26 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case KICK_MSG_TIMEOUT:
|
case KICK_MSG_TIMEOUT:
|
||||||
CONS_Printf(M_GetText("left the game (Connection timeout)\n"));
|
HU_AddChatText(va("\x82*%s left the game (Connection timeout)", player_names[pnum]), false);
|
||||||
kickreason = KR_TIMEOUT;
|
kickreason = KR_TIMEOUT;
|
||||||
break;
|
break;
|
||||||
case KICK_MSG_PLAYER_QUIT:
|
case KICK_MSG_PLAYER_QUIT:
|
||||||
if (netgame) // not splitscreen/bots
|
if (netgame) // not splitscreen/bots
|
||||||
CONS_Printf(M_GetText("left the game\n"));
|
HU_AddChatText(va("\x82*%s left the game", player_names[pnum]), false);
|
||||||
kickreason = KR_LEAVE;
|
kickreason = KR_LEAVE;
|
||||||
break;
|
break;
|
||||||
case KICK_MSG_BANNED:
|
case KICK_MSG_BANNED:
|
||||||
CONS_Printf(M_GetText("has been banned (Don't come back)\n"));
|
HU_AddChatText(va("\x82*%s has been banned (Don't come back)", player_names[pnum]), false);
|
||||||
kickreason = KR_BAN;
|
kickreason = KR_BAN;
|
||||||
break;
|
break;
|
||||||
case KICK_MSG_CUSTOM_KICK:
|
case KICK_MSG_CUSTOM_KICK:
|
||||||
READSTRINGN(*p, reason, MAX_REASONLENGTH+1);
|
READSTRINGN(*p, reason, MAX_REASONLENGTH+1);
|
||||||
CONS_Printf(M_GetText("has been kicked (%s)\n"), reason);
|
HU_AddChatText(va("\x82*%s has been kicked (%s)", player_names[pnum], reason), false);
|
||||||
kickreason = KR_KICK;
|
kickreason = KR_KICK;
|
||||||
break;
|
break;
|
||||||
case KICK_MSG_CUSTOM_BAN:
|
case KICK_MSG_CUSTOM_BAN:
|
||||||
READSTRINGN(*p, reason, MAX_REASONLENGTH+1);
|
READSTRINGN(*p, reason, MAX_REASONLENGTH+1);
|
||||||
CONS_Printf(M_GetText("has been banned (%s)\n"), reason);
|
HU_AddChatText(va("\x82*%s has been banned (%s)", player_names[pnum], reason), false);
|
||||||
kickreason = KR_BAN;
|
kickreason = KR_BAN;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -3119,9 +3119,6 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum)
|
||||||
if (newplayernum+1 > doomcom->numslots)
|
if (newplayernum+1 > doomcom->numslots)
|
||||||
doomcom->numslots = (INT16)(newplayernum+1);
|
doomcom->numslots = (INT16)(newplayernum+1);
|
||||||
|
|
||||||
if (netgame)
|
|
||||||
CONS_Printf(M_GetText("Player %d has joined the game (node %d)\n"), newplayernum+1, node);
|
|
||||||
|
|
||||||
// the server is creating my player
|
// the server is creating my player
|
||||||
if (node == mynode)
|
if (node == mynode)
|
||||||
{
|
{
|
||||||
|
@ -3143,11 +3140,17 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum)
|
||||||
D_SendPlayerConfig();
|
D_SendPlayerConfig();
|
||||||
addedtogame = true;
|
addedtogame = true;
|
||||||
}
|
}
|
||||||
else if (server && netgame && cv_showjoinaddress.value)
|
|
||||||
|
if (netgame)
|
||||||
{
|
{
|
||||||
const char *address;
|
if (server && cv_showjoinaddress.value)
|
||||||
if (I_GetNodeAddress && (address = I_GetNodeAddress(node)) != NULL)
|
{
|
||||||
CONS_Printf(M_GetText("Player Address is %s\n"), address);
|
const char *address;
|
||||||
|
if (I_GetNodeAddress && (address = I_GetNodeAddress(node)) != NULL)
|
||||||
|
HU_AddChatText(va("\x82*Player %d has joined the game (node %d) (%s)", newplayernum+1, node, address), false); // merge join notification + IP to avoid clogging console/chat.
|
||||||
|
}
|
||||||
|
else
|
||||||
|
HU_AddChatText(va("\x82*Player %d has joined the game (node %d)", newplayernum+1, node), false); // if you don't wanna see the join address.
|
||||||
}
|
}
|
||||||
|
|
||||||
if (server && multiplayer && motd[0] != '\0')
|
if (server && multiplayer && motd[0] != '\0')
|
||||||
|
|
|
@ -309,6 +309,7 @@ typedef struct
|
||||||
} ATTRPACK clientconfig_pak;
|
} ATTRPACK clientconfig_pak;
|
||||||
|
|
||||||
#define MAXSERVERNAME 32
|
#define MAXSERVERNAME 32
|
||||||
|
#define MAXFILENEEDED 915
|
||||||
// This packet is too large
|
// This packet is too large
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
@ -330,7 +331,7 @@ typedef struct
|
||||||
unsigned char mapmd5[16];
|
unsigned char mapmd5[16];
|
||||||
UINT8 actnum;
|
UINT8 actnum;
|
||||||
UINT8 iszone;
|
UINT8 iszone;
|
||||||
UINT8 fileneeded[915]; // is filled with writexxx (byteptr.h)
|
UINT8 fileneeded[MAXFILENEEDED]; // is filled with writexxx (byteptr.h)
|
||||||
} ATTRPACK serverinfo_pak;
|
} ATTRPACK serverinfo_pak;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
|
55
src/d_main.c
55
src/d_main.c
|
@ -74,6 +74,7 @@ int snprintf(char *str, size_t n, const char *fmt, ...);
|
||||||
#include "m_cond.h" // condition initialization
|
#include "m_cond.h" // condition initialization
|
||||||
#include "fastcmp.h"
|
#include "fastcmp.h"
|
||||||
#include "keys.h"
|
#include "keys.h"
|
||||||
|
#include "filesrch.h" // refreshdirmenu, mainwadstally
|
||||||
|
|
||||||
#ifdef CMAKECONFIG
|
#ifdef CMAKECONFIG
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
@ -178,6 +179,7 @@ void D_PostEvent_end(void) {};
|
||||||
UINT8 shiftdown = 0; // 0x1 left, 0x2 right
|
UINT8 shiftdown = 0; // 0x1 left, 0x2 right
|
||||||
UINT8 ctrldown = 0; // 0x1 left, 0x2 right
|
UINT8 ctrldown = 0; // 0x1 left, 0x2 right
|
||||||
UINT8 altdown = 0; // 0x1 left, 0x2 right
|
UINT8 altdown = 0; // 0x1 left, 0x2 right
|
||||||
|
boolean capslock = 0; // gee i wonder what this does.
|
||||||
//
|
//
|
||||||
// D_ModifierKeyResponder
|
// D_ModifierKeyResponder
|
||||||
// Sets global shift/ctrl/alt variables, never actually eats events
|
// Sets global shift/ctrl/alt variables, never actually eats events
|
||||||
|
@ -582,6 +584,8 @@ void D_SRB2Loop(void)
|
||||||
realtics = entertic - oldentertics;
|
realtics = entertic - oldentertics;
|
||||||
oldentertics = entertic;
|
oldentertics = entertic;
|
||||||
|
|
||||||
|
refreshdirmenu = 0; // not sure where to put this, here as good as any?
|
||||||
|
|
||||||
#ifdef DEBUGFILE
|
#ifdef DEBUGFILE
|
||||||
if (!realtics)
|
if (!realtics)
|
||||||
if (debugload)
|
if (debugload)
|
||||||
|
@ -846,17 +850,21 @@ static void IdentifyVersion(void)
|
||||||
|
|
||||||
#if !defined (HAVE_SDL) || defined (HAVE_MIXER)
|
#if !defined (HAVE_SDL) || defined (HAVE_MIXER)
|
||||||
{
|
{
|
||||||
|
#define MUSICTEST(str) \
|
||||||
|
{\
|
||||||
|
const char *musicpath = va(pandf,srb2waddir,str);\
|
||||||
|
int ms = W_VerifyNMUSlumps(musicpath); \
|
||||||
|
if (ms == 1) \
|
||||||
|
D_AddFile(musicpath); \
|
||||||
|
else if (ms == 0) \
|
||||||
|
I_Error("File "str" has been modified with non-music/sound lumps"); \
|
||||||
|
}
|
||||||
|
|
||||||
#if defined (DC) && 0
|
#if defined (DC) && 0
|
||||||
const char *musicfile = "music_dc.dta";
|
MUSICTEST("music_dc.dta")
|
||||||
#else
|
#else
|
||||||
const char *musicfile = "music.dta";
|
MUSICTEST("music.dta")
|
||||||
#endif
|
#endif
|
||||||
const char *musicpath = va(pandf,srb2waddir,musicfile);
|
|
||||||
int ms = W_VerifyNMUSlumps(musicpath); // Don't forget the music!
|
|
||||||
if (ms == 1)
|
|
||||||
D_AddFile(musicpath);
|
|
||||||
else if (ms == 0)
|
|
||||||
I_Error("File %s has been modified with non-music lumps",musicfile);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -1132,25 +1140,36 @@ void D_SRB2Main(void)
|
||||||
#endif
|
#endif
|
||||||
D_CleanFile();
|
D_CleanFile();
|
||||||
|
|
||||||
|
mainwads = 0;
|
||||||
|
|
||||||
#ifndef DEVELOP // md5s last updated 12/14/14
|
#ifndef DEVELOP // md5s last updated 12/14/14
|
||||||
|
|
||||||
// Check MD5s of autoloaded files
|
// Check MD5s of autoloaded files
|
||||||
W_VerifyFileMD5(0, ASSET_HASH_SRB2_SRB); // srb2.srb/srb2.wad
|
W_VerifyFileMD5(mainwads++, ASSET_HASH_SRB2_SRB); // srb2.srb/srb2.wad
|
||||||
W_VerifyFileMD5(1, ASSET_HASH_ZONES_DTA); // zones.dta
|
W_VerifyFileMD5(mainwads++, ASSET_HASH_ZONES_DTA); // zones.dta
|
||||||
W_VerifyFileMD5(2, ASSET_HASH_PLAYER_DTA); // player.dta
|
W_VerifyFileMD5(mainwads++, ASSET_HASH_PLAYER_DTA); // player.dta
|
||||||
W_VerifyFileMD5(3, ASSET_HASH_RINGS_DTA); // rings.dta
|
W_VerifyFileMD5(mainwads++, ASSET_HASH_RINGS_DTA); // rings.dta
|
||||||
#ifdef USE_PATCH_DTA
|
#ifdef USE_PATCH_DTA
|
||||||
W_VerifyFileMD5(4, ASSET_HASH_PATCH_DTA); // patch.dta
|
W_VerifyFileMD5(mainwads++, ASSET_HASH_PATCH_DTA); // patch.dta
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// don't check music.dta because people like to modify it, and it doesn't matter if they do
|
// don't check music.dta because people like to modify it, and it doesn't matter if they do
|
||||||
// ...except it does if they slip maps in there, and that's what W_VerifyNMUSlumps is for.
|
// ...except it does if they slip maps in there, and that's what W_VerifyNMUSlumps is for.
|
||||||
|
//mainwads++; // music.dta does not increment mainwads (see <= 2.1.21)
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
mainwads++; // srb2.srb/srb2.wad
|
||||||
|
mainwads++; // zones.dta
|
||||||
|
mainwads++; // player.dta
|
||||||
|
mainwads++; // rings.dta
|
||||||
|
#ifdef USE_PATCH_DTA
|
||||||
|
mainwads++; // patch.dta
|
||||||
|
#endif
|
||||||
|
//mainwads++; // music.dta does not increment mainwads (see <= 2.1.21)
|
||||||
|
|
||||||
#endif //ifndef DEVELOP
|
#endif //ifndef DEVELOP
|
||||||
|
|
||||||
mainwads = 4; // there are 4 wads not to unload
|
mainwadstally = packetsizetally;
|
||||||
#ifdef USE_PATCH_DTA
|
|
||||||
++mainwads; // patch.dta adds one more
|
|
||||||
#endif
|
|
||||||
|
|
||||||
cht_Init();
|
cht_Init();
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#define MAXNETNODES 32
|
#define MAXNETNODES 32
|
||||||
#define BROADCASTADDR MAXNETNODES
|
#define BROADCASTADDR MAXNETNODES
|
||||||
#define MAXSPLITSCREENPLAYERS 2 // Max number of players on a single computer
|
#define MAXSPLITSCREENPLAYERS 2 // Max number of players on a single computer
|
||||||
|
//#define NETSPLITSCREEN // Kart's splitscreen netgame feature
|
||||||
|
|
||||||
#define STATLENGTH (TICRATE*2)
|
#define STATLENGTH (TICRATE*2)
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
#include "d_main.h"
|
#include "d_main.h"
|
||||||
#include "m_random.h"
|
#include "m_random.h"
|
||||||
#include "f_finale.h"
|
#include "f_finale.h"
|
||||||
|
#include "filesrch.h"
|
||||||
#include "mserv.h"
|
#include "mserv.h"
|
||||||
#include "md5.h"
|
#include "md5.h"
|
||||||
#include "z_zone.h"
|
#include "z_zone.h"
|
||||||
|
@ -673,6 +674,14 @@ void D_RegisterClientCommands(void)
|
||||||
CV_RegisterVar(&cv_usegamma);
|
CV_RegisterVar(&cv_usegamma);
|
||||||
|
|
||||||
// m_menu.c
|
// m_menu.c
|
||||||
|
CV_RegisterVar(&cv_compactscoreboard);
|
||||||
|
CV_RegisterVar(&cv_chatheight);
|
||||||
|
CV_RegisterVar(&cv_chatwidth);
|
||||||
|
CV_RegisterVar(&cv_chattime);
|
||||||
|
CV_RegisterVar(&cv_chatspamprotection);
|
||||||
|
CV_RegisterVar(&cv_chatbacktint);
|
||||||
|
CV_RegisterVar(&cv_consolechat);
|
||||||
|
CV_RegisterVar(&cv_chatnotifications);
|
||||||
CV_RegisterVar(&cv_crosshair);
|
CV_RegisterVar(&cv_crosshair);
|
||||||
CV_RegisterVar(&cv_crosshair2);
|
CV_RegisterVar(&cv_crosshair2);
|
||||||
CV_RegisterVar(&cv_alwaysfreelook);
|
CV_RegisterVar(&cv_alwaysfreelook);
|
||||||
|
@ -698,6 +707,14 @@ void D_RegisterClientCommands(void)
|
||||||
CV_RegisterVar(&cv_firenaxis);
|
CV_RegisterVar(&cv_firenaxis);
|
||||||
CV_RegisterVar(&cv_firenaxis2);
|
CV_RegisterVar(&cv_firenaxis2);
|
||||||
|
|
||||||
|
// filesrch.c
|
||||||
|
CV_RegisterVar(&cv_addons_option);
|
||||||
|
CV_RegisterVar(&cv_addons_folder);
|
||||||
|
CV_RegisterVar(&cv_addons_md5);
|
||||||
|
CV_RegisterVar(&cv_addons_showall);
|
||||||
|
CV_RegisterVar(&cv_addons_search_type);
|
||||||
|
CV_RegisterVar(&cv_addons_search_case);
|
||||||
|
|
||||||
// WARNING: the order is important when initialising mouse2
|
// WARNING: the order is important when initialising mouse2
|
||||||
// we need the mouse2port
|
// we need the mouse2port
|
||||||
CV_RegisterVar(&cv_mouse2port);
|
CV_RegisterVar(&cv_mouse2port);
|
||||||
|
@ -988,8 +1005,8 @@ static void SetPlayerName(INT32 playernum, char *newname)
|
||||||
if (strcasecmp(newname, player_names[playernum]) != 0)
|
if (strcasecmp(newname, player_names[playernum]) != 0)
|
||||||
{
|
{
|
||||||
if (netgame)
|
if (netgame)
|
||||||
CONS_Printf(M_GetText("%s renamed to %s\n"),
|
HU_AddChatText(va("\x82*%s renamed to %s", player_names[playernum], newname), false);
|
||||||
player_names[playernum], newname);
|
|
||||||
strcpy(player_names[playernum], newname);
|
strcpy(player_names[playernum], newname);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3147,25 +3164,12 @@ static void Command_Addfile(void)
|
||||||
break;
|
break;
|
||||||
++p;
|
++p;
|
||||||
// check total packet size and no of files currently loaded
|
// check total packet size and no of files currently loaded
|
||||||
|
// See W_LoadWadFile in w_wad.c
|
||||||
|
if ((numwadfiles >= MAX_WADFILES)
|
||||||
|
|| ((packetsizetally + nameonlylength(fn) + 22) > MAXFILENEEDED*sizeof(UINT8)))
|
||||||
{
|
{
|
||||||
size_t packetsize = 0;
|
CONS_Alert(CONS_ERROR, M_GetText("Too many files loaded to add %s\n"), fn);
|
||||||
serverinfo_pak *dummycheck = NULL;
|
return;
|
||||||
|
|
||||||
// Shut the compiler up.
|
|
||||||
(void)dummycheck;
|
|
||||||
|
|
||||||
// See W_LoadWadFile in w_wad.c
|
|
||||||
for (i = 0; i < numwadfiles; i++)
|
|
||||||
packetsize += nameonlylength(wadfiles[i]->filename) + 22;
|
|
||||||
|
|
||||||
packetsize += nameonlylength(fn) + 22;
|
|
||||||
|
|
||||||
if ((numwadfiles >= MAX_WADFILES)
|
|
||||||
|| (packetsize > sizeof(dummycheck->fileneeded)))
|
|
||||||
{
|
|
||||||
CONS_Alert(CONS_ERROR, M_GetText("Too many files loaded to add %s\n"), fn);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
WRITESTRINGN(buf_p,p,240);
|
WRITESTRINGN(buf_p,p,240);
|
||||||
|
@ -3251,7 +3255,6 @@ static void Got_RequestAddfilecmd(UINT8 **cp, INT32 playernum)
|
||||||
boolean kick = false;
|
boolean kick = false;
|
||||||
boolean toomany = false;
|
boolean toomany = false;
|
||||||
INT32 i,j;
|
INT32 i,j;
|
||||||
size_t packetsize = 0;
|
|
||||||
serverinfo_pak *dummycheck = NULL;
|
serverinfo_pak *dummycheck = NULL;
|
||||||
|
|
||||||
// Shut the compiler up.
|
// Shut the compiler up.
|
||||||
|
@ -3282,13 +3285,8 @@ static void Got_RequestAddfilecmd(UINT8 **cp, INT32 playernum)
|
||||||
}
|
}
|
||||||
|
|
||||||
// See W_LoadWadFile in w_wad.c
|
// See W_LoadWadFile in w_wad.c
|
||||||
for (i = 0; i < numwadfiles; i++)
|
|
||||||
packetsize += nameonlylength(wadfiles[i]->filename) + 22;
|
|
||||||
|
|
||||||
packetsize += nameonlylength(filename) + 22;
|
|
||||||
|
|
||||||
if ((numwadfiles >= MAX_WADFILES)
|
if ((numwadfiles >= MAX_WADFILES)
|
||||||
|| (packetsize > sizeof(dummycheck->fileneeded)))
|
|| ((packetsizetally + nameonlylength(filename) + 22) > MAXFILENEEDED*sizeof(UINT8)))
|
||||||
toomany = true;
|
toomany = true;
|
||||||
else
|
else
|
||||||
ncs = findfile(filename,md5sum,true);
|
ncs = findfile(filename,md5sum,true);
|
||||||
|
@ -3518,6 +3516,9 @@ static void Command_Playintro_f(void)
|
||||||
if (netgame)
|
if (netgame)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (dirmenu)
|
||||||
|
closefilemenu(true);
|
||||||
|
|
||||||
F_StartIntro();
|
F_StartIntro();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4075,6 +4076,9 @@ void Command_ExitGame_f(void)
|
||||||
cv_debug = 0;
|
cv_debug = 0;
|
||||||
emeralds = 0;
|
emeralds = 0;
|
||||||
|
|
||||||
|
if (dirmenu)
|
||||||
|
closefilemenu(true);
|
||||||
|
|
||||||
if (!modeattacking)
|
if (!modeattacking)
|
||||||
D_StartTitle();
|
D_StartTitle();
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,6 +104,7 @@ INT32 lastfilenum = -1;
|
||||||
/** Fills a serverinfo packet with information about wad files loaded.
|
/** Fills a serverinfo packet with information about wad files loaded.
|
||||||
*
|
*
|
||||||
* \todo Give this function a better name since it is in global scope.
|
* \todo Give this function a better name since it is in global scope.
|
||||||
|
* Used to have size limiting built in - now handed via W_LoadWadFile in w_wad.c
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
UINT8 *PutFileNeeded(void)
|
UINT8 *PutFileNeeded(void)
|
||||||
|
@ -112,29 +113,22 @@ UINT8 *PutFileNeeded(void)
|
||||||
UINT8 *p = netbuffer->u.serverinfo.fileneeded;
|
UINT8 *p = netbuffer->u.serverinfo.fileneeded;
|
||||||
char wadfilename[MAX_WADPATH] = "";
|
char wadfilename[MAX_WADPATH] = "";
|
||||||
UINT8 filestatus;
|
UINT8 filestatus;
|
||||||
size_t bytesused = 0;
|
|
||||||
|
|
||||||
for (i = 0; i < numwadfiles; i++)
|
for (i = 0; i < numwadfiles; i++)
|
||||||
{
|
{
|
||||||
// If it has only music/sound lumps, mark it as unimportant
|
// If it has only music/sound lumps, don't put it in the list
|
||||||
if (W_VerifyNMUSlumps(wadfiles[i]->filename))
|
if (!wadfiles[i]->important)
|
||||||
filestatus = 0;
|
continue;
|
||||||
else
|
|
||||||
filestatus = 1; // Important
|
filestatus = 1; // Importance - not really used any more, holds 1 by default for backwards compat with MS
|
||||||
|
|
||||||
// Store in the upper four bits
|
// Store in the upper four bits
|
||||||
if (!cv_downloading.value)
|
if (!cv_downloading.value)
|
||||||
filestatus += (2 << 4); // Won't send
|
filestatus += (2 << 4); // Won't send
|
||||||
else if ((wadfiles[i]->filesize > (UINT32)cv_maxsend.value * 1024))
|
else if ((wadfiles[i]->filesize <= (UINT32)cv_maxsend.value * 1024))
|
||||||
filestatus += (0 << 4); // Won't send
|
|
||||||
else
|
|
||||||
filestatus += (1 << 4); // Will send if requested
|
filestatus += (1 << 4); // Will send if requested
|
||||||
|
// else
|
||||||
bytesused += (nameonlylength(wadfilename) + 22);
|
// filestatus += (0 << 4); -- Won't send, too big
|
||||||
|
|
||||||
// Don't write too far...
|
|
||||||
if (bytesused > sizeof(netbuffer->u.serverinfo.fileneeded))
|
|
||||||
I_Error("Too many wad files added to host a game. (%s, stopped on %s)\n", sizeu1(bytesused), wadfilename);
|
|
||||||
|
|
||||||
WRITEUINT8(p, filestatus);
|
WRITEUINT8(p, filestatus);
|
||||||
|
|
||||||
|
@ -167,7 +161,6 @@ void D_ParseFileneeded(INT32 fileneedednum_parm, UINT8 *fileneededstr)
|
||||||
{
|
{
|
||||||
fileneeded[i].status = FS_NOTFOUND; // We haven't even started looking for the file yet
|
fileneeded[i].status = FS_NOTFOUND; // We haven't even started looking for the file yet
|
||||||
filestatus = READUINT8(p); // The first byte is the file status
|
filestatus = READUINT8(p); // The first byte is the file status
|
||||||
fileneeded[i].important = (UINT8)(filestatus & 3);
|
|
||||||
fileneeded[i].willsend = (UINT8)(filestatus >> 4);
|
fileneeded[i].willsend = (UINT8)(filestatus >> 4);
|
||||||
fileneeded[i].totalsize = READUINT32(p); // The four next bytes are the file size
|
fileneeded[i].totalsize = READUINT32(p); // The four next bytes are the file size
|
||||||
fileneeded[i].file = NULL; // The file isn't open yet
|
fileneeded[i].file = NULL; // The file isn't open yet
|
||||||
|
@ -197,7 +190,7 @@ boolean CL_CheckDownloadable(void)
|
||||||
UINT8 i,dlstatus = 0;
|
UINT8 i,dlstatus = 0;
|
||||||
|
|
||||||
for (i = 0; i < fileneedednum; i++)
|
for (i = 0; i < fileneedednum; i++)
|
||||||
if (fileneeded[i].status != FS_FOUND && fileneeded[i].status != FS_OPEN && fileneeded[i].important)
|
if (fileneeded[i].status != FS_FOUND && fileneeded[i].status != FS_OPEN)
|
||||||
{
|
{
|
||||||
if (fileneeded[i].willsend == 1)
|
if (fileneeded[i].willsend == 1)
|
||||||
continue;
|
continue;
|
||||||
|
@ -218,7 +211,7 @@ boolean CL_CheckDownloadable(void)
|
||||||
// not downloadable, put reason in console
|
// not downloadable, put reason in console
|
||||||
CONS_Alert(CONS_NOTICE, M_GetText("You need additional files to connect to this server:\n"));
|
CONS_Alert(CONS_NOTICE, M_GetText("You need additional files to connect to this server:\n"));
|
||||||
for (i = 0; i < fileneedednum; i++)
|
for (i = 0; i < fileneedednum; i++)
|
||||||
if (fileneeded[i].status != FS_FOUND && fileneeded[i].status != FS_OPEN && fileneeded[i].important)
|
if (fileneeded[i].status != FS_FOUND && fileneeded[i].status != FS_OPEN)
|
||||||
{
|
{
|
||||||
CONS_Printf(" * \"%s\" (%dK)", fileneeded[i].filename, fileneeded[i].totalsize >> 10);
|
CONS_Printf(" * \"%s\" (%dK)", fileneeded[i].filename, fileneeded[i].totalsize >> 10);
|
||||||
|
|
||||||
|
@ -271,7 +264,7 @@ boolean CL_SendRequestFile(void)
|
||||||
|
|
||||||
for (i = 0; i < fileneedednum; i++)
|
for (i = 0; i < fileneedednum; i++)
|
||||||
if (fileneeded[i].status != FS_FOUND && fileneeded[i].status != FS_OPEN
|
if (fileneeded[i].status != FS_FOUND && fileneeded[i].status != FS_OPEN
|
||||||
&& fileneeded[i].important && (fileneeded[i].willsend == 0 || fileneeded[i].willsend == 2))
|
&& (fileneeded[i].willsend == 0 || fileneeded[i].willsend == 2))
|
||||||
{
|
{
|
||||||
I_Error("Attempted to download files that were not sendable");
|
I_Error("Attempted to download files that were not sendable");
|
||||||
}
|
}
|
||||||
|
@ -280,8 +273,7 @@ boolean CL_SendRequestFile(void)
|
||||||
netbuffer->packettype = PT_REQUESTFILE;
|
netbuffer->packettype = PT_REQUESTFILE;
|
||||||
p = (char *)netbuffer->u.textcmd;
|
p = (char *)netbuffer->u.textcmd;
|
||||||
for (i = 0; i < fileneedednum; i++)
|
for (i = 0; i < fileneedednum; i++)
|
||||||
if ((fileneeded[i].status == FS_NOTFOUND || fileneeded[i].status == FS_MD5SUMBAD)
|
if ((fileneeded[i].status == FS_NOTFOUND || fileneeded[i].status == FS_MD5SUMBAD))
|
||||||
&& fileneeded[i].important)
|
|
||||||
{
|
{
|
||||||
totalfreespaceneeded += fileneeded[i].totalsize;
|
totalfreespaceneeded += fileneeded[i].totalsize;
|
||||||
nameonly(fileneeded[i].filename);
|
nameonly(fileneeded[i].filename);
|
||||||
|
@ -339,10 +331,6 @@ INT32 CL_CheckFiles(void)
|
||||||
INT32 ret = 1;
|
INT32 ret = 1;
|
||||||
size_t packetsize = 0;
|
size_t packetsize = 0;
|
||||||
size_t filestoget = 0;
|
size_t filestoget = 0;
|
||||||
serverinfo_pak *dummycheck = NULL;
|
|
||||||
|
|
||||||
// Shut the compiler up.
|
|
||||||
(void)dummycheck;
|
|
||||||
|
|
||||||
// if (M_CheckParm("-nofiles"))
|
// if (M_CheckParm("-nofiles"))
|
||||||
// return 1;
|
// return 1;
|
||||||
|
@ -360,13 +348,7 @@ INT32 CL_CheckFiles(void)
|
||||||
CONS_Debug(DBG_NETPLAY, "game is modified; only doing basic checks\n");
|
CONS_Debug(DBG_NETPLAY, "game is modified; only doing basic checks\n");
|
||||||
for (i = 1, j = 1; i < fileneedednum || j < numwadfiles;)
|
for (i = 1, j = 1; i < fileneedednum || j < numwadfiles;)
|
||||||
{
|
{
|
||||||
if (i < fileneedednum && !fileneeded[i].important)
|
if (j < numwadfiles && !wadfiles[j]->important)
|
||||||
{
|
|
||||||
// Eh whatever, don't care
|
|
||||||
++i;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (j < numwadfiles && W_VerifyNMUSlumps(wadfiles[j]->filename))
|
|
||||||
{
|
{
|
||||||
// Unimportant on our side. still don't care.
|
// Unimportant on our side. still don't care.
|
||||||
++j;
|
++j;
|
||||||
|
@ -392,8 +374,7 @@ INT32 CL_CheckFiles(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
// See W_LoadWadFile in w_wad.c
|
// See W_LoadWadFile in w_wad.c
|
||||||
for (i = 0; i < numwadfiles; i++)
|
packetsize = packetsizetally;
|
||||||
packetsize += nameonlylength(wadfiles[i]->filename) + 22;
|
|
||||||
|
|
||||||
for (i = 1; i < fileneedednum; i++)
|
for (i = 1; i < fileneedednum; i++)
|
||||||
{
|
{
|
||||||
|
@ -411,13 +392,13 @@ INT32 CL_CheckFiles(void)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (fileneeded[i].status != FS_NOTFOUND || !fileneeded[i].important)
|
if (fileneeded[i].status != FS_NOTFOUND)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
packetsize += nameonlylength(fileneeded[i].filename) + 22;
|
packetsize += nameonlylength(fileneeded[i].filename) + 22;
|
||||||
|
|
||||||
if ((numwadfiles+filestoget >= MAX_WADFILES)
|
if ((numwadfiles+filestoget >= MAX_WADFILES)
|
||||||
|| (packetsize > sizeof(dummycheck->fileneeded)))
|
|| (packetsize > MAXFILENEEDED*sizeof(UINT8)))
|
||||||
return 3;
|
return 3;
|
||||||
|
|
||||||
filestoget++;
|
filestoget++;
|
||||||
|
@ -449,27 +430,8 @@ void CL_LoadServerFiles(void)
|
||||||
fileneeded[i].status = FS_OPEN;
|
fileneeded[i].status = FS_OPEN;
|
||||||
}
|
}
|
||||||
else if (fileneeded[i].status == FS_MD5SUMBAD)
|
else if (fileneeded[i].status == FS_MD5SUMBAD)
|
||||||
{
|
I_Error("Wrong version of file %s", fileneeded[i].filename);
|
||||||
// If the file is marked important, don't even bother proceeding.
|
else
|
||||||
if (fileneeded[i].important)
|
|
||||||
I_Error("Wrong version of important file %s", fileneeded[i].filename);
|
|
||||||
|
|
||||||
// If it isn't, no need to worry the user with a console message,
|
|
||||||
// although it can't hurt to put something in the debug file.
|
|
||||||
|
|
||||||
// ...but wait a second. What if the local version is "important"?
|
|
||||||
if (!W_VerifyNMUSlumps(fileneeded[i].filename))
|
|
||||||
I_Error("File %s should only contain music and sound effects!",
|
|
||||||
fileneeded[i].filename);
|
|
||||||
|
|
||||||
// Okay, NOW we know it's safe. Whew.
|
|
||||||
P_AddWadFile(fileneeded[i].filename);
|
|
||||||
if (fileneeded[i].important)
|
|
||||||
G_SetGameModified(true);
|
|
||||||
fileneeded[i].status = FS_OPEN;
|
|
||||||
DEBFILE(va("File %s found but with different md5sum\n", fileneeded[i].filename));
|
|
||||||
}
|
|
||||||
else if (fileneeded[i].important)
|
|
||||||
{
|
{
|
||||||
const char *s;
|
const char *s;
|
||||||
switch(fileneeded[i].status)
|
switch(fileneeded[i].status)
|
||||||
|
@ -939,10 +901,11 @@ void nameonly(char *s)
|
||||||
{
|
{
|
||||||
ns = &(s[j+1]);
|
ns = &(s[j+1]);
|
||||||
len = strlen(ns);
|
len = strlen(ns);
|
||||||
if (false)
|
#if 0
|
||||||
M_Memcpy(s, ns, len+1);
|
M_Memcpy(s, ns, len+1);
|
||||||
else
|
#else
|
||||||
memmove(s, ns, len+1);
|
memmove(s, ns, len+1);
|
||||||
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,6 @@ typedef enum
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
UINT8 important;
|
|
||||||
UINT8 willsend; // Is the server willing to send it?
|
UINT8 willsend; // Is the server willing to send it?
|
||||||
char filename[MAX_WADPATH];
|
char filename[MAX_WADPATH];
|
||||||
UINT8 md5sum[16];
|
UINT8 md5sum[16];
|
||||||
|
|
|
@ -8338,7 +8338,6 @@ static inline int lib_getenum(lua_State *L)
|
||||||
lua_pushinteger(L, token);
|
lua_pushinteger(L, token);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -150,9 +150,9 @@ extern FILE *logstream;
|
||||||
// we use comprevision and compbranch instead.
|
// we use comprevision and compbranch instead.
|
||||||
#else
|
#else
|
||||||
#define VERSION 201 // Game version
|
#define VERSION 201 // Game version
|
||||||
#define SUBVERSION 21 // more precise version number
|
#define SUBVERSION 22 // more precise version number
|
||||||
#define VERSIONSTRING "v2.1.21"
|
#define VERSIONSTRING "v2.1.22"
|
||||||
#define VERSIONSTRINGW L"v2.1.21"
|
#define VERSIONSTRINGW L"v2.1.22"
|
||||||
// Hey! If you change this, add 1 to the MODVERSION below!
|
// Hey! If you change this, add 1 to the MODVERSION below!
|
||||||
// Otherwise we can't force updates!
|
// Otherwise we can't force updates!
|
||||||
#endif
|
#endif
|
||||||
|
@ -161,6 +161,9 @@ extern FILE *logstream;
|
||||||
// Comment or uncomment this as necessary.
|
// Comment or uncomment this as necessary.
|
||||||
#define USE_PATCH_DTA
|
#define USE_PATCH_DTA
|
||||||
|
|
||||||
|
// Use .kart extension addons
|
||||||
|
//#define USE_KART
|
||||||
|
|
||||||
// Modification options
|
// Modification options
|
||||||
// If you want to take advantage of the Master Server's ability to force clients to update
|
// If you want to take advantage of the Master Server's ability to force clients to update
|
||||||
// to the latest version, fill these out. Otherwise, just comment out UPDATE_ALERT and leave
|
// to the latest version, fill these out. Otherwise, just comment out UPDATE_ALERT and leave
|
||||||
|
@ -214,7 +217,21 @@ extern FILE *logstream;
|
||||||
// it's only for detection of the version the player is using so the MS can alert them of an update.
|
// it's only for detection of the version the player is using so the MS can alert them of an update.
|
||||||
// Only set it higher, not lower, obviously.
|
// Only set it higher, not lower, obviously.
|
||||||
// Note that we use this to help keep internal testing in check; this is why v2.1.0 is not version "1".
|
// Note that we use this to help keep internal testing in check; this is why v2.1.0 is not version "1".
|
||||||
#define MODVERSION 26
|
#define MODVERSION 27
|
||||||
|
|
||||||
|
// To version config.cfg, MAJOREXECVERSION is set equal to MODVERSION automatically.
|
||||||
|
// Increment MINOREXECVERSION whenever a config change is needed that does not correspond
|
||||||
|
// to an increment in MODVERSION. This might never happen in practice.
|
||||||
|
// If MODVERSION increases, set MINOREXECVERSION to 0.
|
||||||
|
#define MAJOREXECVERSION MODVERSION
|
||||||
|
#define MINOREXECVERSION 0
|
||||||
|
// (It would have been nice to use VERSION and SUBVERSION but those are zero'd out for DEVELOP builds)
|
||||||
|
|
||||||
|
// Macros
|
||||||
|
#define GETMAJOREXECVERSION(v) (v & 0xFFFF)
|
||||||
|
#define GETMINOREXECVERSION(v) (v >> 16)
|
||||||
|
#define GETEXECVERSION(major,minor) (major + (minor << 16))
|
||||||
|
#define EXECVERSION GETEXECVERSION(MAJOREXECVERSION, MINOREXECVERSION)
|
||||||
|
|
||||||
// =========================================================================
|
// =========================================================================
|
||||||
|
|
||||||
|
@ -396,6 +413,7 @@ extern INT32 cv_debug;
|
||||||
|
|
||||||
// Modifier key variables, accessible anywhere
|
// Modifier key variables, accessible anywhere
|
||||||
extern UINT8 shiftdown, ctrldown, altdown;
|
extern UINT8 shiftdown, ctrldown, altdown;
|
||||||
|
extern boolean capslock;
|
||||||
|
|
||||||
// if we ever make our alloc stuff...
|
// if we ever make our alloc stuff...
|
||||||
#define ZZ_Alloc(x) Z_Malloc(x, PU_STATIC, NULL)
|
#define ZZ_Alloc(x) Z_Malloc(x, PU_STATIC, NULL)
|
||||||
|
@ -410,6 +428,15 @@ INT32 I_GetKey(void);
|
||||||
#define max(x, y) (((x) > (y)) ? (x) : (y))
|
#define max(x, y) (((x) > (y)) ? (x) : (y))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Floating point comparison epsilons from float.h
|
||||||
|
#ifndef FLT_EPSILON
|
||||||
|
#define FLT_EPSILON 1.1920928955078125e-7f
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef DBL_EPSILON
|
||||||
|
#define DBL_EPSILON 2.2204460492503131e-16
|
||||||
|
#endif
|
||||||
|
|
||||||
// An assert-type mechanism.
|
// An assert-type mechanism.
|
||||||
#ifdef PARANOIA
|
#ifdef PARANOIA
|
||||||
#define I_Assert(e) ((e) ? (void)0 : I_Error("assert failed: %s, file %s, line %d", #e, __FILE__, __LINE__))
|
#define I_Assert(e) ((e) ? (void)0 : I_Error("assert failed: %s, file %s, line %d", #e, __FILE__, __LINE__))
|
||||||
|
|
|
@ -997,7 +997,9 @@ static const char *credits[] = {
|
||||||
"Gregor \"Oogaland\" Dick",
|
"Gregor \"Oogaland\" Dick",
|
||||||
"Louis-Antoine \"LJSonic\" de Moulins", // for fixing 2.1's netcode (de Rochefort doesn't quite fit on the screen sorry lol)
|
"Louis-Antoine \"LJSonic\" de Moulins", // for fixing 2.1's netcode (de Rochefort doesn't quite fit on the screen sorry lol)
|
||||||
"Julio \"Chaos Zero 64\" Guir",
|
"Julio \"Chaos Zero 64\" Guir",
|
||||||
|
"\"Jimita\"",
|
||||||
"\"Kalaron\"", // Coded some of Sryder13's collection of OpenGL fixes, especially fog
|
"\"Kalaron\"", // Coded some of Sryder13's collection of OpenGL fixes, especially fog
|
||||||
|
"\"Lat'\"", // SRB2-CHAT, the chat window from Kart
|
||||||
"Matthew \"Shuffle\" Marsalko",
|
"Matthew \"Shuffle\" Marsalko",
|
||||||
"Steven \"StroggOnMeth\" McGranahan",
|
"Steven \"StroggOnMeth\" McGranahan",
|
||||||
"\"Morph\"", // For SRB2Morphed stuff
|
"\"Morph\"", // For SRB2Morphed stuff
|
||||||
|
@ -1006,9 +1008,9 @@ static const char *credits[] = {
|
||||||
"Tasos \"tatokis\" Sahanidis", // Corrected C FixedMul, making 64-bit builds netplay compatible
|
"Tasos \"tatokis\" Sahanidis", // Corrected C FixedMul, making 64-bit builds netplay compatible
|
||||||
"\"Steel Titanium\"",
|
"\"Steel Titanium\"",
|
||||||
"Ben \"Cue\" Woodford",
|
"Ben \"Cue\" Woodford",
|
||||||
// Git contributors with 5+ approved merges, at least a few of substantive quality, may be named
|
// Git contributors with 5+ approved merges of substantive quality,
|
||||||
// Everyone else is acknowledged here
|
// or contributors with at least one groundbreaking merge, may be named.
|
||||||
"STJr Git Contributors",
|
// Everyone else is acknowledged under "Special Thanks > SRB2 Community Contributors".
|
||||||
"",
|
"",
|
||||||
"\1Sprite Artists",
|
"\1Sprite Artists",
|
||||||
"Odi \"Iceman404\" Atunzu",
|
"Odi \"Iceman404\" Atunzu",
|
||||||
|
@ -1089,7 +1091,10 @@ static const char *credits[] = {
|
||||||
"Pascal \"CodeImp\" vd Heiden", // Doom Builder developer
|
"Pascal \"CodeImp\" vd Heiden", // Doom Builder developer
|
||||||
"Randi Heit (<!>)", // For their MSPaint <!> sprite that we nicked
|
"Randi Heit (<!>)", // For their MSPaint <!> sprite that we nicked
|
||||||
"Simon \"sirjuddington\" Judd", // SLADE developer
|
"Simon \"sirjuddington\" Judd", // SLADE developer
|
||||||
|
// Acknowledged here are the following:
|
||||||
|
// Minor merge request authors, see guideline above
|
||||||
|
// Golden - Expanded thin font
|
||||||
|
"SRB2 Community Contributors",
|
||||||
"",
|
"",
|
||||||
"\1Produced By",
|
"\1Produced By",
|
||||||
"Sonic Team Junior",
|
"Sonic Team Junior",
|
||||||
|
|
477
src/filesrch.c
477
src/filesrch.c
|
@ -31,6 +31,8 @@
|
||||||
#include "filesrch.h"
|
#include "filesrch.h"
|
||||||
#include "d_netfil.h"
|
#include "d_netfil.h"
|
||||||
#include "m_misc.h"
|
#include "m_misc.h"
|
||||||
|
#include "z_zone.h"
|
||||||
|
#include "m_menu.h" // Addons_option_Onchange
|
||||||
|
|
||||||
#if (defined (_WIN32) && !defined (_WIN32_WCE)) && defined (_MSC_VER) && !defined (_XBOX)
|
#if (defined (_WIN32) && !defined (_WIN32_WCE)) && defined (_MSC_VER) && !defined (_XBOX)
|
||||||
|
|
||||||
|
@ -255,6 +257,28 @@ readdir (DIR * dirp)
|
||||||
return (struct dirent *) 0;
|
return (struct dirent *) 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* rewinddir
|
||||||
|
*
|
||||||
|
* Makes the next readdir start from the beginning.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
rewinddir (DIR * dirp)
|
||||||
|
{
|
||||||
|
errno = 0;
|
||||||
|
|
||||||
|
/* Check for valid DIR struct. */
|
||||||
|
if (!dirp)
|
||||||
|
{
|
||||||
|
errno = EFAULT;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
dirp->dd_stat = 0;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* closedir
|
* closedir
|
||||||
*
|
*
|
||||||
|
@ -285,6 +309,41 @@ closedir (DIR * dirp)
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static CV_PossibleValue_t addons_cons_t[] = {{0, "Default"},
|
||||||
|
#if 1
|
||||||
|
{1, "HOME"}, {2, "SRB2"},
|
||||||
|
#endif
|
||||||
|
{3, "CUSTOM"}, {0, NULL}};
|
||||||
|
|
||||||
|
consvar_t cv_addons_option = {"addons_option", "Default", CV_SAVE|CV_CALL, addons_cons_t, Addons_option_Onchange, 0, NULL, NULL, 0, 0, NULL};
|
||||||
|
consvar_t cv_addons_folder = {"addons_folder", "", CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
|
|
||||||
|
static CV_PossibleValue_t addons_md5_cons_t[] = {{0, "Name"}, {1, "Contents"}, {0, NULL}};
|
||||||
|
consvar_t cv_addons_md5 = {"addons_md5", "Name", CV_SAVE, addons_md5_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
|
|
||||||
|
consvar_t cv_addons_showall = {"addons_showall", "No", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
|
|
||||||
|
consvar_t cv_addons_search_case = {"addons_search_case", "No", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
|
|
||||||
|
static CV_PossibleValue_t addons_search_type_cons_t[] = {{0, "Start"}, {1, "Anywhere"}, {0, NULL}};
|
||||||
|
consvar_t cv_addons_search_type = {"addons_search_type", "Anywhere", CV_SAVE, addons_search_type_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
|
|
||||||
|
char menupath[1024];
|
||||||
|
size_t menupathindex[menudepth];
|
||||||
|
size_t menudepthleft = menudepth;
|
||||||
|
|
||||||
|
char menusearch[MAXSTRINGLENGTH+1];
|
||||||
|
|
||||||
|
char **dirmenu, **coredirmenu; // core only local for this file
|
||||||
|
size_t sizedirmenu, sizecoredirmenu; // ditto
|
||||||
|
size_t dir_on[menudepth];
|
||||||
|
UINT8 refreshdirmenu = 0;
|
||||||
|
char *refreshdirname = NULL;
|
||||||
|
|
||||||
|
size_t packetsizetally = 0;
|
||||||
|
size_t mainwadstally = 0;
|
||||||
|
|
||||||
#if defined (_XBOX) && defined (_MSC_VER)
|
#if defined (_XBOX) && defined (_MSC_VER)
|
||||||
filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *wantedmd5sum,
|
filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *wantedmd5sum,
|
||||||
boolean completepath, int maxsearchdepth)
|
boolean completepath, int maxsearchdepth)
|
||||||
|
@ -296,6 +355,25 @@ filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *want
|
||||||
completepath = false;
|
completepath = false;
|
||||||
return FS_NOTFOUND;
|
return FS_NOTFOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void closefilemenu(boolean validsize)
|
||||||
|
{
|
||||||
|
(void)validsize;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void searchfilemenu(char *tempname)
|
||||||
|
{
|
||||||
|
(void)tempname;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean preparefilemenu(boolean samedepth)
|
||||||
|
{
|
||||||
|
(void)samedepth;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
#elif defined (_WIN32_WCE)
|
#elif defined (_WIN32_WCE)
|
||||||
filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *wantedmd5sum,
|
filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *wantedmd5sum,
|
||||||
boolean completepath, int maxsearchdepth)
|
boolean completepath, int maxsearchdepth)
|
||||||
|
@ -346,7 +424,27 @@ filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *want
|
||||||
#endif
|
#endif
|
||||||
return FS_NOTFOUND;
|
return FS_NOTFOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void closefilemenu(boolean validsize)
|
||||||
|
{
|
||||||
|
(void)validsize;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void searchfilemenu(char *tempname)
|
||||||
|
{
|
||||||
|
(void)tempname;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean preparefilemenu(boolean samedepth)
|
||||||
|
{
|
||||||
|
(void)samedepth;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *wantedmd5sum, boolean completepath, int maxsearchdepth)
|
filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *wantedmd5sum, boolean completepath, int maxsearchdepth)
|
||||||
{
|
{
|
||||||
filestatus_t retval = FS_NOTFOUND;
|
filestatus_t retval = FS_NOTFOUND;
|
||||||
|
@ -387,25 +485,29 @@ filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *want
|
||||||
{
|
{
|
||||||
searchpath[searchpathindex[depthleft]]=0;
|
searchpath[searchpathindex[depthleft]]=0;
|
||||||
dent = readdir(dirhandle[depthleft]);
|
dent = readdir(dirhandle[depthleft]);
|
||||||
if (dent)
|
|
||||||
strcpy(&searchpath[searchpathindex[depthleft]],dent->d_name);
|
|
||||||
|
|
||||||
if (!dent)
|
if (!dent)
|
||||||
|
{
|
||||||
closedir(dirhandle[depthleft++]);
|
closedir(dirhandle[depthleft++]);
|
||||||
else if (dent->d_name[0]=='.' &&
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dent->d_name[0]=='.' &&
|
||||||
(dent->d_name[1]=='\0' ||
|
(dent->d_name[1]=='\0' ||
|
||||||
(dent->d_name[1]=='.' &&
|
(dent->d_name[1]=='.' &&
|
||||||
dent->d_name[2]=='\0')))
|
dent->d_name[2]=='\0')))
|
||||||
{
|
{
|
||||||
// we don't want to scan uptree
|
// we don't want to scan uptree
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
else if (stat(searchpath,&fsstat) < 0) // do we want to follow symlinks? if not: change it to lstat
|
|
||||||
{
|
// okay, now we actually want searchpath to incorporate d_name
|
||||||
// was the file (re)moved? can't stat it
|
strcpy(&searchpath[searchpathindex[depthleft]],dent->d_name);
|
||||||
}
|
|
||||||
|
if (stat(searchpath,&fsstat) < 0) // do we want to follow symlinks? if not: change it to lstat
|
||||||
|
; // was the file (re)moved? can't stat it
|
||||||
else if (S_ISDIR(fsstat.st_mode) && depthleft)
|
else if (S_ISDIR(fsstat.st_mode) && depthleft)
|
||||||
{
|
{
|
||||||
strcpy(&searchpath[searchpathindex[depthleft]],dent->d_name);
|
|
||||||
searchpathindex[--depthleft] = strlen(searchpath) + 1;
|
searchpathindex[--depthleft] = strlen(searchpath) + 1;
|
||||||
dirhandle[depthleft] = opendir(searchpath);
|
dirhandle[depthleft] = opendir(searchpath);
|
||||||
if (!dirhandle[depthleft])
|
if (!dirhandle[depthleft])
|
||||||
|
@ -444,6 +546,365 @@ filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *want
|
||||||
free(searchname);
|
free(searchname);
|
||||||
free(searchpathindex);
|
free(searchpathindex);
|
||||||
free(dirhandle);
|
free(dirhandle);
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char exttable[NUM_EXT_TABLE][7] = { // maximum extension length (currently 4) plus 3 (null terminator, stop, and length including previous two)
|
||||||
|
"\5.txt", "\5.cfg", // exec
|
||||||
|
"\5.wad",
|
||||||
|
#ifdef USE_KART
|
||||||
|
"\6.kart",
|
||||||
|
#endif
|
||||||
|
"\5.pk3", "\5.soc", "\5.lua"}; // addfile
|
||||||
|
|
||||||
|
char filenamebuf[MAX_WADFILES][MAX_WADPATH];
|
||||||
|
|
||||||
|
|
||||||
|
static boolean filemenucmp(char *haystack, char *needle)
|
||||||
|
{
|
||||||
|
static char localhaystack[128];
|
||||||
|
strlcpy(localhaystack, haystack, 128);
|
||||||
|
if (!cv_addons_search_case.value)
|
||||||
|
strupr(localhaystack);
|
||||||
|
if (cv_addons_search_type.value)
|
||||||
|
return (strstr(localhaystack, needle) != 0);
|
||||||
|
return (!strncmp(localhaystack, needle, menusearch[0]));
|
||||||
|
}
|
||||||
|
|
||||||
|
void closefilemenu(boolean validsize)
|
||||||
|
{
|
||||||
|
// search
|
||||||
|
if (dirmenu)
|
||||||
|
{
|
||||||
|
if (dirmenu != coredirmenu)
|
||||||
|
{
|
||||||
|
if (dirmenu[0] && ((UINT8)(dirmenu[0][DIR_TYPE]) == EXT_NORESULTS))
|
||||||
|
{
|
||||||
|
Z_Free(dirmenu[0]);
|
||||||
|
dirmenu[0] = NULL;
|
||||||
|
}
|
||||||
|
Z_Free(dirmenu);
|
||||||
|
}
|
||||||
|
dirmenu = NULL;
|
||||||
|
sizedirmenu = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (coredirmenu)
|
||||||
|
{
|
||||||
|
// core
|
||||||
|
if (validsize)
|
||||||
|
{
|
||||||
|
for (; sizecoredirmenu > 0; sizecoredirmenu--)
|
||||||
|
{
|
||||||
|
Z_Free(coredirmenu[sizecoredirmenu-1]);
|
||||||
|
coredirmenu[sizecoredirmenu-1] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
sizecoredirmenu = 0;
|
||||||
|
|
||||||
|
Z_Free(coredirmenu);
|
||||||
|
coredirmenu = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (refreshdirname)
|
||||||
|
Z_Free(refreshdirname);
|
||||||
|
refreshdirname = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void searchfilemenu(char *tempname)
|
||||||
|
{
|
||||||
|
size_t i, first;
|
||||||
|
char localmenusearch[MAXSTRINGLENGTH] = "";
|
||||||
|
|
||||||
|
if (dirmenu)
|
||||||
|
{
|
||||||
|
if (dirmenu != coredirmenu)
|
||||||
|
{
|
||||||
|
if (dirmenu[0] && ((UINT8)(dirmenu[0][DIR_TYPE]) == EXT_NORESULTS))
|
||||||
|
{
|
||||||
|
Z_Free(dirmenu[0]);
|
||||||
|
dirmenu[0] = NULL;
|
||||||
|
}
|
||||||
|
//Z_Free(dirmenu); -- Z_Realloc later tho...
|
||||||
|
}
|
||||||
|
else
|
||||||
|
dirmenu = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
first = (((UINT8)(coredirmenu[0][DIR_TYPE]) == EXT_UP) ? 1 : 0); // skip UP...
|
||||||
|
|
||||||
|
if (!menusearch[0])
|
||||||
|
{
|
||||||
|
if (dirmenu)
|
||||||
|
Z_Free(dirmenu);
|
||||||
|
dirmenu = coredirmenu;
|
||||||
|
sizedirmenu = sizecoredirmenu;
|
||||||
|
|
||||||
|
if (tempname)
|
||||||
|
{
|
||||||
|
for (i = first; i < sizedirmenu; i++)
|
||||||
|
{
|
||||||
|
if (!strcmp(dirmenu[i]+DIR_STRING, tempname))
|
||||||
|
{
|
||||||
|
dir_on[menudepthleft] = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == sizedirmenu)
|
||||||
|
dir_on[menudepthleft] = first;
|
||||||
|
|
||||||
|
Z_Free(tempname);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
strcpy(localmenusearch, menusearch+1);
|
||||||
|
if (!cv_addons_search_case.value)
|
||||||
|
strupr(localmenusearch);
|
||||||
|
|
||||||
|
sizedirmenu = 0;
|
||||||
|
for (i = first; i < sizecoredirmenu; i++)
|
||||||
|
{
|
||||||
|
if (filemenucmp(coredirmenu[i]+DIR_STRING, localmenusearch))
|
||||||
|
sizedirmenu++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!sizedirmenu) // no results...
|
||||||
|
{
|
||||||
|
if ((!(dirmenu = Z_Realloc(dirmenu, sizeof(char *), PU_STATIC, NULL)))
|
||||||
|
|| !(dirmenu[0] = Z_StrDup(va("%c\13No results...", EXT_NORESULTS))))
|
||||||
|
I_Error("searchfilemenu(): could not create \"No results...\".");
|
||||||
|
sizedirmenu = 1;
|
||||||
|
dir_on[menudepthleft] = 0;
|
||||||
|
if (tempname)
|
||||||
|
Z_Free(tempname);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(dirmenu = Z_Realloc(dirmenu, sizedirmenu*sizeof(char *), PU_STATIC, NULL)))
|
||||||
|
I_Error("searchfilemenu(): could not reallocate dirmenu.");
|
||||||
|
|
||||||
|
sizedirmenu = 0;
|
||||||
|
for (i = first; i < sizecoredirmenu; i++)
|
||||||
|
{
|
||||||
|
if (filemenucmp(coredirmenu[i]+DIR_STRING, localmenusearch))
|
||||||
|
{
|
||||||
|
if (tempname && !strcmp(coredirmenu[i]+DIR_STRING, tempname))
|
||||||
|
{
|
||||||
|
dir_on[menudepthleft] = sizedirmenu;
|
||||||
|
Z_Free(tempname);
|
||||||
|
tempname = NULL;
|
||||||
|
}
|
||||||
|
dirmenu[sizedirmenu++] = coredirmenu[i]; // pointer reuse
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tempname)
|
||||||
|
{
|
||||||
|
dir_on[menudepthleft] = 0; //first; -- can't be first, causes problems
|
||||||
|
Z_Free(tempname);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean preparefilemenu(boolean samedepth)
|
||||||
|
{
|
||||||
|
DIR *dirhandle;
|
||||||
|
struct dirent *dent;
|
||||||
|
struct stat fsstat;
|
||||||
|
size_t pos = 0, folderpos = 0, numfolders = 0;
|
||||||
|
char *tempname = NULL;
|
||||||
|
|
||||||
|
if (samedepth)
|
||||||
|
{
|
||||||
|
if (dirmenu && dirmenu[dir_on[menudepthleft]])
|
||||||
|
tempname = Z_StrDup(dirmenu[dir_on[menudepthleft]]+DIR_STRING); // don't need to I_Error if can't make - not important, just QoL
|
||||||
|
}
|
||||||
|
else
|
||||||
|
menusearch[0] = menusearch[1] = 0; // clear search
|
||||||
|
|
||||||
|
if (!(dirhandle = opendir(menupath))) // get directory
|
||||||
|
{
|
||||||
|
closefilemenu(true);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (; sizecoredirmenu > 0; sizecoredirmenu--) // clear out existing items
|
||||||
|
{
|
||||||
|
Z_Free(coredirmenu[sizecoredirmenu-1]);
|
||||||
|
coredirmenu[sizecoredirmenu-1] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
menupath[menupathindex[menudepthleft]] = 0;
|
||||||
|
dent = readdir(dirhandle);
|
||||||
|
|
||||||
|
if (!dent)
|
||||||
|
break;
|
||||||
|
else if (dent->d_name[0]=='.' &&
|
||||||
|
(dent->d_name[1]=='\0' ||
|
||||||
|
(dent->d_name[1]=='.' &&
|
||||||
|
dent->d_name[2]=='\0')))
|
||||||
|
continue; // we don't want to scan uptree
|
||||||
|
|
||||||
|
strcpy(&menupath[menupathindex[menudepthleft]],dent->d_name);
|
||||||
|
|
||||||
|
if (stat(menupath,&fsstat) < 0) // do we want to follow symlinks? if not: change it to lstat
|
||||||
|
; // was the file (re)moved? can't stat it
|
||||||
|
else // is a file or directory
|
||||||
|
{
|
||||||
|
if (!S_ISDIR(fsstat.st_mode)) // file
|
||||||
|
{
|
||||||
|
if (!cv_addons_showall.value)
|
||||||
|
{
|
||||||
|
size_t len = strlen(dent->d_name)+1;
|
||||||
|
UINT8 ext;
|
||||||
|
for (ext = 0; ext < NUM_EXT_TABLE; ext++)
|
||||||
|
if (!strcasecmp(exttable[ext]+1, dent->d_name+len-(exttable[ext][0]))) break; // extension comparison
|
||||||
|
if (ext == NUM_EXT_TABLE) continue; // not an addfile-able (or exec-able) file
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // directory
|
||||||
|
numfolders++;
|
||||||
|
|
||||||
|
sizecoredirmenu++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!sizecoredirmenu)
|
||||||
|
{
|
||||||
|
closedir(dirhandle);
|
||||||
|
closefilemenu(false);
|
||||||
|
if (tempname)
|
||||||
|
Z_Free(tempname);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (menudepthleft != menudepth-1) // Make room for UP...
|
||||||
|
{
|
||||||
|
sizecoredirmenu++;
|
||||||
|
numfolders++;
|
||||||
|
folderpos++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dirmenu && dirmenu == coredirmenu)
|
||||||
|
dirmenu = NULL;
|
||||||
|
|
||||||
|
if (!(coredirmenu = Z_Realloc(coredirmenu, sizecoredirmenu*sizeof(char *), PU_STATIC, NULL)))
|
||||||
|
{
|
||||||
|
closedir(dirhandle); // just in case
|
||||||
|
I_Error("preparefilemenu(): could not reallocate coredirmenu.");
|
||||||
|
}
|
||||||
|
|
||||||
|
rewinddir(dirhandle);
|
||||||
|
|
||||||
|
while ((pos+folderpos) < sizecoredirmenu)
|
||||||
|
{
|
||||||
|
menupath[menupathindex[menudepthleft]] = 0;
|
||||||
|
dent = readdir(dirhandle);
|
||||||
|
|
||||||
|
if (!dent)
|
||||||
|
break;
|
||||||
|
else if (dent->d_name[0]=='.' &&
|
||||||
|
(dent->d_name[1]=='\0' ||
|
||||||
|
(dent->d_name[1]=='.' &&
|
||||||
|
dent->d_name[2]=='\0')))
|
||||||
|
continue; // we don't want to scan uptree
|
||||||
|
|
||||||
|
strcpy(&menupath[menupathindex[menudepthleft]],dent->d_name);
|
||||||
|
|
||||||
|
if (stat(menupath,&fsstat) < 0) // do we want to follow symlinks? if not: change it to lstat
|
||||||
|
; // was the file (re)moved? can't stat it
|
||||||
|
else // is a file or directory
|
||||||
|
{
|
||||||
|
char *temp;
|
||||||
|
size_t len = strlen(dent->d_name)+1;
|
||||||
|
UINT8 ext = EXT_FOLDER;
|
||||||
|
UINT8 folder;
|
||||||
|
|
||||||
|
if (!S_ISDIR(fsstat.st_mode)) // file
|
||||||
|
{
|
||||||
|
if (!((numfolders+pos) < sizecoredirmenu)) continue; // crash prevention
|
||||||
|
for (; ext < NUM_EXT_TABLE; ext++)
|
||||||
|
if (!strcasecmp(exttable[ext]+1, dent->d_name+len-(exttable[ext][0]))) break; // extension comparison
|
||||||
|
if (ext == NUM_EXT_TABLE && !cv_addons_showall.value) continue; // not an addfile-able (or exec-able) file
|
||||||
|
ext += EXT_START; // moving to be appropriate position
|
||||||
|
|
||||||
|
if (ext >= EXT_LOADSTART)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
for (i = 0; i < numwadfiles; i++)
|
||||||
|
{
|
||||||
|
if (!filenamebuf[i][0])
|
||||||
|
{
|
||||||
|
strncpy(filenamebuf[i], wadfiles[i]->filename, MAX_WADPATH);
|
||||||
|
filenamebuf[i][MAX_WADPATH - 1] = '\0';
|
||||||
|
nameonly(filenamebuf[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(dent->d_name, filenamebuf[i]))
|
||||||
|
continue;
|
||||||
|
if (cv_addons_md5.value && !checkfilemd5(menupath, wadfiles[i]->md5sum))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ext |= EXT_LOADED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (ext == EXT_TXT)
|
||||||
|
{
|
||||||
|
if (!strcmp(dent->d_name, "log.txt") || !strcmp(dent->d_name, "errorlog.txt"))
|
||||||
|
ext |= EXT_LOADED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp(dent->d_name, configfile))
|
||||||
|
ext |= EXT_LOADED;
|
||||||
|
|
||||||
|
folder = 0;
|
||||||
|
}
|
||||||
|
else // directory
|
||||||
|
len += (folder = 1);
|
||||||
|
|
||||||
|
if (len > 255)
|
||||||
|
len = 255;
|
||||||
|
|
||||||
|
if (!(temp = Z_Malloc((len+DIR_STRING+folder) * sizeof (char), PU_STATIC, NULL)))
|
||||||
|
I_Error("preparefilemenu(): could not create file entry.");
|
||||||
|
temp[DIR_TYPE] = ext;
|
||||||
|
temp[DIR_LEN] = (UINT8)(len);
|
||||||
|
strlcpy(temp+DIR_STRING, dent->d_name, len);
|
||||||
|
if (folder)
|
||||||
|
{
|
||||||
|
strcpy(temp+len, PATHSEP);
|
||||||
|
coredirmenu[folderpos++] = temp;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
coredirmenu[numfolders + pos++] = temp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
closedir(dirhandle);
|
||||||
|
|
||||||
|
if ((menudepthleft != menudepth-1) // now for UP... entry
|
||||||
|
&& !(coredirmenu[0] = Z_StrDup(va("%c\5UP...", EXT_UP))))
|
||||||
|
I_Error("preparefilemenu(): could not create \"UP...\".");
|
||||||
|
|
||||||
|
menupath[menupathindex[menudepthleft]] = 0;
|
||||||
|
sizecoredirmenu = (numfolders+pos); // just in case things shrink between opening and rewind
|
||||||
|
|
||||||
|
if (!sizecoredirmenu)
|
||||||
|
{
|
||||||
|
dir_on[menudepthleft] = 0;
|
||||||
|
closefilemenu(false);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
searchfilemenu(tempname);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -6,6 +6,9 @@
|
||||||
|
|
||||||
#include "doomdef.h"
|
#include "doomdef.h"
|
||||||
#include "d_netfil.h"
|
#include "d_netfil.h"
|
||||||
|
#include "m_menu.h" // MAXSTRINGLENGTH
|
||||||
|
|
||||||
|
extern consvar_t cv_addons_option, cv_addons_folder, cv_addons_md5, cv_addons_showall, cv_addons_search_case, cv_addons_search_type;
|
||||||
|
|
||||||
/** \brief The filesearch function
|
/** \brief The filesearch function
|
||||||
|
|
||||||
|
@ -25,4 +28,71 @@
|
||||||
filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *wantedmd5sum,
|
filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *wantedmd5sum,
|
||||||
boolean completepath, int maxsearchdepth);
|
boolean completepath, int maxsearchdepth);
|
||||||
|
|
||||||
|
#define menudepth 20
|
||||||
|
|
||||||
|
extern char menupath[1024];
|
||||||
|
extern size_t menupathindex[menudepth];
|
||||||
|
extern size_t menudepthleft;
|
||||||
|
|
||||||
|
extern char menusearch[MAXSTRINGLENGTH+1];
|
||||||
|
|
||||||
|
extern char **dirmenu;
|
||||||
|
extern size_t sizedirmenu;
|
||||||
|
extern size_t dir_on[menudepth];
|
||||||
|
extern UINT8 refreshdirmenu;
|
||||||
|
extern char *refreshdirname;
|
||||||
|
|
||||||
|
extern size_t packetsizetally;
|
||||||
|
extern size_t mainwadstally;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
EXT_FOLDER = 0,
|
||||||
|
EXT_UP,
|
||||||
|
EXT_NORESULTS,
|
||||||
|
EXT_START,
|
||||||
|
EXT_TXT = EXT_START,
|
||||||
|
EXT_CFG,
|
||||||
|
EXT_LOADSTART,
|
||||||
|
EXT_WAD = EXT_LOADSTART,
|
||||||
|
#ifdef USE_KART
|
||||||
|
EXT_KART,
|
||||||
|
#endif
|
||||||
|
EXT_PK3,
|
||||||
|
EXT_SOC,
|
||||||
|
EXT_LUA, // allowed even if not HAVE_BLUA so that we can yell on load attempt
|
||||||
|
NUM_EXT,
|
||||||
|
NUM_EXT_TABLE = NUM_EXT-EXT_START,
|
||||||
|
EXT_LOADED = 0x80
|
||||||
|
/*
|
||||||
|
obviously there can only be 0x7F supported extensions in
|
||||||
|
addons menu because we're cramming this into a char out of
|
||||||
|
laziness/easy memory allocation (what's the difference?)
|
||||||
|
and have stolen a bit to show whether it's loaded or not
|
||||||
|
in practice the size of the data type is probably overkill
|
||||||
|
toast 02/05/17
|
||||||
|
*/
|
||||||
|
} ext_enum;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
DIR_TYPE = 0,
|
||||||
|
DIR_LEN,
|
||||||
|
DIR_STRING
|
||||||
|
} dirname_enum;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
REFRESHDIR_NORMAL = 1,
|
||||||
|
REFRESHDIR_ADDFILE = 2,
|
||||||
|
REFRESHDIR_WARNING = 4,
|
||||||
|
REFRESHDIR_ERROR = 8,
|
||||||
|
REFRESHDIR_NOTLOADED = 16,
|
||||||
|
REFRESHDIR_MAX = 32
|
||||||
|
} refreshdir_enum;
|
||||||
|
|
||||||
|
void closefilemenu(boolean validsize);
|
||||||
|
void searchfilemenu(char *tempname);
|
||||||
|
boolean preparefilemenu(boolean samedepth);
|
||||||
|
|
||||||
#endif // __FILESRCH_H__
|
#endif // __FILESRCH_H__
|
||||||
|
|
33
src/g_game.c
33
src/g_game.c
|
@ -347,6 +347,37 @@ static CV_PossibleValue_t joyaxis_cons_t[] = {{0, "None"},
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// don't mind me putting these here, I was lazy to figure out where else I could put those without blowing up the compiler.
|
||||||
|
|
||||||
|
// it automatically becomes compact with 20+ players, but if you like it, I guess you can turn that on!
|
||||||
|
consvar_t cv_compactscoreboard= {"compactscoreboard", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
|
|
||||||
|
// chat timer thingy
|
||||||
|
static CV_PossibleValue_t chattime_cons_t[] = {{5, "MIN"}, {999, "MAX"}, {0, NULL}};
|
||||||
|
consvar_t cv_chattime = {"chattime", "8", CV_SAVE, chattime_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
|
|
||||||
|
// chatwidth
|
||||||
|
static CV_PossibleValue_t chatwidth_cons_t[] = {{64, "MIN"}, {150, "MAX"}, {0, NULL}};
|
||||||
|
consvar_t cv_chatwidth = {"chatwidth", "128", CV_SAVE, chatwidth_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
|
|
||||||
|
// chatheight
|
||||||
|
static CV_PossibleValue_t chatheight_cons_t[] = {{6, "MIN"}, {22, "MAX"}, {0, NULL}};
|
||||||
|
consvar_t cv_chatheight= {"chatheight", "8", CV_SAVE, chatheight_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
|
|
||||||
|
// chat notifications (do you want to hear beeps? I'd understand if you didn't.)
|
||||||
|
consvar_t cv_chatnotifications= {"chatnotifications", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
|
|
||||||
|
// chat spam protection (why would you want to disable that???)
|
||||||
|
consvar_t cv_chatspamprotection= {"chatspamprotection", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
|
|
||||||
|
// minichat text background
|
||||||
|
consvar_t cv_chatbacktint = {"chatbacktint", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
|
|
||||||
|
// old shit console chat. (mostly exists for stuff like terminal, not because I cared if anyone liked the old chat.)
|
||||||
|
static CV_PossibleValue_t consolechat_cons_t[] = {{0, "Window"}, {1, "Console"}, {2, "Window (Hidden)"}, {0, NULL}};
|
||||||
|
consvar_t cv_consolechat = {"chatmode", "Window", CV_SAVE, consolechat_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
|
|
||||||
|
|
||||||
consvar_t cv_crosshair = {"crosshair", "Cross", CV_SAVE, crosshair_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
consvar_t cv_crosshair = {"crosshair", "Cross", CV_SAVE, crosshair_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
consvar_t cv_crosshair2 = {"crosshair2", "Cross", CV_SAVE, crosshair_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
consvar_t cv_crosshair2 = {"crosshair2", "Cross", CV_SAVE, crosshair_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
consvar_t cv_invertmouse = {"invertmouse", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
consvar_t cv_invertmouse = {"invertmouse", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
|
@ -3662,7 +3693,7 @@ void G_InitNew(UINT8 pultmode, const char *mapname, boolean resetplayer, boolean
|
||||||
unlocktriggers = 0;
|
unlocktriggers = 0;
|
||||||
|
|
||||||
// clear itemfinder, just in case
|
// clear itemfinder, just in case
|
||||||
if (!dedicated) // except in dedicated servers, where it is not registered and can actually I_Error debug builds
|
if (!dedicated) // except in dedicated servers, where it is not registered and can actually I_Error debug builds
|
||||||
CV_StealthSetValue(&cv_itemfinder, 0);
|
CV_StealthSetValue(&cv_itemfinder, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,6 +54,7 @@ extern tic_t timeinmap; // Ticker for time spent in level (used for levelcard di
|
||||||
extern INT16 rw_maximums[NUM_WEAPONS];
|
extern INT16 rw_maximums[NUM_WEAPONS];
|
||||||
|
|
||||||
// used in game menu
|
// used in game menu
|
||||||
|
extern consvar_t cv_chatwidth, cv_chatnotifications, cv_chatheight, cv_chattime, cv_consolechat, cv_chatbacktint, cv_chatspamprotection, cv_compactscoreboard;
|
||||||
extern consvar_t cv_crosshair, cv_crosshair2;
|
extern consvar_t cv_crosshair, cv_crosshair2;
|
||||||
extern consvar_t cv_invertmouse, cv_alwaysfreelook, cv_chasefreelook, cv_mousemove;
|
extern consvar_t cv_invertmouse, cv_alwaysfreelook, cv_chasefreelook, cv_mousemove;
|
||||||
extern consvar_t cv_invertmouse2, cv_alwaysfreelook2, cv_chasefreelook2, cv_mousemove2;
|
extern consvar_t cv_invertmouse2, cv_alwaysfreelook2, cv_chasefreelook2, cv_mousemove2;
|
||||||
|
|
205
src/g_input.c
205
src/g_input.c
|
@ -98,6 +98,8 @@ void G_MapEventsToControls(event_t *ev)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ev_mouse: // buttons are virtual keys
|
case ev_mouse: // buttons are virtual keys
|
||||||
|
if (menuactive || CON_Ready() || chat_on)
|
||||||
|
break;
|
||||||
mousex = (INT32)(ev->data2*((cv_mousesens.value*cv_mousesens.value)/110.0f + 0.1f));
|
mousex = (INT32)(ev->data2*((cv_mousesens.value*cv_mousesens.value)/110.0f + 0.1f));
|
||||||
mousey = (INT32)(ev->data3*((cv_mousesens.value*cv_mousesens.value)/110.0f + 0.1f));
|
mousey = (INT32)(ev->data3*((cv_mousesens.value*cv_mousesens.value)/110.0f + 0.1f));
|
||||||
mlooky = (INT32)(ev->data3*((cv_mouseysens.value*cv_mousesens.value)/110.0f + 0.1f));
|
mlooky = (INT32)(ev->data3*((cv_mouseysens.value*cv_mousesens.value)/110.0f + 0.1f));
|
||||||
|
@ -105,7 +107,7 @@ void G_MapEventsToControls(event_t *ev)
|
||||||
|
|
||||||
case ev_joystick: // buttons are virtual keys
|
case ev_joystick: // buttons are virtual keys
|
||||||
i = ev->data1;
|
i = ev->data1;
|
||||||
if (i >= JOYAXISSET)
|
if (i >= JOYAXISSET || menuactive || CON_Ready() || chat_on)
|
||||||
break;
|
break;
|
||||||
if (ev->data2 != INT32_MAX) joyxmove[i] = ev->data2;
|
if (ev->data2 != INT32_MAX) joyxmove[i] = ev->data2;
|
||||||
if (ev->data3 != INT32_MAX) joyymove[i] = ev->data3;
|
if (ev->data3 != INT32_MAX) joyymove[i] = ev->data3;
|
||||||
|
@ -113,13 +115,15 @@ void G_MapEventsToControls(event_t *ev)
|
||||||
|
|
||||||
case ev_joystick2: // buttons are virtual keys
|
case ev_joystick2: // buttons are virtual keys
|
||||||
i = ev->data1;
|
i = ev->data1;
|
||||||
if (i >= JOYAXISSET)
|
if (i >= JOYAXISSET || menuactive || CON_Ready() || chat_on)
|
||||||
break;
|
break;
|
||||||
if (ev->data2 != INT32_MAX) joy2xmove[i] = ev->data2;
|
if (ev->data2 != INT32_MAX) joy2xmove[i] = ev->data2;
|
||||||
if (ev->data3 != INT32_MAX) joy2ymove[i] = ev->data3;
|
if (ev->data3 != INT32_MAX) joy2ymove[i] = ev->data3;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ev_mouse2: // buttons are virtual keys
|
case ev_mouse2: // buttons are virtual keys
|
||||||
|
if (menuactive || CON_Ready() || chat_on)
|
||||||
|
break;
|
||||||
mouse2x = (INT32)(ev->data2*((cv_mousesens2.value*cv_mousesens2.value)/110.0f + 0.1f));
|
mouse2x = (INT32)(ev->data2*((cv_mousesens2.value*cv_mousesens2.value)/110.0f + 0.1f));
|
||||||
mouse2y = (INT32)(ev->data3*((cv_mousesens2.value*cv_mousesens2.value)/110.0f + 0.1f));
|
mouse2y = (INT32)(ev->data3*((cv_mousesens2.value*cv_mousesens2.value)/110.0f + 0.1f));
|
||||||
mlook2y = (INT32)(ev->data3*((cv_mouseysens2.value*cv_mousesens2.value)/110.0f + 0.1f));
|
mlook2y = (INT32)(ev->data3*((cv_mouseysens2.value*cv_mousesens2.value)/110.0f + 0.1f));
|
||||||
|
@ -1204,6 +1208,7 @@ void G_Controldefault(void)
|
||||||
gamecontrol[gc_lookup ][0] = KEY_UPARROW;
|
gamecontrol[gc_lookup ][0] = KEY_UPARROW;
|
||||||
gamecontrol[gc_lookdown ][0] = KEY_DOWNARROW;
|
gamecontrol[gc_lookdown ][0] = KEY_DOWNARROW;
|
||||||
gamecontrol[gc_centerview ][0] = KEY_END;
|
gamecontrol[gc_centerview ][0] = KEY_END;
|
||||||
|
gamecontrol[gc_centerview ][1] = KEY_JOY1+9; // Right Stick
|
||||||
gamecontrol[gc_talkkey ][0] = 't';
|
gamecontrol[gc_talkkey ][0] = 't';
|
||||||
gamecontrol[gc_talkkey ][1] = KEY_HAT1+2; // D-Pad Left
|
gamecontrol[gc_talkkey ][1] = KEY_HAT1+2; // D-Pad Left
|
||||||
gamecontrol[gc_teamkey ][0] = 'y';
|
gamecontrol[gc_teamkey ][0] = 'y';
|
||||||
|
@ -1224,6 +1229,7 @@ void G_Controldefault(void)
|
||||||
gamecontrolbis[gc_tossflag ][0] = KEY_2JOY1+0; // A
|
gamecontrolbis[gc_tossflag ][0] = KEY_2JOY1+0; // A
|
||||||
gamecontrolbis[gc_use ][0] = KEY_2JOY1+4; // LB
|
gamecontrolbis[gc_use ][0] = KEY_2JOY1+4; // LB
|
||||||
gamecontrolbis[gc_camreset ][0] = KEY_2JOY1+3; // Y
|
gamecontrolbis[gc_camreset ][0] = KEY_2JOY1+3; // Y
|
||||||
|
gamecontrolbis[gc_centerview][0] = KEY_2JOY1+9; // Right Stick
|
||||||
gamecontrolbis[gc_jump ][0] = KEY_2JOY1+5; // RB
|
gamecontrolbis[gc_jump ][0] = KEY_2JOY1+5; // RB
|
||||||
//gamecontrolbis[gc_pause ][0] = KEY_2JOY1+6; // Back
|
//gamecontrolbis[gc_pause ][0] = KEY_2JOY1+6; // Back
|
||||||
//gamecontrolbis[gc_systemmenu][0] = KEY_2JOY1+7; // Start
|
//gamecontrolbis[gc_systemmenu][0] = KEY_2JOY1+7; // Start
|
||||||
|
@ -1333,30 +1339,166 @@ void G_SaveKeySetting(FILE *f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void G_CheckDoubleUsage(INT32 keynum)
|
INT32 G_CheckDoubleUsage(INT32 keynum, boolean modify)
|
||||||
{
|
{
|
||||||
|
INT32 result = gc_null;
|
||||||
if (cv_controlperkey.value == 1)
|
if (cv_controlperkey.value == 1)
|
||||||
{
|
{
|
||||||
INT32 i;
|
INT32 i;
|
||||||
for (i = 0; i < num_gamecontrols; i++)
|
for (i = 0; i < num_gamecontrols; i++)
|
||||||
{
|
{
|
||||||
if (gamecontrol[i][0] == keynum)
|
if (gamecontrol[i][0] == keynum)
|
||||||
gamecontrol[i][0] = KEY_NULL;
|
{
|
||||||
|
result = i;
|
||||||
|
if (modify) gamecontrol[i][0] = KEY_NULL;
|
||||||
|
}
|
||||||
if (gamecontrol[i][1] == keynum)
|
if (gamecontrol[i][1] == keynum)
|
||||||
gamecontrol[i][1] = KEY_NULL;
|
{
|
||||||
|
result = i;
|
||||||
|
if (modify) gamecontrol[i][1] = KEY_NULL;
|
||||||
|
}
|
||||||
if (gamecontrolbis[i][0] == keynum)
|
if (gamecontrolbis[i][0] == keynum)
|
||||||
gamecontrolbis[i][0] = KEY_NULL;
|
{
|
||||||
|
result = i;
|
||||||
|
if (modify) gamecontrolbis[i][0] = KEY_NULL;
|
||||||
|
}
|
||||||
if (gamecontrolbis[i][1] == keynum)
|
if (gamecontrolbis[i][1] == keynum)
|
||||||
gamecontrolbis[i][1] = KEY_NULL;
|
{
|
||||||
|
result = i;
|
||||||
|
if (modify) gamecontrolbis[i][1] = KEY_NULL;
|
||||||
|
}
|
||||||
|
if (result && !modify)
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setcontrol(INT32 (*gc)[2], INT32 na)
|
static INT32 G_FilterKeyByVersion(INT32 numctrl, INT32 keyidx, INT32 player, INT32 *keynum1, INT32 *keynum2, boolean *nestedoverride)
|
||||||
|
{
|
||||||
|
// Special case: ignore KEY_PAUSE because it's hardcoded
|
||||||
|
if (keyidx == 0 && *keynum1 == KEY_PAUSE)
|
||||||
|
{
|
||||||
|
if (*keynum2 != KEY_PAUSE)
|
||||||
|
{
|
||||||
|
*keynum1 = *keynum2; // shift down keynum2 and continue
|
||||||
|
*keynum2 = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return -1; // skip setting control
|
||||||
|
}
|
||||||
|
else if (keyidx == 1 && *keynum2 == KEY_PAUSE)
|
||||||
|
return -1; // skip setting control
|
||||||
|
|
||||||
|
#if !defined (DC) && !defined (_PSP) && !defined (GP2X) && !defined (_NDS) && !defined(WMINPUT) && !defined(_WII)
|
||||||
|
if (GETMAJOREXECVERSION(cv_execversion.value) < 27 && ( // v2.1.22
|
||||||
|
numctrl == gc_weaponnext || numctrl == gc_weaponprev || numctrl == gc_tossflag ||
|
||||||
|
numctrl == gc_use || numctrl == gc_camreset || numctrl == gc_jump ||
|
||||||
|
numctrl == gc_pause || numctrl == gc_systemmenu || numctrl == gc_camtoggle ||
|
||||||
|
numctrl == gc_screenshot || numctrl == gc_talkkey || numctrl == gc_scores ||
|
||||||
|
numctrl == gc_centerview
|
||||||
|
))
|
||||||
|
{
|
||||||
|
INT32 keynum = 0, existingctrl = 0;
|
||||||
|
INT32 defaultkey;
|
||||||
|
boolean defaultoverride = false;
|
||||||
|
|
||||||
|
// get the default gamecontrol
|
||||||
|
if (player == 0 && numctrl == gc_systemmenu)
|
||||||
|
defaultkey = gamecontrol[numctrl][0];
|
||||||
|
else
|
||||||
|
defaultkey = (player == 1 ? gamecontrolbis[numctrl][0] : gamecontrol[numctrl][1]);
|
||||||
|
|
||||||
|
// Assign joypad button defaults if there is an open slot.
|
||||||
|
// At this point, gamecontrol/bis should have the default controls
|
||||||
|
// (unless LOADCONFIG is being run)
|
||||||
|
//
|
||||||
|
// If the player runs SETCONTROL in-game, this block should not be reached
|
||||||
|
// because EXECVERSION is locked onto the latest version.
|
||||||
|
if (keyidx == 0 && !*keynum1)
|
||||||
|
{
|
||||||
|
if (*keynum2) // push keynum2 down; this is an edge case
|
||||||
|
{
|
||||||
|
*keynum1 = *keynum2;
|
||||||
|
*keynum2 = 0;
|
||||||
|
keynum = *keynum1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
keynum = defaultkey;
|
||||||
|
defaultoverride = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (keyidx == 1 && (!*keynum2 || (!*keynum1 && *keynum2))) // last one is the same edge case as above
|
||||||
|
{
|
||||||
|
keynum = defaultkey;
|
||||||
|
defaultoverride = true;
|
||||||
|
}
|
||||||
|
else // default to the specified keynum
|
||||||
|
keynum = (keyidx == 1 ? *keynum2 : *keynum1);
|
||||||
|
|
||||||
|
// Did our last call override keynum2?
|
||||||
|
if (*nestedoverride)
|
||||||
|
{
|
||||||
|
defaultoverride = true;
|
||||||
|
*nestedoverride = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fill keynum2 with the default control
|
||||||
|
if (keyidx == 0 && !*keynum2)
|
||||||
|
{
|
||||||
|
*keynum2 = defaultkey;
|
||||||
|
// Tell the next call that this is an override
|
||||||
|
*nestedoverride = true;
|
||||||
|
|
||||||
|
// if keynum2 already matches keynum1, we probably recursed
|
||||||
|
// so unset it
|
||||||
|
if (*keynum1 == *keynum2)
|
||||||
|
{
|
||||||
|
*keynum2 = 0;
|
||||||
|
*nestedoverride = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if the key is being used somewhere else before passing it
|
||||||
|
// pass it through if it's the same numctrl. This is an edge case -- when using
|
||||||
|
// LOADCONFIG, gamecontrol is not reset with default.
|
||||||
|
//
|
||||||
|
// Also, only check if we're actually overriding, to preserve behavior where
|
||||||
|
// config'd keys overwrite default keys.
|
||||||
|
if (defaultoverride)
|
||||||
|
existingctrl = G_CheckDoubleUsage(keynum, false);
|
||||||
|
|
||||||
|
if (keynum && (!existingctrl || existingctrl == numctrl))
|
||||||
|
return keynum;
|
||||||
|
else if (keyidx == 0 && *keynum2)
|
||||||
|
{
|
||||||
|
// try it again and push down keynum2
|
||||||
|
*keynum1 = *keynum2;
|
||||||
|
*keynum2 = 0;
|
||||||
|
return G_FilterKeyByVersion(numctrl, keyidx, player, keynum1, keynum2, nestedoverride);
|
||||||
|
// recursion *should* be safe because we only assign keynum2 to a joy default
|
||||||
|
// and then clear it if we find that keynum1 already has the joy default.
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// All's good, so pass the keynum as-is
|
||||||
|
if (keyidx == 1)
|
||||||
|
return *keynum2;
|
||||||
|
else //if (keyidx == 0)
|
||||||
|
return *keynum1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void setcontrol(INT32 (*gc)[2])
|
||||||
{
|
{
|
||||||
INT32 numctrl;
|
INT32 numctrl;
|
||||||
const char *namectrl;
|
const char *namectrl;
|
||||||
INT32 keynum;
|
INT32 keynum, keynum1, keynum2;
|
||||||
|
INT32 player = ((void*)gc == (void*)&gamecontrolbis ? 1 : 0);
|
||||||
|
boolean nestedoverride = false;
|
||||||
|
|
||||||
namectrl = COM_Argv(1);
|
namectrl = COM_Argv(1);
|
||||||
for (numctrl = 0; numctrl < num_gamecontrols && stricmp(namectrl, gamecontrolname[numctrl]);
|
for (numctrl = 0; numctrl < num_gamecontrols && stricmp(namectrl, gamecontrolname[numctrl]);
|
||||||
|
@ -1367,31 +1509,38 @@ static void setcontrol(INT32 (*gc)[2], INT32 na)
|
||||||
CONS_Printf(M_GetText("Control '%s' unknown\n"), namectrl);
|
CONS_Printf(M_GetText("Control '%s' unknown\n"), namectrl);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
keynum = G_KeyStringtoNum(COM_Argv(2));
|
keynum1 = G_KeyStringtoNum(COM_Argv(2));
|
||||||
|
keynum2 = G_KeyStringtoNum(COM_Argv(3));
|
||||||
|
keynum = G_FilterKeyByVersion(numctrl, 0, player, &keynum1, &keynum2, &nestedoverride);
|
||||||
|
|
||||||
if (keynum == KEY_PAUSE) // fail silently; pause is hardcoded
|
if (keynum >= 0)
|
||||||
{
|
{
|
||||||
if (na == 4)
|
(void)G_CheckDoubleUsage(keynum, true);
|
||||||
|
|
||||||
|
// if keynum was rejected, try it again with keynum2
|
||||||
|
if (!keynum && keynum2)
|
||||||
{
|
{
|
||||||
na--;
|
keynum1 = keynum2; // push down keynum2
|
||||||
keynum = G_KeyStringtoNum(COM_Argv(3));
|
keynum2 = 0;
|
||||||
if (keynum == KEY_PAUSE)
|
keynum = G_FilterKeyByVersion(numctrl, 0, player, &keynum1, &keynum2, &nestedoverride);
|
||||||
return;
|
if (keynum >= 0)
|
||||||
|
(void)G_CheckDoubleUsage(keynum, true);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
G_CheckDoubleUsage(keynum);
|
if (keynum >= 0)
|
||||||
gc[numctrl][0] = keynum;
|
gc[numctrl][0] = keynum;
|
||||||
|
|
||||||
if (na == 4)
|
if (keynum2)
|
||||||
{
|
{
|
||||||
keynum = G_KeyStringtoNum(COM_Argv(3));
|
keynum = G_FilterKeyByVersion(numctrl, 1, player, &keynum1, &keynum2, &nestedoverride);
|
||||||
if (keynum != KEY_PAUSE)
|
if (keynum >= 0)
|
||||||
gc[numctrl][1] = keynum;
|
{
|
||||||
else
|
if (keynum != gc[numctrl][0])
|
||||||
gc[numctrl][1] = 0;
|
gc[numctrl][1] = keynum;
|
||||||
|
else
|
||||||
|
gc[numctrl][1] = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
gc[numctrl][1] = 0;
|
gc[numctrl][1] = 0;
|
||||||
|
@ -1409,7 +1558,7 @@ void Command_Setcontrol_f(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
setcontrol(gamecontrol, na);
|
setcontrol(gamecontrol);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Command_Setcontrol2_f(void)
|
void Command_Setcontrol2_f(void)
|
||||||
|
@ -1424,5 +1573,5 @@ void Command_Setcontrol2_f(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
setcontrol(gamecontrolbis, na);
|
setcontrol(gamecontrolbis);
|
||||||
}
|
}
|
||||||
|
|
|
@ -165,6 +165,6 @@ void Command_Setcontrol_f(void);
|
||||||
void Command_Setcontrol2_f(void);
|
void Command_Setcontrol2_f(void);
|
||||||
void G_Controldefault(void);
|
void G_Controldefault(void);
|
||||||
void G_SaveKeySetting(FILE *f);
|
void G_SaveKeySetting(FILE *f);
|
||||||
void G_CheckDoubleUsage(INT32 keynum);
|
INT32 G_CheckDoubleUsage(INT32 keynum, boolean modify);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -790,6 +790,110 @@ void HWR_drawAMline(const fline_t *fl, INT32 color)
|
||||||
HWD.pfnDraw2DLine(&v1, &v2, color_rgba);
|
HWD.pfnDraw2DLine(&v1, &v2, color_rgba);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// -------------------+
|
||||||
|
// HWR_DrawConsoleFill : draw flat coloured transparent rectangle because that's cool, and hw sucks less than sw for that.
|
||||||
|
// -------------------+
|
||||||
|
void HWR_DrawConsoleFill(INT32 x, INT32 y, INT32 w, INT32 h, UINT32 color, INT32 options)
|
||||||
|
{
|
||||||
|
FOutVector v[4];
|
||||||
|
FSurfaceInfo Surf;
|
||||||
|
float fx, fy, fw, fh;
|
||||||
|
|
||||||
|
if (w < 0 || h < 0)
|
||||||
|
return; // consistency w/ software
|
||||||
|
|
||||||
|
// 3--2
|
||||||
|
// | /|
|
||||||
|
// |/ |
|
||||||
|
// 0--1
|
||||||
|
|
||||||
|
fx = (float)x;
|
||||||
|
fy = (float)y;
|
||||||
|
fw = (float)w;
|
||||||
|
fh = (float)h;
|
||||||
|
|
||||||
|
if (!(options & V_NOSCALESTART))
|
||||||
|
{
|
||||||
|
float dupx = (float)vid.dupx, dupy = (float)vid.dupy;
|
||||||
|
|
||||||
|
if (x == 0 && y == 0 && w == BASEVIDWIDTH && h == BASEVIDHEIGHT)
|
||||||
|
{
|
||||||
|
RGBA_t rgbaColour = V_GetColor(color);
|
||||||
|
FRGBAFloat clearColour;
|
||||||
|
clearColour.red = (float)rgbaColour.s.red / 255;
|
||||||
|
clearColour.green = (float)rgbaColour.s.green / 255;
|
||||||
|
clearColour.blue = (float)rgbaColour.s.blue / 255;
|
||||||
|
clearColour.alpha = 1;
|
||||||
|
HWD.pfnClearBuffer(true, false, &clearColour);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fx *= dupx;
|
||||||
|
fy *= dupy;
|
||||||
|
fw *= dupx;
|
||||||
|
fh *= dupy;
|
||||||
|
|
||||||
|
if (fabsf((float)vid.width - ((float)BASEVIDWIDTH * dupx)) > 1.0E-36f)
|
||||||
|
{
|
||||||
|
if (options & V_SNAPTORIGHT)
|
||||||
|
fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx));
|
||||||
|
else if (!(options & V_SNAPTOLEFT))
|
||||||
|
fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx)) / 2;
|
||||||
|
}
|
||||||
|
if (fabsf((float)vid.height - ((float)BASEVIDHEIGHT * dupy)) > 1.0E-36f)
|
||||||
|
{
|
||||||
|
// same thing here
|
||||||
|
if (options & V_SNAPTOBOTTOM)
|
||||||
|
fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy));
|
||||||
|
else if (!(options & V_SNAPTOTOP))
|
||||||
|
fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy)) / 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fx >= vid.width || fy >= vid.height)
|
||||||
|
return;
|
||||||
|
if (fx < 0)
|
||||||
|
{
|
||||||
|
fw += fx;
|
||||||
|
fx = 0;
|
||||||
|
}
|
||||||
|
if (fy < 0)
|
||||||
|
{
|
||||||
|
fh += fy;
|
||||||
|
fy = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fw <= 0 || fh <= 0)
|
||||||
|
return;
|
||||||
|
if (fx + fw > vid.width)
|
||||||
|
fw = (float)vid.width - fx;
|
||||||
|
if (fy + fh > vid.height)
|
||||||
|
fh = (float)vid.height - fy;
|
||||||
|
|
||||||
|
fx = -1 + fx / (vid.width / 2);
|
||||||
|
fy = 1 - fy / (vid.height / 2);
|
||||||
|
fw = fw / (vid.width / 2);
|
||||||
|
fh = fh / (vid.height / 2);
|
||||||
|
|
||||||
|
v[0].x = v[3].x = fx;
|
||||||
|
v[2].x = v[1].x = fx + fw;
|
||||||
|
v[0].y = v[1].y = fy;
|
||||||
|
v[2].y = v[3].y = fy - fh;
|
||||||
|
|
||||||
|
//Hurdler: do we still use this argb color? if not, we should remove it
|
||||||
|
v[0].argb = v[1].argb = v[2].argb = v[3].argb = 0xff00ff00; //;
|
||||||
|
v[0].z = v[1].z = v[2].z = v[3].z = 1.0f;
|
||||||
|
|
||||||
|
v[0].sow = v[3].sow = 0.0f;
|
||||||
|
v[2].sow = v[1].sow = 1.0f;
|
||||||
|
v[0].tow = v[1].tow = 0.0f;
|
||||||
|
v[2].tow = v[3].tow = 1.0f;
|
||||||
|
|
||||||
|
Surf.FlatColor.rgba = UINT2RGBA(color);
|
||||||
|
Surf.FlatColor.s.alpha = 0x80;
|
||||||
|
|
||||||
|
HWD.pfnDrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Modulated|PF_Translucent|PF_NoDepthTest);
|
||||||
|
}
|
||||||
|
|
||||||
// -----------------+
|
// -----------------+
|
||||||
// HWR_DrawFill : draw flat coloured rectangle, with no texture
|
// HWR_DrawFill : draw flat coloured rectangle, with no texture
|
||||||
|
|
|
@ -51,6 +51,7 @@ void HWR_CreatePlanePolygons(INT32 bspnum);
|
||||||
void HWR_CreateStaticLightmaps(INT32 bspnum);
|
void HWR_CreateStaticLightmaps(INT32 bspnum);
|
||||||
void HWR_PrepLevelCache(size_t pnumtextures);
|
void HWR_PrepLevelCache(size_t pnumtextures);
|
||||||
void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color);
|
void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color);
|
||||||
|
void HWR_DrawConsoleFill(INT32 x, INT32 y, INT32 w, INT32 h, UINT32 color, INT32 options); // Lat: separate flags from color since color needs to be an uint to work right.
|
||||||
void HWR_DrawPic(INT32 x,INT32 y,lumpnum_t lumpnum);
|
void HWR_DrawPic(INT32 x,INT32 y,lumpnum_t lumpnum);
|
||||||
|
|
||||||
void HWR_AddCommands(void);
|
void HWR_AddCommands(void);
|
||||||
|
|
1474
src/hu_stuff.c
1474
src/hu_stuff.c
File diff suppressed because it is too large
Load diff
|
@ -21,7 +21,7 @@
|
||||||
//------------------------------------
|
//------------------------------------
|
||||||
// heads up font
|
// heads up font
|
||||||
//------------------------------------
|
//------------------------------------
|
||||||
#define HU_FONTSTART '\x1F' // the first font character
|
#define HU_FONTSTART '\x16' // the first font character
|
||||||
#define HU_FONTEND '~'
|
#define HU_FONTEND '~'
|
||||||
|
|
||||||
#define HU_FONTSIZE (HU_FONTEND - HU_FONTSTART + 1)
|
#define HU_FONTSIZE (HU_FONTEND - HU_FONTSTART + 1)
|
||||||
|
@ -57,6 +57,20 @@ typedef struct
|
||||||
// chat stuff
|
// chat stuff
|
||||||
//------------------------------------
|
//------------------------------------
|
||||||
#define HU_MAXMSGLEN 224
|
#define HU_MAXMSGLEN 224
|
||||||
|
#define CHAT_BUFSIZE 64 // that's enough messages, right? We'll delete the older ones when that gets out of hand.
|
||||||
|
#ifdef NETSPLITSCREEN
|
||||||
|
#define OLDCHAT (cv_consolechat.value == 1 || dedicated || vid.width < 640)
|
||||||
|
#else
|
||||||
|
#define OLDCHAT (cv_consolechat.value == 1 || dedicated || vid.width < 640 || splitscreen)
|
||||||
|
#endif
|
||||||
|
#define CHAT_MUTE (cv_mute.value && !(server || IsPlayerAdmin(consoleplayer))) // this still allows to open the chat but not to type. That's used for scrolling and whatnot.
|
||||||
|
#define OLD_MUTE (OLDCHAT && cv_mute.value && !(server || IsPlayerAdmin(consoleplayer))) // this is used to prevent oldchat from opening when muted.
|
||||||
|
|
||||||
|
// some functions
|
||||||
|
void HU_AddChatText(const char *text, boolean playsound);
|
||||||
|
|
||||||
|
// set true when entering a chat message
|
||||||
|
extern boolean chat_on;
|
||||||
|
|
||||||
extern patch_t *hu_font[HU_FONTSIZE], *tny_font[HU_FONTSIZE];
|
extern patch_t *hu_font[HU_FONTSIZE], *tny_font[HU_FONTSIZE];
|
||||||
extern patch_t *tallnum[10];
|
extern patch_t *tallnum[10];
|
||||||
|
@ -72,9 +86,6 @@ extern patch_t *bmatcico;
|
||||||
extern patch_t *tagico;
|
extern patch_t *tagico;
|
||||||
extern patch_t *tallminus;
|
extern patch_t *tallminus;
|
||||||
|
|
||||||
// set true when entering a chat message
|
|
||||||
extern boolean chat_on;
|
|
||||||
|
|
||||||
// set true whenever the tab rankings are being shown for any reason
|
// set true whenever the tab rankings are being shown for any reason
|
||||||
extern boolean hu_showscores;
|
extern boolean hu_showscores;
|
||||||
|
|
||||||
|
@ -87,12 +98,12 @@ void HU_LoadGraphics(void);
|
||||||
void HU_Start(void);
|
void HU_Start(void);
|
||||||
|
|
||||||
boolean HU_Responder(event_t *ev);
|
boolean HU_Responder(event_t *ev);
|
||||||
|
|
||||||
void HU_Ticker(void);
|
void HU_Ticker(void);
|
||||||
void HU_Drawer(void);
|
void HU_Drawer(void);
|
||||||
char HU_dequeueChatChar(void);
|
char HU_dequeueChatChar(void);
|
||||||
void HU_Erase(void);
|
void HU_Erase(void);
|
||||||
void HU_clearChatChars(void);
|
void HU_clearChatChars(void);
|
||||||
|
void HU_drawPing(INT32 x, INT32 y, INT32 ping, boolean notext); // Lat': Ping drawer for scoreboard.
|
||||||
void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, INT32 whiteplayer);
|
void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, INT32 whiteplayer);
|
||||||
void HU_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer);
|
void HU_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer);
|
||||||
void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, INT32 whiteplayer);
|
void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, INT32 whiteplayer);
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
#include "m_random.h"
|
#include "m_random.h"
|
||||||
#include "s_sound.h"
|
#include "s_sound.h"
|
||||||
#include "g_game.h"
|
#include "g_game.h"
|
||||||
#include "hu_stuff.h"
|
#include "hu_stuff.h" // HU_AddChatText
|
||||||
#include "console.h"
|
#include "console.h"
|
||||||
#include "d_netcmd.h" // IsPlayerAdmin
|
#include "d_netcmd.h" // IsPlayerAdmin
|
||||||
|
|
||||||
|
@ -91,6 +91,51 @@ static int lib_print(lua_State *L)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Print stuff in the chat, or in the console if we can't.
|
||||||
|
static int lib_chatprint(lua_State *L)
|
||||||
|
{
|
||||||
|
const char *str = luaL_checkstring(L, 1); // retrieve string
|
||||||
|
boolean sound = lua_optboolean(L, 2); // retrieve sound boolean
|
||||||
|
int len = strlen(str);
|
||||||
|
|
||||||
|
if (str == NULL) // error if we don't have a string!
|
||||||
|
return luaL_error(L, LUA_QL("tostring") " must return a string to " LUA_QL("chatprint"));
|
||||||
|
|
||||||
|
if (len > 255) // string is too long!!!
|
||||||
|
return luaL_error(L, "String exceeds the 255 characters limit of the chat buffer.");
|
||||||
|
|
||||||
|
HU_AddChatText(str, sound);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Same as above, but do it for only one player.
|
||||||
|
static int lib_chatprintf(lua_State *L)
|
||||||
|
{
|
||||||
|
int n = lua_gettop(L); /* number of arguments */
|
||||||
|
const char *str = luaL_checkstring(L, 2); // retrieve string
|
||||||
|
boolean sound = lua_optboolean(L, 3); // sound?
|
||||||
|
int len = strlen(str);
|
||||||
|
player_t *plr;
|
||||||
|
|
||||||
|
if (n < 2)
|
||||||
|
return luaL_error(L, "chatprintf requires at least two arguments: player and text.");
|
||||||
|
|
||||||
|
plr = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); // retrieve player
|
||||||
|
if (!plr)
|
||||||
|
return LUA_ErrInvalid(L, "player_t");
|
||||||
|
if (plr != &players[consoleplayer])
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (str == NULL) // error if we don't have a string!
|
||||||
|
return luaL_error(L, LUA_QL("tostring") " must return a string to " LUA_QL("chatprintf"));
|
||||||
|
|
||||||
|
if (len > 255) // string is too long!!!
|
||||||
|
return luaL_error(L, "String exceeds the 255 characters limit of the chat buffer.");
|
||||||
|
|
||||||
|
HU_AddChatText(str, sound);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int lib_evalMath(lua_State *L)
|
static int lib_evalMath(lua_State *L)
|
||||||
{
|
{
|
||||||
const char *word = luaL_checkstring(L, 1);
|
const char *word = luaL_checkstring(L, 1);
|
||||||
|
@ -1709,7 +1754,7 @@ static int lib_sStartSound(lua_State *L)
|
||||||
const void *origin = NULL;
|
const void *origin = NULL;
|
||||||
sfxenum_t sound_id = luaL_checkinteger(L, 2);
|
sfxenum_t sound_id = luaL_checkinteger(L, 2);
|
||||||
player_t *player = NULL;
|
player_t *player = NULL;
|
||||||
NOHUD
|
//NOHUD // kys @whoever did this.
|
||||||
if (sound_id >= NUMSFX)
|
if (sound_id >= NUMSFX)
|
||||||
return luaL_error(L, "sfx %d out of range (0 - %d)", sound_id, NUMSFX-1);
|
return luaL_error(L, "sfx %d out of range (0 - %d)", sound_id, NUMSFX-1);
|
||||||
if (!lua_isnil(L, 1))
|
if (!lua_isnil(L, 1))
|
||||||
|
@ -1725,7 +1770,12 @@ static int lib_sStartSound(lua_State *L)
|
||||||
return LUA_ErrInvalid(L, "player_t");
|
return LUA_ErrInvalid(L, "player_t");
|
||||||
}
|
}
|
||||||
if (!player || P_IsLocalPlayer(player))
|
if (!player || P_IsLocalPlayer(player))
|
||||||
|
{
|
||||||
|
if (hud_running)
|
||||||
|
origin = NULL; // HUD rendering startsound shouldn't have an origin, just remove it instead of having a retarded error.
|
||||||
|
|
||||||
S_StartSound(origin, sound_id);
|
S_StartSound(origin, sound_id);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2052,6 +2102,8 @@ static int lib_gTicsToMilliseconds(lua_State *L)
|
||||||
|
|
||||||
static luaL_Reg lib[] = {
|
static luaL_Reg lib[] = {
|
||||||
{"print", lib_print},
|
{"print", lib_print},
|
||||||
|
{"chatprint", lib_chatprint},
|
||||||
|
{"chatprintf", lib_chatprintf},
|
||||||
{"EvalMath", lib_evalMath},
|
{"EvalMath", lib_evalMath},
|
||||||
{"IsPlayerAdmin", lib_isPlayerAdmin},
|
{"IsPlayerAdmin", lib_isPlayerAdmin},
|
||||||
|
|
||||||
|
|
|
@ -952,7 +952,7 @@ boolean LUAh_LinedefExecute(line_t *line, mobj_t *mo, sector_t *sector)
|
||||||
return hooked;
|
return hooked;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hook for player chat
|
|
||||||
boolean LUAh_PlayerMsg(int source, int target, int flags, char *msg)
|
boolean LUAh_PlayerMsg(int source, int target, int flags, char *msg)
|
||||||
{
|
{
|
||||||
hook_p hookp;
|
hook_p hookp;
|
||||||
|
@ -1005,6 +1005,7 @@ boolean LUAh_PlayerMsg(int source, int target, int flags, char *msg)
|
||||||
return hooked;
|
return hooked;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Hook for hurt messages
|
// Hook for hurt messages
|
||||||
boolean LUAh_HurtMsg(player_t *player, mobj_t *inflictor, mobj_t *source)
|
boolean LUAh_HurtMsg(player_t *player, mobj_t *inflictor, mobj_t *source)
|
||||||
{
|
{
|
||||||
|
|
653
src/m_menu.c
653
src/m_menu.c
|
@ -33,6 +33,9 @@
|
||||||
#include "s_sound.h"
|
#include "s_sound.h"
|
||||||
#include "i_system.h"
|
#include "i_system.h"
|
||||||
|
|
||||||
|
// Addfile
|
||||||
|
#include "filesrch.h"
|
||||||
|
|
||||||
#include "v_video.h"
|
#include "v_video.h"
|
||||||
#include "i_video.h"
|
#include "i_video.h"
|
||||||
#include "keys.h"
|
#include "keys.h"
|
||||||
|
@ -75,7 +78,6 @@ int snprintf(char *str, size_t n, const char *fmt, ...);
|
||||||
#define SMALLLINEHEIGHT 8
|
#define SMALLLINEHEIGHT 8
|
||||||
#define SLIDER_RANGE 10
|
#define SLIDER_RANGE 10
|
||||||
#define SLIDER_WIDTH (8*SLIDER_RANGE+6)
|
#define SLIDER_WIDTH (8*SLIDER_RANGE+6)
|
||||||
#define MAXSTRINGLENGTH 32
|
|
||||||
#define SERVERS_PER_PAGE 11
|
#define SERVERS_PER_PAGE 11
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
|
@ -205,6 +207,8 @@ menu_t MessageDef;
|
||||||
|
|
||||||
menu_t SPauseDef;
|
menu_t SPauseDef;
|
||||||
|
|
||||||
|
#define lsheadingheight 16
|
||||||
|
|
||||||
// Sky Room
|
// Sky Room
|
||||||
static void M_CustomLevelSelect(INT32 choice);
|
static void M_CustomLevelSelect(INT32 choice);
|
||||||
static void M_CustomWarp(INT32 choice);
|
static void M_CustomWarp(INT32 choice);
|
||||||
|
@ -292,15 +296,22 @@ menu_t OP_SoundOptionsDef;
|
||||||
|
|
||||||
//Misc
|
//Misc
|
||||||
menu_t OP_DataOptionsDef, OP_ScreenshotOptionsDef, OP_EraseDataDef;
|
menu_t OP_DataOptionsDef, OP_ScreenshotOptionsDef, OP_EraseDataDef;
|
||||||
menu_t OP_GameOptionsDef, OP_ServerOptionsDef;
|
menu_t OP_GameOptionsDef, OP_ChatOptionsDef, OP_ServerOptionsDef;
|
||||||
menu_t OP_NetgameOptionsDef, OP_GametypeOptionsDef;
|
menu_t OP_NetgameOptionsDef, OP_GametypeOptionsDef;
|
||||||
menu_t OP_MonitorToggleDef;
|
menu_t OP_MonitorToggleDef;
|
||||||
static void M_ScreenshotOptions(INT32 choice);
|
static void M_ScreenshotOptions(INT32 choice);
|
||||||
static void M_EraseData(INT32 choice);
|
static void M_EraseData(INT32 choice);
|
||||||
|
|
||||||
|
static void M_Addons(INT32 choice);
|
||||||
|
static void M_AddonsOptions(INT32 choice);
|
||||||
|
static patch_t *addonsp[NUM_EXT+5];
|
||||||
|
|
||||||
|
#define numaddonsshown 4
|
||||||
|
|
||||||
// Drawing functions
|
// Drawing functions
|
||||||
static void M_DrawGenericMenu(void);
|
static void M_DrawGenericMenu(void);
|
||||||
static void M_DrawCenteredMenu(void);
|
static void M_DrawCenteredMenu(void);
|
||||||
|
static void M_DrawAddons(void);
|
||||||
static void M_DrawSkyRoom(void);
|
static void M_DrawSkyRoom(void);
|
||||||
static void M_DrawChecklist(void);
|
static void M_DrawChecklist(void);
|
||||||
static void M_DrawEmblemHints(void);
|
static void M_DrawEmblemHints(void);
|
||||||
|
@ -335,6 +346,7 @@ static boolean M_CancelConnect(void);
|
||||||
#endif
|
#endif
|
||||||
static boolean M_ExitPandorasBox(void);
|
static boolean M_ExitPandorasBox(void);
|
||||||
static boolean M_QuitMultiPlayerMenu(void);
|
static boolean M_QuitMultiPlayerMenu(void);
|
||||||
|
static void M_HandleAddons(INT32 choice);
|
||||||
static void M_HandleSoundTest(INT32 choice);
|
static void M_HandleSoundTest(INT32 choice);
|
||||||
static void M_HandleImageDef(INT32 choice);
|
static void M_HandleImageDef(INT32 choice);
|
||||||
static void M_HandleLoadSave(INT32 choice);
|
static void M_HandleLoadSave(INT32 choice);
|
||||||
|
@ -442,10 +454,11 @@ static consvar_t cv_dummymares = {"dummymares", "Overall", CV_HIDEN|CV_CALL, dum
|
||||||
// ---------
|
// ---------
|
||||||
static menuitem_t MainMenu[] =
|
static menuitem_t MainMenu[] =
|
||||||
{
|
{
|
||||||
{IT_CALL |IT_STRING, NULL, "Secrets", M_SecretsMenu, 84},
|
{IT_CALL |IT_STRING, NULL, "Secrets", M_SecretsMenu, 76},
|
||||||
{IT_CALL |IT_STRING, NULL, "1 player", M_SinglePlayerMenu, 92},
|
{IT_CALL |IT_STRING, NULL, "1 player", M_SinglePlayerMenu, 84},
|
||||||
{IT_SUBMENU|IT_STRING, NULL, "multiplayer", &MP_MainDef, 100},
|
{IT_SUBMENU|IT_STRING, NULL, "multiplayer", &MP_MainDef, 92},
|
||||||
{IT_CALL |IT_STRING, NULL, "options", M_Options, 108},
|
{IT_CALL |IT_STRING, NULL, "options", M_Options, 100},
|
||||||
|
{IT_CALL |IT_STRING, NULL, "Addons", M_Addons, 108},
|
||||||
{IT_CALL |IT_STRING, NULL, "quit game", M_QuitSRB2, 116},
|
{IT_CALL |IT_STRING, NULL, "quit game", M_QuitSRB2, 116},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -455,9 +468,15 @@ typedef enum
|
||||||
singleplr,
|
singleplr,
|
||||||
multiplr,
|
multiplr,
|
||||||
options,
|
options,
|
||||||
|
addons,
|
||||||
quitdoom
|
quitdoom
|
||||||
} main_e;
|
} main_e;
|
||||||
|
|
||||||
|
static menuitem_t MISC_AddonsMenu[] =
|
||||||
|
{
|
||||||
|
{IT_KEYHANDLER | IT_NOTHING, NULL, "", M_HandleAddons, 0}, // dummy menuitem for the control func
|
||||||
|
};
|
||||||
|
|
||||||
// ---------------------------------
|
// ---------------------------------
|
||||||
// Pause Menu Mode Attacking Edition
|
// Pause Menu Mode Attacking Edition
|
||||||
// ---------------------------------
|
// ---------------------------------
|
||||||
|
@ -480,6 +499,7 @@ typedef enum
|
||||||
// ---------------------
|
// ---------------------
|
||||||
static menuitem_t MPauseMenu[] =
|
static menuitem_t MPauseMenu[] =
|
||||||
{
|
{
|
||||||
|
{IT_STRING | IT_CALL, NULL, "Add-ons...", M_Addons, 8},
|
||||||
{IT_STRING | IT_SUBMENU, NULL, "Scramble Teams...", &MISC_ScrambleTeamDef, 16},
|
{IT_STRING | IT_SUBMENU, NULL, "Scramble Teams...", &MISC_ScrambleTeamDef, 16},
|
||||||
{IT_STRING | IT_CALL, NULL, "Switch Map..." , M_MapChange, 24},
|
{IT_STRING | IT_CALL, NULL, "Switch Map..." , M_MapChange, 24},
|
||||||
|
|
||||||
|
@ -499,7 +519,8 @@ static menuitem_t MPauseMenu[] =
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
mpause_scramble = 0,
|
mpause_addons = 0,
|
||||||
|
mpause_scramble,
|
||||||
mpause_switchmap,
|
mpause_switchmap,
|
||||||
|
|
||||||
mpause_continue,
|
mpause_continue,
|
||||||
|
@ -985,6 +1006,7 @@ static menuitem_t OP_MainMenu[] =
|
||||||
|
|
||||||
{IT_SUBMENU | IT_STRING, NULL, "Game Options...", &OP_GameOptionsDef, 70},
|
{IT_SUBMENU | IT_STRING, NULL, "Game Options...", &OP_GameOptionsDef, 70},
|
||||||
{IT_SUBMENU | IT_STRING, NULL, "Server Options...", &OP_ServerOptionsDef, 80},
|
{IT_SUBMENU | IT_STRING, NULL, "Server Options...", &OP_ServerOptionsDef, 80},
|
||||||
|
{IT_STRING | IT_CALL, NULL, "Add-on Options...", M_AddonsOptions, 90},
|
||||||
};
|
};
|
||||||
|
|
||||||
static menuitem_t OP_ControlsMenu[] =
|
static menuitem_t OP_ControlsMenu[] =
|
||||||
|
@ -1293,28 +1315,60 @@ static menuitem_t OP_EraseDataMenu[] =
|
||||||
{IT_STRING | IT_CALL, NULL, "\x85" "Erase ALL Data", M_EraseData, 40},
|
{IT_STRING | IT_CALL, NULL, "\x85" "Erase ALL Data", M_EraseData, 40},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static menuitem_t OP_AddonsOptionsMenu[] =
|
||||||
|
{
|
||||||
|
{IT_HEADER, NULL, "Menu", NULL, 0},
|
||||||
|
{IT_STRING|IT_CVAR, NULL, "Location", &cv_addons_option, 10},
|
||||||
|
{IT_STRING|IT_CVAR|IT_CV_STRING, NULL, "Custom Folder", &cv_addons_folder, 20},
|
||||||
|
{IT_STRING|IT_CVAR, NULL, "Identify add-ons via", &cv_addons_md5, 48},
|
||||||
|
{IT_STRING|IT_CVAR, NULL, "Show unsupported file types", &cv_addons_showall, 58},
|
||||||
|
|
||||||
|
{IT_HEADER, NULL, "Search", NULL, 76},
|
||||||
|
{IT_STRING|IT_CVAR, NULL, "Matching", &cv_addons_search_type, 86},
|
||||||
|
{IT_STRING|IT_CVAR, NULL, "Case-sensitive", &cv_addons_search_case, 96},
|
||||||
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
op_addons_folder = 2,
|
||||||
|
};
|
||||||
|
|
||||||
static menuitem_t OP_GameOptionsMenu[] =
|
static menuitem_t OP_GameOptionsMenu[] =
|
||||||
{
|
{
|
||||||
#ifndef NONET
|
#ifndef NONET
|
||||||
{IT_STRING | IT_CVAR | IT_CV_STRING,
|
{IT_STRING | IT_CVAR | IT_CV_STRING,
|
||||||
NULL, "Master server", &cv_masterserver, 10},
|
NULL, "Master server", &cv_masterserver, 10},
|
||||||
#endif
|
#endif
|
||||||
{IT_STRING | IT_CVAR, NULL, "Show HUD", &cv_showhud, 40},
|
{IT_STRING | IT_SUBMENU, NULL, "Chat Options...", &OP_ChatOptionsDef, 40},
|
||||||
|
{IT_STRING | IT_CVAR, NULL, "Show HUD", &cv_showhud, 50},
|
||||||
{IT_STRING | IT_CVAR | IT_CV_SLIDER,
|
{IT_STRING | IT_CVAR | IT_CV_SLIDER,
|
||||||
NULL, "HUD Visibility", &cv_translucenthud, 50},
|
NULL, "HUD Visibility", &cv_translucenthud, 60},
|
||||||
{IT_STRING | IT_CVAR, NULL, "Timer Display", &cv_timetic, 60},
|
{IT_STRING | IT_CVAR, NULL, "Timer Display", &cv_timetic, 70},
|
||||||
|
{IT_STRING | IT_CVAR, NULL, "Always Compact Rankings", &cv_compactscoreboard, 80},
|
||||||
#ifdef SEENAMES
|
#ifdef SEENAMES
|
||||||
{IT_STRING | IT_CVAR, NULL, "HUD Player Names", &cv_seenames, 80},
|
{IT_STRING | IT_CVAR, NULL, "HUD Player Names", &cv_seenames, 90},
|
||||||
#endif
|
#endif
|
||||||
{IT_STRING | IT_CVAR, NULL, "Log Hazard Damage", &cv_hazardlog, 90},
|
{IT_STRING | IT_CVAR, NULL, "Log Hazard Damage", &cv_hazardlog, 100},
|
||||||
|
|
||||||
{IT_STRING | IT_CVAR, NULL, "Console Back Color", &cons_backcolor, 100},
|
{IT_STRING | IT_CVAR, NULL, "Console Back Color", &cons_backcolor, 110},
|
||||||
{IT_STRING | IT_CVAR, NULL, "Console Text Size", &cv_constextsize,110},
|
{IT_STRING | IT_CVAR, NULL, "Console Text Size", &cv_constextsize,120},
|
||||||
{IT_STRING | IT_CVAR, NULL, "Uppercase Console", &cv_allcaps, 120},
|
{IT_STRING | IT_CVAR, NULL, "Uppercase Console", &cv_allcaps, 130},
|
||||||
|
|
||||||
{IT_STRING | IT_CVAR, NULL, "Title Screen Demos", &cv_rollingdemos, 140},
|
{IT_STRING | IT_CVAR, NULL, "Title Screen Demos", &cv_rollingdemos, 140},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static menuitem_t OP_ChatOptionsMenu[] =
|
||||||
|
{
|
||||||
|
{IT_STRING | IT_CVAR, NULL, "Chat Mode", &cv_consolechat, 10},
|
||||||
|
|
||||||
|
{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Chat Box Width", &cv_chatwidth, 30},
|
||||||
|
{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Chat Box Height", &cv_chatheight, 40},
|
||||||
|
{IT_STRING | IT_CVAR, NULL, "Message Fadeout Time", &cv_chattime, 50},
|
||||||
|
{IT_STRING | IT_CVAR, NULL, "Chat Notifications", &cv_chatnotifications, 60},
|
||||||
|
{IT_STRING | IT_CVAR, NULL, "Spam Protection", &cv_chatspamprotection, 70},
|
||||||
|
{IT_STRING | IT_CVAR, NULL, "Chat background tint", &cv_chatbacktint, 80},
|
||||||
|
};
|
||||||
|
|
||||||
static menuitem_t OP_ServerOptionsMenu[] =
|
static menuitem_t OP_ServerOptionsMenu[] =
|
||||||
{
|
{
|
||||||
{IT_STRING | IT_SUBMENU, NULL, "General netgame options...", &OP_NetgameOptionsDef, 10},
|
{IT_STRING | IT_SUBMENU, NULL, "General netgame options...", &OP_NetgameOptionsDef, 10},
|
||||||
|
@ -1407,6 +1461,18 @@ static menuitem_t OP_MonitorToggleMenu[] =
|
||||||
// Main Menu and related
|
// Main Menu and related
|
||||||
menu_t MainDef = CENTERMENUSTYLE(NULL, MainMenu, NULL, 72);
|
menu_t MainDef = CENTERMENUSTYLE(NULL, MainMenu, NULL, 72);
|
||||||
|
|
||||||
|
menu_t MISC_AddonsDef =
|
||||||
|
{
|
||||||
|
NULL,
|
||||||
|
sizeof (MISC_AddonsMenu)/sizeof (menuitem_t),
|
||||||
|
&MainDef,
|
||||||
|
MISC_AddonsMenu,
|
||||||
|
M_DrawAddons,
|
||||||
|
50, 28,
|
||||||
|
0,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
menu_t MAPauseDef = PAUSEMENUSTYLE(MAPauseMenu, 40, 72);
|
menu_t MAPauseDef = PAUSEMENUSTYLE(MAPauseMenu, 40, 72);
|
||||||
menu_t SPauseDef = PAUSEMENUSTYLE(SPauseMenu, 40, 72);
|
menu_t SPauseDef = PAUSEMENUSTYLE(SPauseMenu, 40, 72);
|
||||||
menu_t MPauseDef = PAUSEMENUSTYLE(MPauseMenu, 40, 72);
|
menu_t MPauseDef = PAUSEMENUSTYLE(MPauseMenu, 40, 72);
|
||||||
|
@ -1417,6 +1483,9 @@ menu_t MISC_ChangeTeamDef = DEFAULTMENUSTYLE(NULL, MISC_ChangeTeamMenu, &MPauseD
|
||||||
menu_t MISC_ChangeLevelDef = MAPICONMENUSTYLE(NULL, MISC_ChangeLevelMenu, &MPauseDef);
|
menu_t MISC_ChangeLevelDef = MAPICONMENUSTYLE(NULL, MISC_ChangeLevelMenu, &MPauseDef);
|
||||||
menu_t MISC_HelpDef = IMAGEDEF(MISC_HelpMenu);
|
menu_t MISC_HelpDef = IMAGEDEF(MISC_HelpMenu);
|
||||||
|
|
||||||
|
static INT32 highlightflags, recommendedflags, warningflags;
|
||||||
|
|
||||||
|
|
||||||
// Sky Room
|
// Sky Room
|
||||||
menu_t SR_PandoraDef =
|
menu_t SR_PandoraDef =
|
||||||
{
|
{
|
||||||
|
@ -1709,6 +1778,7 @@ menu_t OP_ServerOptionsDef = DEFAULTMENUSTYLE("M_SERVER", OP_ServerOptionsMenu,
|
||||||
|
|
||||||
menu_t OP_NetgameOptionsDef = DEFAULTMENUSTYLE("M_SERVER", OP_NetgameOptionsMenu, &OP_ServerOptionsDef, 30, 30);
|
menu_t OP_NetgameOptionsDef = DEFAULTMENUSTYLE("M_SERVER", OP_NetgameOptionsMenu, &OP_ServerOptionsDef, 30, 30);
|
||||||
menu_t OP_GametypeOptionsDef = DEFAULTMENUSTYLE("M_SERVER", OP_GametypeOptionsMenu, &OP_ServerOptionsDef, 30, 30);
|
menu_t OP_GametypeOptionsDef = DEFAULTMENUSTYLE("M_SERVER", OP_GametypeOptionsMenu, &OP_ServerOptionsDef, 30, 30);
|
||||||
|
menu_t OP_ChatOptionsDef = DEFAULTMENUSTYLE("M_GAME", OP_ChatOptionsMenu, &OP_GameOptionsDef, 30, 30);
|
||||||
menu_t OP_MonitorToggleDef =
|
menu_t OP_MonitorToggleDef =
|
||||||
{
|
{
|
||||||
"M_SERVER",
|
"M_SERVER",
|
||||||
|
@ -1751,6 +1821,7 @@ menu_t OP_OpenGLColorDef =
|
||||||
#endif
|
#endif
|
||||||
menu_t OP_DataOptionsDef = DEFAULTMENUSTYLE("M_DATA", OP_DataOptionsMenu, &OP_MainDef, 60, 30);
|
menu_t OP_DataOptionsDef = DEFAULTMENUSTYLE("M_DATA", OP_DataOptionsMenu, &OP_MainDef, 60, 30);
|
||||||
menu_t OP_ScreenshotOptionsDef = DEFAULTMENUSTYLE("M_DATA", OP_ScreenshotOptionsMenu, &OP_DataOptionsDef, 30, 30);
|
menu_t OP_ScreenshotOptionsDef = DEFAULTMENUSTYLE("M_DATA", OP_ScreenshotOptionsMenu, &OP_DataOptionsDef, 30, 30);
|
||||||
|
menu_t OP_AddonsOptionsDef = DEFAULTMENUSTYLE("M_ADDONS", OP_AddonsOptionsMenu, &OP_MainDef, 30, 30);
|
||||||
menu_t OP_EraseDataDef = DEFAULTMENUSTYLE("M_DATA", OP_EraseDataMenu, &OP_DataOptionsDef, 60, 30);
|
menu_t OP_EraseDataDef = DEFAULTMENUSTYLE("M_DATA", OP_EraseDataMenu, &OP_DataOptionsDef, 60, 30);
|
||||||
|
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
|
@ -1976,6 +2047,12 @@ void Moviemode_mode_Onchange(void)
|
||||||
OP_ScreenshotOptionsMenu[i].status = IT_STRING|IT_CVAR;
|
OP_ScreenshotOptionsMenu[i].status = IT_STRING|IT_CVAR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Addons_option_Onchange(void)
|
||||||
|
{
|
||||||
|
OP_AddonsOptionsMenu[op_addons_folder].status =
|
||||||
|
(cv_addons_option.value == 3 ? IT_CVAR|IT_STRING|IT_CV_STRING : IT_DISABLED);
|
||||||
|
}
|
||||||
|
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
// END ORGANIZATION STUFF.
|
// END ORGANIZATION STUFF.
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
|
@ -2606,6 +2683,7 @@ void M_StartControlPanel(void)
|
||||||
else // multiplayer
|
else // multiplayer
|
||||||
{
|
{
|
||||||
MPauseMenu[mpause_switchmap].status = IT_DISABLED;
|
MPauseMenu[mpause_switchmap].status = IT_DISABLED;
|
||||||
|
MPauseMenu[mpause_addons].status = IT_DISABLED;
|
||||||
MPauseMenu[mpause_scramble].status = IT_DISABLED;
|
MPauseMenu[mpause_scramble].status = IT_DISABLED;
|
||||||
MPauseMenu[mpause_psetupsplit].status = IT_DISABLED;
|
MPauseMenu[mpause_psetupsplit].status = IT_DISABLED;
|
||||||
MPauseMenu[mpause_psetupsplit2].status = IT_DISABLED;
|
MPauseMenu[mpause_psetupsplit2].status = IT_DISABLED;
|
||||||
|
@ -2617,6 +2695,7 @@ void M_StartControlPanel(void)
|
||||||
if ((server || IsPlayerAdmin(consoleplayer)))
|
if ((server || IsPlayerAdmin(consoleplayer)))
|
||||||
{
|
{
|
||||||
MPauseMenu[mpause_switchmap].status = IT_STRING | IT_CALL;
|
MPauseMenu[mpause_switchmap].status = IT_STRING | IT_CALL;
|
||||||
|
MPauseMenu[mpause_addons].status = IT_STRING | IT_CALL;
|
||||||
if (G_GametypeHasTeams())
|
if (G_GametypeHasTeams())
|
||||||
MPauseMenu[mpause_scramble].status = IT_STRING | IT_SUBMENU;
|
MPauseMenu[mpause_scramble].status = IT_STRING | IT_SUBMENU;
|
||||||
}
|
}
|
||||||
|
@ -3856,6 +3935,548 @@ static void M_HandleImageDef(INT32 choice)
|
||||||
// MISC MAIN MENU OPTIONS
|
// MISC MAIN MENU OPTIONS
|
||||||
// ======================
|
// ======================
|
||||||
|
|
||||||
|
static void M_AddonsOptions(INT32 choice)
|
||||||
|
{
|
||||||
|
(void)choice;
|
||||||
|
Addons_option_Onchange();
|
||||||
|
|
||||||
|
M_SetupNextMenu(&OP_AddonsOptionsDef);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define LOCATIONSTRING1 "Visit \x83SRB2.ORG/MODS\x80 to get & make add-ons!"
|
||||||
|
//#define LOCATIONSTRING2 "Visit \x88SRB2.ORG/MODS\x80 to get & make add-ons!"
|
||||||
|
|
||||||
|
static void M_Addons(INT32 choice)
|
||||||
|
{
|
||||||
|
const char *pathname = ".";
|
||||||
|
|
||||||
|
(void)choice;
|
||||||
|
|
||||||
|
// If M_GetGameypeColor() is ever ported from Kart, then remove this.
|
||||||
|
highlightflags = V_YELLOWMAP;
|
||||||
|
recommendedflags = V_GREENMAP;
|
||||||
|
warningflags = V_REDMAP;
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
if (cv_addons_option.value == 0)
|
||||||
|
pathname = usehome ? srb2home : srb2path;
|
||||||
|
else if (cv_addons_option.value == 1)
|
||||||
|
pathname = srb2home;
|
||||||
|
else if (cv_addons_option.value == 2)
|
||||||
|
pathname = srb2path;
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
if (cv_addons_option.value == 3 && *cv_addons_folder.string != '\0')
|
||||||
|
pathname = cv_addons_folder.string;
|
||||||
|
|
||||||
|
strlcpy(menupath, pathname, 1024);
|
||||||
|
menupathindex[(menudepthleft = menudepth-1)] = strlen(menupath) + 1;
|
||||||
|
|
||||||
|
if (menupath[menupathindex[menudepthleft]-2] != PATHSEP[0])
|
||||||
|
{
|
||||||
|
menupath[menupathindex[menudepthleft]-1] = PATHSEP[0];
|
||||||
|
menupath[menupathindex[menudepthleft]] = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
--menupathindex[menudepthleft];
|
||||||
|
|
||||||
|
if (!preparefilemenu(false))
|
||||||
|
{
|
||||||
|
M_StartMessage(va("No files/folders found.\n\n%s\n\n(Press a key)\n",LOCATIONSTRING1),NULL,MM_NOTHING);
|
||||||
|
// (recommendedflags == V_SKYMAP ? LOCATIONSTRING2 : LOCATIONSTRING1))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
dir_on[menudepthleft] = 0;
|
||||||
|
|
||||||
|
if (addonsp[0]) // never going to have some provided but not all, saves individually checking
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
for (i = 0; i < NUM_EXT+5; i++)
|
||||||
|
W_UnlockCachedPatch(addonsp[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
addonsp[EXT_FOLDER] = W_CachePatchName("M_FFLDR", PU_STATIC);
|
||||||
|
addonsp[EXT_UP] = W_CachePatchName("M_FBACK", PU_STATIC);
|
||||||
|
addonsp[EXT_NORESULTS] = W_CachePatchName("M_FNOPE", PU_STATIC);
|
||||||
|
addonsp[EXT_TXT] = W_CachePatchName("M_FTXT", PU_STATIC);
|
||||||
|
addonsp[EXT_CFG] = W_CachePatchName("M_FCFG", PU_STATIC);
|
||||||
|
addonsp[EXT_WAD] = W_CachePatchName("M_FWAD", PU_STATIC);
|
||||||
|
#ifdef USE_KART
|
||||||
|
addonsp[EXT_KART] = W_CachePatchName("M_FKART", PU_STATIC);
|
||||||
|
#endif
|
||||||
|
addonsp[EXT_PK3] = W_CachePatchName("M_FPK3", PU_STATIC);
|
||||||
|
addonsp[EXT_SOC] = W_CachePatchName("M_FSOC", PU_STATIC);
|
||||||
|
addonsp[EXT_LUA] = W_CachePatchName("M_FLUA", PU_STATIC);
|
||||||
|
addonsp[NUM_EXT] = W_CachePatchName("M_FUNKN", PU_STATIC);
|
||||||
|
addonsp[NUM_EXT+1] = W_CachePatchName("M_FSEL", PU_STATIC);
|
||||||
|
addonsp[NUM_EXT+2] = W_CachePatchName("M_FLOAD", PU_STATIC);
|
||||||
|
addonsp[NUM_EXT+3] = W_CachePatchName("M_FSRCH", PU_STATIC);
|
||||||
|
addonsp[NUM_EXT+4] = W_CachePatchName("M_FSAVE", PU_STATIC);
|
||||||
|
|
||||||
|
MISC_AddonsDef.prevMenu = currentMenu;
|
||||||
|
M_SetupNextMenu(&MISC_AddonsDef);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define width 4
|
||||||
|
#define vpadding 27
|
||||||
|
#define h (BASEVIDHEIGHT-(2*vpadding))
|
||||||
|
#define NUMCOLOURS 8 // when toast's coding it's british english hacker fucker
|
||||||
|
static void M_DrawTemperature(INT32 x, fixed_t t)
|
||||||
|
{
|
||||||
|
INT32 y;
|
||||||
|
|
||||||
|
// bounds check
|
||||||
|
if (t > FRACUNIT)
|
||||||
|
t = FRACUNIT;
|
||||||
|
/*else if (t < 0) -- not needed
|
||||||
|
t = 0;*/
|
||||||
|
|
||||||
|
// scale
|
||||||
|
if (t > 1)
|
||||||
|
t = (FixedMul(h<<FRACBITS, t)>>FRACBITS);
|
||||||
|
|
||||||
|
// border
|
||||||
|
V_DrawFill(x - 1, vpadding, 1, h, 120);
|
||||||
|
V_DrawFill(x + width, vpadding, 1, h, 120);
|
||||||
|
V_DrawFill(x - 1, vpadding-1, width+2, 1, 120);
|
||||||
|
V_DrawFill(x - 1, vpadding+h, width+2, 1, 120);
|
||||||
|
|
||||||
|
// bar itself
|
||||||
|
y = h;
|
||||||
|
if (t)
|
||||||
|
for (t = h - t; y > 0; y--)
|
||||||
|
{
|
||||||
|
UINT8 colours[NUMCOLOURS] = {135, 133, 92, 77, 114, 178, 161, 162};
|
||||||
|
UINT8 c;
|
||||||
|
if (y <= t) break;
|
||||||
|
if (y+vpadding >= BASEVIDHEIGHT/2)
|
||||||
|
c = 185;
|
||||||
|
else
|
||||||
|
c = colours[(NUMCOLOURS*(y-1))/(h/2)];
|
||||||
|
V_DrawFill(x, y-1 + vpadding, width, 1, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
// fill the rest of the backing
|
||||||
|
if (y)
|
||||||
|
V_DrawFill(x, vpadding, width, y, 30);
|
||||||
|
}
|
||||||
|
#undef width
|
||||||
|
#undef vpadding
|
||||||
|
#undef h
|
||||||
|
#undef NUMCOLOURS
|
||||||
|
|
||||||
|
static char *M_AddonsHeaderPath(void)
|
||||||
|
{
|
||||||
|
UINT32 len;
|
||||||
|
static char header[1024];
|
||||||
|
|
||||||
|
strlcpy(header, va("%s folder%s", cv_addons_option.string, menupath+menupathindex[menudepth-1]-1), 1024);
|
||||||
|
len = strlen(header);
|
||||||
|
if (len > 34)
|
||||||
|
{
|
||||||
|
len = len-34;
|
||||||
|
header[len] = header[len+1] = header[len+2] = '.';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
len = 0;
|
||||||
|
|
||||||
|
return header+len;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define UNEXIST S_StartSound(NULL, sfx_lose);\
|
||||||
|
M_SetupNextMenu(MISC_AddonsDef.prevMenu);\
|
||||||
|
M_StartMessage(va("\x82%s\x80\nThis folder no longer exists!\nAborting to main menu.\n\n(Press a key)\n", M_AddonsHeaderPath()),NULL,MM_NOTHING)
|
||||||
|
|
||||||
|
#define CLEARNAME Z_Free(refreshdirname);\
|
||||||
|
refreshdirname = NULL
|
||||||
|
|
||||||
|
static void M_AddonsClearName(INT32 choice)
|
||||||
|
{
|
||||||
|
CLEARNAME;
|
||||||
|
M_StopMessage(choice);
|
||||||
|
}
|
||||||
|
|
||||||
|
// returns whether to do message draw
|
||||||
|
static boolean M_AddonsRefresh(void)
|
||||||
|
{
|
||||||
|
if ((refreshdirmenu & REFRESHDIR_NORMAL) && !preparefilemenu(true))
|
||||||
|
{
|
||||||
|
UNEXIST;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (refreshdirmenu & REFRESHDIR_ADDFILE)
|
||||||
|
{
|
||||||
|
char *message = NULL;
|
||||||
|
|
||||||
|
if (refreshdirmenu & REFRESHDIR_NOTLOADED)
|
||||||
|
{
|
||||||
|
S_StartSound(NULL, sfx_lose);
|
||||||
|
if (refreshdirmenu & REFRESHDIR_MAX)
|
||||||
|
message = va("%c%s\x80\nMaximum number of add-ons reached.\nA file could not be loaded.\nIf you want to play with this add-on, restart the game to clear existing ones.\n\n(Press a key)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), refreshdirname);
|
||||||
|
else
|
||||||
|
message = va("%c%s\x80\nA file was not loaded.\nCheck the console log for more information.\n\n(Press a key)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), refreshdirname);
|
||||||
|
}
|
||||||
|
else if (refreshdirmenu & (REFRESHDIR_WARNING|REFRESHDIR_ERROR))
|
||||||
|
{
|
||||||
|
S_StartSound(NULL, sfx_skid);
|
||||||
|
message = va("%c%s\x80\nA file was loaded with %s.\nCheck the console log for more information.\n\n(Press a key)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), refreshdirname, ((refreshdirmenu & REFRESHDIR_ERROR) ? "errors" : "warnings"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (message)
|
||||||
|
{
|
||||||
|
M_StartMessage(message,M_AddonsClearName,MM_EVENTHANDLER);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
S_StartSound(NULL, sfx_strpst);
|
||||||
|
CLEARNAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void M_DrawAddons(void)
|
||||||
|
{
|
||||||
|
INT32 x, y;
|
||||||
|
ssize_t i, m;
|
||||||
|
const UINT8 *flashcol = NULL;
|
||||||
|
UINT8 hilicol;
|
||||||
|
|
||||||
|
// hack - need to refresh at end of frame to handle addfile...
|
||||||
|
if (refreshdirmenu & M_AddonsRefresh())
|
||||||
|
{
|
||||||
|
M_DrawMessageMenu();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Playing())
|
||||||
|
V_DrawCenteredString(BASEVIDWIDTH/2, 5, warningflags, "Adding files mid-game may cause problems.");
|
||||||
|
else
|
||||||
|
V_DrawCenteredString(BASEVIDWIDTH/2, 5, 0, LOCATIONSTRING1);
|
||||||
|
// (recommendedflags == V_SKYMAP ? LOCATIONSTRING2 : LOCATIONSTRING1)
|
||||||
|
|
||||||
|
if (numwadfiles <= mainwads+1)
|
||||||
|
y = 0;
|
||||||
|
else if (numwadfiles >= MAX_WADFILES)
|
||||||
|
y = FRACUNIT;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
x = FixedDiv(((ssize_t)(numwadfiles) - (ssize_t)(mainwads+1))<<FRACBITS, ((ssize_t)MAX_WADFILES - (ssize_t)(mainwads+1))<<FRACBITS);
|
||||||
|
y = FixedDiv((((ssize_t)packetsizetally-(ssize_t)mainwadstally)<<FRACBITS), ((((ssize_t)MAXFILENEEDED*sizeof(UINT8)-(ssize_t)mainwadstally)-(5+22))<<FRACBITS)); // 5+22 = (a.ext + checksum length) is minimum addition to packet size tally
|
||||||
|
if (x > y)
|
||||||
|
y = x;
|
||||||
|
if (y > FRACUNIT) // happens because of how we're shrinkin' it a little
|
||||||
|
y = FRACUNIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
M_DrawTemperature(BASEVIDWIDTH - 19 - 5, y);
|
||||||
|
|
||||||
|
// DRAW MENU
|
||||||
|
x = currentMenu->x;
|
||||||
|
y = currentMenu->y + 1;
|
||||||
|
|
||||||
|
hilicol = V_GetStringColormap(highlightflags)[120];
|
||||||
|
|
||||||
|
V_DrawString(x-21, (y - 16) + (lsheadingheight - 12), highlightflags|V_ALLOWLOWERCASE, M_AddonsHeaderPath());
|
||||||
|
V_DrawFill(x-21, (y - 16) + (lsheadingheight - 3), MAXSTRINGLENGTH*8+6, 1, hilicol);
|
||||||
|
V_DrawFill(x-21, (y - 16) + (lsheadingheight - 2), MAXSTRINGLENGTH*8+6, 1, 30);
|
||||||
|
|
||||||
|
m = (BASEVIDHEIGHT - currentMenu->y + 2) - (y - 1);
|
||||||
|
V_DrawFill(x - 21, y - 1, MAXSTRINGLENGTH*8+6, m, 239);
|
||||||
|
|
||||||
|
// scrollbar!
|
||||||
|
if (sizedirmenu <= (2*numaddonsshown + 1))
|
||||||
|
i = 0;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ssize_t q = m;
|
||||||
|
m = ((2*numaddonsshown + 1) * m)/sizedirmenu;
|
||||||
|
if (dir_on[menudepthleft] <= numaddonsshown) // all the way up
|
||||||
|
i = 0;
|
||||||
|
else if (sizedirmenu <= (dir_on[menudepthleft] + numaddonsshown + 1)) // all the way down
|
||||||
|
i = q-m;
|
||||||
|
else
|
||||||
|
i = ((dir_on[menudepthleft] - numaddonsshown) * (q-m))/(sizedirmenu - (2*numaddonsshown + 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
V_DrawFill(x + MAXSTRINGLENGTH*8+5 - 21, (y - 1) + i, 1, m, hilicol);
|
||||||
|
|
||||||
|
// get bottom...
|
||||||
|
m = dir_on[menudepthleft] + numaddonsshown + 1;
|
||||||
|
if (m > (ssize_t)sizedirmenu)
|
||||||
|
m = sizedirmenu;
|
||||||
|
|
||||||
|
// then compute top and adjust bottom if needed!
|
||||||
|
if (m < (2*numaddonsshown + 1))
|
||||||
|
{
|
||||||
|
m = min(sizedirmenu, 2*numaddonsshown + 1);
|
||||||
|
i = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
i = m - (2*numaddonsshown + 1);
|
||||||
|
|
||||||
|
if (i != 0)
|
||||||
|
V_DrawString(19, y+4 - (skullAnimCounter/5), highlightflags, "\x1A");
|
||||||
|
|
||||||
|
if (skullAnimCounter < 4)
|
||||||
|
flashcol = V_GetStringColormap(highlightflags);
|
||||||
|
|
||||||
|
for (; i < m; i++)
|
||||||
|
{
|
||||||
|
UINT32 flags = V_ALLOWLOWERCASE;
|
||||||
|
if (y > BASEVIDHEIGHT) break;
|
||||||
|
if (dirmenu[i])
|
||||||
|
#define type (UINT8)(dirmenu[i][DIR_TYPE])
|
||||||
|
{
|
||||||
|
if (type & EXT_LOADED)
|
||||||
|
{
|
||||||
|
flags |= V_TRANSLUCENT;
|
||||||
|
V_DrawSmallScaledPatch(x-(16+4), y, V_TRANSLUCENT, addonsp[(type & ~EXT_LOADED)]);
|
||||||
|
V_DrawSmallScaledPatch(x-(16+4), y, 0, addonsp[NUM_EXT+2]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
V_DrawSmallScaledPatch(x-(16+4), y, 0, addonsp[(type & ~EXT_LOADED)]);
|
||||||
|
|
||||||
|
if ((size_t)i == dir_on[menudepthleft])
|
||||||
|
{
|
||||||
|
V_DrawFixedPatch((x-(16+4))<<FRACBITS, (y)<<FRACBITS, FRACUNIT/2, 0, addonsp[NUM_EXT+1], flashcol);
|
||||||
|
flags = V_ALLOWLOWERCASE|highlightflags;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define charsonside 14
|
||||||
|
if (dirmenu[i][DIR_LEN] > (charsonside*2 + 3))
|
||||||
|
V_DrawString(x, y+4, flags, va("%.*s...%s", charsonside, dirmenu[i]+DIR_STRING, dirmenu[i]+DIR_STRING+dirmenu[i][DIR_LEN]-(charsonside+1)));
|
||||||
|
#undef charsonside
|
||||||
|
else
|
||||||
|
V_DrawString(x, y+4, flags, dirmenu[i]+DIR_STRING);
|
||||||
|
}
|
||||||
|
#undef type
|
||||||
|
y += 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m != (ssize_t)sizedirmenu)
|
||||||
|
V_DrawString(19, y-12 + (skullAnimCounter/5), highlightflags, "\x1B");
|
||||||
|
|
||||||
|
y = BASEVIDHEIGHT - currentMenu->y + 1;
|
||||||
|
|
||||||
|
M_DrawTextBox(x - (21 + 5), y, MAXSTRINGLENGTH, 1);
|
||||||
|
if (menusearch[0])
|
||||||
|
V_DrawString(x - 18, y + 8, V_ALLOWLOWERCASE, menusearch+1);
|
||||||
|
else
|
||||||
|
V_DrawString(x - 18, y + 8, V_ALLOWLOWERCASE|V_TRANSLUCENT, "Type to search...");
|
||||||
|
if (skullAnimCounter < 4)
|
||||||
|
V_DrawCharacter(x - 18 + V_StringWidth(menusearch+1, 0), y + 8,
|
||||||
|
'_' | 0x80, false);
|
||||||
|
|
||||||
|
x -= (21 + 5 + 16);
|
||||||
|
V_DrawSmallScaledPatch(x, y + 4, (menusearch[0] ? 0 : V_TRANSLUCENT), addonsp[NUM_EXT+3]);
|
||||||
|
|
||||||
|
x = BASEVIDWIDTH - x - 16;
|
||||||
|
V_DrawSmallScaledPatch(x, y + 4, ((!modifiedgame || savemoddata) ? 0 : V_TRANSLUCENT), addonsp[NUM_EXT+4]);
|
||||||
|
|
||||||
|
if (modifiedgame)
|
||||||
|
V_DrawSmallScaledPatch(x, y + 4, 0, addonsp[NUM_EXT+2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void M_AddonExec(INT32 ch)
|
||||||
|
{
|
||||||
|
if (ch != 'y' && ch != KEY_ENTER)
|
||||||
|
return;
|
||||||
|
|
||||||
|
S_StartSound(NULL, sfx_zoom);
|
||||||
|
COM_BufAddText(va("exec \"%s%s\"", menupath, dirmenu[dir_on[menudepthleft]]+DIR_STRING));
|
||||||
|
}
|
||||||
|
|
||||||
|
#define len menusearch[0]
|
||||||
|
static boolean M_ChangeStringAddons(INT32 choice)
|
||||||
|
{
|
||||||
|
if (shiftdown && choice >= 32 && choice <= 127)
|
||||||
|
choice = shiftxform[choice];
|
||||||
|
|
||||||
|
switch (choice)
|
||||||
|
{
|
||||||
|
case KEY_DEL:
|
||||||
|
if (len)
|
||||||
|
{
|
||||||
|
len = menusearch[1] = 0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case KEY_BACKSPACE:
|
||||||
|
if (len)
|
||||||
|
{
|
||||||
|
menusearch[1+--len] = 0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (choice >= 32 && choice <= 127)
|
||||||
|
{
|
||||||
|
if (len < MAXSTRINGLENGTH - 1)
|
||||||
|
{
|
||||||
|
menusearch[1+len++] = (char)choice;
|
||||||
|
menusearch[1+len] = 0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#undef len
|
||||||
|
|
||||||
|
static void M_HandleAddons(INT32 choice)
|
||||||
|
{
|
||||||
|
boolean exitmenu = false; // exit to previous menu
|
||||||
|
|
||||||
|
if (M_ChangeStringAddons(choice))
|
||||||
|
{
|
||||||
|
char *tempname = NULL;
|
||||||
|
if (dirmenu && dirmenu[dir_on[menudepthleft]])
|
||||||
|
tempname = Z_StrDup(dirmenu[dir_on[menudepthleft]]+DIR_STRING); // don't need to I_Error if can't make - not important, just QoL
|
||||||
|
#if 0 // much slower
|
||||||
|
if (!preparefilemenu(true))
|
||||||
|
{
|
||||||
|
UNEXIST;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#else // streamlined
|
||||||
|
searchfilemenu(tempname);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (choice)
|
||||||
|
{
|
||||||
|
case KEY_DOWNARROW:
|
||||||
|
if (dir_on[menudepthleft] < sizedirmenu-1)
|
||||||
|
dir_on[menudepthleft]++;
|
||||||
|
S_StartSound(NULL, sfx_menu1);
|
||||||
|
break;
|
||||||
|
case KEY_UPARROW:
|
||||||
|
if (dir_on[menudepthleft])
|
||||||
|
dir_on[menudepthleft]--;
|
||||||
|
S_StartSound(NULL, sfx_menu1);
|
||||||
|
break;
|
||||||
|
case KEY_PGDN:
|
||||||
|
{
|
||||||
|
UINT8 i;
|
||||||
|
for (i = numaddonsshown; i && (dir_on[menudepthleft] < sizedirmenu-1); i--)
|
||||||
|
dir_on[menudepthleft]++;
|
||||||
|
}
|
||||||
|
S_StartSound(NULL, sfx_menu1);
|
||||||
|
break;
|
||||||
|
case KEY_PGUP:
|
||||||
|
{
|
||||||
|
UINT8 i;
|
||||||
|
for (i = numaddonsshown; i && (dir_on[menudepthleft]); i--)
|
||||||
|
dir_on[menudepthleft]--;
|
||||||
|
}
|
||||||
|
S_StartSound(NULL, sfx_menu1);
|
||||||
|
break;
|
||||||
|
case KEY_ENTER:
|
||||||
|
{
|
||||||
|
boolean refresh = true;
|
||||||
|
if (!dirmenu[dir_on[menudepthleft]])
|
||||||
|
S_StartSound(NULL, sfx_lose);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch (dirmenu[dir_on[menudepthleft]][DIR_TYPE])
|
||||||
|
{
|
||||||
|
case EXT_FOLDER:
|
||||||
|
strcpy(&menupath[menupathindex[menudepthleft]],dirmenu[dir_on[menudepthleft]]+DIR_STRING);
|
||||||
|
if (menudepthleft)
|
||||||
|
{
|
||||||
|
menupathindex[--menudepthleft] = strlen(menupath);
|
||||||
|
menupath[menupathindex[menudepthleft]] = 0;
|
||||||
|
|
||||||
|
if (!preparefilemenu(false))
|
||||||
|
{
|
||||||
|
S_StartSound(NULL, sfx_skid);
|
||||||
|
M_StartMessage(va("%c%s\x80\nThis folder is empty.\n\n(Press a key)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), M_AddonsHeaderPath()),NULL,MM_NOTHING);
|
||||||
|
menupath[menupathindex[++menudepthleft]] = 0;
|
||||||
|
|
||||||
|
if (!preparefilemenu(true))
|
||||||
|
{
|
||||||
|
UNEXIST;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
S_StartSound(NULL, sfx_menu1);
|
||||||
|
dir_on[menudepthleft] = 1;
|
||||||
|
}
|
||||||
|
refresh = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
S_StartSound(NULL, sfx_lose);
|
||||||
|
M_StartMessage(va("%c%s\x80\nThis folder is too deep to navigate to!\n\n(Press a key)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), M_AddonsHeaderPath()),NULL,MM_NOTHING);
|
||||||
|
menupath[menupathindex[menudepthleft]] = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case EXT_UP:
|
||||||
|
S_StartSound(NULL, sfx_menu1);
|
||||||
|
menupath[menupathindex[++menudepthleft]] = 0;
|
||||||
|
if (!preparefilemenu(false))
|
||||||
|
{
|
||||||
|
UNEXIST;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case EXT_TXT:
|
||||||
|
M_StartMessage(va("%c%s\x80\nThis file may not be a console script.\nAttempt to run anyways? \n\n(Press 'Y' to confirm)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), dirmenu[dir_on[menudepthleft]]+DIR_STRING),M_AddonExec,MM_YESNO);
|
||||||
|
break;
|
||||||
|
case EXT_CFG:
|
||||||
|
M_AddonExec(KEY_ENTER);
|
||||||
|
break;
|
||||||
|
case EXT_LUA:
|
||||||
|
#ifndef HAVE_BLUA
|
||||||
|
S_StartSound(NULL, sfx_lose);
|
||||||
|
M_StartMessage(va("%c%s\x80\nThis copy of SRB2 was compiled\nwithout support for .lua files.\n\n(Press a key)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), dirmenu[dir_on[menudepthleft]]+DIR_STRING),NULL,MM_NOTHING);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
// else intentional fallthrough
|
||||||
|
case EXT_SOC:
|
||||||
|
case EXT_WAD:
|
||||||
|
#ifdef USE_KART
|
||||||
|
case EXT_KART:
|
||||||
|
#endif
|
||||||
|
case EXT_PK3:
|
||||||
|
COM_BufAddText(va("addfile \"%s%s\"", menupath, dirmenu[dir_on[menudepthleft]]+DIR_STRING));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
S_StartSound(NULL, sfx_lose);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (refresh)
|
||||||
|
refreshdirmenu |= REFRESHDIR_NORMAL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case KEY_ESCAPE:
|
||||||
|
exitmenu = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (exitmenu)
|
||||||
|
{
|
||||||
|
closefilemenu(true);
|
||||||
|
|
||||||
|
// Secret menu!
|
||||||
|
MainMenu[secrets].status = (M_AnySecretUnlocked()) ? (IT_STRING | IT_CALL) : (IT_DISABLED);
|
||||||
|
|
||||||
|
if (currentMenu->prevMenu)
|
||||||
|
M_SetupNextMenu(currentMenu->prevMenu);
|
||||||
|
else
|
||||||
|
M_ClearMenus(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void M_PandorasBox(INT32 choice)
|
static void M_PandorasBox(INT32 choice)
|
||||||
{
|
{
|
||||||
(void)choice;
|
(void)choice;
|
||||||
|
@ -6960,7 +7581,7 @@ static void M_ChangecontrolResponse(event_t *ev)
|
||||||
found = 0;
|
found = 0;
|
||||||
setupcontrols[control][1] = KEY_NULL; //replace key 1,clear key2
|
setupcontrols[control][1] = KEY_NULL; //replace key 1,clear key2
|
||||||
}
|
}
|
||||||
G_CheckDoubleUsage(ch);
|
(void)G_CheckDoubleUsage(ch, true);
|
||||||
setupcontrols[control][found] = ch;
|
setupcontrols[control][found] = ch;
|
||||||
}
|
}
|
||||||
S_StartSound(NULL, sfx_strpst);
|
S_StartSound(NULL, sfx_strpst);
|
||||||
|
|
|
@ -124,6 +124,8 @@ boolean M_CanShowLevelInList(INT32 mapnum, INT32 gt);
|
||||||
#define IT_HEADER (IT_SPACE +IT_HEADERTEXT)
|
#define IT_HEADER (IT_SPACE +IT_HEADERTEXT)
|
||||||
#define IT_SECRET (IT_SPACE +IT_QUESTIONMARKS)
|
#define IT_SECRET (IT_SPACE +IT_QUESTIONMARKS)
|
||||||
|
|
||||||
|
#define MAXSTRINGLENGTH 32
|
||||||
|
|
||||||
typedef union
|
typedef union
|
||||||
{
|
{
|
||||||
struct menu_s *submenu; // IT_SUBMENU
|
struct menu_s *submenu; // IT_SUBMENU
|
||||||
|
@ -223,6 +225,9 @@ void M_CheatActivationResponder(INT32 ch);
|
||||||
void Moviemode_mode_Onchange(void);
|
void Moviemode_mode_Onchange(void);
|
||||||
void Screenshot_option_Onchange(void);
|
void Screenshot_option_Onchange(void);
|
||||||
|
|
||||||
|
// Addons menu updating
|
||||||
|
void Addons_option_Onchange(void);
|
||||||
|
|
||||||
// These defines make it a little easier to make menus
|
// These defines make it a little easier to make menus
|
||||||
#define DEFAULTMENUSTYLE(header, source, prev, x, y)\
|
#define DEFAULTMENUSTYLE(header, source, prev, x, y)\
|
||||||
{\
|
{\
|
||||||
|
|
16
src/m_misc.c
16
src/m_misc.c
|
@ -447,7 +447,7 @@ void Command_LoadConfig_f(void)
|
||||||
G_Controldefault();
|
G_Controldefault();
|
||||||
|
|
||||||
// temporarily reset execversion to default
|
// temporarily reset execversion to default
|
||||||
cv_execversion.flags &= ~CV_HIDEN;
|
CV_ToggleExecVersion(true);
|
||||||
COM_BufInsertText(va("%s \"%s\"\n", cv_execversion.name, cv_execversion.defaultvalue));
|
COM_BufInsertText(va("%s \"%s\"\n", cv_execversion.name, cv_execversion.defaultvalue));
|
||||||
CV_InitFilterVar();
|
CV_InitFilterVar();
|
||||||
|
|
||||||
|
@ -455,8 +455,8 @@ void Command_LoadConfig_f(void)
|
||||||
COM_BufInsertText(va("exec \"%s\"\n", configfile));
|
COM_BufInsertText(va("exec \"%s\"\n", configfile));
|
||||||
|
|
||||||
// don't filter anymore vars and don't let this convsvar be changed
|
// don't filter anymore vars and don't let this convsvar be changed
|
||||||
COM_BufInsertText(va("%s \"%d\"\n", cv_execversion.name, MODVERSION));
|
COM_BufInsertText(va("%s \"%d\"\n", cv_execversion.name, EXECVERSION));
|
||||||
cv_execversion.flags |= CV_HIDEN;
|
CV_ToggleExecVersion(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Saves the current configuration and loads another.
|
/** Saves the current configuration and loads another.
|
||||||
|
@ -498,7 +498,7 @@ void M_FirstLoadConfig(void)
|
||||||
|
|
||||||
// temporarily reset execversion to default
|
// temporarily reset execversion to default
|
||||||
// we shouldn't need to do this, but JUST in case...
|
// we shouldn't need to do this, but JUST in case...
|
||||||
cv_execversion.flags &= ~CV_HIDEN;
|
CV_ToggleExecVersion(true);
|
||||||
COM_BufInsertText(va("%s \"%s\"\n", cv_execversion.name, cv_execversion.defaultvalue));
|
COM_BufInsertText(va("%s \"%s\"\n", cv_execversion.name, cv_execversion.defaultvalue));
|
||||||
CV_InitFilterVar();
|
CV_InitFilterVar();
|
||||||
|
|
||||||
|
@ -507,8 +507,8 @@ void M_FirstLoadConfig(void)
|
||||||
// no COM_BufExecute() needed; that does it right away
|
// no COM_BufExecute() needed; that does it right away
|
||||||
|
|
||||||
// don't filter anymore vars and don't let this convsvar be changed
|
// don't filter anymore vars and don't let this convsvar be changed
|
||||||
COM_BufInsertText(va("%s \"%d\"\n", cv_execversion.name, MODVERSION));
|
COM_BufInsertText(va("%s \"%d\"\n", cv_execversion.name, EXECVERSION));
|
||||||
cv_execversion.flags |= CV_HIDEN;
|
CV_ToggleExecVersion(false);
|
||||||
|
|
||||||
// make sure I_Quit() will write back the correct config
|
// make sure I_Quit() will write back the correct config
|
||||||
// (do not write back the config if it crash before)
|
// (do not write back the config if it crash before)
|
||||||
|
@ -574,8 +574,8 @@ void M_SaveConfig(const char *filename)
|
||||||
fprintf(f, "// SRB2 configuration file.\n");
|
fprintf(f, "// SRB2 configuration file.\n");
|
||||||
|
|
||||||
// print execversion FIRST, because subsequent consvars need to be filtered
|
// print execversion FIRST, because subsequent consvars need to be filtered
|
||||||
// always print current MODVERSION
|
// always print current EXECVERSION
|
||||||
fprintf(f, "%s \"%d\"\n", cv_execversion.name, MODVERSION);
|
fprintf(f, "%s \"%d\"\n", cv_execversion.name, EXECVERSION);
|
||||||
|
|
||||||
// FIXME: save key aliases if ever implemented..
|
// FIXME: save key aliases if ever implemented..
|
||||||
|
|
||||||
|
|
|
@ -7274,6 +7274,8 @@ void P_MobjThinker(mobj_t *mobj)
|
||||||
// Assumedly in splitscreen players will be on opposing teams
|
// Assumedly in splitscreen players will be on opposing teams
|
||||||
if (players[consoleplayer].ctfteam == 1 || splitscreen)
|
if (players[consoleplayer].ctfteam == 1 || splitscreen)
|
||||||
S_StartSound(NULL, sfx_hoop1);
|
S_StartSound(NULL, sfx_hoop1);
|
||||||
|
else if (players[consoleplayer].ctfteam == 2)
|
||||||
|
S_StartSound(NULL, sfx_hoop3);
|
||||||
|
|
||||||
redflag = flagmo;
|
redflag = flagmo;
|
||||||
}
|
}
|
||||||
|
@ -7285,6 +7287,8 @@ void P_MobjThinker(mobj_t *mobj)
|
||||||
// Assumedly in splitscreen players will be on opposing teams
|
// Assumedly in splitscreen players will be on opposing teams
|
||||||
if (players[consoleplayer].ctfteam == 2 || splitscreen)
|
if (players[consoleplayer].ctfteam == 2 || splitscreen)
|
||||||
S_StartSound(NULL, sfx_hoop1);
|
S_StartSound(NULL, sfx_hoop1);
|
||||||
|
else if (players[consoleplayer].ctfteam == 1)
|
||||||
|
S_StartSound(NULL, sfx_hoop3);
|
||||||
|
|
||||||
blueflag = flagmo;
|
blueflag = flagmo;
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,6 +54,8 @@
|
||||||
|
|
||||||
#include "v_video.h"
|
#include "v_video.h"
|
||||||
|
|
||||||
|
#include "filesrch.h" // refreshdirmenu
|
||||||
|
|
||||||
// wipes
|
// wipes
|
||||||
#include "f_finale.h"
|
#include "f_finale.h"
|
||||||
|
|
||||||
|
@ -3197,6 +3199,7 @@ boolean P_AddWadFile(const char *wadfilename)
|
||||||
|
|
||||||
if ((numlumps = W_InitFile(wadfilename)) == INT16_MAX)
|
if ((numlumps = W_InitFile(wadfilename)) == INT16_MAX)
|
||||||
{
|
{
|
||||||
|
refreshdirmenu |= REFRESHDIR_NOTLOADED;
|
||||||
CONS_Printf(M_GetText("Errors occurred while loading %s; not added.\n"), wadfilename);
|
CONS_Printf(M_GetText("Errors occurred while loading %s; not added.\n"), wadfilename);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1220,7 +1220,7 @@ INT32 R_CreateColormap(char *p1, char *p2, char *p3)
|
||||||
continue;
|
continue;
|
||||||
if (maskcolor == extra_colormaps[i].maskcolor
|
if (maskcolor == extra_colormaps[i].maskcolor
|
||||||
&& fadecolor == extra_colormaps[i].fadecolor
|
&& fadecolor == extra_colormaps[i].fadecolor
|
||||||
&& fabsf((float)(maskamt - extra_colormaps[i].maskamt)) < 1.0E-36f
|
&& fabs(maskamt - extra_colormaps[i].maskamt) < DBL_EPSILON
|
||||||
&& fadestart == extra_colormaps[i].fadestart
|
&& fadestart == extra_colormaps[i].fadestart
|
||||||
&& fadeend == extra_colormaps[i].fadeend
|
&& fadeend == extra_colormaps[i].fadeend
|
||||||
&& fog == extra_colormaps[i].fog)
|
&& fog == extra_colormaps[i].fog)
|
||||||
|
|
|
@ -1126,9 +1126,6 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
||||||
// Get data for the column
|
// Get data for the column
|
||||||
col = (column_t *)((UINT8 *)R_GetColumn(texnum,maskedtexturecol[dc_x]) - 3);
|
col = (column_t *)((UINT8 *)R_GetColumn(texnum,maskedtexturecol[dc_x]) - 3);
|
||||||
|
|
||||||
// guess what I just fixed? -monster psychic cat
|
|
||||||
dc_colormap = colormaps;
|
|
||||||
|
|
||||||
// SoM: New code does not rely on R_DrawColumnShadowed_8 which
|
// SoM: New code does not rely on R_DrawColumnShadowed_8 which
|
||||||
// will (hopefully) put less strain on the stack.
|
// will (hopefully) put less strain on the stack.
|
||||||
if (dc_numlights)
|
if (dc_numlights)
|
||||||
|
|
|
@ -1214,7 +1214,7 @@
|
||||||
C01FCF4B08A954540054247B /* Debug */ = {
|
C01FCF4B08A954540054247B /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
CURRENT_PROJECT_VERSION = 2.1.21;
|
CURRENT_PROJECT_VERSION = 2.1.22;
|
||||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
NORMALSRB2,
|
NORMALSRB2,
|
||||||
|
@ -1226,7 +1226,7 @@
|
||||||
C01FCF4C08A954540054247B /* Release */ = {
|
C01FCF4C08A954540054247B /* Release */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
CURRENT_PROJECT_VERSION = 2.1.21;
|
CURRENT_PROJECT_VERSION = 2.1.22;
|
||||||
GCC_ENABLE_FIX_AND_CONTINUE = NO;
|
GCC_ENABLE_FIX_AND_CONTINUE = NO;
|
||||||
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
|
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
|
||||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||||
|
|
|
@ -1214,7 +1214,7 @@
|
||||||
C01FCF4B08A954540054247B /* Debug */ = {
|
C01FCF4B08A954540054247B /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
CURRENT_PROJECT_VERSION = 2.1.21;
|
CURRENT_PROJECT_VERSION = 2.1.22;
|
||||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
NORMALSRB2,
|
NORMALSRB2,
|
||||||
|
@ -1226,7 +1226,7 @@
|
||||||
C01FCF4C08A954540054247B /* Release */ = {
|
C01FCF4C08A954540054247B /* Release */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
CURRENT_PROJECT_VERSION = 2.1.21;
|
CURRENT_PROJECT_VERSION = 2.1.22;
|
||||||
GCC_ENABLE_FIX_AND_CONTINUE = NO;
|
GCC_ENABLE_FIX_AND_CONTINUE = NO;
|
||||||
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
|
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
|
||||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||||
|
|
183
src/v_video.c
183
src/v_video.c
|
@ -841,6 +841,145 @@ void V_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c)
|
||||||
memset(dest, c, w * vid.bpp);
|
memset(dest, c, w * vid.bpp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HWRENDER
|
||||||
|
// This is now a function since it's otherwise repeated 2 times and honestly looks retarded:
|
||||||
|
static UINT32 V_GetHWConsBackColor(void)
|
||||||
|
{
|
||||||
|
UINT32 hwcolor;
|
||||||
|
switch (cons_backcolor.value)
|
||||||
|
{
|
||||||
|
case 0: hwcolor = 0xffffff00; break; // White
|
||||||
|
case 1: hwcolor = 0x80808000; break; // Gray
|
||||||
|
case 2: hwcolor = 0xdeb88700; break; // Sepia
|
||||||
|
case 3: hwcolor = 0x40201000; break; // Brown
|
||||||
|
case 4: hwcolor = 0xfa807200; break; // Pink
|
||||||
|
case 5: hwcolor = 0xff69b400; break; // Raspberry
|
||||||
|
case 6: hwcolor = 0xff000000; break; // Red
|
||||||
|
case 7: hwcolor = 0xffd68300; break; // Creamsicle
|
||||||
|
case 8: hwcolor = 0xff800000; break; // Orange
|
||||||
|
case 9: hwcolor = 0xdaa52000; break; // Gold
|
||||||
|
case 10: hwcolor = 0x80800000; break; // Yellow
|
||||||
|
case 11: hwcolor = 0x00ff0000; break; // Emerald
|
||||||
|
case 12: hwcolor = 0x00800000; break; // Green
|
||||||
|
case 13: hwcolor = 0x4080ff00; break; // Cyan
|
||||||
|
case 14: hwcolor = 0x4682b400; break; // Steel
|
||||||
|
case 15: hwcolor = 0x1e90ff00; break; // Periwinkle
|
||||||
|
case 16: hwcolor = 0x0000ff00; break; // Blue
|
||||||
|
case 17: hwcolor = 0xff00ff00; break; // Purple
|
||||||
|
case 18: hwcolor = 0xee82ee00; break; // Lavender
|
||||||
|
// Default green
|
||||||
|
default: hwcolor = 0x00800000; break;
|
||||||
|
}
|
||||||
|
return hwcolor;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// THANK YOU MPC!!!
|
||||||
|
|
||||||
|
void V_DrawFillConsoleMap(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c)
|
||||||
|
{
|
||||||
|
UINT8 *dest;
|
||||||
|
INT32 u, v;
|
||||||
|
UINT8 *fadetable;
|
||||||
|
UINT32 alphalevel = 0;
|
||||||
|
|
||||||
|
if (rendermode == render_none)
|
||||||
|
return;
|
||||||
|
|
||||||
|
#ifdef HWRENDER
|
||||||
|
if (rendermode != render_soft && rendermode != render_none)
|
||||||
|
{
|
||||||
|
UINT32 hwcolor = V_GetHWConsBackColor();
|
||||||
|
HWR_DrawConsoleFill(x, y, w, h, hwcolor, c); // we still use the regular color stuff but only for flags. actual draw color is "hwcolor" for this.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!(c & V_NOSCALESTART))
|
||||||
|
{
|
||||||
|
INT32 dupx = vid.dupx, dupy = vid.dupy;
|
||||||
|
|
||||||
|
if (x == 0 && y == 0 && w == BASEVIDWIDTH && h == BASEVIDHEIGHT)
|
||||||
|
{ // Clear the entire screen, from dest to deststop. Yes, this really works.
|
||||||
|
memset(screens[0], (UINT8)(c&255), vid.width * vid.height * vid.bpp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
x *= dupx;
|
||||||
|
y *= dupy;
|
||||||
|
w *= dupx;
|
||||||
|
h *= dupy;
|
||||||
|
|
||||||
|
// Center it if necessary
|
||||||
|
if (vid.width != BASEVIDWIDTH * dupx)
|
||||||
|
{
|
||||||
|
// dupx adjustments pretend that screen width is BASEVIDWIDTH * dupx,
|
||||||
|
// so center this imaginary screen
|
||||||
|
if (c & V_SNAPTORIGHT)
|
||||||
|
x += (vid.width - (BASEVIDWIDTH * dupx));
|
||||||
|
else if (!(c & V_SNAPTOLEFT))
|
||||||
|
x += (vid.width - (BASEVIDWIDTH * dupx)) / 2;
|
||||||
|
}
|
||||||
|
if (vid.height != BASEVIDHEIGHT * dupy)
|
||||||
|
{
|
||||||
|
// same thing here
|
||||||
|
if (c & V_SNAPTOBOTTOM)
|
||||||
|
y += (vid.height - (BASEVIDHEIGHT * dupy));
|
||||||
|
else if (!(c & V_SNAPTOTOP))
|
||||||
|
y += (vid.height - (BASEVIDHEIGHT * dupy)) / 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (x >= vid.width || y >= vid.height)
|
||||||
|
return; // off the screen
|
||||||
|
if (x < 0) {
|
||||||
|
w += x;
|
||||||
|
x = 0;
|
||||||
|
}
|
||||||
|
if (y < 0) {
|
||||||
|
h += y;
|
||||||
|
y = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (w <= 0 || h <= 0)
|
||||||
|
return; // zero width/height wouldn't draw anything
|
||||||
|
if (x + w > vid.width)
|
||||||
|
w = vid.width-x;
|
||||||
|
if (y + h > vid.height)
|
||||||
|
h = vid.height-y;
|
||||||
|
|
||||||
|
dest = screens[0] + y*vid.width + x;
|
||||||
|
|
||||||
|
if ((alphalevel = ((c & V_ALPHAMASK) >> V_ALPHASHIFT)))
|
||||||
|
{
|
||||||
|
if (alphalevel == 13)
|
||||||
|
alphalevel = hudminusalpha[cv_translucenthud.value];
|
||||||
|
else if (alphalevel == 14)
|
||||||
|
alphalevel = 10 - cv_translucenthud.value;
|
||||||
|
else if (alphalevel == 15)
|
||||||
|
alphalevel = hudplusalpha[cv_translucenthud.value];
|
||||||
|
|
||||||
|
if (alphalevel >= 10)
|
||||||
|
return; // invis
|
||||||
|
}
|
||||||
|
|
||||||
|
c &= 255;
|
||||||
|
|
||||||
|
// Jimita (12-04-2018)
|
||||||
|
w = min(w, vid.width);
|
||||||
|
h = min(h, vid.height);
|
||||||
|
fadetable = ((UINT8 *)transtables + ((alphalevel-1)<<FF_TRANSSHIFT) + (c*256));
|
||||||
|
for (v = 0; v < h; v++, dest += vid.width)
|
||||||
|
for (u = 0; u < w; u++)
|
||||||
|
{
|
||||||
|
if (!alphalevel)
|
||||||
|
dest[u] = consolebgmap[dest[u]];
|
||||||
|
else
|
||||||
|
dest[u] = fadetable[consolebgmap[dest[u]]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Fills a box of pixels using a flat texture as a pattern, scaled to screen size.
|
// Fills a box of pixels using a flat texture as a pattern, scaled to screen size.
|
||||||
//
|
//
|
||||||
|
@ -983,21 +1122,7 @@ void V_DrawFadeConsBack(INT32 plines)
|
||||||
#ifdef HWRENDER // not win32 only 19990829 by Kin
|
#ifdef HWRENDER // not win32 only 19990829 by Kin
|
||||||
if (rendermode != render_soft && rendermode != render_none)
|
if (rendermode != render_soft && rendermode != render_none)
|
||||||
{
|
{
|
||||||
UINT32 hwcolor;
|
UINT32 hwcolor = V_GetHWConsBackColor();
|
||||||
switch (cons_backcolor.value)
|
|
||||||
{
|
|
||||||
case 0: hwcolor = 0xffffff00; break; // White
|
|
||||||
case 1: hwcolor = 0x80808000; break; // Gray
|
|
||||||
case 2: hwcolor = 0x40201000; break; // Brown
|
|
||||||
case 3: hwcolor = 0xff000000; break; // Red
|
|
||||||
case 4: hwcolor = 0xff800000; break; // Orange
|
|
||||||
case 5: hwcolor = 0x80800000; break; // Yellow
|
|
||||||
case 6: hwcolor = 0x00800000; break; // Green
|
|
||||||
case 7: hwcolor = 0x0000ff00; break; // Blue
|
|
||||||
case 8: hwcolor = 0x4080ff00; break; // Cyan
|
|
||||||
// Default green
|
|
||||||
default: hwcolor = 0x00800000; break;
|
|
||||||
}
|
|
||||||
HWR_DrawConsoleBack(hwcolor, plines);
|
HWR_DrawConsoleBack(hwcolor, plines);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1012,7 +1137,7 @@ void V_DrawFadeConsBack(INT32 plines)
|
||||||
|
|
||||||
// Gets string colormap, used for 0x80 color codes
|
// Gets string colormap, used for 0x80 color codes
|
||||||
//
|
//
|
||||||
static const UINT8 *V_GetStringColormap(INT32 colorflags)
|
UINT8 *V_GetStringColormap(INT32 colorflags)
|
||||||
{
|
{
|
||||||
switch ((colorflags & V_CHARCOLORMASK) >> V_CHARCOLORSHIFT)
|
switch ((colorflags & V_CHARCOLORMASK) >> V_CHARCOLORSHIFT)
|
||||||
{
|
{
|
||||||
|
@ -1061,6 +1186,32 @@ void V_DrawCharacter(INT32 x, INT32 y, INT32 c, boolean lowercaseallowed)
|
||||||
V_DrawScaledPatch(x, y, flags, hu_font[c]);
|
V_DrawScaledPatch(x, y, flags, hu_font[c]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Writes a single character for the chat. (draw WHITE if bit 7 set)
|
||||||
|
// Essentially the same as the above but it's small or big depending on what resolution you've chosen to huge..
|
||||||
|
//
|
||||||
|
void V_DrawChatCharacter(INT32 x, INT32 y, INT32 c, boolean lowercaseallowed, UINT8 *colormap)
|
||||||
|
{
|
||||||
|
INT32 w, flags;
|
||||||
|
//const UINT8 *colormap = V_GetStringColormap(c);
|
||||||
|
|
||||||
|
flags = c & ~(V_CHARCOLORMASK | V_PARAMMASK);
|
||||||
|
c &= 0x7f;
|
||||||
|
if (lowercaseallowed)
|
||||||
|
c -= HU_FONTSTART;
|
||||||
|
else
|
||||||
|
c = toupper(c) - HU_FONTSTART;
|
||||||
|
if (c < 0 || c >= HU_FONTSIZE || !hu_font[c])
|
||||||
|
return;
|
||||||
|
|
||||||
|
w = (vid.width < 640 ) ? (SHORT(hu_font[c]->width)/2) : (SHORT(hu_font[c]->width)); // use normal sized characters if we're using a terribly low resolution.
|
||||||
|
if (x + w > vid.width)
|
||||||
|
return;
|
||||||
|
|
||||||
|
V_DrawFixedPatch(x*FRACUNIT, y*FRACUNIT, (vid.width < 640) ? (FRACUNIT) : (FRACUNIT/2), flags, hu_font[c], colormap);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// Precompile a wordwrapped string to any given width.
|
// Precompile a wordwrapped string to any given width.
|
||||||
// This is a muuuch better method than V_WORDWRAP.
|
// This is a muuuch better method than V_WORDWRAP.
|
||||||
char *V_WordWrap(INT32 x, INT32 w, INT32 option, const char *string)
|
char *V_WordWrap(INT32 x, INT32 w, INT32 option, const char *string)
|
||||||
|
|
|
@ -139,6 +139,7 @@ void V_DrawScaledPic (INT32 px1, INT32 py1, INT32 scrn, INT32 lumpnum);
|
||||||
|
|
||||||
// fill a box with a single color
|
// fill a box with a single color
|
||||||
void V_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c);
|
void V_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c);
|
||||||
|
void V_DrawFillConsoleMap(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c);
|
||||||
// fill a box with a flat as a pattern
|
// fill a box with a flat as a pattern
|
||||||
void V_DrawFlatFill(INT32 x, INT32 y, INT32 w, INT32 h, lumpnum_t flatnum);
|
void V_DrawFlatFill(INT32 x, INT32 y, INT32 w, INT32 h, lumpnum_t flatnum);
|
||||||
|
|
||||||
|
@ -149,11 +150,16 @@ void V_DrawFadeConsBack(INT32 plines);
|
||||||
|
|
||||||
// draw a single character
|
// draw a single character
|
||||||
void V_DrawCharacter(INT32 x, INT32 y, INT32 c, boolean lowercaseallowed);
|
void V_DrawCharacter(INT32 x, INT32 y, INT32 c, boolean lowercaseallowed);
|
||||||
|
// draw a single character, but for the chat
|
||||||
|
void V_DrawChatCharacter(INT32 x, INT32 y, INT32 c, boolean lowercaseallowed, UINT8 *colormap);
|
||||||
|
|
||||||
|
UINT8 *V_GetStringColormap(INT32 colorflags);
|
||||||
|
|
||||||
void V_DrawLevelTitle(INT32 x, INT32 y, INT32 option, const char *string);
|
void V_DrawLevelTitle(INT32 x, INT32 y, INT32 option, const char *string);
|
||||||
|
|
||||||
// wordwrap a string using the hu_font
|
// wordwrap a string using the hu_font
|
||||||
char *V_WordWrap(INT32 x, INT32 w, INT32 option, const char *string);
|
char *V_WordWrap(INT32 x, INT32 w, INT32 option, const char *string);
|
||||||
|
UINT8 *V_GetStringColormap(INT32 colorflags);
|
||||||
|
|
||||||
// draw a string using the hu_font
|
// draw a string using the hu_font
|
||||||
void V_DrawString(INT32 x, INT32 y, INT32 option, const char *string);
|
void V_DrawString(INT32 x, INT32 y, INT32 option, const char *string);
|
||||||
|
|
46
src/w_wad.c
46
src/w_wad.c
|
@ -34,6 +34,8 @@
|
||||||
#include "z_zone.h"
|
#include "z_zone.h"
|
||||||
#include "fastcmp.h"
|
#include "fastcmp.h"
|
||||||
|
|
||||||
|
#include "filesrch.h"
|
||||||
|
|
||||||
#include "i_video.h" // rendermode
|
#include "i_video.h" // rendermode
|
||||||
#include "d_netfil.h"
|
#include "d_netfil.h"
|
||||||
#include "dehacked.h"
|
#include "dehacked.h"
|
||||||
|
@ -647,12 +649,22 @@ UINT16 W_InitFile(const char *filename)
|
||||||
restype_t type;
|
restype_t type;
|
||||||
UINT16 numlumps = 0;
|
UINT16 numlumps = 0;
|
||||||
size_t i;
|
size_t i;
|
||||||
size_t packetsize = 0;
|
size_t packetsize;
|
||||||
serverinfo_pak *dummycheck = NULL;
|
|
||||||
UINT8 md5sum[16];
|
UINT8 md5sum[16];
|
||||||
|
boolean important;
|
||||||
|
|
||||||
// Shut the compiler up.
|
if (!(refreshdirmenu & REFRESHDIR_ADDFILE))
|
||||||
(void)dummycheck;
|
refreshdirmenu = REFRESHDIR_NORMAL|REFRESHDIR_ADDFILE; // clean out cons_alerts that happened earlier
|
||||||
|
|
||||||
|
if (refreshdirname)
|
||||||
|
Z_Free(refreshdirname);
|
||||||
|
if (dirmenu)
|
||||||
|
{
|
||||||
|
refreshdirname = Z_StrDup(filename);
|
||||||
|
nameonly(refreshdirname);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
refreshdirname = NULL;
|
||||||
|
|
||||||
//CONS_Debug(DBG_SETUP, "Loading %s\n", filename);
|
//CONS_Debug(DBG_SETUP, "Loading %s\n", filename);
|
||||||
//
|
//
|
||||||
|
@ -661,6 +673,7 @@ UINT16 W_InitFile(const char *filename)
|
||||||
if (numwadfiles >= MAX_WADFILES)
|
if (numwadfiles >= MAX_WADFILES)
|
||||||
{
|
{
|
||||||
CONS_Alert(CONS_ERROR, M_GetText("Maximum wad files reached\n"));
|
CONS_Alert(CONS_ERROR, M_GetText("Maximum wad files reached\n"));
|
||||||
|
refreshdirmenu |= REFRESHDIR_MAX;
|
||||||
return INT16_MAX;
|
return INT16_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -670,21 +683,21 @@ UINT16 W_InitFile(const char *filename)
|
||||||
|
|
||||||
// Check if wad files will overflow fileneededbuffer. Only the filename part
|
// Check if wad files will overflow fileneededbuffer. Only the filename part
|
||||||
// is send in the packet; cf.
|
// is send in the packet; cf.
|
||||||
for (i = 0; i < numwadfiles; i++)
|
// see PutFileNeeded in d_netfil.c
|
||||||
|
if ((important = !W_VerifyNMUSlumps(filename)))
|
||||||
{
|
{
|
||||||
packetsize += nameonlylength(wadfiles[i]->filename);
|
packetsize = packetsizetally + nameonlylength(filename) + 22;
|
||||||
packetsize += 22; // MD5, etc.
|
|
||||||
}
|
|
||||||
|
|
||||||
packetsize += nameonlylength(filename);
|
if (packetsize > MAXFILENEEDED*sizeof(UINT8))
|
||||||
packetsize += 22;
|
{
|
||||||
|
CONS_Alert(CONS_ERROR, M_GetText("Maximum wad files reached\n"));
|
||||||
|
refreshdirmenu |= REFRESHDIR_MAX;
|
||||||
|
if (handle)
|
||||||
|
fclose(handle);
|
||||||
|
return INT16_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
if (packetsize > sizeof(dummycheck->fileneeded))
|
packetsizetally = packetsize;
|
||||||
{
|
|
||||||
CONS_Alert(CONS_ERROR, M_GetText("Maximum wad files reached\n"));
|
|
||||||
if (handle)
|
|
||||||
fclose(handle);
|
|
||||||
return INT16_MAX;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NOMD5
|
#ifndef NOMD5
|
||||||
|
@ -741,6 +754,7 @@ UINT16 W_InitFile(const char *filename)
|
||||||
wadfile->handle = handle;
|
wadfile->handle = handle;
|
||||||
wadfile->numlumps = (UINT16)numlumps;
|
wadfile->numlumps = (UINT16)numlumps;
|
||||||
wadfile->lumpinfo = lumpinfo;
|
wadfile->lumpinfo = lumpinfo;
|
||||||
|
wadfile->important = important;
|
||||||
fseek(handle, 0, SEEK_END);
|
fseek(handle, 0, SEEK_END);
|
||||||
wadfile->filesize = (unsigned)ftell(handle);
|
wadfile->filesize = (unsigned)ftell(handle);
|
||||||
wadfile->type = type;
|
wadfile->type = type;
|
||||||
|
|
|
@ -110,6 +110,7 @@ typedef struct wadfile_s
|
||||||
FILE *handle;
|
FILE *handle;
|
||||||
UINT32 filesize; // for network
|
UINT32 filesize; // for network
|
||||||
UINT8 md5sum[16];
|
UINT8 md5sum[16];
|
||||||
|
boolean important;
|
||||||
} wadfile_t;
|
} wadfile_t;
|
||||||
|
|
||||||
#define WADFILENUM(lumpnum) (UINT16)((lumpnum)>>16) // wad flumpnum>>16) // wad file number in upper word
|
#define WADFILENUM(lumpnum) (UINT16)((lumpnum)>>16) // wad flumpnum>>16) // wad file number in upper word
|
||||||
|
|
Loading…
Reference in a new issue